blob: f59eeb0868ec7d7369367a2e05c672d2167d70f1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530783/*
784 * define short names for the global vendor params
785 * used by __wlan_hdd_cfg80211_get_station_cmd()
786 */
787#define STATION_INVALID \
788 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
789#define STATION_INFO \
790 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
791#define STATION_ASSOC_FAIL_REASON \
792 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530793#define STATION_REMOTE \
794 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530795#define STATION_MAX \
796 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
797
798static const struct nla_policy
799hdd_get_station_policy[STATION_MAX + 1] = {
800 [STATION_INFO] = {.type = NLA_FLAG},
801 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
802};
803
804/**
805 * hdd_get_station_assoc_fail() - Handle get station assoc fail
806 * @hdd_ctx: HDD context within host driver
807 * @wdev: wireless device
808 *
809 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
810 * Validate cmd attributes and send the station info to upper layers.
811 *
812 * Return: Success(0) or reason code for failure
813 */
814static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
815 hdd_adapter_t *adapter)
816{
817 struct sk_buff *skb = NULL;
818 uint32_t nl_buf_len;
819 hdd_station_ctx_t *hdd_sta_ctx;
820
821 nl_buf_len = NLMSG_HDRLEN;
822 nl_buf_len += sizeof(uint32_t);
823 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
824
825 if (!skb) {
826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
827 return -ENOMEM;
828 }
829
830 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
831
832 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
833 hdd_sta_ctx->conn_info.assoc_status_code)) {
834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
835 goto fail;
836 }
837 return cfg80211_vendor_cmd_reply(skb);
838fail:
839 if (skb)
840 kfree_skb(skb);
841 return -EINVAL;
842}
843
844/**
845 * hdd_map_auth_type() - transform auth type specific to
846 * vendor command
847 * @auth_type: csr auth type
848 *
849 * Return: Success(0) or reason code for failure
850 */
851static int hdd_convert_auth_type(uint32_t auth_type)
852{
853 uint32_t ret_val;
854
855 switch (auth_type) {
856 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
857 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
858 break;
859 case eCSR_AUTH_TYPE_SHARED_KEY:
860 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
861 break;
862 case eCSR_AUTH_TYPE_WPA:
863 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
864 break;
865 case eCSR_AUTH_TYPE_WPA_PSK:
866 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
867 break;
868 case eCSR_AUTH_TYPE_AUTOSWITCH:
869 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
870 break;
871 case eCSR_AUTH_TYPE_WPA_NONE:
872 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
873 break;
874 case eCSR_AUTH_TYPE_RSN:
875 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
876 break;
877 case eCSR_AUTH_TYPE_RSN_PSK:
878 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
879 break;
880 case eCSR_AUTH_TYPE_FT_RSN:
881 ret_val = QCA_WLAN_AUTH_TYPE_FT;
882 break;
883 case eCSR_AUTH_TYPE_FT_RSN_PSK:
884 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
885 break;
886 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
887 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
888 break;
889 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
890 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
891 break;
892#ifdef FEATURE_WLAN_ESE
893 case eCSR_AUTH_TYPE_CCKM_WPA:
894 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
895 break;
896 case eCSR_AUTH_TYPE_CCKM_RSN:
897 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
898 break;
899#endif
900 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
901 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
902 break;
903 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
904 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
905 break;
906 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
907 case eCSR_AUTH_TYPE_FAILED:
908 case eCSR_AUTH_TYPE_NONE:
909 default:
910 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
911 break;
912 }
913 return ret_val;
914}
915
916/**
917 * hdd_map_dot_11_mode() - transform dot11mode type specific to
918 * vendor command
919 * @dot11mode: dot11mode
920 *
921 * Return: Success(0) or reason code for failure
922 */
923static int hdd_convert_dot11mode(uint32_t dot11mode)
924{
925 uint32_t ret_val;
926
927 switch (dot11mode) {
928 case eCSR_CFG_DOT11_MODE_11A:
929 ret_val = QCA_WLAN_802_11_MODE_11A;
930 break;
931 case eCSR_CFG_DOT11_MODE_11B:
932 ret_val = QCA_WLAN_802_11_MODE_11B;
933 break;
934 case eCSR_CFG_DOT11_MODE_11G:
935 ret_val = QCA_WLAN_802_11_MODE_11G;
936 break;
937 case eCSR_CFG_DOT11_MODE_11N:
938 ret_val = QCA_WLAN_802_11_MODE_11N;
939 break;
940 case eCSR_CFG_DOT11_MODE_11AC:
941 ret_val = QCA_WLAN_802_11_MODE_11AC;
942 break;
943 case eCSR_CFG_DOT11_MODE_AUTO:
944 case eCSR_CFG_DOT11_MODE_ABG:
945 default:
946 ret_val = QCA_WLAN_802_11_MODE_INVALID;
947 }
948 return ret_val;
949}
950
951/**
952 * hdd_add_tx_bitrate() - add tx bitrate attribute
953 * @skb: pointer to sk buff
954 * @hdd_sta_ctx: pointer to hdd station context
955 * @idx: attribute index
956 *
957 * Return: Success(0) or reason code for failure
958 */
959static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
960 hdd_station_ctx_t *hdd_sta_ctx,
961 int idx)
962{
963 struct nlattr *nla_attr;
964 uint32_t bitrate, bitrate_compat;
965
966 nla_attr = nla_nest_start(skb, idx);
967 if (!nla_attr)
968 goto fail;
969 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
970 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
971
972 /* report 16-bit bitrate only if we can */
973 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
974 if (bitrate > 0 &&
975 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
977 goto fail;
978 }
979 if (bitrate_compat > 0 &&
980 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
982 goto fail;
983 }
984 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
985 hdd_sta_ctx->conn_info.txrate.nss)) {
986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
987 goto fail;
988 }
989 nla_nest_end(skb, nla_attr);
990 return 0;
991fail:
992 return -EINVAL;
993}
994
995/**
996 * hdd_add_sta_info() - add station info attribute
997 * @skb: pointer to sk buff
998 * @hdd_sta_ctx: pointer to hdd station context
999 * @idx: attribute index
1000 *
1001 * Return: Success(0) or reason code for failure
1002 */
1003static int32_t hdd_add_sta_info(struct sk_buff *skb,
1004 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1005{
1006 struct nlattr *nla_attr;
1007
1008 nla_attr = nla_nest_start(skb, idx);
1009 if (!nla_attr)
1010 goto fail;
1011 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1012 (hdd_sta_ctx->conn_info.signal + 100))) {
1013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1014 goto fail;
1015 }
1016 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1017 goto fail;
1018 nla_nest_end(skb, nla_attr);
1019 return 0;
1020fail:
1021 return -EINVAL;
1022}
1023
1024/**
1025 * hdd_add_survey_info() - add survey info attribute
1026 * @skb: pointer to sk buff
1027 * @hdd_sta_ctx: pointer to hdd station context
1028 * @idx: attribute index
1029 *
1030 * Return: Success(0) or reason code for failure
1031 */
1032static int32_t hdd_add_survey_info(struct sk_buff *skb,
1033 hdd_station_ctx_t *hdd_sta_ctx,
1034 int idx)
1035{
1036 struct nlattr *nla_attr;
1037
1038 nla_attr = nla_nest_start(skb, idx);
1039 if (!nla_attr)
1040 goto fail;
1041 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1042 hdd_sta_ctx->conn_info.freq) ||
1043 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1044 (hdd_sta_ctx->conn_info.noise + 100))) {
1045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1046 goto fail;
1047 }
1048 nla_nest_end(skb, nla_attr);
1049 return 0;
1050fail:
1051 return -EINVAL;
1052}
1053
1054/**
1055 * hdd_add_link_standard_info() - add link info attribute
1056 * @skb: pointer to sk buff
1057 * @hdd_sta_ctx: pointer to hdd station context
1058 * @idx: attribute index
1059 *
1060 * Return: Success(0) or reason code for failure
1061 */
1062static int32_t
1063hdd_add_link_standard_info(struct sk_buff *skb,
1064 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1065{
1066 struct nlattr *nla_attr;
1067
1068 nla_attr = nla_nest_start(skb, idx);
1069 if (!nla_attr)
1070 goto fail;
1071 if (nla_put(skb,
1072 NL80211_ATTR_SSID,
1073 hdd_sta_ctx->conn_info.SSID.SSID.length,
1074 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1076 goto fail;
1077 }
1078 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1079 goto fail;
1080 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1081 goto fail;
1082 nla_nest_end(skb, nla_attr);
1083 return 0;
1084fail:
1085 return -EINVAL;
1086}
1087
1088/**
1089 * hdd_add_ap_standard_info() - add ap info attribute
1090 * @skb: pointer to sk buff
1091 * @hdd_sta_ctx: pointer to hdd station context
1092 * @idx: attribute index
1093 *
1094 * Return: Success(0) or reason code for failure
1095 */
1096static int32_t
1097hdd_add_ap_standard_info(struct sk_buff *skb,
1098 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1099{
1100 struct nlattr *nla_attr;
1101
1102 nla_attr = nla_nest_start(skb, idx);
1103 if (!nla_attr)
1104 goto fail;
1105 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1106 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1107 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1108 &hdd_sta_ctx->conn_info.vht_caps)) {
1109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1110 goto fail;
1111 }
1112 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1113 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1114 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1115 &hdd_sta_ctx->conn_info.ht_caps)) {
1116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1117 goto fail;
1118 }
1119 nla_nest_end(skb, nla_attr);
1120 return 0;
1121fail:
1122 return -EINVAL;
1123}
1124
1125/**
1126 * hdd_get_station_info() - send BSS information to supplicant
1127 * @hdd_ctx: pointer to hdd context
1128 * @adapter: pointer to adapter
1129 *
1130 * Return: 0 if success else error status
1131 */
1132static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1133 hdd_adapter_t *adapter)
1134{
1135 struct sk_buff *skb = NULL;
1136 uint8_t *tmp_hs20 = NULL;
1137 uint32_t nl_buf_len;
1138 hdd_station_ctx_t *hdd_sta_ctx;
1139
1140 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1141
1142 nl_buf_len = NLMSG_HDRLEN;
1143 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1144 sizeof(hdd_sta_ctx->conn_info.freq) +
1145 sizeof(hdd_sta_ctx->conn_info.noise) +
1146 sizeof(hdd_sta_ctx->conn_info.signal) +
1147 (sizeof(uint32_t) * 2) +
1148 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1149 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1150 sizeof(hdd_sta_ctx->conn_info.authType) +
1151 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1152 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1153 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1154 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1155 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1156 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1157 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1158 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1159 1);
1160 }
1161 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1162 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1163 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1164 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1165
1166
1167 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1168 if (!skb) {
1169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1170 __func__, __LINE__);
1171 return -ENOMEM;
1172 }
1173
1174 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1175 LINK_INFO_STANDARD_NL80211_ATTR)) {
1176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1177 goto fail;
1178 }
1179 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1180 AP_INFO_STANDARD_NL80211_ATTR)) {
1181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1182 goto fail;
1183 }
1184 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1185 hdd_sta_ctx->conn_info.roam_count) ||
1186 nla_put_u32(skb, INFO_AKM,
1187 hdd_convert_auth_type(
1188 hdd_sta_ctx->conn_info.authType)) ||
1189 nla_put_u32(skb, WLAN802_11_MODE,
1190 hdd_convert_dot11mode(
1191 hdd_sta_ctx->conn_info.dot11Mode))) {
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1193 goto fail;
1194 }
1195 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1196 if (nla_put(skb, HT_OPERATION,
1197 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1198 &hdd_sta_ctx->conn_info.ht_operation)) {
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1200 goto fail;
1201 }
1202 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1203 if (nla_put(skb, VHT_OPERATION,
1204 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1205 &hdd_sta_ctx->conn_info.vht_operation)) {
1206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1207 goto fail;
1208 }
1209 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1210 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1211 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1212 tmp_hs20 + 1)) {
1213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1214 goto fail;
1215 }
1216
1217 return cfg80211_vendor_cmd_reply(skb);
1218fail:
1219 if (skb)
1220 kfree_skb(skb);
1221 return -EINVAL;
1222}
1223
1224/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301225 * hdd_add_survey_info_sap_get_len - get data length used in
1226 * hdd_add_survey_info_sap()
1227 *
1228 * This function calculates the data length used in hdd_add_survey_info_sap()
1229 *
1230 * Return: total data length used in hdd_add_survey_info_sap()
1231 */
1232static uint32_t hdd_add_survey_info_sap_get_len(void)
1233{
1234 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1235}
1236
1237/**
1238 * hdd_add_survey_info - add survey info attribute
1239 * @skb: pointer to response skb buffer
1240 * @stainfo: station information
1241 * @idx: attribute type index for nla_next_start()
1242 *
1243 * This function adds survey info attribute to response skb buffer
1244 *
1245 * Return : 0 on success and errno on failure
1246 */
1247static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1248 struct hdd_cache_sta_info *stainfo,
1249 int idx)
1250{
1251 struct nlattr *nla_attr;
1252
1253 nla_attr = nla_nest_start(skb, idx);
1254 if (!nla_attr)
1255 goto fail;
1256 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1257 stainfo->freq)) {
1258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1259 FL("put fail"));
1260 goto fail;
1261 }
1262 nla_nest_end(skb, nla_attr);
1263 return 0;
1264fail:
1265 return -EINVAL;
1266}
1267
1268/**
1269 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1270 * hdd_add_tx_bitrate_sap()
1271 *
1272 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1273 *
1274 * Return: total data length used in hdd_add_tx_bitrate_sap()
1275 */
1276static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1277{
1278 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1279}
1280
1281/**
1282 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1283 * @skb: pointer to response skb buffer
1284 * @stainfo: station information
1285 * @idx: attribute type index for nla_next_start()
1286 *
1287 * This function adds vht nss attribute to response skb buffer
1288 *
1289 * Return : 0 on success and errno on failure
1290 */
1291static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1292 struct hdd_cache_sta_info *stainfo,
1293 int idx)
1294{
1295 struct nlattr *nla_attr;
1296
1297 nla_attr = nla_nest_start(skb, idx);
1298 if (!nla_attr)
1299 goto fail;
1300
1301 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1302 stainfo->nss)) {
1303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1304 FL("put fail"));
1305 goto fail;
1306 }
1307 nla_nest_end(skb, nla_attr);
1308 return 0;
1309fail:
1310 return -EINVAL;
1311}
1312
1313/**
1314 * hdd_add_sta_info_sap_get_len - get data length used in
1315 * hdd_add_sta_info_sap()
1316 *
1317 * This function calculates the data length used in hdd_add_sta_info_sap()
1318 *
1319 * Return: total data length used in hdd_add_sta_info_sap()
1320 */
1321static uint32_t hdd_add_sta_info_sap_get_len(void)
1322{
1323 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1324 hdd_add_tx_bitrate_sap_get_len());
1325}
1326
1327/**
1328 * hdd_add_sta_info_sap - add sta signal info attribute
1329 * @skb: pointer to response skb buffer
1330 * @rssi: peer rssi value
1331 * @stainfo: station information
1332 * @idx: attribute type index for nla_next_start()
1333 *
1334 * This function adds sta signal attribute to response skb buffer
1335 *
1336 * Return : 0 on success and errno on failure
1337 */
1338static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1339 struct hdd_cache_sta_info *stainfo, int idx)
1340{
1341 struct nlattr *nla_attr;
1342
1343 nla_attr = nla_nest_start(skb, idx);
1344 if (!nla_attr)
1345 goto fail;
1346
1347 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, rssi)) {
1348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1349 FL("put fail"));
1350 goto fail;
1351 }
1352 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1354 FL("put fail"));
1355 goto fail;
1356 }
1357
1358 nla_nest_end(skb, nla_attr);
1359 return 0;
1360fail:
1361 return -EINVAL;
1362}
1363
1364/**
1365 * hdd_add_link_standard_info_sap_get_len - get data length used in
1366 * hdd_add_link_standard_info_sap()
1367 *
1368 * This function calculates the data length used in
1369 * hdd_add_link_standard_info_sap()
1370 *
1371 * Return: total data length used in hdd_add_link_standard_info_sap()
1372 */
1373static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1374{
1375 return ((NLA_HDRLEN) +
1376 hdd_add_survey_info_sap_get_len() +
1377 hdd_add_sta_info_sap_get_len() +
1378 (sizeof(uint32_t) + NLA_HDRLEN));
1379}
1380
1381/**
1382 * hdd_add_link_standard_info_sap - add add link info attribut
1383 * @skb: pointer to response skb buffer
1384 * @stainfo: station information
1385 * @idx: attribute type index for nla_next_start()
1386 *
1387 * This function adds link info attribut to response skb buffer
1388 *
1389 * Return : 0 on success and errno on failure
1390 */
1391static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1392 struct hdd_cache_sta_info *stainfo,
1393 int idx)
1394{
1395 struct nlattr *nla_attr;
1396
1397 nla_attr = nla_nest_start(skb, idx);
1398 if (!nla_attr)
1399 goto fail;
1400 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1401 goto fail;
1402 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1403 goto fail;
1404
1405 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1407 FL("put fail"));
1408 goto fail;
1409 }
1410
1411 nla_nest_end(skb, nla_attr);
1412 return 0;
1413fail:
1414 return -EINVAL;
1415}
1416
1417/**
1418 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1419 * hdd_add_ap_standard_info_sap()
1420 * @stainfo: station information
1421 *
1422 * This function calculates the data length used in
1423 * hdd_add_ap_standard_info_sap()
1424 *
1425 * Return: total data length used in hdd_add_ap_standard_info_sap()
1426 */
1427static uint32_t hdd_add_ap_standard_info_sap_get_len(
1428 struct hdd_cache_sta_info *stainfo)
1429{
1430 uint32_t len;
1431
1432 len = NLA_HDRLEN;
1433 if (stainfo->vht_present)
1434 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1435 if (stainfo->ht_present)
1436 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1437
1438 return len;
1439}
1440
1441/**
1442 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1443 * @skb: pointer to response skb buffer
1444 * @stainfo: station information
1445 * @idx: attribute type index for nla_next_start()
1446 *
1447 * This function adds HT and VHT info attributes to response skb buffer
1448 *
1449 * Return : 0 on success and errno on failure
1450 */
1451static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1452 struct hdd_cache_sta_info *stainfo,
1453 int idx)
1454{
1455 struct nlattr *nla_attr;
1456
1457 nla_attr = nla_nest_start(skb, idx);
1458 if (!nla_attr)
1459 goto fail;
1460
1461 if (stainfo->vht_present) {
1462 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1463 sizeof(stainfo->vht_caps),
1464 &stainfo->vht_caps)) {
1465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1466 FL("put fail"));
1467 goto fail;
1468 }
1469 }
1470 if (stainfo->ht_present) {
1471 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1472 sizeof(stainfo->ht_caps),
1473 &stainfo->ht_caps)) {
1474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1475 FL("put fail"));
1476 goto fail;
1477 }
1478 }
1479 nla_nest_end(skb, nla_attr);
1480 return 0;
1481fail:
1482 return -EINVAL;
1483}
1484
1485/**
1486 * hdd_decode_ch_width - decode channel band width based
1487 * @ch_width: encoded enum value holding channel band width
1488 *
1489 * This function decodes channel band width from the given encoded enum value.
1490 *
1491 * Returns: decoded channel band width.
1492 */
1493static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1494{
1495 switch (ch_width) {
1496 case 0:
1497 return 20;
1498 case 1:
1499 return 40;
1500 case 2:
1501 return 80;
1502 default:
1503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1504 "invalid enum: %d", ch_width);
1505 return 20;
1506 }
1507}
1508
1509/**
1510 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1511 * @hdd_ctx: hdd context
1512 * @adapter: hostapd interface
1513 * @mac_addr: mac address of requested peer
1514 *
1515 * This function collect and indicate the cached(deleted) peer's info
1516 *
1517 * Return: 0 on success, otherwise error value
1518 */
1519static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1520 hdd_adapter_t *adapter,
1521 v_MACADDR_t mac_addr)
1522{
1523 struct hdd_cache_sta_info *stainfo;
1524 struct sk_buff *skb = NULL;
1525 uint32_t nl_buf_len;
1526 uint8_t cw;
1527 ptSapContext sap_ctx;
1528 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1529
1530 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1531 if(sap_ctx == NULL){
1532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1533 FL("psapCtx is NULL"));
1534 return -ENOENT;
1535 }
1536
1537 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1538 mac_addr.bytes);
1539 if (!stainfo) {
1540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1541 "peer " MAC_ADDRESS_STR " not found",
1542 MAC_ADDR_ARRAY(mac_addr.bytes));
1543 return -EINVAL;
1544 }
1545 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1547 "peer " MAC_ADDRESS_STR " is in connected state",
1548 MAC_ADDR_ARRAY(mac_addr.bytes));
1549 return -EINVAL;
1550 }
1551
1552
1553 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1554 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1555 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1556 (sizeof(cw) + NLA_HDRLEN) +
1557 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1558
1559 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1560 if (!skb) {
1561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1562 return -ENOMEM;
1563 }
1564
1565 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1566 LINK_INFO_STANDARD_NL80211_ATTR)) {
1567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1568 goto fail;
1569 }
1570
1571 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1572 AP_INFO_STANDARD_NL80211_ATTR)) {
1573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1574 goto fail;
1575 }
1576
1577 /* upper layer expects decoded channel BW */
1578 cw = hdd_decode_ch_width(stainfo->ch_width);
1579 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1580 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1582 goto fail;
1583 }
1584 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
1585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1586 goto fail;
1587 }
1588
1589 vos_mem_zero(stainfo, sizeof(*stainfo));
1590
1591 return cfg80211_vendor_cmd_reply(skb);
1592fail:
1593 if (skb)
1594 kfree_skb(skb);
1595
1596 return -EINVAL;
1597}
1598
1599/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301600 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1601 * @wiphy: corestack handler
1602 * @wdev: wireless device
1603 * @data: data
1604 * @data_len: data length
1605 *
1606 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1607 * Validate cmd attributes and send the station info to upper layers.
1608 *
1609 * Return: Success(0) or reason code for failure
1610 */
1611static int32_t
1612__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1613 struct wireless_dev *wdev,
1614 const void *data,
1615 int data_len)
1616{
1617 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1618 struct net_device *dev = wdev->netdev;
1619 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1620 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1621 int32_t status;
1622
1623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1624 if (VOS_FTM_MODE == hdd_get_conparam()) {
1625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1626 status = -EPERM;
1627 goto out;
1628 }
1629
1630 status = wlan_hdd_validate_context(hdd_ctx);
1631 if (0 != status)
1632 goto out;
1633
1634
1635 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1636 data, data_len, NULL);
1637 if (status) {
1638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1639 goto out;
1640 }
1641
1642 /* Parse and fetch Command Type*/
1643 if (tb[STATION_INFO]) {
1644 status = hdd_get_station_info(hdd_ctx, adapter);
1645 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1646 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301647 } else if (tb[STATION_REMOTE]) {
1648 v_MACADDR_t mac_addr;
1649
1650 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1651 adapter->device_mode != WLAN_HDD_P2P_GO) {
1652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1653 adapter->device_mode);
1654 status = -EINVAL;
1655 goto out;
1656 }
1657
1658 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1659 VOS_MAC_ADDRESS_LEN);
1660
1661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1662 MAC_ADDR_ARRAY(mac_addr.bytes));
1663
1664 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1665 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301666 } else {
1667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1668 status = -EINVAL;
1669 goto out;
1670 }
1671 EXIT();
1672out:
1673 return status;
1674}
1675
1676/**
1677 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1678 * @wiphy: corestack handler
1679 * @wdev: wireless device
1680 * @data: data
1681 * @data_len: data length
1682 *
1683 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1684 * Validate cmd attributes and send the station info to upper layers.
1685 *
1686 * Return: Success(0) or reason code for failure
1687 */
1688static int32_t
1689hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1690 struct wireless_dev *wdev,
1691 const void *data,
1692 int data_len)
1693{
1694 int ret;
1695
1696 vos_ssr_protect(__func__);
1697 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1698 vos_ssr_unprotect(__func__);
1699
1700 return ret;
1701}
1702
1703/*
1704 * undef short names defined for get station command
1705 * used by __wlan_hdd_cfg80211_get_station_cmd()
1706 */
1707#undef STATION_INVALID
1708#undef STATION_INFO
1709#undef STATION_ASSOC_FAIL_REASON
1710#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301711
Sunil Duttc69bccb2014-05-26 21:30:20 +05301712#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1713
1714static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1715 struct sk_buff *vendor_event)
1716{
1717 if (nla_put_u8(vendor_event,
1718 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1719 stats->rate.preamble) ||
1720 nla_put_u8(vendor_event,
1721 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1722 stats->rate.nss) ||
1723 nla_put_u8(vendor_event,
1724 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1725 stats->rate.bw) ||
1726 nla_put_u8(vendor_event,
1727 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1728 stats->rate.rateMcsIdx) ||
1729 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1730 stats->rate.bitrate ) ||
1731 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1732 stats->txMpdu ) ||
1733 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1734 stats->rxMpdu ) ||
1735 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1736 stats->mpduLost ) ||
1737 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1738 stats->retries) ||
1739 nla_put_u32(vendor_event,
1740 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1741 stats->retriesShort ) ||
1742 nla_put_u32(vendor_event,
1743 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1744 stats->retriesLong))
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1748 return FALSE;
1749 }
1750 return TRUE;
1751}
1752
1753static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1754 struct sk_buff *vendor_event)
1755{
1756 u32 i = 0;
1757 struct nlattr *rateInfo;
1758 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1759 stats->type) ||
1760 nla_put(vendor_event,
1761 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1762 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1763 nla_put_u32(vendor_event,
1764 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1765 stats->capabilities) ||
1766 nla_put_u32(vendor_event,
1767 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1768 stats->numRate))
1769 {
1770 hddLog(VOS_TRACE_LEVEL_ERROR,
1771 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1772 goto error;
1773 }
1774
1775 rateInfo = nla_nest_start(vendor_event,
1776 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301777 if(!rateInfo)
1778 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 for (i = 0; i < stats->numRate; i++)
1780 {
1781 struct nlattr *rates;
1782 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1783 stats->rateStats +
1784 (i * sizeof(tSirWifiRateStat)));
1785 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301786 if(!rates)
1787 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788
1789 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1790 {
1791 hddLog(VOS_TRACE_LEVEL_ERROR,
1792 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1793 return FALSE;
1794 }
1795 nla_nest_end(vendor_event, rates);
1796 }
1797 nla_nest_end(vendor_event, rateInfo);
1798
1799 return TRUE;
1800error:
1801 return FALSE;
1802}
1803
1804static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1805 struct sk_buff *vendor_event)
1806{
1807 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1808 stats->ac ) ||
1809 nla_put_u32(vendor_event,
1810 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1811 stats->txMpdu ) ||
1812 nla_put_u32(vendor_event,
1813 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1814 stats->rxMpdu ) ||
1815 nla_put_u32(vendor_event,
1816 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1817 stats->txMcast ) ||
1818 nla_put_u32(vendor_event,
1819 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1820 stats->rxMcast ) ||
1821 nla_put_u32(vendor_event,
1822 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1823 stats->rxAmpdu ) ||
1824 nla_put_u32(vendor_event,
1825 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1826 stats->txAmpdu ) ||
1827 nla_put_u32(vendor_event,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1829 stats->mpduLost )||
1830 nla_put_u32(vendor_event,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1832 stats->retries ) ||
1833 nla_put_u32(vendor_event,
1834 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1835 stats->retriesShort ) ||
1836 nla_put_u32(vendor_event,
1837 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1838 stats->retriesLong ) ||
1839 nla_put_u32(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1841 stats->contentionTimeMin ) ||
1842 nla_put_u32(vendor_event,
1843 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1844 stats->contentionTimeMax ) ||
1845 nla_put_u32(vendor_event,
1846 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1847 stats->contentionTimeAvg ) ||
1848 nla_put_u32(vendor_event,
1849 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1850 stats->contentionNumSamples ))
1851 {
1852 hddLog(VOS_TRACE_LEVEL_ERROR,
1853 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1854 return FALSE;
1855 }
1856 return TRUE;
1857}
1858
1859static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1860 struct sk_buff *vendor_event)
1861{
Dino Myclec8f3f332014-07-21 16:48:27 +05301862 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301863 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1864 nla_put(vendor_event,
1865 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1866 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1867 nla_put_u32(vendor_event,
1868 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1869 stats->state ) ||
1870 nla_put_u32(vendor_event,
1871 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1872 stats->roaming ) ||
1873 nla_put_u32(vendor_event,
1874 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1875 stats->capabilities ) ||
1876 nla_put(vendor_event,
1877 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1878 strlen(stats->ssid), stats->ssid) ||
1879 nla_put(vendor_event,
1880 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1881 WNI_CFG_BSSID_LEN, stats->bssid) ||
1882 nla_put(vendor_event,
1883 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1884 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1885 nla_put(vendor_event,
1886 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1887 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1888 )
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR,
1891 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1892 return FALSE;
1893 }
1894 return TRUE;
1895}
1896
Dino Mycle3b9536d2014-07-09 22:05:24 +05301897static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1898 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 struct sk_buff *vendor_event)
1900{
1901 int i = 0;
1902 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1904 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301905 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301906
Sunil Duttc69bccb2014-05-26 21:30:20 +05301907 if (FALSE == put_wifi_interface_info(
1908 &pWifiIfaceStat->info,
1909 vendor_event))
1910 {
1911 hddLog(VOS_TRACE_LEVEL_ERROR,
1912 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1913 return FALSE;
1914
1915 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301916 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1917 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1918 if (NULL == pWifiIfaceStatTL)
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1921 return FALSE;
1922 }
1923
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301924 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1925 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1926 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1927 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1928
1929 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1930 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1931 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1932 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301933
1934 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1935 {
1936 if (VOS_STATUS_SUCCESS ==
1937 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1938 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1939 {
1940 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1941 * obtained from TL structure
1942 */
1943
1944 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1945 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301946 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1947
Srinivas Dasari98947432014-11-07 19:41:24 +05301948 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1949 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1950 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1951 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1952 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1953 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1954 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1955 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301956
Srinivas Dasari98947432014-11-07 19:41:24 +05301957 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1958 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1959 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1960 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1961 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1962 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1963 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1964 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301965
Srinivas Dasari98947432014-11-07 19:41:24 +05301966 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1967 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1968 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1969 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1970 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1971 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1972 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1973 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301974 }
1975 else
1976 {
1977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1978 }
1979
Dino Mycle3b9536d2014-07-09 22:05:24 +05301980 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1981 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1982 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1983 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1984 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1985 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1986 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1987 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1988 }
1989 else
1990 {
1991 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1992 }
1993
1994
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995
1996 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301997 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1998 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1999 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2001 pWifiIfaceStat->beaconRx) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2004 pWifiIfaceStat->mgmtRx) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2007 pWifiIfaceStat->mgmtActionRx) ||
2008 nla_put_u32(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2010 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302011 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2013 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302014 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2016 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302017 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2019 pWifiIfaceStat->rssiAck))
2020 {
2021 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302022 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2023 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302024 return FALSE;
2025 }
2026
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302027#ifdef FEATURE_EXT_LL_STAT
2028 /*
2029 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2030 * then host should send Leaky AP stats to upper layer,
2031 * otherwise no need to send these stats.
2032 */
2033 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2034 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2035 )
2036 {
2037 hddLog(VOS_TRACE_LEVEL_INFO,
2038 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2039 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2040 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2041 pWifiIfaceStat->leakyApStat.rx_leak_window,
2042 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2043 if (nla_put_u32(vendor_event,
2044 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2045 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2046 nla_put_u32(vendor_event,
2047 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2048 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2049 nla_put_u32(vendor_event,
2050 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2051 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
2052 nla_put_u64(vendor_event,
2053 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2054 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR,
2057 FL("EXT_LL_STAT put fail"));
2058 vos_mem_free(pWifiIfaceStatTL);
2059 return FALSE;
2060 }
2061 }
2062#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302063 wmmInfo = nla_nest_start(vendor_event,
2064 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302065 if(!wmmInfo)
2066 {
2067 vos_mem_free(pWifiIfaceStatTL);
2068 return FALSE;
2069 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 for (i = 0; i < WIFI_AC_MAX; i++)
2071 {
2072 struct nlattr *wmmStats;
2073 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302074 if(!wmmStats)
2075 {
2076 vos_mem_free(pWifiIfaceStatTL);
2077 return FALSE;
2078 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302079 if (FALSE == put_wifi_wmm_ac_stat(
2080 &pWifiIfaceStat->AccessclassStats[i],
2081 vendor_event))
2082 {
2083 hddLog(VOS_TRACE_LEVEL_ERROR,
2084 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302085 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 return FALSE;
2087 }
2088
2089 nla_nest_end(vendor_event, wmmStats);
2090 }
2091 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302092 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302093 return TRUE;
2094}
2095
2096static tSirWifiInterfaceMode
2097 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2098{
2099 switch (deviceMode)
2100 {
2101 case WLAN_HDD_INFRA_STATION:
2102 return WIFI_INTERFACE_STA;
2103 case WLAN_HDD_SOFTAP:
2104 return WIFI_INTERFACE_SOFTAP;
2105 case WLAN_HDD_P2P_CLIENT:
2106 return WIFI_INTERFACE_P2P_CLIENT;
2107 case WLAN_HDD_P2P_GO:
2108 return WIFI_INTERFACE_P2P_GO;
2109 case WLAN_HDD_IBSS:
2110 return WIFI_INTERFACE_IBSS;
2111 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302112 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302113 }
2114}
2115
2116static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2117 tpSirWifiInterfaceInfo pInfo)
2118{
2119 v_U8_t *staMac = NULL;
2120 hdd_station_ctx_t *pHddStaCtx;
2121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2122 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2123
2124 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2125
2126 vos_mem_copy(pInfo->macAddr,
2127 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2128
2129 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2130 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2131 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2132 {
2133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2134 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2135 {
2136 pInfo->state = WIFI_DISCONNECTED;
2137 }
2138 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2139 {
2140 hddLog(VOS_TRACE_LEVEL_ERROR,
2141 "%s: Session ID %d, Connection is in progress", __func__,
2142 pAdapter->sessionId);
2143 pInfo->state = WIFI_ASSOCIATING;
2144 }
2145 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2146 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2147 {
2148 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2149 hddLog(VOS_TRACE_LEVEL_ERROR,
2150 "%s: client " MAC_ADDRESS_STR
2151 " is in the middle of WPS/EAPOL exchange.", __func__,
2152 MAC_ADDR_ARRAY(staMac));
2153 pInfo->state = WIFI_AUTHENTICATING;
2154 }
2155 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2156 {
2157 pInfo->state = WIFI_ASSOCIATED;
2158 vos_mem_copy(pInfo->bssid,
2159 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2160 vos_mem_copy(pInfo->ssid,
2161 pHddStaCtx->conn_info.SSID.SSID.ssId,
2162 pHddStaCtx->conn_info.SSID.SSID.length);
2163 //NULL Terminate the string.
2164 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2165 }
2166 }
2167 vos_mem_copy(pInfo->countryStr,
2168 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2169
2170 vos_mem_copy(pInfo->apCountryStr,
2171 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2172
2173 return TRUE;
2174}
2175
2176/*
2177 * hdd_link_layer_process_peer_stats () - This function is called after
2178 * receiving Link Layer Peer statistics from FW.This function converts
2179 * the firmware data to the NL data and sends the same to the kernel/upper
2180 * layers.
2181 */
2182static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2183 v_VOID_t *pData)
2184{
2185 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 tpSirWifiPeerStat pWifiPeerStat;
2187 tpSirWifiPeerInfo pWifiPeerInfo;
2188 struct nlattr *peerInfo;
2189 struct sk_buff *vendor_event;
2190 int status, i;
2191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302192 ENTER();
2193
Sunil Duttc69bccb2014-05-26 21:30:20 +05302194 status = wlan_hdd_validate_context(pHddCtx);
2195 if (0 != status)
2196 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302197 return;
2198 }
2199
2200 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2201
2202 hddLog(VOS_TRACE_LEVEL_INFO,
2203 "LL_STATS_PEER_ALL : numPeers %u",
2204 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302205 /*
2206 * Allocate a size of 4096 for the peer stats comprising
2207 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2208 * sizeof (tSirWifiRateStat).Each field is put with an
2209 * NL attribute.The size of 4096 is considered assuming
2210 * that number of rates shall not exceed beyond 50 with
2211 * the sizeof (tSirWifiRateStat) being 32.
2212 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302213 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2214 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302215 if (!vendor_event)
2216 {
2217 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302218 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219 __func__);
2220 return;
2221 }
2222 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302223 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2224 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2225 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302226 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2227 pWifiPeerStat->numPeers))
2228 {
2229 hddLog(VOS_TRACE_LEVEL_ERROR,
2230 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2231 kfree_skb(vendor_event);
2232 return;
2233 }
2234
2235 peerInfo = nla_nest_start(vendor_event,
2236 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302237 if(!peerInfo)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR,
2240 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2241 __func__);
2242 kfree_skb(vendor_event);
2243 return;
2244 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302245
2246 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2247 pWifiPeerStat->peerInfo);
2248
2249 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2250 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302251 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302252 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302253
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302254 if(!peers)
2255 {
2256 hddLog(VOS_TRACE_LEVEL_ERROR,
2257 "%s: peer stats put fail",
2258 __func__);
2259 kfree_skb(vendor_event);
2260 return;
2261 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302262 if (FALSE == put_wifi_peer_info(
2263 pWifiPeerInfo, vendor_event))
2264 {
2265 hddLog(VOS_TRACE_LEVEL_ERROR,
2266 "%s: put_wifi_peer_info put fail", __func__);
2267 kfree_skb(vendor_event);
2268 return;
2269 }
2270
2271 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2272 pWifiPeerStat->peerInfo +
2273 (i * sizeof(tSirWifiPeerInfo)) +
2274 (numRate * sizeof (tSirWifiRateStat)));
2275 nla_nest_end(vendor_event, peers);
2276 }
2277 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302278 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302279 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280}
2281
2282/*
2283 * hdd_link_layer_process_iface_stats () - This function is called after
2284 * receiving Link Layer Interface statistics from FW.This function converts
2285 * the firmware data to the NL data and sends the same to the kernel/upper
2286 * layers.
2287 */
2288static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2289 v_VOID_t *pData)
2290{
2291 tpSirWifiIfaceStat pWifiIfaceStat;
2292 struct sk_buff *vendor_event;
2293 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2294 int status;
2295
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302296 ENTER();
2297
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298 status = wlan_hdd_validate_context(pHddCtx);
2299 if (0 != status)
2300 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302301 return;
2302 }
2303 /*
2304 * Allocate a size of 4096 for the interface stats comprising
2305 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2306 * assuming that all these fit with in the limit.Please take
2307 * a call on the limit based on the data requirements on
2308 * interface statistics.
2309 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302310 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2311 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302312 if (!vendor_event)
2313 {
2314 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302315 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302316 return;
2317 }
2318
2319 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2320
Dino Mycle3b9536d2014-07-09 22:05:24 +05302321
2322 if (FALSE == hdd_get_interface_info( pAdapter,
2323 &pWifiIfaceStat->info))
2324 {
2325 hddLog(VOS_TRACE_LEVEL_ERROR,
2326 FL("hdd_get_interface_info get fail") );
2327 kfree_skb(vendor_event);
2328 return;
2329 }
2330
2331 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2332 vendor_event))
2333 {
2334 hddLog(VOS_TRACE_LEVEL_ERROR,
2335 FL("put_wifi_iface_stats fail") );
2336 kfree_skb(vendor_event);
2337 return;
2338 }
2339
Sunil Duttc69bccb2014-05-26 21:30:20 +05302340 hddLog(VOS_TRACE_LEVEL_INFO,
2341 "WMI_LINK_STATS_IFACE Data");
2342
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302343 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302344
2345 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302346}
2347
2348/*
2349 * hdd_link_layer_process_radio_stats () - This function is called after
2350 * receiving Link Layer Radio statistics from FW.This function converts
2351 * the firmware data to the NL data and sends the same to the kernel/upper
2352 * layers.
2353 */
2354static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2355 v_VOID_t *pData)
2356{
2357 int status, i;
2358 tpSirWifiRadioStat pWifiRadioStat;
2359 tpSirWifiChannelStats pWifiChannelStats;
2360 struct sk_buff *vendor_event;
2361 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2362 struct nlattr *chList;
2363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302364 ENTER();
2365
Sunil Duttc69bccb2014-05-26 21:30:20 +05302366 status = wlan_hdd_validate_context(pHddCtx);
2367 if (0 != status)
2368 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302369 return;
2370 }
2371 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2372
2373 hddLog(VOS_TRACE_LEVEL_INFO,
2374 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302375 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376 " radio is %d onTime is %u "
2377 " txTime is %u rxTime is %u "
2378 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302380 " onTimePnoScan is %u onTimeHs20 is %u "
2381 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302382 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302383 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2384 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2385 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302387 pWifiRadioStat->onTimeRoamScan,
2388 pWifiRadioStat->onTimePnoScan,
2389 pWifiRadioStat->onTimeHs20,
2390 pWifiRadioStat->numChannels);
2391 /*
2392 * Allocate a size of 4096 for the Radio stats comprising
2393 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2394 * (tSirWifiChannelStats).Each channel data is put with an
2395 * NL attribute.The size of 4096 is considered assuming that
2396 * number of channels shall not exceed beyond 60 with the
2397 * sizeof (tSirWifiChannelStats) being 24 bytes.
2398 */
2399
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302400 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2401 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302402 if (!vendor_event)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302405 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302406 return;
2407 }
2408
2409 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302410 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2411 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2412 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302413 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2414 pWifiRadioStat->radio) ||
2415 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302416 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2417 NUM_RADIOS) ||
2418 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302419 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2420 pWifiRadioStat->onTime) ||
2421 nla_put_u32(vendor_event,
2422 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2423 pWifiRadioStat->txTime) ||
2424 nla_put_u32(vendor_event,
2425 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2426 pWifiRadioStat->rxTime) ||
2427 nla_put_u32(vendor_event,
2428 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2429 pWifiRadioStat->onTimeScan) ||
2430 nla_put_u32(vendor_event,
2431 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2432 pWifiRadioStat->onTimeNbd) ||
2433 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2435 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302436 nla_put_u32(vendor_event,
2437 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2438 pWifiRadioStat->onTimeRoamScan) ||
2439 nla_put_u32(vendor_event,
2440 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2441 pWifiRadioStat->onTimePnoScan) ||
2442 nla_put_u32(vendor_event,
2443 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2444 pWifiRadioStat->onTimeHs20) ||
2445 nla_put_u32(vendor_event,
2446 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2447 pWifiRadioStat->numChannels))
2448 {
2449 hddLog(VOS_TRACE_LEVEL_ERROR,
2450 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2451 kfree_skb(vendor_event);
2452 return ;
2453 }
2454
2455 chList = nla_nest_start(vendor_event,
2456 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302457 if(!chList)
2458 {
2459 hddLog(VOS_TRACE_LEVEL_ERROR,
2460 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2461 __func__);
2462 kfree_skb(vendor_event);
2463 return;
2464 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302465 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2466 {
2467 struct nlattr *chInfo;
2468
2469 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2470 pWifiRadioStat->channels +
2471 (i * sizeof(tSirWifiChannelStats)));
2472
Sunil Duttc69bccb2014-05-26 21:30:20 +05302473 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302474 if(!chInfo)
2475 {
2476 hddLog(VOS_TRACE_LEVEL_ERROR,
2477 "%s: failed to put chInfo",
2478 __func__);
2479 kfree_skb(vendor_event);
2480 return;
2481 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302482
2483 if (nla_put_u32(vendor_event,
2484 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2485 pWifiChannelStats->channel.width) ||
2486 nla_put_u32(vendor_event,
2487 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2488 pWifiChannelStats->channel.centerFreq) ||
2489 nla_put_u32(vendor_event,
2490 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2491 pWifiChannelStats->channel.centerFreq0) ||
2492 nla_put_u32(vendor_event,
2493 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2494 pWifiChannelStats->channel.centerFreq1) ||
2495 nla_put_u32(vendor_event,
2496 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2497 pWifiChannelStats->onTime) ||
2498 nla_put_u32(vendor_event,
2499 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2500 pWifiChannelStats->ccaBusyTime))
2501 {
2502 hddLog(VOS_TRACE_LEVEL_ERROR,
2503 FL("cfg80211_vendor_event_alloc failed") );
2504 kfree_skb(vendor_event);
2505 return ;
2506 }
2507 nla_nest_end(vendor_event, chInfo);
2508 }
2509 nla_nest_end(vendor_event, chList);
2510
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302511 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302512
2513 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302514 return;
2515}
2516
2517/*
2518 * hdd_link_layer_stats_ind_callback () - This function is called after
2519 * receiving Link Layer indications from FW.This callback converts the firmware
2520 * data to the NL data and send the same to the kernel/upper layers.
2521 */
2522static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2523 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302524 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525{
Dino Mycled3d50022014-07-07 12:58:25 +05302526 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2527 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302529 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302530 int status;
2531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302532 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302533
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302534 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302535 if (0 != status)
2536 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302537 return;
2538 }
2539
Dino Mycled3d50022014-07-07 12:58:25 +05302540 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2541 if (NULL == pAdapter)
2542 {
2543 hddLog(VOS_TRACE_LEVEL_ERROR,
2544 FL(" MAC address %pM does not exist with host"),
2545 macAddr);
2546 return;
2547 }
2548
Sunil Duttc69bccb2014-05-26 21:30:20 +05302549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302550 "%s: Interface: %s LLStats indType: %d", __func__,
2551 pAdapter->dev->name, indType);
2552
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553 switch (indType)
2554 {
2555 case SIR_HAL_LL_STATS_RESULTS_RSP:
2556 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302557 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302558 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2559 "respId = %u, moreResultToFollow = %u",
2560 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2561 macAddr, linkLayerStatsResults->respId,
2562 linkLayerStatsResults->moreResultToFollow);
2563
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302564 spin_lock(&hdd_context_lock);
2565 context = &pHddCtx->ll_stats_context;
2566 /* validate response received from target */
2567 if ((context->request_id != linkLayerStatsResults->respId) ||
2568 !(context->request_bitmap & linkLayerStatsResults->paramId))
2569 {
2570 spin_unlock(&hdd_context_lock);
2571 hddLog(LOGE,
2572 FL("Error : Request id %d response id %d request bitmap 0x%x"
2573 "response bitmap 0x%x"),
2574 context->request_id, linkLayerStatsResults->respId,
2575 context->request_bitmap, linkLayerStatsResults->paramId);
2576 return;
2577 }
2578 spin_unlock(&hdd_context_lock);
2579
Sunil Duttc69bccb2014-05-26 21:30:20 +05302580 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2581 {
2582 hdd_link_layer_process_radio_stats(pAdapter,
2583 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302584 spin_lock(&hdd_context_lock);
2585 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2586 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302587 }
2588 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2589 {
2590 hdd_link_layer_process_iface_stats(pAdapter,
2591 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302592 spin_lock(&hdd_context_lock);
2593 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2594 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302595 }
2596 else if ( linkLayerStatsResults->paramId &
2597 WMI_LINK_STATS_ALL_PEER )
2598 {
2599 hdd_link_layer_process_peer_stats(pAdapter,
2600 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302601 spin_lock(&hdd_context_lock);
2602 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2603 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302604 } /* WMI_LINK_STATS_ALL_PEER */
2605 else
2606 {
2607 hddLog(VOS_TRACE_LEVEL_ERROR,
2608 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2609 }
2610
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302611 spin_lock(&hdd_context_lock);
2612 /* complete response event if all requests are completed */
2613 if (0 == context->request_bitmap)
2614 complete(&context->response_event);
2615 spin_unlock(&hdd_context_lock);
2616
Sunil Duttc69bccb2014-05-26 21:30:20 +05302617 break;
2618 }
2619 default:
2620 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2621 break;
2622 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302623
2624 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302625 return;
2626}
2627
2628const struct
2629nla_policy
2630qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2631{
2632 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2633 { .type = NLA_U32 },
2634 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2635 { .type = NLA_U32 },
2636};
2637
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302638static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2639 struct wireless_dev *wdev,
2640 const void *data,
2641 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302642{
2643 int status;
2644 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302645 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302646 struct net_device *dev = wdev->netdev;
2647 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2648 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2649
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302650 ENTER();
2651
Sunil Duttc69bccb2014-05-26 21:30:20 +05302652 status = wlan_hdd_validate_context(pHddCtx);
2653 if (0 != status)
2654 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302655 return -EINVAL;
2656 }
2657
2658 if (NULL == pAdapter)
2659 {
2660 hddLog(VOS_TRACE_LEVEL_ERROR,
2661 FL("HDD adapter is Null"));
2662 return -ENODEV;
2663 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302664 /* check the LLStats Capability */
2665 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2666 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2667 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302668 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302669 FL("Link Layer Statistics not supported by Firmware"));
2670 return -EINVAL;
2671 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672
2673 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2674 (struct nlattr *)data,
2675 data_len, qca_wlan_vendor_ll_set_policy))
2676 {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2678 return -EINVAL;
2679 }
2680 if (!tb_vendor
2681 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2682 {
2683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2684 return -EINVAL;
2685 }
2686 if (!tb_vendor[
2687 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2688 {
2689 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2690 return -EINVAL;
2691 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302692 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302693 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302694
Dino Mycledf0a5d92014-07-04 09:41:55 +05302695 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302696 nla_get_u32(
2697 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2698
Dino Mycledf0a5d92014-07-04 09:41:55 +05302699 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302700 nla_get_u32(
2701 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2702
Dino Mycled3d50022014-07-07 12:58:25 +05302703 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2704 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302705
2706
2707 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302708 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2709 "Statistics Gathering = %d ",
2710 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2711 linkLayerStatsSetReq.mpduSizeThreshold,
2712 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302713
2714 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2715 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302716 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302717 {
2718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2719 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302720 return -EINVAL;
2721
2722 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302723
Sunil Duttc69bccb2014-05-26 21:30:20 +05302724 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302725 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302726 {
2727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2728 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302729 return -EINVAL;
2730 }
2731
2732 pAdapter->isLinkLayerStatsSet = 1;
2733
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302734 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302735 return 0;
2736}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302737static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2738 struct wireless_dev *wdev,
2739 const void *data,
2740 int data_len)
2741{
2742 int ret = 0;
2743
2744 vos_ssr_protect(__func__);
2745 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2746 vos_ssr_unprotect(__func__);
2747
2748 return ret;
2749}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2754{
2755 /* Unsigned 32bit value provided by the caller issuing the GET stats
2756 * command. When reporting
2757 * the stats results, the driver uses the same value to indicate
2758 * which GET request the results
2759 * correspond to.
2760 */
2761 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2762
2763 /* Unsigned 32bit value . bit mask to identify what statistics are
2764 requested for retrieval */
2765 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2766};
2767
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302768static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2769 struct wireless_dev *wdev,
2770 const void *data,
2771 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302772{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302773 unsigned long rc;
2774 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2776 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302777 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 struct net_device *dev = wdev->netdev;
2779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302780 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302781 int status;
2782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302783 ENTER();
2784
Sunil Duttc69bccb2014-05-26 21:30:20 +05302785 status = wlan_hdd_validate_context(pHddCtx);
2786 if (0 != status)
2787 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302788 return -EINVAL ;
2789 }
2790
2791 if (NULL == pAdapter)
2792 {
2793 hddLog(VOS_TRACE_LEVEL_FATAL,
2794 "%s: HDD adapter is Null", __func__);
2795 return -ENODEV;
2796 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302797
2798 if (pHddStaCtx == NULL)
2799 {
2800 hddLog(VOS_TRACE_LEVEL_FATAL,
2801 "%s: HddStaCtx is Null", __func__);
2802 return -ENODEV;
2803 }
2804
Dino Mycledf0a5d92014-07-04 09:41:55 +05302805 /* check the LLStats Capability */
2806 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2807 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2808 {
2809 hddLog(VOS_TRACE_LEVEL_ERROR,
2810 FL("Link Layer Statistics not supported by Firmware"));
2811 return -EINVAL;
2812 }
2813
Sunil Duttc69bccb2014-05-26 21:30:20 +05302814
2815 if (!pAdapter->isLinkLayerStatsSet)
2816 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302817 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302818 "%s: isLinkLayerStatsSet : %d",
2819 __func__, pAdapter->isLinkLayerStatsSet);
2820 return -EINVAL;
2821 }
2822
Mukul Sharma10313ba2015-07-29 19:14:39 +05302823 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2824 {
2825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2826 "%s: Roaming in progress, so unable to proceed this request", __func__);
2827 return -EBUSY;
2828 }
2829
Sunil Duttc69bccb2014-05-26 21:30:20 +05302830 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2831 (struct nlattr *)data,
2832 data_len, qca_wlan_vendor_ll_get_policy))
2833 {
2834 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2835 return -EINVAL;
2836 }
2837
2838 if (!tb_vendor
2839 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2842 return -EINVAL;
2843 }
2844
2845 if (!tb_vendor
2846 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2847 {
2848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2849 return -EINVAL;
2850 }
2851
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852
Dino Mycledf0a5d92014-07-04 09:41:55 +05302853 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302854 nla_get_u32( tb_vendor[
2855 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302856 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302857 nla_get_u32( tb_vendor[
2858 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2859
Dino Mycled3d50022014-07-07 12:58:25 +05302860 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2861 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302862
2863 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302864 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2865 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302866 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302867
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302868 spin_lock(&hdd_context_lock);
2869 context = &pHddCtx->ll_stats_context;
2870 context->request_id = linkLayerStatsGetReq.reqId;
2871 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2872 INIT_COMPLETION(context->response_event);
2873 spin_unlock(&hdd_context_lock);
2874
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302876 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302877 {
2878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2879 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880 return -EINVAL;
2881 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302882
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302883 rc = wait_for_completion_timeout(&context->response_event,
2884 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2885 if (!rc)
2886 {
2887 hddLog(LOGE,
2888 FL("Target response timed out request id %d request bitmap 0x%x"),
2889 context->request_id, context->request_bitmap);
2890 return -ETIMEDOUT;
2891 }
2892
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302893 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302894 return 0;
2895}
2896
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302897static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2898 struct wireless_dev *wdev,
2899 const void *data,
2900 int data_len)
2901{
2902 int ret = 0;
2903
2904 vos_ssr_protect(__func__);
2905 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2906 vos_ssr_unprotect(__func__);
2907
2908 return ret;
2909}
2910
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911const struct
2912nla_policy
2913qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2914{
2915 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2916 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2917 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2919};
2920
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302921static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2922 struct wireless_dev *wdev,
2923 const void *data,
2924 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302925{
2926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2927 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302929 struct net_device *dev = wdev->netdev;
2930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2931 u32 statsClearReqMask;
2932 u8 stopReq;
2933 int status;
2934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302935 ENTER();
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937 status = wlan_hdd_validate_context(pHddCtx);
2938 if (0 != status)
2939 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302940 return -EINVAL;
2941 }
2942
2943 if (NULL == pAdapter)
2944 {
2945 hddLog(VOS_TRACE_LEVEL_FATAL,
2946 "%s: HDD adapter is Null", __func__);
2947 return -ENODEV;
2948 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302949 /* check the LLStats Capability */
2950 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2951 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2952 {
2953 hddLog(VOS_TRACE_LEVEL_ERROR,
2954 FL("Enable LLStats Capability"));
2955 return -EINVAL;
2956 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302957
2958 if (!pAdapter->isLinkLayerStatsSet)
2959 {
2960 hddLog(VOS_TRACE_LEVEL_FATAL,
2961 "%s: isLinkLayerStatsSet : %d",
2962 __func__, pAdapter->isLinkLayerStatsSet);
2963 return -EINVAL;
2964 }
2965
2966 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2967 (struct nlattr *)data,
2968 data_len, qca_wlan_vendor_ll_clr_policy))
2969 {
2970 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2971 return -EINVAL;
2972 }
2973
2974 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2975
2976 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2977 {
2978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2979 return -EINVAL;
2980
2981 }
2982
Sunil Duttc69bccb2014-05-26 21:30:20 +05302983
Dino Mycledf0a5d92014-07-04 09:41:55 +05302984 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985 nla_get_u32(
2986 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2987
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u8(
2990 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2991
2992 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302993 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302994
Dino Mycled3d50022014-07-07 12:58:25 +05302995 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2996 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302997
2998 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302999 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3000 "statsClearReqMask = 0x%X, stopReq = %d",
3001 linkLayerStatsClearReq.reqId,
3002 linkLayerStatsClearReq.macAddr,
3003 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303004 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303005
3006 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303007 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 {
3009 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303010 hdd_station_ctx_t *pHddStaCtx;
3011
3012 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3013 if (VOS_STATUS_SUCCESS !=
3014 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3015 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3016 {
3017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3018 "WLANTL_ClearInterfaceStats Failed", __func__);
3019 return -EINVAL;
3020 }
3021 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3022 (statsClearReqMask & WIFI_STATS_IFACE)) {
3023 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3024 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3025 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3026 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3027 }
3028
Sunil Duttc69bccb2014-05-26 21:30:20 +05303029 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3030 2 * sizeof(u32) +
3031 NLMSG_HDRLEN);
3032
3033 if (temp_skbuff != NULL)
3034 {
3035
3036 if (nla_put_u32(temp_skbuff,
3037 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3038 statsClearReqMask) ||
3039 nla_put_u32(temp_skbuff,
3040 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3041 stopReq))
3042 {
3043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3044 kfree_skb(temp_skbuff);
3045 return -EINVAL;
3046 }
3047 /* If the ask is to stop the stats collection as part of clear
3048 * (stopReq = 1) , ensure that no further requests of get
3049 * go to the firmware by having isLinkLayerStatsSet set to 0.
3050 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 * case the firmware is just asked to clear the statistics.
3053 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303054 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303055 pAdapter->isLinkLayerStatsSet = 0;
3056 return cfg80211_vendor_cmd_reply(temp_skbuff);
3057 }
3058 return -ENOMEM;
3059 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303060
3061 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303062 return -EINVAL;
3063}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303064static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3065 struct wireless_dev *wdev,
3066 const void *data,
3067 int data_len)
3068{
3069 int ret = 0;
3070
3071 vos_ssr_protect(__func__);
3072 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3073 vos_ssr_unprotect(__func__);
3074
3075 return ret;
3076
3077
3078}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303079#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3080
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081#ifdef WLAN_FEATURE_EXTSCAN
3082static const struct nla_policy
3083wlan_hdd_extscan_config_policy
3084 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3085{
3086 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3087 { .type = NLA_U32 },
3088 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3089 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303090 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3091 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3093 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3094 { .type = NLA_U32 },
3095 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3096 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3097
3098 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3099 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3100 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3101 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3102 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303103 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3104 { .type = NLA_U32 },
3105 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3106 { .type = NLA_U32 },
3107 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3108 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303109 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3110 { .type = NLA_U32 },
3111 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3112 { .type = NLA_U32 },
3113 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3114 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3116 { .type = NLA_U8 },
3117 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303118 { .type = NLA_U8 },
3119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3120 { .type = NLA_U8 },
3121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3122 { .type = NLA_U8 },
3123
3124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3125 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3127 .type = NLA_UNSPEC,
3128 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3130 { .type = NLA_S32 },
3131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3132 { .type = NLA_S32 },
3133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3134 { .type = NLA_U32 },
3135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3136 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3138 { .type = NLA_U32 },
3139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3140 { .type = NLA_BINARY,
3141 .len = IEEE80211_MAX_SSID_LEN + 1 },
3142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303143 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3145 { .type = NLA_U32 },
3146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3147 { .type = NLA_U8 },
3148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3149 { .type = NLA_S32 },
3150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3151 { .type = NLA_S32 },
3152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3153 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154};
3155
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303156/**
3157 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3158 * @ctx: hdd global context
3159 * @data: capabilities data
3160 *
3161 * Return: none
3162 */
3163static void
3164wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303166 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303167 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303168 tSirEXTScanCapabilitiesEvent *data =
3169 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303170
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303171 ENTER();
3172
3173 if (wlan_hdd_validate_context(pHddCtx))
3174 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303175 return;
3176 }
3177
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303178 if (!pMsg)
3179 {
3180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3181 return;
3182 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303183
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303184 vos_spin_lock_acquire(&hdd_context_lock);
3185
3186 context = &pHddCtx->ext_scan_context;
3187 /* validate response received from target*/
3188 if (context->request_id != data->requestId)
3189 {
3190 vos_spin_lock_release(&hdd_context_lock);
3191 hddLog(LOGE,
3192 FL("Target response id did not match: request_id %d resposne_id %d"),
3193 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 return;
3195 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303196 else
3197 {
3198 context->capability_response = *data;
3199 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303200 }
3201
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303202 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204 return;
3205}
3206
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303207/*
3208 * define short names for the global vendor params
3209 * used by wlan_hdd_send_ext_scan_capability()
3210 */
3211#define PARAM_REQUEST_ID \
3212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3213#define PARAM_STATUS \
3214 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3215#define MAX_SCAN_CACHE_SIZE \
3216 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3217#define MAX_SCAN_BUCKETS \
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3219#define MAX_AP_CACHE_PER_SCAN \
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3221#define MAX_RSSI_SAMPLE_SIZE \
3222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3223#define MAX_SCAN_RPT_THRHOLD \
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3225#define MAX_HOTLIST_BSSIDS \
3226 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3227#define MAX_BSSID_HISTORY_ENTRIES \
3228 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3229#define MAX_HOTLIST_SSIDS \
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303231#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303233
3234static int wlan_hdd_send_ext_scan_capability(void *ctx)
3235{
3236 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3237 struct sk_buff *skb = NULL;
3238 int ret;
3239 tSirEXTScanCapabilitiesEvent *data;
3240 tANI_U32 nl_buf_len;
3241
3242 ret = wlan_hdd_validate_context(pHddCtx);
3243 if (0 != ret)
3244 {
3245 return ret;
3246 }
3247
3248 data = &(pHddCtx->ext_scan_context.capability_response);
3249
3250 nl_buf_len = NLMSG_HDRLEN;
3251 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3252 (sizeof(data->status) + NLA_HDRLEN) +
3253 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3254 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3255 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3256 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3257 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3258 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3259 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3260 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3261
3262 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3263
3264 if (!skb)
3265 {
3266 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3267 return -ENOMEM;
3268 }
3269
3270 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3271 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3272 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3273 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3274 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3275 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3276 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3277 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3278
3279 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3280 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3281 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3282 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3283 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3284 data->maxApPerScan) ||
3285 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3286 data->maxRssiSampleSize) ||
3287 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3288 data->maxScanReportingThreshold) ||
3289 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3290 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3291 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303292 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3293 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303294 {
3295 hddLog(LOGE, FL("nla put fail"));
3296 goto nla_put_failure;
3297 }
3298
3299 cfg80211_vendor_cmd_reply(skb);
3300 return 0;
3301
3302nla_put_failure:
3303 kfree_skb(skb);
3304 return -EINVAL;;
3305}
3306
3307/*
3308 * done with short names for the global vendor params
3309 * used by wlan_hdd_send_ext_scan_capability()
3310 */
3311#undef PARAM_REQUEST_ID
3312#undef PARAM_STATUS
3313#undef MAX_SCAN_CACHE_SIZE
3314#undef MAX_SCAN_BUCKETS
3315#undef MAX_AP_CACHE_PER_SCAN
3316#undef MAX_RSSI_SAMPLE_SIZE
3317#undef MAX_SCAN_RPT_THRHOLD
3318#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319#undef MAX_BSSID_HISTORY_ENTRIES
3320#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303321
3322static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3323{
3324 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3325 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303327 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303329 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303330
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303331 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303332 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303333
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303334 if (!pMsg)
3335 {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303337 return;
3338 }
3339
Dino Mycle6fb96c12014-06-10 11:52:40 +05303340 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3341 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3342
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303343 context = &pHddCtx->ext_scan_context;
3344 spin_lock(&hdd_context_lock);
3345 if (context->request_id == pData->requestId) {
3346 context->response_status = pData->status ? -EINVAL : 0;
3347 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303349 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350
3351 /*
3352 * Store the Request ID for comparing with the requestID obtained
3353 * in other requests.HDD shall return a failure is the extscan_stop
3354 * request is issued with a different requestId as that of the
3355 * extscan_start request. Also, This requestId shall be used while
3356 * indicating the full scan results to the upper layers.
3357 * The requestId is stored with the assumption that the firmware
3358 * shall return the ext scan start request's requestId in ext scan
3359 * start response.
3360 */
3361 if (pData->status == 0)
3362 pMac->sme.extScanStartReqId = pData->requestId;
3363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303364 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366}
3367
3368
3369static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3370{
3371 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303373 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303375 ENTER();
3376
3377 if (wlan_hdd_validate_context(pHddCtx)){
3378 return;
3379 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303380
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303381 if (!pMsg)
3382 {
3383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384 return;
3385 }
3386
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303387 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3388 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303389
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303390 context = &pHddCtx->ext_scan_context;
3391 spin_lock(&hdd_context_lock);
3392 if (context->request_id == pData->requestId) {
3393 context->response_status = pData->status ? -EINVAL : 0;
3394 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303396 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303398 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303399 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303400}
3401
Dino Mycle6fb96c12014-06-10 11:52:40 +05303402static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3403 void *pMsg)
3404{
3405 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303406 tpSirEXTScanSetBssidHotListRspParams pData =
3407 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303408 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303410 ENTER();
3411
3412 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 return;
3414 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303416 if (!pMsg)
3417 {
3418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3419 return;
3420 }
3421
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303422 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3423 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303424
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303425 context = &pHddCtx->ext_scan_context;
3426 spin_lock(&hdd_context_lock);
3427 if (context->request_id == pData->requestId) {
3428 context->response_status = pData->status ? -EINVAL : 0;
3429 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303431 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303433 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435}
3436
3437static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3438 void *pMsg)
3439{
3440 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 tpSirEXTScanResetBssidHotlistRspParams pData =
3442 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303443 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303445 ENTER();
3446
3447 if (wlan_hdd_validate_context(pHddCtx)) {
3448 return;
3449 }
3450 if (!pMsg)
3451 {
3452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453 return;
3454 }
3455
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303456 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3457 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303459 context = &pHddCtx->ext_scan_context;
3460 spin_lock(&hdd_context_lock);
3461 if (context->request_id == pData->requestId) {
3462 context->response_status = pData->status ? -EINVAL : 0;
3463 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303465 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303468 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469}
3470
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3472 void *pMsg)
3473{
3474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3475 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303476 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 tANI_S32 totalResults;
3478 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303479 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3480 struct hdd_ext_scan_context *context;
3481 bool ignore_cached_results = false;
3482 tExtscanCachedScanResult *result;
3483 struct nlattr *nla_results;
3484 tANI_U16 ieLength= 0;
3485 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 ENTER();
3488
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303489 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303492 if (!pMsg)
3493 {
3494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3495 return;
3496 }
3497
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303498 spin_lock(&hdd_context_lock);
3499 context = &pHddCtx->ext_scan_context;
3500 ignore_cached_results = context->ignore_cached_results;
3501 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303503 if (ignore_cached_results) {
3504 hddLog(LOGE,
3505 FL("Ignore the cached results received after timeout"));
3506 return;
3507 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303509 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3510 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303511
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303512 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303514 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3515 scan_id_index++) {
3516 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303518 totalResults = result->num_results;
3519 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3520 result->scan_id, result->flags, totalResults);
3521 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303523 do{
3524 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3525 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3526 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303528 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3529 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3530
3531 if (!skb) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR,
3533 FL("cfg80211_vendor_event_alloc failed"));
3534 return;
3535 }
3536
3537 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3538
3539 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3540 pData->requestId) ||
3541 nla_put_u32(skb,
3542 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3543 resultsPerEvent)) {
3544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3545 goto fail;
3546 }
3547 if (nla_put_u8(skb,
3548 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3549 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550 {
3551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3552 goto fail;
3553 }
3554
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303555 if (nla_put_u32(skb,
3556 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3557 result->scan_id)) {
3558 hddLog(LOGE, FL("put fail"));
3559 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303562 nla_results = nla_nest_start(skb,
3563 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3564 if (!nla_results)
3565 goto fail;
3566
3567 if (resultsPerEvent) {
3568 struct nlattr *aps;
3569 struct nlattr *nla_result;
3570
3571 nla_result = nla_nest_start(skb, scan_id_index);
3572 if(!nla_result)
3573 goto fail;
3574
3575 if (nla_put_u32(skb,
3576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3577 result->scan_id) ||
3578 nla_put_u32(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3580 result->flags) ||
3581 nla_put_u32(skb,
3582 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3583 totalResults)) {
3584 hddLog(LOGE, FL("put fail"));
3585 goto fail;
3586 }
3587
3588 aps = nla_nest_start(skb,
3589 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3590 if (!aps)
3591 {
3592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3593 goto fail;
3594 }
3595
3596 head_ptr = (tpSirWifiScanResult) &(result->ap);
3597
3598 for (j = 0; j < resultsPerEvent; j++, i++) {
3599 struct nlattr *ap;
3600 pSirWifiScanResult = head_ptr + i;
3601
3602 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303603 * Firmware returns timestamp from extscan_start till
3604 * BSSID was cached (in micro seconds). Add this with
3605 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303606 * to derive the time since boot when the
3607 * BSSID was cached.
3608 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303609 pSirWifiScanResult->ts +=
3610 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3612 "Ssid (%s)"
3613 "Bssid: %pM "
3614 "Channel (%u)"
3615 "Rssi (%d)"
3616 "RTT (%u)"
3617 "RTT_SD (%u)"
3618 "Beacon Period %u"
3619 "Capability 0x%x "
3620 "Ie length %d",
3621 i,
3622 pSirWifiScanResult->ts,
3623 pSirWifiScanResult->ssid,
3624 pSirWifiScanResult->bssid,
3625 pSirWifiScanResult->channel,
3626 pSirWifiScanResult->rssi,
3627 pSirWifiScanResult->rtt,
3628 pSirWifiScanResult->rtt_sd,
3629 pSirWifiScanResult->beaconPeriod,
3630 pSirWifiScanResult->capability,
3631 ieLength);
3632
3633 ap = nla_nest_start(skb, j + 1);
3634 if (!ap)
3635 {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3637 goto fail;
3638 }
3639
3640 if (nla_put_u64(skb,
3641 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3642 pSirWifiScanResult->ts) )
3643 {
3644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3645 goto fail;
3646 }
3647 if (nla_put(skb,
3648 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3649 sizeof(pSirWifiScanResult->ssid),
3650 pSirWifiScanResult->ssid) )
3651 {
3652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3653 goto fail;
3654 }
3655 if (nla_put(skb,
3656 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3657 sizeof(pSirWifiScanResult->bssid),
3658 pSirWifiScanResult->bssid) )
3659 {
3660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3661 goto fail;
3662 }
3663 if (nla_put_u32(skb,
3664 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3665 pSirWifiScanResult->channel) )
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_s32(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3672 pSirWifiScanResult->rssi) )
3673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677 if (nla_put_u32(skb,
3678 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3679 pSirWifiScanResult->rtt) )
3680 {
3681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3682 goto fail;
3683 }
3684 if (nla_put_u32(skb,
3685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3686 pSirWifiScanResult->rtt_sd))
3687 {
3688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3689 goto fail;
3690 }
3691 if (nla_put_u32(skb,
3692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3693 pSirWifiScanResult->beaconPeriod))
3694 {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3696 goto fail;
3697 }
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3700 pSirWifiScanResult->capability))
3701 {
3702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3703 goto fail;
3704 }
3705 if (nla_put_u32(skb,
3706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3707 ieLength))
3708 {
3709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3710 goto fail;
3711 }
3712
3713 if (ieLength)
3714 if (nla_put(skb,
3715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3716 ieLength, ie)) {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3718 goto fail;
3719 }
3720
3721 nla_nest_end(skb, ap);
3722 }
3723 nla_nest_end(skb, aps);
3724 nla_nest_end(skb, nla_result);
3725 }
3726
3727 nla_nest_end(skb, nla_results);
3728
3729 cfg80211_vendor_cmd_reply(skb);
3730
3731 } while (totalResults > 0);
3732 }
3733
3734 if (!pData->moreData) {
3735 spin_lock(&hdd_context_lock);
3736 context->response_status = 0;
3737 complete(&context->response_event);
3738 spin_unlock(&hdd_context_lock);
3739 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303741 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 return;
3743fail:
3744 kfree_skb(skb);
3745 return;
3746}
3747
3748static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3749 void *pMsg)
3750{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303751 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3753 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303754 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303756 ENTER();
3757
3758 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303759 hddLog(LOGE,
3760 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303761 return;
3762 }
3763 if (!pMsg)
3764 {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 return;
3767 }
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 if (pData->bss_found)
3770 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3771 else
3772 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3773
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3776 NULL,
3777#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303779 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780
3781 if (!skb) {
3782 hddLog(VOS_TRACE_LEVEL_ERROR,
3783 FL("cfg80211_vendor_event_alloc failed"));
3784 return;
3785 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303787 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3788 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3789 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3790 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3791
3792 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303793 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3794 "Ssid (%s) "
3795 "Bssid (" MAC_ADDRESS_STR ") "
3796 "Channel (%u) "
3797 "Rssi (%d) "
3798 "RTT (%u) "
3799 "RTT_SD (%u) ",
3800 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303801 pData->bssHotlist[i].ts,
3802 pData->bssHotlist[i].ssid,
3803 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3804 pData->bssHotlist[i].channel,
3805 pData->bssHotlist[i].rssi,
3806 pData->bssHotlist[i].rtt,
3807 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808 }
3809
3810 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3811 pData->requestId) ||
3812 nla_put_u32(skb,
3813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303814 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3816 goto fail;
3817 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303818 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819 struct nlattr *aps;
3820
3821 aps = nla_nest_start(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3823 if (!aps)
3824 goto fail;
3825
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303826 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303827 struct nlattr *ap;
3828
3829 ap = nla_nest_start(skb, i + 1);
3830 if (!ap)
3831 goto fail;
3832
3833 if (nla_put_u64(skb,
3834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303835 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836 nla_put(skb,
3837 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303838 sizeof(pData->bssHotlist[i].ssid),
3839 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303840 nla_put(skb,
3841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303842 sizeof(pData->bssHotlist[i].bssid),
3843 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303844 nla_put_u32(skb,
3845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303846 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303847 nla_put_s32(skb,
3848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303849 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303850 nla_put_u32(skb,
3851 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303852 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 nla_put_u32(skb,
3854 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303855 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303856 goto fail;
3857
3858 nla_nest_end(skb, ap);
3859 }
3860 nla_nest_end(skb, aps);
3861
3862 if (nla_put_u8(skb,
3863 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3864 pData->moreData))
3865 goto fail;
3866 }
3867
3868 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303869 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870 return;
3871
3872fail:
3873 kfree_skb(skb);
3874 return;
3875
3876}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877
3878static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3879 void *pMsg)
3880{
3881 struct sk_buff *skb;
3882 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3883 tpSirWifiFullScanResultEvent pData =
3884 (tpSirWifiFullScanResultEvent) (pMsg);
3885
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303886 ENTER();
3887
3888 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303889 hddLog(LOGE,
3890 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891 return;
3892 }
3893 if (!pMsg)
3894 {
3895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303896 return;
3897 }
3898
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303899 /*
3900 * If the full scan result including IE data exceeds NL 4K size
3901 * limitation, drop that beacon/probe rsp frame.
3902 */
3903 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3904 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3905 return;
3906 }
3907
Dino Mycle6fb96c12014-06-10 11:52:40 +05303908 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3910 NULL,
3911#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3913 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3914 GFP_KERNEL);
3915
3916 if (!skb) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR,
3918 FL("cfg80211_vendor_event_alloc failed"));
3919 return;
3920 }
3921
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3923 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3924 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3925 "Ssid (%s)"
3926 "Bssid (" MAC_ADDRESS_STR ")"
3927 "Channel (%u)"
3928 "Rssi (%d)"
3929 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303930 "RTT_SD (%u)"
3931 "Bcn Period %d"
3932 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933 pData->ap.ts,
3934 pData->ap.ssid,
3935 MAC_ADDR_ARRAY(pData->ap.bssid),
3936 pData->ap.channel,
3937 pData->ap.rssi,
3938 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303939 pData->ap.rtt_sd,
3940 pData->ap.beaconPeriod,
3941 pData->ap.capability);
3942
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3944 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3945 pData->requestId) ||
3946 nla_put_u64(skb,
3947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3948 pData->ap.ts) ||
3949 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3950 sizeof(pData->ap.ssid),
3951 pData->ap.ssid) ||
3952 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3953 WNI_CFG_BSSID_LEN,
3954 pData->ap.bssid) ||
3955 nla_put_u32(skb,
3956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3957 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303958 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 pData->ap.rssi) ||
3960 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3961 pData->ap.rtt) ||
3962 nla_put_u32(skb,
3963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3964 pData->ap.rtt_sd) ||
3965 nla_put_u16(skb,
3966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3967 pData->ap.beaconPeriod) ||
3968 nla_put_u16(skb,
3969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3970 pData->ap.capability) ||
3971 nla_put_u32(skb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303973 pData->ieLength) ||
3974 nla_put_u8(skb,
3975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3976 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 {
3978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3979 goto nla_put_failure;
3980 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303981
3982 if (pData->ieLength) {
3983 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3984 pData->ieLength,
3985 pData->ie))
3986 {
3987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3988 goto nla_put_failure;
3989 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303990 }
3991
3992 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303993 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994 return;
3995
3996nla_put_failure:
3997 kfree_skb(skb);
3998 return;
3999}
4000
4001static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4002 void *pMsg)
4003{
4004 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4005 struct sk_buff *skb = NULL;
4006 tpSirEXTScanResultsAvailableIndParams pData =
4007 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
4022 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4024 NULL,
4025#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4027 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4028 GFP_KERNEL);
4029
4030 if (!skb) {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("cfg80211_vendor_event_alloc failed"));
4033 return;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4037 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4038 pData->numResultsAvailable);
4039 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4040 pData->requestId) ||
4041 nla_put_u32(skb,
4042 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4043 pData->numResultsAvailable)) {
4044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4045 goto nla_put_failure;
4046 }
4047
4048 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304049 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304050 return;
4051
4052nla_put_failure:
4053 kfree_skb(skb);
4054 return;
4055}
4056
4057static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4058{
4059 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4060 struct sk_buff *skb = NULL;
4061 tpSirEXTScanProgressIndParams pData =
4062 (tpSirEXTScanProgressIndParams) pMsg;
4063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304064 ENTER();
4065
4066 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304067 hddLog(LOGE,
4068 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304069 return;
4070 }
4071 if (!pMsg)
4072 {
4073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074 return;
4075 }
4076
4077 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4079 NULL,
4080#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304081 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4082 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4083 GFP_KERNEL);
4084
4085 if (!skb) {
4086 hddLog(VOS_TRACE_LEVEL_ERROR,
4087 FL("cfg80211_vendor_event_alloc failed"));
4088 return;
4089 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4092 pData->extScanEventType);
4093 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4094 pData->status);
4095
4096 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4097 pData->extScanEventType) ||
4098 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4100 pData->requestId) ||
4101 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4103 pData->status)) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4105 goto nla_put_failure;
4106 }
4107
4108 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304109 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 return;
4111
4112nla_put_failure:
4113 kfree_skb(skb);
4114 return;
4115}
4116
4117void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4118 void *pMsg)
4119{
4120 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4121
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304122 ENTER();
4123
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 return;
4126 }
4127
4128 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4129
4130
4131 switch(evType) {
4132 case SIR_HAL_EXTSCAN_START_RSP:
4133 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4134 break;
4135
4136 case SIR_HAL_EXTSCAN_STOP_RSP:
4137 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4138 break;
4139 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4140 /* There is no need to send this response to upper layer
4141 Just log the message */
4142 hddLog(VOS_TRACE_LEVEL_INFO,
4143 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4144 break;
4145 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4146 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4147 break;
4148
4149 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4150 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4151 break;
4152
Dino Mycle6fb96c12014-06-10 11:52:40 +05304153 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304154 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304155 break;
4156 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4157 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4158 break;
4159 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4160 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4161 break;
4162 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4163 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4164 break;
4165 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4166 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4167 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4169 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4170 break;
4171 default:
4172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4173 break;
4174 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304175 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176}
4177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304178static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4179 struct wireless_dev *wdev,
4180 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181{
Dino Myclee8843b32014-07-04 14:21:45 +05304182 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 struct net_device *dev = wdev->netdev;
4184 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4185 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4186 struct nlattr
4187 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4188 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304189 struct hdd_ext_scan_context *context;
4190 unsigned long rc;
4191 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304193 ENTER();
4194
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195 status = wlan_hdd_validate_context(pHddCtx);
4196 if (0 != status)
4197 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 return -EINVAL;
4199 }
Dino Myclee8843b32014-07-04 14:21:45 +05304200 /* check the EXTScan Capability */
4201 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304202 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4203 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304204 {
4205 hddLog(VOS_TRACE_LEVEL_ERROR,
4206 FL("EXTScan not enabled/supported by Firmware"));
4207 return -EINVAL;
4208 }
4209
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4211 data, dataLen,
4212 wlan_hdd_extscan_config_policy)) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4214 return -EINVAL;
4215 }
4216
4217 /* Parse and fetch request Id */
4218 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4220 return -EINVAL;
4221 }
4222
Dino Myclee8843b32014-07-04 14:21:45 +05304223 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226
Dino Myclee8843b32014-07-04 14:21:45 +05304227 reqMsg.sessionId = pAdapter->sessionId;
4228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304230 vos_spin_lock_acquire(&hdd_context_lock);
4231 context = &pHddCtx->ext_scan_context;
4232 context->request_id = reqMsg.requestId;
4233 INIT_COMPLETION(context->response_event);
4234 vos_spin_lock_release(&hdd_context_lock);
4235
Dino Myclee8843b32014-07-04 14:21:45 +05304236 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304237 if (!HAL_STATUS_SUCCESS(status)) {
4238 hddLog(VOS_TRACE_LEVEL_ERROR,
4239 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 return -EINVAL;
4241 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304242
4243 rc = wait_for_completion_timeout(&context->response_event,
4244 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4245 if (!rc) {
4246 hddLog(LOGE, FL("Target response timed out"));
4247 return -ETIMEDOUT;
4248 }
4249
4250 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4251 if (ret)
4252 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4253
4254 return ret;
4255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304256 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 return 0;
4258}
4259
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304260static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4261 struct wireless_dev *wdev,
4262 const void *data, int dataLen)
4263{
4264 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304266 vos_ssr_protect(__func__);
4267 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4268 vos_ssr_unprotect(__func__);
4269
4270 return ret;
4271}
4272
4273static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4274 struct wireless_dev *wdev,
4275 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276{
Dino Myclee8843b32014-07-04 14:21:45 +05304277 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 struct net_device *dev = wdev->netdev;
4279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4280 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4281 struct nlattr
4282 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4283 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304284 struct hdd_ext_scan_context *context;
4285 unsigned long rc;
4286 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304288 ENTER();
4289
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304290 if (VOS_FTM_MODE == hdd_get_conparam()) {
4291 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4292 return -EINVAL;
4293 }
4294
Dino Mycle6fb96c12014-06-10 11:52:40 +05304295 status = wlan_hdd_validate_context(pHddCtx);
4296 if (0 != status)
4297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304298 return -EINVAL;
4299 }
Dino Myclee8843b32014-07-04 14:21:45 +05304300 /* check the EXTScan Capability */
4301 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304302 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4303 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304304 {
4305 hddLog(VOS_TRACE_LEVEL_ERROR,
4306 FL("EXTScan not enabled/supported by Firmware"));
4307 return -EINVAL;
4308 }
4309
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4311 data, dataLen,
4312 wlan_hdd_extscan_config_policy)) {
4313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4314 return -EINVAL;
4315 }
4316 /* Parse and fetch request Id */
4317 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4319 return -EINVAL;
4320 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321
Dino Myclee8843b32014-07-04 14:21:45 +05304322 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304323 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4324
Dino Myclee8843b32014-07-04 14:21:45 +05304325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326
Dino Myclee8843b32014-07-04 14:21:45 +05304327 reqMsg.sessionId = pAdapter->sessionId;
4328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304329
4330 /* Parse and fetch flush parameter */
4331 if (!tb
4332 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4333 {
4334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4335 goto failed;
4336 }
Dino Myclee8843b32014-07-04 14:21:45 +05304337 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4339
Dino Myclee8843b32014-07-04 14:21:45 +05304340 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304341
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304342 spin_lock(&hdd_context_lock);
4343 context = &pHddCtx->ext_scan_context;
4344 context->request_id = reqMsg.requestId;
4345 context->ignore_cached_results = false;
4346 INIT_COMPLETION(context->response_event);
4347 spin_unlock(&hdd_context_lock);
4348
Dino Myclee8843b32014-07-04 14:21:45 +05304349 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304350 if (!HAL_STATUS_SUCCESS(status)) {
4351 hddLog(VOS_TRACE_LEVEL_ERROR,
4352 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304353 return -EINVAL;
4354 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304355
4356 rc = wait_for_completion_timeout(&context->response_event,
4357 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4358 if (!rc) {
4359 hddLog(LOGE, FL("Target response timed out"));
4360 retval = -ETIMEDOUT;
4361 spin_lock(&hdd_context_lock);
4362 context->ignore_cached_results = true;
4363 spin_unlock(&hdd_context_lock);
4364 } else {
4365 spin_lock(&hdd_context_lock);
4366 retval = context->response_status;
4367 spin_unlock(&hdd_context_lock);
4368 }
4369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304370 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304371 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372
4373failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304374 return -EINVAL;
4375}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304376static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4377 struct wireless_dev *wdev,
4378 const void *data, int dataLen)
4379{
4380 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304381
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304382 vos_ssr_protect(__func__);
4383 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4384 vos_ssr_unprotect(__func__);
4385
4386 return ret;
4387}
4388
4389static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304390 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304391 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304392{
4393 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4394 struct net_device *dev = wdev->netdev;
4395 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4397 struct nlattr
4398 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4399 struct nlattr
4400 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4401 struct nlattr *apTh;
4402 eHalStatus status;
4403 tANI_U8 i = 0;
4404 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304405 struct hdd_ext_scan_context *context;
4406 tANI_U32 request_id;
4407 unsigned long rc;
4408 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304410 ENTER();
4411
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304412 if (VOS_FTM_MODE == hdd_get_conparam()) {
4413 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4414 return -EINVAL;
4415 }
4416
Dino Mycle6fb96c12014-06-10 11:52:40 +05304417 status = wlan_hdd_validate_context(pHddCtx);
4418 if (0 != status)
4419 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304420 return -EINVAL;
4421 }
Dino Myclee8843b32014-07-04 14:21:45 +05304422 /* check the EXTScan Capability */
4423 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304424 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4425 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304426 {
4427 hddLog(VOS_TRACE_LEVEL_ERROR,
4428 FL("EXTScan not enabled/supported by Firmware"));
4429 return -EINVAL;
4430 }
4431
Dino Mycle6fb96c12014-06-10 11:52:40 +05304432 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4433 data, dataLen,
4434 wlan_hdd_extscan_config_policy)) {
4435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4436 return -EINVAL;
4437 }
4438
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4445 vos_mem_malloc(sizeof(*pReqMsg));
4446 if (!pReqMsg) {
4447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4448 return -ENOMEM;
4449 }
4450
Dino Myclee8843b32014-07-04 14:21:45 +05304451
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 pReqMsg->requestId = nla_get_u32(
4453 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4454 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4455
4456 /* Parse and fetch number of APs */
4457 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4459 goto fail;
4460 }
4461
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304462 /* Parse and fetch lost ap sample size */
4463 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4464 hddLog(LOGE, FL("attr lost ap sample size failed"));
4465 goto fail;
4466 }
4467
4468 pReqMsg->lostBssidSampleSize = nla_get_u32(
4469 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4470 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4471
Dino Mycle6fb96c12014-06-10 11:52:40 +05304472 pReqMsg->sessionId = pAdapter->sessionId;
4473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4474
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304475 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304477 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4478 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4479 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4480 goto fail;
4481 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483
4484 nla_for_each_nested(apTh,
4485 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304486 if (i == pReqMsg->numBssid) {
4487 hddLog(LOGW, FL("Ignoring excess AP"));
4488 break;
4489 }
4490
Dino Mycle6fb96c12014-06-10 11:52:40 +05304491 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4492 nla_data(apTh), nla_len(apTh),
4493 NULL)) {
4494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4495 goto fail;
4496 }
4497
4498 /* Parse and fetch MAC address */
4499 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4501 goto fail;
4502 }
4503 memcpy(pReqMsg->ap[i].bssid, nla_data(
4504 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4505 sizeof(tSirMacAddr));
4506 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4507
4508 /* Parse and fetch low RSSI */
4509 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4511 goto fail;
4512 }
4513 pReqMsg->ap[i].low = nla_get_s32(
4514 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4515 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4516
4517 /* Parse and fetch high RSSI */
4518 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4519 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4520 goto fail;
4521 }
4522 pReqMsg->ap[i].high = nla_get_s32(
4523 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4524 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4525 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304526 i++;
4527 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304529 if (i < pReqMsg->numBssid) {
4530 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4531 i, pReqMsg->numBssid);
4532 pReqMsg->numBssid = i;
4533 }
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 context = &pHddCtx->ext_scan_context;
4536 spin_lock(&hdd_context_lock);
4537 INIT_COMPLETION(context->response_event);
4538 context->request_id = request_id = pReqMsg->requestId;
4539 spin_unlock(&hdd_context_lock);
4540
Dino Mycle6fb96c12014-06-10 11:52:40 +05304541 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4542 if (!HAL_STATUS_SUCCESS(status)) {
4543 hddLog(VOS_TRACE_LEVEL_ERROR,
4544 FL("sme_SetBssHotlist failed(err=%d)"), status);
4545 vos_mem_free(pReqMsg);
4546 return -EINVAL;
4547 }
4548
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304549 /* request was sent -- wait for the response */
4550 rc = wait_for_completion_timeout(&context->response_event,
4551 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4552
4553 if (!rc) {
4554 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4555 retval = -ETIMEDOUT;
4556 } else {
4557 spin_lock(&hdd_context_lock);
4558 if (context->request_id == request_id)
4559 retval = context->response_status;
4560 else
4561 retval = -EINVAL;
4562 spin_unlock(&hdd_context_lock);
4563 }
4564
Dino Myclee8843b32014-07-04 14:21:45 +05304565 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304566 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304567 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304568
4569fail:
4570 vos_mem_free(pReqMsg);
4571 return -EINVAL;
4572}
4573
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304574static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4575 struct wireless_dev *wdev,
4576 const void *data, int dataLen)
4577{
4578 int ret = 0;
4579
4580 vos_ssr_protect(__func__);
4581 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4582 dataLen);
4583 vos_ssr_unprotect(__func__);
4584
4585 return ret;
4586}
4587
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304588static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304589 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304590 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304592 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4593 struct net_device *dev = wdev->netdev;
4594 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4595 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4596 uint8_t num_channels = 0;
4597 uint8_t num_chan_new = 0;
4598 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304600 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 tWifiBand wifiBand;
4602 eHalStatus status;
4603 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304604 tANI_U8 i,j,k;
4605 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 ENTER();
4608
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609 status = wlan_hdd_validate_context(pHddCtx);
4610 if (0 != status)
4611 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 return -EINVAL;
4613 }
Dino Myclee8843b32014-07-04 14:21:45 +05304614
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4616 data, dataLen,
4617 wlan_hdd_extscan_config_policy)) {
4618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4619 return -EINVAL;
4620 }
4621
4622 /* Parse and fetch request Id */
4623 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4625 return -EINVAL;
4626 }
4627 requestId = nla_get_u32(
4628 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4630
4631 /* Parse and fetch wifi band */
4632 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4633 {
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4635 return -EINVAL;
4636 }
4637 wifiBand = nla_get_u32(
4638 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4639 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4640
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304641 /* Parse and fetch max channels */
4642 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4643 {
4644 hddLog(LOGE, FL("attr max channels failed"));
4645 return -EINVAL;
4646 }
4647 maxChannels = nla_get_u32(
4648 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4650
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304652 wifiBand, chan_list,
4653 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304654 if (eHAL_STATUS_SUCCESS != status) {
4655 hddLog(VOS_TRACE_LEVEL_ERROR,
4656 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4657 return -EINVAL;
4658 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304659
Agrawal Ashish16abf782016-08-18 22:42:59 +05304660 num_channels = VOS_MIN(num_channels, maxChannels);
4661 num_chan_new = num_channels;
4662 /* remove the indoor only channels if iface is SAP */
4663 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4664 {
4665 num_chan_new = 0;
4666 for (i = 0; i < num_channels; i++)
4667 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4668 if (wiphy->bands[j] == NULL)
4669 continue;
4670 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4671 if ((chan_list[i] ==
4672 wiphy->bands[j]->channels[k].center_freq) &&
4673 (!(wiphy->bands[j]->channels[k].flags &
4674 IEEE80211_CHAN_INDOOR_ONLY))) {
4675 chan_list[num_chan_new] = chan_list[i];
4676 num_chan_new++;
4677 }
4678 }
4679 }
4680 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304681
Agrawal Ashish16abf782016-08-18 22:42:59 +05304682 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4683 for (i = 0; i < num_chan_new; i++)
4684 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4685 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304686
4687 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304688 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 NLMSG_HDRLEN);
4690
4691 if (!replySkb) {
4692 hddLog(VOS_TRACE_LEVEL_ERROR,
4693 FL("valid channels: buffer alloc fail"));
4694 return -EINVAL;
4695 }
4696 if (nla_put_u32(replySkb,
4697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304698 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304700 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304701
4702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4703 kfree_skb(replySkb);
4704 return -EINVAL;
4705 }
4706
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304707 ret = cfg80211_vendor_cmd_reply(replySkb);
4708
4709 EXIT();
4710 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304711}
4712
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304713static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4714 struct wireless_dev *wdev,
4715 const void *data, int dataLen)
4716{
4717 int ret = 0;
4718
4719 vos_ssr_protect(__func__);
4720 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4721 dataLen);
4722 vos_ssr_unprotect(__func__);
4723
4724 return ret;
4725}
4726
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304727static int hdd_extscan_start_fill_bucket_channel_spec(
4728 hdd_context_t *pHddCtx,
4729 tpSirEXTScanStartReqParams pReqMsg,
4730 struct nlattr **tb)
4731{
4732 struct nlattr *bucket[
4733 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4734 struct nlattr *channel[
4735 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4736 struct nlattr *buckets;
4737 struct nlattr *channels;
4738 int rem1, rem2;
4739 eHalStatus status;
4740 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304741 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4743 tANI_U32 passive_max_chn_time, active_max_chn_time;
4744
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304745 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304746 bktIndex = 0;
4747
4748 nla_for_each_nested(buckets,
4749 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304750 if (bktIndex >= expected_buckets) {
4751 hddLog(LOGW, FL("ignoring excess buckets"));
4752 break;
4753 }
4754
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304755 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304756 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4757 nla_data(buckets), nla_len(buckets),
4758 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304759 hddLog(LOGE, FL("nla_parse failed"));
4760 return -EINVAL;
4761 }
4762
4763 /* Parse and fetch bucket spec */
4764 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4765 hddLog(LOGE, FL("attr bucket index failed"));
4766 return -EINVAL;
4767 }
4768 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4769 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4770 hddLog(LOG1, FL("Bucket spec Index %d"),
4771 pReqMsg->buckets[bktIndex].bucket);
4772
4773 /* Parse and fetch wifi band */
4774 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4775 hddLog(LOGE, FL("attr wifi band failed"));
4776 return -EINVAL;
4777 }
4778 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4779 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4780 hddLog(LOG1, FL("Wifi band %d"),
4781 pReqMsg->buckets[bktIndex].band);
4782
4783 /* Parse and fetch period */
4784 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4785 hddLog(LOGE, FL("attr period failed"));
4786 return -EINVAL;
4787 }
4788 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4789 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4790 hddLog(LOG1, FL("period %d"),
4791 pReqMsg->buckets[bktIndex].period);
4792
4793 /* Parse and fetch report events */
4794 if (!bucket[
4795 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4796 hddLog(LOGE, FL("attr report events failed"));
4797 return -EINVAL;
4798 }
4799 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4800 bucket[
4801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4802 hddLog(LOG1, FL("report events %d"),
4803 pReqMsg->buckets[bktIndex].reportEvents);
4804
4805 /* Parse and fetch max period */
4806 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4807 hddLog(LOGE, FL("attr max period failed"));
4808 return -EINVAL;
4809 }
4810 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4811 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4812 hddLog(LOG1, FL("max period %u"),
4813 pReqMsg->buckets[bktIndex].max_period);
4814
4815 /* Parse and fetch exponent */
4816 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4817 hddLog(LOGE, FL("attr exponent failed"));
4818 return -EINVAL;
4819 }
4820 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4821 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4822 hddLog(LOG1, FL("exponent %u"),
4823 pReqMsg->buckets[bktIndex].exponent);
4824
4825 /* Parse and fetch step count */
4826 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4827 hddLog(LOGE, FL("attr step count failed"));
4828 return -EINVAL;
4829 }
4830 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4831 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4832 hddLog(LOG1, FL("Step count %u"),
4833 pReqMsg->buckets[bktIndex].step_count);
4834
4835 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4836 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4837
4838 /* Framework shall pass the channel list if the input WiFi band is
4839 * WIFI_BAND_UNSPECIFIED.
4840 * If the input WiFi band is specified (any value other than
4841 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4842 */
4843 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4844 numChannels = 0;
4845 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4846 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4847 pReqMsg->buckets[bktIndex].band,
4848 chanList, &numChannels);
4849 if (!HAL_STATUS_SUCCESS(status)) {
4850 hddLog(LOGE,
4851 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4852 status);
4853 return -EINVAL;
4854 }
4855
4856 pReqMsg->buckets[bktIndex].numChannels =
4857 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4858 hddLog(LOG1, FL("Num channels %d"),
4859 pReqMsg->buckets[bktIndex].numChannels);
4860
4861 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4862 j++) {
4863 pReqMsg->buckets[bktIndex].channels[j].channel =
4864 chanList[j];
4865 pReqMsg->buckets[bktIndex].channels[j].
4866 chnlClass = 0;
4867 if (CSR_IS_CHANNEL_DFS(
4868 vos_freq_to_chan(chanList[j]))) {
4869 pReqMsg->buckets[bktIndex].channels[j].
4870 passive = 1;
4871 pReqMsg->buckets[bktIndex].channels[j].
4872 dwellTimeMs = passive_max_chn_time;
4873 } else {
4874 pReqMsg->buckets[bktIndex].channels[j].
4875 passive = 0;
4876 pReqMsg->buckets[bktIndex].channels[j].
4877 dwellTimeMs = active_max_chn_time;
4878 }
4879
4880 hddLog(LOG1,
4881 "Channel %u Passive %u Dwell time %u ms",
4882 pReqMsg->buckets[bktIndex].channels[j].channel,
4883 pReqMsg->buckets[bktIndex].channels[j].passive,
4884 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4885 }
4886
4887 bktIndex++;
4888 continue;
4889 }
4890
4891 /* Parse and fetch number of channels */
4892 if (!bucket[
4893 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4894 hddLog(LOGE, FL("attr num channels failed"));
4895 return -EINVAL;
4896 }
4897
4898 pReqMsg->buckets[bktIndex].numChannels =
4899 nla_get_u32(bucket[
4900 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4901 hddLog(LOG1, FL("num channels %d"),
4902 pReqMsg->buckets[bktIndex].numChannels);
4903
4904 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4905 hddLog(LOGE, FL("attr channel spec failed"));
4906 return -EINVAL;
4907 }
4908
4909 j = 0;
4910 nla_for_each_nested(channels,
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4912 if (nla_parse(channel,
4913 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4914 nla_data(channels), nla_len(channels),
4915 wlan_hdd_extscan_config_policy)) {
4916 hddLog(LOGE, FL("nla_parse failed"));
4917 return -EINVAL;
4918 }
4919
4920 /* Parse and fetch channel */
4921 if (!channel[
4922 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4923 hddLog(LOGE, FL("attr channel failed"));
4924 return -EINVAL;
4925 }
4926 pReqMsg->buckets[bktIndex].channels[j].channel =
4927 nla_get_u32(channel[
4928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4929 hddLog(LOG1, FL("channel %u"),
4930 pReqMsg->buckets[bktIndex].channels[j].channel);
4931
4932 /* Parse and fetch dwell time */
4933 if (!channel[
4934 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4935 hddLog(LOGE, FL("attr dwelltime failed"));
4936 return -EINVAL;
4937 }
4938 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4939 nla_get_u32(channel[
4940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4941
4942 hddLog(LOG1, FL("Dwell time (%u ms)"),
4943 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4944
4945
4946 /* Parse and fetch channel spec passive */
4947 if (!channel[
4948 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4949 hddLog(LOGE,
4950 FL("attr channel spec passive failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].channels[j].passive =
4954 nla_get_u8(channel[
4955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4956 hddLog(LOG1, FL("Chnl spec passive %u"),
4957 pReqMsg->buckets[bktIndex].channels[j].passive);
4958
4959 j++;
4960 }
4961
4962 bktIndex++;
4963 }
4964
4965 return 0;
4966}
4967
4968
4969/*
4970 * define short names for the global vendor params
4971 * used by wlan_hdd_cfg80211_extscan_start()
4972 */
4973#define PARAM_MAX \
4974QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4975#define PARAM_REQUEST_ID \
4976QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4977#define PARAM_BASE_PERIOD \
4978QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4979#define PARAM_MAX_AP_PER_SCAN \
4980QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4981#define PARAM_RPT_THRHLD_PERCENT \
4982QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4983#define PARAM_RPT_THRHLD_NUM_SCANS \
4984QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4985#define PARAM_NUM_BUCKETS \
4986QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4987
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304988static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304989 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304990 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304991{
Dino Myclee8843b32014-07-04 14:21:45 +05304992 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304993 struct net_device *dev = wdev->netdev;
4994 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4996 struct nlattr *tb[PARAM_MAX + 1];
4997 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304998 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304999 tANI_U32 request_id;
5000 struct hdd_ext_scan_context *context;
5001 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305002
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305003 ENTER();
5004
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305005 if (VOS_FTM_MODE == hdd_get_conparam()) {
5006 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5007 return -EINVAL;
5008 }
5009
Dino Mycle6fb96c12014-06-10 11:52:40 +05305010 status = wlan_hdd_validate_context(pHddCtx);
5011 if (0 != status)
5012 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305013 return -EINVAL;
5014 }
Dino Myclee8843b32014-07-04 14:21:45 +05305015 /* check the EXTScan Capability */
5016 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305017 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5018 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305019 {
5020 hddLog(VOS_TRACE_LEVEL_ERROR,
5021 FL("EXTScan not enabled/supported by Firmware"));
5022 return -EINVAL;
5023 }
5024
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305025 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305026 data, dataLen,
5027 wlan_hdd_extscan_config_policy)) {
5028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5029 return -EINVAL;
5030 }
5031
5032 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305033 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305034 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5035 return -EINVAL;
5036 }
5037
Dino Myclee8843b32014-07-04 14:21:45 +05305038 pReqMsg = (tpSirEXTScanStartReqParams)
5039 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305040 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5042 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305043 }
5044
5045 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305046 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305047 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5048
5049 pReqMsg->sessionId = pAdapter->sessionId;
5050 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5051
5052 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305053 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5055 goto fail;
5056 }
5057 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305058 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5060 pReqMsg->basePeriod);
5061
5062 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305063 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5065 goto fail;
5066 }
5067 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305068 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5070 pReqMsg->maxAPperScan);
5071
5072 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305073 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5075 goto fail;
5076 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305077 pReqMsg->reportThresholdPercent = nla_get_u8(
5078 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305079 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305080 pReqMsg->reportThresholdPercent);
5081
5082 /* Parse and fetch report threshold num scans */
5083 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5084 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5085 goto fail;
5086 }
5087 pReqMsg->reportThresholdNumScans = nla_get_u8(
5088 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5089 hddLog(LOG1, FL("Report Threshold num scans %d"),
5090 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305091
5092 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305093 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5095 goto fail;
5096 }
5097 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305098 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305099 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5100 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5101 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5102 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5103 }
5104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5105 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305106
Dino Mycle6fb96c12014-06-10 11:52:40 +05305107 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5109 goto fail;
5110 }
5111
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305112 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305113
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305114 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5115 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305116
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305117 context = &pHddCtx->ext_scan_context;
5118 spin_lock(&hdd_context_lock);
5119 INIT_COMPLETION(context->response_event);
5120 context->request_id = request_id = pReqMsg->requestId;
5121 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305122
Dino Mycle6fb96c12014-06-10 11:52:40 +05305123 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5124 if (!HAL_STATUS_SUCCESS(status)) {
5125 hddLog(VOS_TRACE_LEVEL_ERROR,
5126 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305127 goto fail;
5128 }
5129
Srinivas Dasari91727c12016-03-23 17:59:06 +05305130 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5131
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305132 /* request was sent -- wait for the response */
5133 rc = wait_for_completion_timeout(&context->response_event,
5134 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5135
5136 if (!rc) {
5137 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5138 retval = -ETIMEDOUT;
5139 } else {
5140 spin_lock(&hdd_context_lock);
5141 if (context->request_id == request_id)
5142 retval = context->response_status;
5143 else
5144 retval = -EINVAL;
5145 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305146 }
5147
Dino Myclee8843b32014-07-04 14:21:45 +05305148 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305149 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305150 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305151
5152fail:
5153 vos_mem_free(pReqMsg);
5154 return -EINVAL;
5155}
5156
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305157/*
5158 * done with short names for the global vendor params
5159 * used by wlan_hdd_cfg80211_extscan_start()
5160 */
5161#undef PARAM_MAX
5162#undef PARAM_REQUEST_ID
5163#undef PARAM_BASE_PERIOD
5164#undef PARAMS_MAX_AP_PER_SCAN
5165#undef PARAMS_RPT_THRHLD_PERCENT
5166#undef PARAMS_RPT_THRHLD_NUM_SCANS
5167#undef PARAMS_NUM_BUCKETS
5168
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305169static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5170 struct wireless_dev *wdev,
5171 const void *data, int dataLen)
5172{
5173 int ret = 0;
5174
5175 vos_ssr_protect(__func__);
5176 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5177 vos_ssr_unprotect(__func__);
5178
5179 return ret;
5180}
5181
5182static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305183 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305184 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305185{
Dino Myclee8843b32014-07-04 14:21:45 +05305186 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 struct net_device *dev = wdev->netdev;
5188 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5189 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5190 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5191 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305192 int retval;
5193 unsigned long rc;
5194 struct hdd_ext_scan_context *context;
5195 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305197 ENTER();
5198
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305199 if (VOS_FTM_MODE == hdd_get_conparam()) {
5200 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5201 return -EINVAL;
5202 }
5203
Dino Mycle6fb96c12014-06-10 11:52:40 +05305204 status = wlan_hdd_validate_context(pHddCtx);
5205 if (0 != status)
5206 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305207 return -EINVAL;
5208 }
Dino Myclee8843b32014-07-04 14:21:45 +05305209 /* check the EXTScan Capability */
5210 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305211 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5212 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305213 {
5214 hddLog(VOS_TRACE_LEVEL_ERROR,
5215 FL("EXTScan not enabled/supported by Firmware"));
5216 return -EINVAL;
5217 }
5218
Dino Mycle6fb96c12014-06-10 11:52:40 +05305219 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5220 data, dataLen,
5221 wlan_hdd_extscan_config_policy)) {
5222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5223 return -EINVAL;
5224 }
5225
5226 /* Parse and fetch request Id */
5227 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5229 return -EINVAL;
5230 }
5231
Dino Myclee8843b32014-07-04 14:21:45 +05305232 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305235
Dino Myclee8843b32014-07-04 14:21:45 +05305236 reqMsg.sessionId = pAdapter->sessionId;
5237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305238
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305239 context = &pHddCtx->ext_scan_context;
5240 spin_lock(&hdd_context_lock);
5241 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305242 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305243 spin_unlock(&hdd_context_lock);
5244
Dino Myclee8843b32014-07-04 14:21:45 +05305245 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 if (!HAL_STATUS_SUCCESS(status)) {
5247 hddLog(VOS_TRACE_LEVEL_ERROR,
5248 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305249 return -EINVAL;
5250 }
5251
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305252 /* request was sent -- wait for the response */
5253 rc = wait_for_completion_timeout(&context->response_event,
5254 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5255
5256 if (!rc) {
5257 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5258 retval = -ETIMEDOUT;
5259 } else {
5260 spin_lock(&hdd_context_lock);
5261 if (context->request_id == request_id)
5262 retval = context->response_status;
5263 else
5264 retval = -EINVAL;
5265 spin_unlock(&hdd_context_lock);
5266 }
5267
5268 return retval;
5269
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305270 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305271 return 0;
5272}
5273
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305274static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5275 struct wireless_dev *wdev,
5276 const void *data, int dataLen)
5277{
5278 int ret = 0;
5279
5280 vos_ssr_protect(__func__);
5281 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5282 vos_ssr_unprotect(__func__);
5283
5284 return ret;
5285}
5286
5287static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305288 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305289 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305290{
Dino Myclee8843b32014-07-04 14:21:45 +05305291 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305292 struct net_device *dev = wdev->netdev;
5293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5294 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5295 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5296 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305297 struct hdd_ext_scan_context *context;
5298 tANI_U32 request_id;
5299 unsigned long rc;
5300 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305304 if (VOS_FTM_MODE == hdd_get_conparam()) {
5305 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5306 return -EINVAL;
5307 }
5308
Dino Mycle6fb96c12014-06-10 11:52:40 +05305309 status = wlan_hdd_validate_context(pHddCtx);
5310 if (0 != status)
5311 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305312 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305313 return -EINVAL;
5314 }
Dino Myclee8843b32014-07-04 14:21:45 +05305315 /* check the EXTScan Capability */
5316 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305317 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5318 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305319 {
5320 hddLog(VOS_TRACE_LEVEL_ERROR,
5321 FL("EXTScan not enabled/supported by Firmware"));
5322 return -EINVAL;
5323 }
5324
Dino Mycle6fb96c12014-06-10 11:52:40 +05305325 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5326 data, dataLen,
5327 wlan_hdd_extscan_config_policy)) {
5328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5329 return -EINVAL;
5330 }
5331
5332 /* Parse and fetch request Id */
5333 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5335 return -EINVAL;
5336 }
5337
Dino Myclee8843b32014-07-04 14:21:45 +05305338 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305339 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305340 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305341
Dino Myclee8843b32014-07-04 14:21:45 +05305342 reqMsg.sessionId = pAdapter->sessionId;
5343 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305344
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305345 context = &pHddCtx->ext_scan_context;
5346 spin_lock(&hdd_context_lock);
5347 INIT_COMPLETION(context->response_event);
5348 context->request_id = request_id = reqMsg.requestId;
5349 spin_unlock(&hdd_context_lock);
5350
Dino Myclee8843b32014-07-04 14:21:45 +05305351 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305352 if (!HAL_STATUS_SUCCESS(status)) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR,
5354 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305355 return -EINVAL;
5356 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305357
5358 /* request was sent -- wait for the response */
5359 rc = wait_for_completion_timeout(&context->response_event,
5360 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5361 if (!rc) {
5362 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5363 retval = -ETIMEDOUT;
5364 } else {
5365 spin_lock(&hdd_context_lock);
5366 if (context->request_id == request_id)
5367 retval = context->response_status;
5368 else
5369 retval = -EINVAL;
5370 spin_unlock(&hdd_context_lock);
5371 }
5372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305373 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305374 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305375}
5376
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305377static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5378 struct wireless_dev *wdev,
5379 const void *data, int dataLen)
5380{
5381 int ret = 0;
5382
5383 vos_ssr_protect(__func__);
5384 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5385 vos_ssr_unprotect(__func__);
5386
5387 return ret;
5388}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305389#endif /* WLAN_FEATURE_EXTSCAN */
5390
Atul Mittal115287b2014-07-08 13:26:33 +05305391/*EXT TDLS*/
5392static const struct nla_policy
5393wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5394{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305395 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5396 .type = NLA_UNSPEC,
5397 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305398 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5399 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5400 {.type = NLA_S32 },
5401 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5402 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5403
5404};
5405
5406static const struct nla_policy
5407wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5408{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305409 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5410 .type = NLA_UNSPEC,
5411 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305412
5413};
5414
5415static const struct nla_policy
5416wlan_hdd_tdls_config_state_change_policy[
5417 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5418{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305419 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5420 .type = NLA_UNSPEC,
5421 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305422 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5423 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305424 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5425 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5426 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305427
5428};
5429
5430static const struct nla_policy
5431wlan_hdd_tdls_config_get_status_policy[
5432 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5433{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305434 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5435 .type = NLA_UNSPEC,
5436 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305437 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5438 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305439 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5440 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5441 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305442
5443};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305444
5445static const struct nla_policy
5446wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5447{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305448 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5449 .type = NLA_UNSPEC,
5450 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305451};
5452
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305453static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305454 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305455 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305456 int data_len)
5457{
5458
5459 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5460 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305462 ENTER();
5463
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305464 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305465 return -EINVAL;
5466 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305467 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305468 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305469 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305470 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305471 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305473 return -ENOTSUPP;
5474 }
5475
5476 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5477 data, data_len, wlan_hdd_mac_config)) {
5478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5479 return -EINVAL;
5480 }
5481
5482 /* Parse and fetch mac address */
5483 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5485 return -EINVAL;
5486 }
5487
5488 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5489 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5490 VOS_MAC_ADDR_LAST_3_BYTES);
5491
Siddharth Bhal76972212014-10-15 16:22:51 +05305492 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5493
5494 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305495 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5496 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305497 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5498 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5499 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5500 {
5501 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5502 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5503 VOS_MAC_ADDRESS_LEN);
5504 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305505 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305506
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305507 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5508 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305510 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305511 return 0;
5512}
5513
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305514static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5515 struct wireless_dev *wdev,
5516 const void *data,
5517 int data_len)
5518{
5519 int ret = 0;
5520
5521 vos_ssr_protect(__func__);
5522 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5523 vos_ssr_unprotect(__func__);
5524
5525 return ret;
5526}
5527
5528static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305529 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305530 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305531 int data_len)
5532{
5533 u8 peer[6] = {0};
5534 struct net_device *dev = wdev->netdev;
5535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5537 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5538 eHalStatus ret;
5539 tANI_S32 state;
5540 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305541 tANI_S32 global_operating_class = 0;
5542 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305543 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305544 int retVal;
5545
5546 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305547
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305548 if (!pAdapter) {
5549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5550 return -EINVAL;
5551 }
5552
Atul Mittal115287b2014-07-08 13:26:33 +05305553 ret = wlan_hdd_validate_context(pHddCtx);
5554 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305556 return -EINVAL;
5557 }
5558 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305560 return -ENOTSUPP;
5561 }
5562 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5563 data, data_len,
5564 wlan_hdd_tdls_config_get_status_policy)) {
5565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5566 return -EINVAL;
5567 }
5568
5569 /* Parse and fetch mac address */
5570 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5572 return -EINVAL;
5573 }
5574
5575 memcpy(peer, nla_data(
5576 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5577 sizeof(peer));
5578 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5579
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305580 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305581
Atul Mittal115287b2014-07-08 13:26:33 +05305582 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305583 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305584 NLMSG_HDRLEN);
5585
5586 if (!skb) {
5587 hddLog(VOS_TRACE_LEVEL_ERROR,
5588 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5589 return -EINVAL;
5590 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305591 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 +05305592 reason,
5593 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305594 global_operating_class,
5595 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305596 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305597 if (nla_put_s32(skb,
5598 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5599 state) ||
5600 nla_put_s32(skb,
5601 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5602 reason) ||
5603 nla_put_s32(skb,
5604 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5605 global_operating_class) ||
5606 nla_put_s32(skb,
5607 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5608 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305609
5610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5611 goto nla_put_failure;
5612 }
5613
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305614 retVal = cfg80211_vendor_cmd_reply(skb);
5615 EXIT();
5616 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305617
5618nla_put_failure:
5619 kfree_skb(skb);
5620 return -EINVAL;
5621}
5622
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305623static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5624 struct wireless_dev *wdev,
5625 const void *data,
5626 int data_len)
5627{
5628 int ret = 0;
5629
5630 vos_ssr_protect(__func__);
5631 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5632 vos_ssr_unprotect(__func__);
5633
5634 return ret;
5635}
5636
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305637static int wlan_hdd_cfg80211_exttdls_callback(
5638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5639 const tANI_U8* mac,
5640#else
5641 tANI_U8* mac,
5642#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305643 tANI_S32 state,
5644 tANI_S32 reason,
5645 void *ctx)
5646{
5647 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305648 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305649 tANI_S32 global_operating_class = 0;
5650 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305651 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305653 ENTER();
5654
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305655 if (!pAdapter) {
5656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5657 return -EINVAL;
5658 }
5659
5660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305661 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305663 return -EINVAL;
5664 }
5665
5666 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305668 return -ENOTSUPP;
5669 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305670 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5672 NULL,
5673#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305674 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5675 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5676 GFP_KERNEL);
5677
5678 if (!skb) {
5679 hddLog(VOS_TRACE_LEVEL_ERROR,
5680 FL("cfg80211_vendor_event_alloc failed"));
5681 return -EINVAL;
5682 }
5683 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305684 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5685 reason,
5686 state,
5687 global_operating_class,
5688 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305689 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5690 MAC_ADDR_ARRAY(mac));
5691
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305692 if (nla_put(skb,
5693 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5694 VOS_MAC_ADDR_SIZE, mac) ||
5695 nla_put_s32(skb,
5696 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5697 state) ||
5698 nla_put_s32(skb,
5699 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5700 reason) ||
5701 nla_put_s32(skb,
5702 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5703 channel) ||
5704 nla_put_s32(skb,
5705 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5706 global_operating_class)
5707 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5709 goto nla_put_failure;
5710 }
5711
5712 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305713 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305714 return (0);
5715
5716nla_put_failure:
5717 kfree_skb(skb);
5718 return -EINVAL;
5719}
5720
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305721static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305722 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305723 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305724 int data_len)
5725{
5726 u8 peer[6] = {0};
5727 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305728 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5729 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5730 eHalStatus status;
5731 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305732 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305733 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305734
5735 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305736
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305737 if (!dev) {
5738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5739 return -EINVAL;
5740 }
5741
5742 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5743 if (!pAdapter) {
5744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5745 return -EINVAL;
5746 }
5747
Atul Mittal115287b2014-07-08 13:26:33 +05305748 status = wlan_hdd_validate_context(pHddCtx);
5749 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305751 return -EINVAL;
5752 }
5753 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305755 return -ENOTSUPP;
5756 }
5757 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5758 data, data_len,
5759 wlan_hdd_tdls_config_enable_policy)) {
5760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5761 return -EINVAL;
5762 }
5763
5764 /* Parse and fetch mac address */
5765 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5767 return -EINVAL;
5768 }
5769
5770 memcpy(peer, nla_data(
5771 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5772 sizeof(peer));
5773 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5774
5775 /* Parse and fetch channel */
5776 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5778 return -EINVAL;
5779 }
5780 pReqMsg.channel = nla_get_s32(
5781 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5782 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5783
5784 /* Parse and fetch global operating class */
5785 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5787 return -EINVAL;
5788 }
5789 pReqMsg.global_operating_class = nla_get_s32(
5790 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5791 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5792 pReqMsg.global_operating_class);
5793
5794 /* Parse and fetch latency ms */
5795 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5797 return -EINVAL;
5798 }
5799 pReqMsg.max_latency_ms = nla_get_s32(
5800 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5801 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5802 pReqMsg.max_latency_ms);
5803
5804 /* Parse and fetch required bandwidth kbps */
5805 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5807 return -EINVAL;
5808 }
5809
5810 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5811 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5812 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5813 pReqMsg.min_bandwidth_kbps);
5814
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305815 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305816 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305817 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305818 wlan_hdd_cfg80211_exttdls_callback);
5819
5820 EXIT();
5821 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305822}
5823
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305824static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5825 struct wireless_dev *wdev,
5826 const void *data,
5827 int data_len)
5828{
5829 int ret = 0;
5830
5831 vos_ssr_protect(__func__);
5832 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5833 vos_ssr_unprotect(__func__);
5834
5835 return ret;
5836}
5837
5838static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305839 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305840 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305841 int data_len)
5842{
5843 u8 peer[6] = {0};
5844 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305845 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5846 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5847 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305848 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305849 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305850
5851 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305852
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305853 if (!dev) {
5854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5855 return -EINVAL;
5856 }
5857
5858 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5859 if (!pAdapter) {
5860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5861 return -EINVAL;
5862 }
5863
Atul Mittal115287b2014-07-08 13:26:33 +05305864 status = wlan_hdd_validate_context(pHddCtx);
5865 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305867 return -EINVAL;
5868 }
5869 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305871 return -ENOTSUPP;
5872 }
5873 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5874 data, data_len,
5875 wlan_hdd_tdls_config_disable_policy)) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5877 return -EINVAL;
5878 }
5879 /* Parse and fetch mac address */
5880 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5882 return -EINVAL;
5883 }
5884
5885 memcpy(peer, nla_data(
5886 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5887 sizeof(peer));
5888 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305890 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5891
5892 EXIT();
5893 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305894}
5895
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305896static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5897 struct wireless_dev *wdev,
5898 const void *data,
5899 int data_len)
5900{
5901 int ret = 0;
5902
5903 vos_ssr_protect(__func__);
5904 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5905 vos_ssr_unprotect(__func__);
5906
5907 return ret;
5908}
5909
Dasari Srinivas7875a302014-09-26 17:50:57 +05305910static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305911__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305912 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305913 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305914{
5915 struct net_device *dev = wdev->netdev;
5916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5917 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5918 struct sk_buff *skb = NULL;
5919 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305920 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305922 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305923
5924 ret = wlan_hdd_validate_context(pHddCtx);
5925 if (0 != ret)
5926 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305927 return ret;
5928 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305929 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5930 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5931 fset |= WIFI_FEATURE_INFRA;
5932 }
5933
5934 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5935 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5936 fset |= WIFI_FEATURE_INFRA_5G;
5937 }
5938
5939#ifdef WLAN_FEATURE_P2P
5940 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5941 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5942 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5943 fset |= WIFI_FEATURE_P2P;
5944 }
5945#endif
5946
5947 /* Soft-AP is supported currently by default */
5948 fset |= WIFI_FEATURE_SOFT_AP;
5949
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305950 /* HOTSPOT is a supplicant feature, enable it by default */
5951 fset |= WIFI_FEATURE_HOTSPOT;
5952
Dasari Srinivas7875a302014-09-26 17:50:57 +05305953#ifdef WLAN_FEATURE_EXTSCAN
5954 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305955 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5956 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5957 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305958 fset |= WIFI_FEATURE_EXTSCAN;
5959 }
5960#endif
5961
Dasari Srinivas7875a302014-09-26 17:50:57 +05305962 if (sme_IsFeatureSupportedByFW(NAN)) {
5963 hddLog(LOG1, FL("NAN is supported by firmware"));
5964 fset |= WIFI_FEATURE_NAN;
5965 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305966
5967 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305968 if (sme_IsFeatureSupportedByFW(RTT) &&
5969 pHddCtx->cfg_ini->enable_rtt_support) {
5970 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305971 fset |= WIFI_FEATURE_D2AP_RTT;
5972 }
5973
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305974 if (sme_IsFeatureSupportedByFW(RTT3)) {
5975 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5976 fset |= WIFI_FEATURE_RTT3;
5977 }
5978
Dasari Srinivas7875a302014-09-26 17:50:57 +05305979#ifdef FEATURE_WLAN_BATCH_SCAN
5980 if (fset & WIFI_FEATURE_EXTSCAN) {
5981 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5982 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5983 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5984 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5985 fset |= WIFI_FEATURE_BATCH_SCAN;
5986 }
5987#endif
5988
5989#ifdef FEATURE_WLAN_SCAN_PNO
5990 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5991 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5992 hddLog(LOG1, FL("PNO is supported by firmware"));
5993 fset |= WIFI_FEATURE_PNO;
5994 }
5995#endif
5996
5997 /* STA+STA is supported currently by default */
5998 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5999
6000#ifdef FEATURE_WLAN_TDLS
6001 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6002 sme_IsFeatureSupportedByFW(TDLS)) {
6003 hddLog(LOG1, FL("TDLS is supported by firmware"));
6004 fset |= WIFI_FEATURE_TDLS;
6005 }
6006
6007 /* TDLS_OFFCHANNEL is not supported currently by default */
6008#endif
6009
6010#ifdef WLAN_AP_STA_CONCURRENCY
6011 /* AP+STA concurrency is supported currently by default */
6012 fset |= WIFI_FEATURE_AP_STA;
6013#endif
6014
Mukul Sharma5add0532015-08-17 15:57:47 +05306015#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306016 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6017 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306018 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6019 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306020 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306021#endif
6022
Dasari Srinivas7875a302014-09-26 17:50:57 +05306023 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6024 NLMSG_HDRLEN);
6025
6026 if (!skb) {
6027 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6028 return -EINVAL;
6029 }
6030 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6031
6032 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6033 hddLog(LOGE, FL("nla put fail"));
6034 goto nla_put_failure;
6035 }
6036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306037 ret = cfg80211_vendor_cmd_reply(skb);
6038 EXIT();
6039 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306040
6041nla_put_failure:
6042 kfree_skb(skb);
6043 return -EINVAL;
6044}
6045
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306046static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306047wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6048 struct wireless_dev *wdev,
6049 const void *data, int data_len)
6050{
6051 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306052 vos_ssr_protect(__func__);
6053 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6054 vos_ssr_unprotect(__func__);
6055
6056 return ret;
6057}
6058
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306059
6060static const struct
6061nla_policy
6062qca_wlan_vendor_wifi_logger_get_ring_data_policy
6063[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6064 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6065 = {.type = NLA_U32 },
6066};
6067
6068static int
6069 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6070 struct wireless_dev *wdev,
6071 const void *data,
6072 int data_len)
6073{
6074 int ret;
6075 VOS_STATUS status;
6076 uint32_t ring_id;
6077 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6078 struct nlattr *tb
6079 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6080
6081 ENTER();
6082
6083 ret = wlan_hdd_validate_context(hdd_ctx);
6084 if (0 != ret) {
6085 return ret;
6086 }
6087
6088 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6089 data, data_len,
6090 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6091 hddLog(LOGE, FL("Invalid attribute"));
6092 return -EINVAL;
6093 }
6094
6095 /* Parse and fetch ring id */
6096 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6097 hddLog(LOGE, FL("attr ATTR failed"));
6098 return -EINVAL;
6099 }
6100
6101 ring_id = nla_get_u32(
6102 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6103
6104 hddLog(LOG1, FL("Bug report triggered by framework"));
6105
6106 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6107 WLAN_LOG_INDICATOR_FRAMEWORK,
6108 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306109 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306110 );
6111 if (VOS_STATUS_SUCCESS != status) {
6112 hddLog(LOGE, FL("Failed to trigger bug report"));
6113
6114 return -EINVAL;
6115 }
6116
6117 return 0;
6118
6119
6120}
6121
6122
6123static int
6124 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6125 struct wireless_dev *wdev,
6126 const void *data,
6127 int data_len)
6128{
6129 int ret = 0;
6130
6131 vos_ssr_protect(__func__);
6132 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6133 wdev, data, data_len);
6134 vos_ssr_unprotect(__func__);
6135
6136 return ret;
6137
6138}
6139
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306140#define MAX_CONCURRENT_MATRIX \
6141 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6142#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6143 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6144static const struct nla_policy
6145wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6146 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6147};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306148
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306149static int
6150__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306151 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306152 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306153{
6154 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6155 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306156 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306157 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306158 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6159 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306160
6161 ENTER();
6162
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306163 ret = wlan_hdd_validate_context(pHddCtx);
6164 if (0 != ret)
6165 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306166 return ret;
6167 }
6168
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306169 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6170 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306171 hddLog(LOGE, FL("Invalid ATTR"));
6172 return -EINVAL;
6173 }
6174
6175 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306176 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306177 hddLog(LOGE, FL("Attr max feature set size failed"));
6178 return -EINVAL;
6179 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306180 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306181 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6182
6183 /* Fill feature combination matrix */
6184 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306185 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6186 WIFI_FEATURE_P2P;
6187
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306188 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6189 WIFI_FEATURE_SOFT_AP;
6190
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306191 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6192 WIFI_FEATURE_SOFT_AP;
6193
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306194 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6195 WIFI_FEATURE_SOFT_AP |
6196 WIFI_FEATURE_P2P;
6197
6198 /* Add more feature combinations here */
6199
6200 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6201 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6202 hddLog(LOG1, "Feature set matrix");
6203 for (i = 0; i < feature_sets; i++)
6204 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6205
6206 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6207 sizeof(u32) * feature_sets +
6208 NLMSG_HDRLEN);
6209
6210 if (reply_skb) {
6211 if (nla_put_u32(reply_skb,
6212 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6213 feature_sets) ||
6214 nla_put(reply_skb,
6215 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6216 sizeof(u32) * feature_sets, feature_set_matrix)) {
6217 hddLog(LOGE, FL("nla put fail"));
6218 kfree_skb(reply_skb);
6219 return -EINVAL;
6220 }
6221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306222 ret = cfg80211_vendor_cmd_reply(reply_skb);
6223 EXIT();
6224 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306225 }
6226 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6227 return -ENOMEM;
6228
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306229}
6230
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306231#undef MAX_CONCURRENT_MATRIX
6232#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6233
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306234static int
6235wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6236 struct wireless_dev *wdev,
6237 const void *data, int data_len)
6238{
6239 int ret = 0;
6240
6241 vos_ssr_protect(__func__);
6242 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6243 data_len);
6244 vos_ssr_unprotect(__func__);
6245
6246 return ret;
6247}
6248
c_manjeecfd1efb2015-09-25 19:32:34 +05306249
6250static int
6251__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6252 struct wireless_dev *wdev,
6253 const void *data, int data_len)
6254{
6255 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6256 int ret;
6257 ENTER();
6258
6259 ret = wlan_hdd_validate_context(pHddCtx);
6260 if (0 != ret)
6261 {
6262 return ret;
6263 }
6264
6265 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6266 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6267 {
6268 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306269 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306270 }
6271 /*call common API for FW mem dump req*/
6272 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6273
Abhishek Singhc783fa72015-12-09 18:07:34 +05306274 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306275 {
6276 /*indicate to userspace the status of fw mem dump */
6277 wlan_indicate_mem_dump_complete(true);
6278 }
6279 else
6280 {
6281 /*else send failure to userspace */
6282 wlan_indicate_mem_dump_complete(false);
6283 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306284 EXIT();
6285 return ret;
6286}
6287
6288/**
6289 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6290 * @wiphy: pointer to wireless wiphy structure.
6291 * @wdev: pointer to wireless_dev structure.
6292 * @data: Pointer to the NL data.
6293 * @data_len:Length of @data
6294 *
6295 * This is called when wlan driver needs to get the firmware memory dump
6296 * via vendor specific command.
6297 *
6298 * Return: 0 on success, error number otherwise.
6299 */
6300
6301static int
6302wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6303 struct wireless_dev *wdev,
6304 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306305{
6306 int ret = 0;
6307 vos_ssr_protect(__func__);
6308 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6309 data_len);
6310 vos_ssr_unprotect(__func__);
6311 return ret;
6312}
c_manjeecfd1efb2015-09-25 19:32:34 +05306313
Sushant Kaushik8e644982015-09-23 12:18:54 +05306314static const struct
6315nla_policy
6316qca_wlan_vendor_wifi_logger_start_policy
6317[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6318 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6319 = {.type = NLA_U32 },
6320 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6321 = {.type = NLA_U32 },
6322 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6323 = {.type = NLA_U32 },
6324};
6325
6326/**
6327 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6328 * or disable the collection of packet statistics from the firmware
6329 * @wiphy: WIPHY structure pointer
6330 * @wdev: Wireless device structure pointer
6331 * @data: Pointer to the data received
6332 * @data_len: Length of the data received
6333 *
6334 * This function is used to enable or disable the collection of packet
6335 * statistics from the firmware
6336 *
6337 * Return: 0 on success and errno on failure
6338 */
6339static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6340 struct wireless_dev *wdev,
6341 const void *data,
6342 int data_len)
6343{
6344 eHalStatus status;
6345 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6346 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6347 tAniWifiStartLog start_log;
6348
6349 status = wlan_hdd_validate_context(hdd_ctx);
6350 if (0 != status) {
6351 return -EINVAL;
6352 }
6353
6354 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6355 data, data_len,
6356 qca_wlan_vendor_wifi_logger_start_policy)) {
6357 hddLog(LOGE, FL("Invalid attribute"));
6358 return -EINVAL;
6359 }
6360
6361 /* Parse and fetch ring id */
6362 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6363 hddLog(LOGE, FL("attr ATTR failed"));
6364 return -EINVAL;
6365 }
6366 start_log.ringId = nla_get_u32(
6367 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6368 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6369
6370 /* Parse and fetch verbose level */
6371 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6372 hddLog(LOGE, FL("attr verbose_level failed"));
6373 return -EINVAL;
6374 }
6375 start_log.verboseLevel = nla_get_u32(
6376 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6377 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6378
6379 /* Parse and fetch flag */
6380 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6381 hddLog(LOGE, FL("attr flag failed"));
6382 return -EINVAL;
6383 }
6384 start_log.flag = nla_get_u32(
6385 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6386 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6387
6388 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306389 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6390 !vos_isPktStatsEnabled()))
6391
Sushant Kaushik8e644982015-09-23 12:18:54 +05306392 {
6393 hddLog(LOGE, FL("per pkt stats not enabled"));
6394 return -EINVAL;
6395 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306396
Sushant Kaushik33200572015-08-05 16:46:20 +05306397 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306398 return 0;
6399}
6400
6401/**
6402 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6403 * or disable the collection of packet statistics from the firmware
6404 * @wiphy: WIPHY structure pointer
6405 * @wdev: Wireless device structure pointer
6406 * @data: Pointer to the data received
6407 * @data_len: Length of the data received
6408 *
6409 * This function is used to enable or disable the collection of packet
6410 * statistics from the firmware
6411 *
6412 * Return: 0 on success and errno on failure
6413 */
6414static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6415 struct wireless_dev *wdev,
6416 const void *data,
6417 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306418{
6419 int ret = 0;
6420
6421 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306422
6423 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6424 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306425 vos_ssr_unprotect(__func__);
6426
6427 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306428}
6429
6430
Agarwal Ashish738843c2014-09-25 12:27:56 +05306431static const struct nla_policy
6432wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6433 +1] =
6434{
6435 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6436};
6437
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306438static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306439 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306440 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306441 int data_len)
6442{
6443 struct net_device *dev = wdev->netdev;
6444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6445 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6446 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6447 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6448 eHalStatus status;
6449 u32 dfsFlag = 0;
6450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306451 ENTER();
6452
Agarwal Ashish738843c2014-09-25 12:27:56 +05306453 status = wlan_hdd_validate_context(pHddCtx);
6454 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306455 return -EINVAL;
6456 }
6457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6458 data, data_len,
6459 wlan_hdd_set_no_dfs_flag_config_policy)) {
6460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6461 return -EINVAL;
6462 }
6463
6464 /* Parse and fetch required bandwidth kbps */
6465 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6467 return -EINVAL;
6468 }
6469
6470 dfsFlag = nla_get_u32(
6471 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6472 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6473 dfsFlag);
6474
6475 pHddCtx->disable_dfs_flag = dfsFlag;
6476
6477 sme_disable_dfs_channel(hHal, dfsFlag);
6478 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306479
6480 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306481 return 0;
6482}
Atul Mittal115287b2014-07-08 13:26:33 +05306483
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306484static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6485 struct wireless_dev *wdev,
6486 const void *data,
6487 int data_len)
6488{
6489 int ret = 0;
6490
6491 vos_ssr_protect(__func__);
6492 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6493 vos_ssr_unprotect(__func__);
6494
6495 return ret;
6496
6497}
6498
Mukul Sharma2a271632014-10-13 14:59:01 +05306499const struct
6500nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6501{
6502 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306503 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6504 .type = NLA_UNSPEC,
6505 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306506};
6507
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306508static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306509 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306510{
6511
6512 u8 bssid[6] = {0};
6513 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6514 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6515 eHalStatus status = eHAL_STATUS_SUCCESS;
6516 v_U32_t isFwrRoamEnabled = FALSE;
6517 int ret;
6518
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306519 ENTER();
6520
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306521 ret = wlan_hdd_validate_context(pHddCtx);
6522 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306523 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306524 }
6525
6526 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6527 data, data_len,
6528 qca_wlan_vendor_attr);
6529 if (ret){
6530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6531 return -EINVAL;
6532 }
6533
6534 /* Parse and fetch Enable flag */
6535 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6537 return -EINVAL;
6538 }
6539
6540 isFwrRoamEnabled = nla_get_u32(
6541 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6542
6543 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6544
6545 /* Parse and fetch bssid */
6546 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6548 return -EINVAL;
6549 }
6550
6551 memcpy(bssid, nla_data(
6552 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6553 sizeof(bssid));
6554 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6555
6556 //Update roaming
6557 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306558 if (!HAL_STATUS_SUCCESS(status)) {
6559 hddLog(LOGE,
6560 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6561 return -EINVAL;
6562 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306563 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306564 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306565}
6566
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306567static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6568 struct wireless_dev *wdev, const void *data, int data_len)
6569{
6570 int ret = 0;
6571
6572 vos_ssr_protect(__func__);
6573 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6574 vos_ssr_unprotect(__func__);
6575
6576 return ret;
6577}
6578
Sushant Kaushik847890c2015-09-28 16:05:17 +05306579static const struct
6580nla_policy
6581qca_wlan_vendor_get_wifi_info_policy[
6582 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6583 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6584 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6585};
6586
6587
6588/**
6589 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6590 * @wiphy: pointer to wireless wiphy structure.
6591 * @wdev: pointer to wireless_dev structure.
6592 * @data: Pointer to the data to be passed via vendor interface
6593 * @data_len:Length of the data to be passed
6594 *
6595 * This is called when wlan driver needs to send wifi driver related info
6596 * (driver/fw version) to the user space application upon request.
6597 *
6598 * Return: Return the Success or Failure code.
6599 */
6600static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6601 struct wireless_dev *wdev,
6602 const void *data, int data_len)
6603{
6604 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6605 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6606 tSirVersionString version;
6607 uint32 version_len;
6608 uint8 attr;
6609 int status;
6610 struct sk_buff *reply_skb = NULL;
6611
6612 if (VOS_FTM_MODE == hdd_get_conparam()) {
6613 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6614 return -EINVAL;
6615 }
6616
6617 status = wlan_hdd_validate_context(hdd_ctx);
6618 if (0 != status) {
6619 hddLog(LOGE, FL("HDD context is not valid"));
6620 return -EINVAL;
6621 }
6622
6623 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6624 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6625 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6626 return -EINVAL;
6627 }
6628
6629 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6630 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6631 QWLAN_VERSIONSTR);
6632 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6633 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6634 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6635 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6636 hdd_ctx->fw_Version);
6637 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6638 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6639 } else {
6640 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6641 return -EINVAL;
6642 }
6643
6644 version_len = strlen(version);
6645 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6646 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6647 if (!reply_skb) {
6648 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6649 return -ENOMEM;
6650 }
6651
6652 if (nla_put(reply_skb, attr, version_len, version)) {
6653 hddLog(LOGE, FL("nla put fail"));
6654 kfree_skb(reply_skb);
6655 return -EINVAL;
6656 }
6657
6658 return cfg80211_vendor_cmd_reply(reply_skb);
6659}
6660
6661/**
6662 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6663 * @wiphy: pointer to wireless wiphy structure.
6664 * @wdev: pointer to wireless_dev structure.
6665 * @data: Pointer to the data to be passed via vendor interface
6666 * @data_len:Length of the data to be passed
6667 * @data_len: Length of the data received
6668 *
6669 * This function is used to enable or disable the collection of packet
6670 * statistics from the firmware
6671 *
6672 * Return: 0 on success and errno on failure
6673 */
6674
6675static int
6676wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6677 struct wireless_dev *wdev,
6678 const void *data, int data_len)
6679
6680
6681{
6682 int ret = 0;
6683
6684 vos_ssr_protect(__func__);
6685 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6686 wdev, data, data_len);
6687 vos_ssr_unprotect(__func__);
6688
6689 return ret;
6690}
6691
6692
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306693/*
6694 * define short names for the global vendor params
6695 * used by __wlan_hdd_cfg80211_monitor_rssi()
6696 */
6697#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6698#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6699#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6700#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6701#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6702
6703/**---------------------------------------------------------------------------
6704
6705 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6706 monitor start is completed successfully.
6707
6708 \return - None
6709
6710 --------------------------------------------------------------------------*/
6711void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6712{
6713 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6714
6715 if (NULL == pHddCtx)
6716 {
6717 hddLog(VOS_TRACE_LEVEL_ERROR,
6718 "%s: HDD context is NULL",__func__);
6719 return;
6720 }
6721
6722 if (VOS_STATUS_SUCCESS == status)
6723 {
6724 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6725 }
6726 else
6727 {
6728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6729 }
6730
6731 return;
6732}
6733
6734/**---------------------------------------------------------------------------
6735
6736 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6737 stop is completed successfully.
6738
6739 \return - None
6740
6741 --------------------------------------------------------------------------*/
6742void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6743{
6744 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6745
6746 if (NULL == pHddCtx)
6747 {
6748 hddLog(VOS_TRACE_LEVEL_ERROR,
6749 "%s: HDD context is NULL",__func__);
6750 return;
6751 }
6752
6753 if (VOS_STATUS_SUCCESS == status)
6754 {
6755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6756 }
6757 else
6758 {
6759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6760 }
6761
6762 return;
6763}
6764
6765/**
6766 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6767 * @wiphy: Pointer to wireless phy
6768 * @wdev: Pointer to wireless device
6769 * @data: Pointer to data
6770 * @data_len: Data length
6771 *
6772 * Return: 0 on success, negative errno on failure
6773 */
6774
6775static int
6776__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6777 struct wireless_dev *wdev,
6778 const void *data,
6779 int data_len)
6780{
6781 struct net_device *dev = wdev->netdev;
6782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6783 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6784 hdd_station_ctx_t *pHddStaCtx;
6785 struct nlattr *tb[PARAM_MAX + 1];
6786 tpSirRssiMonitorReq pReq;
6787 eHalStatus status;
6788 int ret;
6789 uint32_t control;
6790 static const struct nla_policy policy[PARAM_MAX + 1] = {
6791 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6792 [PARAM_CONTROL] = { .type = NLA_U32 },
6793 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6794 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6795 };
6796
6797 ENTER();
6798
6799 ret = wlan_hdd_validate_context(hdd_ctx);
6800 if (0 != ret) {
6801 return -EINVAL;
6802 }
6803
6804 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6805 hddLog(LOGE, FL("Not in Connected state!"));
6806 return -ENOTSUPP;
6807 }
6808
6809 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6810 hddLog(LOGE, FL("Invalid ATTR"));
6811 return -EINVAL;
6812 }
6813
6814 if (!tb[PARAM_REQUEST_ID]) {
6815 hddLog(LOGE, FL("attr request id failed"));
6816 return -EINVAL;
6817 }
6818
6819 if (!tb[PARAM_CONTROL]) {
6820 hddLog(LOGE, FL("attr control failed"));
6821 return -EINVAL;
6822 }
6823
6824 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6825
6826 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6827 if(NULL == pReq)
6828 {
6829 hddLog(LOGE,
6830 FL("vos_mem_alloc failed "));
6831 return eHAL_STATUS_FAILED_ALLOC;
6832 }
6833 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6834
6835 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6836 pReq->sessionId = pAdapter->sessionId;
6837 pReq->rssiMonitorCbContext = hdd_ctx;
6838 control = nla_get_u32(tb[PARAM_CONTROL]);
6839 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6840
6841 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6842 pReq->requestId, pReq->sessionId, control);
6843
6844 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6845 if (!tb[PARAM_MIN_RSSI]) {
6846 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306847 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306848 }
6849
6850 if (!tb[PARAM_MAX_RSSI]) {
6851 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306852 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306853 }
6854
6855 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6856 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6857 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6858
6859 if (!(pReq->minRssi < pReq->maxRssi)) {
6860 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6861 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306862 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306863 }
6864 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6865 pReq->minRssi, pReq->maxRssi);
6866 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6867
6868 }
6869 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6870 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6871 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6872 }
6873 else {
6874 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306875 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306876 }
6877
6878 if (!HAL_STATUS_SUCCESS(status)) {
6879 hddLog(LOGE,
6880 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306881 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306882 }
6883
6884 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306885fail:
6886 vos_mem_free(pReq);
6887 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306888}
6889
6890/*
6891 * done with short names for the global vendor params
6892 * used by __wlan_hdd_cfg80211_monitor_rssi()
6893 */
6894#undef PARAM_MAX
6895#undef PARAM_CONTROL
6896#undef PARAM_REQUEST_ID
6897#undef PARAM_MAX_RSSI
6898#undef PARAM_MIN_RSSI
6899
6900/**
6901 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6902 * @wiphy: wiphy structure pointer
6903 * @wdev: Wireless device structure pointer
6904 * @data: Pointer to the data received
6905 * @data_len: Length of @data
6906 *
6907 * Return: 0 on success; errno on failure
6908 */
6909static int
6910wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6911 const void *data, int data_len)
6912{
6913 int ret;
6914
6915 vos_ssr_protect(__func__);
6916 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6917 vos_ssr_unprotect(__func__);
6918
6919 return ret;
6920}
6921
6922/**
6923 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6924 * @hddctx: HDD context
6925 * @data: rssi breached event data
6926 *
6927 * This function reads the rssi breached event %data and fill in the skb with
6928 * NL attributes and send up the NL event.
6929 * This callback execute in atomic context and must not invoke any
6930 * blocking calls.
6931 *
6932 * Return: none
6933 */
6934void hdd_rssi_threshold_breached_cb(void *hddctx,
6935 struct rssi_breach_event *data)
6936{
6937 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6938 int status;
6939 struct sk_buff *skb;
6940
6941 ENTER();
6942 status = wlan_hdd_validate_context(pHddCtx);
6943
6944 if (0 != status) {
6945 return;
6946 }
6947
6948 if (!data) {
6949 hddLog(LOGE, FL("data is null"));
6950 return;
6951 }
6952
6953 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6955 NULL,
6956#endif
6957 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6958 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6959 GFP_KERNEL);
6960
6961 if (!skb) {
6962 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6963 return;
6964 }
6965
6966 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6967 data->request_id, data->curr_rssi);
6968 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6969 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6970
6971 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6972 data->request_id) ||
6973 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6974 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6975 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6976 data->curr_rssi)) {
6977 hddLog(LOGE, FL("nla put fail"));
6978 goto fail;
6979 }
6980
6981 cfg80211_vendor_event(skb, GFP_KERNEL);
6982 return;
6983
6984fail:
6985 kfree_skb(skb);
6986 return;
6987}
6988
6989
6990
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306991/**
6992 * __wlan_hdd_cfg80211_setband() - set band
6993 * @wiphy: Pointer to wireless phy
6994 * @wdev: Pointer to wireless device
6995 * @data: Pointer to data
6996 * @data_len: Data length
6997 *
6998 * Return: 0 on success, negative errno on failure
6999 */
7000static int
7001__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7002 struct wireless_dev *wdev,
7003 const void *data,
7004 int data_len)
7005{
7006 struct net_device *dev = wdev->netdev;
7007 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7008 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7009 int ret;
7010 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7011 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7012
7013 ENTER();
7014
7015 ret = wlan_hdd_validate_context(hdd_ctx);
7016 if (0 != ret) {
7017 hddLog(LOGE, FL("HDD context is not valid"));
7018 return ret;
7019 }
7020
7021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7022 policy)) {
7023 hddLog(LOGE, FL("Invalid ATTR"));
7024 return -EINVAL;
7025 }
7026
7027 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7028 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7029 return -EINVAL;
7030 }
7031
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307032 hdd_ctx->isSetBandByNL = TRUE;
7033 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307034 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307035 hdd_ctx->isSetBandByNL = FALSE;
7036
7037 EXIT();
7038 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307039}
7040
7041/**
7042 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7043 * @wiphy: wiphy structure pointer
7044 * @wdev: Wireless device structure pointer
7045 * @data: Pointer to the data received
7046 * @data_len: Length of @data
7047 *
7048 * Return: 0 on success; errno on failure
7049 */
7050static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7051 struct wireless_dev *wdev,
7052 const void *data,
7053 int data_len)
7054{
7055 int ret = 0;
7056
7057 vos_ssr_protect(__func__);
7058 ret = __wlan_hdd_cfg80211_setband(wiphy,
7059 wdev, data, data_len);
7060 vos_ssr_unprotect(__func__);
7061
7062 return ret;
7063}
7064
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307065#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7066/**
7067 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7068 * @hdd_ctx: HDD context
7069 * @request_id: [input] request id
7070 * @pattern_id: [output] pattern id
7071 *
7072 * This function loops through request id to pattern id array
7073 * if the slot is available, store the request id and return pattern id
7074 * if entry exists, return the pattern id
7075 *
7076 * Return: 0 on success and errno on failure
7077 */
7078static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7079 uint32_t request_id,
7080 uint8_t *pattern_id)
7081{
7082 uint32_t i;
7083
7084 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7085 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7086 {
7087 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7088 {
7089 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7090 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7091 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7092 return 0;
7093 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7094 request_id) {
7095 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7096 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7097 return 0;
7098 }
7099 }
7100 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7101 return -EINVAL;
7102}
7103
7104/**
7105 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7106 * @hdd_ctx: HDD context
7107 * @request_id: [input] request id
7108 * @pattern_id: [output] pattern id
7109 *
7110 * This function loops through request id to pattern id array
7111 * reset request id to 0 (slot available again) and
7112 * return pattern id
7113 *
7114 * Return: 0 on success and errno on failure
7115 */
7116static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7117 uint32_t request_id,
7118 uint8_t *pattern_id)
7119{
7120 uint32_t i;
7121
7122 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7123 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7124 {
7125 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7126 {
7127 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7128 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7129 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7130 return 0;
7131 }
7132 }
7133 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7134 return -EINVAL;
7135}
7136
7137
7138/*
7139 * define short names for the global vendor params
7140 * used by __wlan_hdd_cfg80211_offloaded_packets()
7141 */
7142#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7143#define PARAM_REQUEST_ID \
7144 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7145#define PARAM_CONTROL \
7146 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7147#define PARAM_IP_PACKET \
7148 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7149#define PARAM_SRC_MAC_ADDR \
7150 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7151#define PARAM_DST_MAC_ADDR \
7152 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7153#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7154
7155/**
7156 * wlan_hdd_add_tx_ptrn() - add tx pattern
7157 * @adapter: adapter pointer
7158 * @hdd_ctx: hdd context
7159 * @tb: nl attributes
7160 *
7161 * This function reads the NL attributes and forms a AddTxPtrn message
7162 * posts it to SME.
7163 *
7164 */
7165static int
7166wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7167 struct nlattr **tb)
7168{
7169 struct sSirAddPeriodicTxPtrn *add_req;
7170 eHalStatus status;
7171 uint32_t request_id, ret, len;
7172 uint8_t pattern_id = 0;
7173 v_MACADDR_t dst_addr;
7174 uint16_t eth_type = htons(ETH_P_IP);
7175
7176 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7177 {
7178 hddLog(LOGE, FL("Not in Connected state!"));
7179 return -ENOTSUPP;
7180 }
7181
7182 add_req = vos_mem_malloc(sizeof(*add_req));
7183 if (!add_req)
7184 {
7185 hddLog(LOGE, FL("memory allocation failed"));
7186 return -ENOMEM;
7187 }
7188
7189 /* Parse and fetch request Id */
7190 if (!tb[PARAM_REQUEST_ID])
7191 {
7192 hddLog(LOGE, FL("attr request id failed"));
7193 goto fail;
7194 }
7195
7196 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7197 hddLog(LOG1, FL("Request Id: %u"), request_id);
7198 if (request_id == 0)
7199 {
7200 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307201 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307202 }
7203
7204 if (!tb[PARAM_PERIOD])
7205 {
7206 hddLog(LOGE, FL("attr period failed"));
7207 goto fail;
7208 }
7209 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7210 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7211 if (add_req->usPtrnIntervalMs == 0)
7212 {
7213 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7214 goto fail;
7215 }
7216
7217 if (!tb[PARAM_SRC_MAC_ADDR])
7218 {
7219 hddLog(LOGE, FL("attr source mac address failed"));
7220 goto fail;
7221 }
7222 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7223 VOS_MAC_ADDR_SIZE);
7224 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7225 MAC_ADDR_ARRAY(add_req->macAddress));
7226
7227 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7228 VOS_MAC_ADDR_SIZE))
7229 {
7230 hddLog(LOGE,
7231 FL("input src mac address and connected ap bssid are different"));
7232 goto fail;
7233 }
7234
7235 if (!tb[PARAM_DST_MAC_ADDR])
7236 {
7237 hddLog(LOGE, FL("attr dst mac address failed"));
7238 goto fail;
7239 }
7240 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7241 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7242 MAC_ADDR_ARRAY(dst_addr.bytes));
7243
7244 if (!tb[PARAM_IP_PACKET])
7245 {
7246 hddLog(LOGE, FL("attr ip packet failed"));
7247 goto fail;
7248 }
7249 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7250 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7251
7252 if (add_req->ucPtrnSize < 0 ||
7253 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7254 HDD_ETH_HEADER_LEN))
7255 {
7256 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7257 add_req->ucPtrnSize);
7258 goto fail;
7259 }
7260
7261 len = 0;
7262 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7263 len += VOS_MAC_ADDR_SIZE;
7264 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7265 VOS_MAC_ADDR_SIZE);
7266 len += VOS_MAC_ADDR_SIZE;
7267 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7268 len += 2;
7269
7270 /*
7271 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7272 * ------------------------------------------------------------
7273 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7274 * ------------------------------------------------------------
7275 */
7276 vos_mem_copy(&add_req->ucPattern[len],
7277 nla_data(tb[PARAM_IP_PACKET]),
7278 add_req->ucPtrnSize);
7279 add_req->ucPtrnSize += len;
7280
7281 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7282 add_req->ucPattern, add_req->ucPtrnSize);
7283
7284 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7285 if (ret)
7286 {
7287 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7288 goto fail;
7289 }
7290 add_req->ucPtrnId = pattern_id;
7291 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7292
7293 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7294 if (!HAL_STATUS_SUCCESS(status))
7295 {
7296 hddLog(LOGE,
7297 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7298 goto fail;
7299 }
7300
7301 EXIT();
7302 vos_mem_free(add_req);
7303 return 0;
7304
7305fail:
7306 vos_mem_free(add_req);
7307 return -EINVAL;
7308}
7309
7310/**
7311 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7312 * @adapter: adapter pointer
7313 * @hdd_ctx: hdd context
7314 * @tb: nl attributes
7315 *
7316 * This function reads the NL attributes and forms a DelTxPtrn message
7317 * posts it to SME.
7318 *
7319 */
7320static int
7321wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7322 struct nlattr **tb)
7323{
7324 struct sSirDelPeriodicTxPtrn *del_req;
7325 eHalStatus status;
7326 uint32_t request_id, ret;
7327 uint8_t pattern_id = 0;
7328
7329 /* Parse and fetch request Id */
7330 if (!tb[PARAM_REQUEST_ID])
7331 {
7332 hddLog(LOGE, FL("attr request id failed"));
7333 return -EINVAL;
7334 }
7335 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7336 if (request_id == 0)
7337 {
7338 hddLog(LOGE, FL("request_id cannot be zero"));
7339 return -EINVAL;
7340 }
7341
7342 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7343 if (ret)
7344 {
7345 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7346 return -EINVAL;
7347 }
7348
7349 del_req = vos_mem_malloc(sizeof(*del_req));
7350 if (!del_req)
7351 {
7352 hddLog(LOGE, FL("memory allocation failed"));
7353 return -ENOMEM;
7354 }
7355
7356 vos_mem_set(del_req, sizeof(*del_req), 0);
7357 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7358 VOS_MAC_ADDR_SIZE);
7359 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7360 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7361 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7362 request_id, pattern_id, del_req->ucPatternIdBitmap);
7363
7364 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7365 if (!HAL_STATUS_SUCCESS(status))
7366 {
7367 hddLog(LOGE,
7368 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7369 goto fail;
7370 }
7371
7372 EXIT();
7373 vos_mem_free(del_req);
7374 return 0;
7375
7376fail:
7377 vos_mem_free(del_req);
7378 return -EINVAL;
7379}
7380
7381
7382/**
7383 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7384 * @wiphy: Pointer to wireless phy
7385 * @wdev: Pointer to wireless device
7386 * @data: Pointer to data
7387 * @data_len: Data length
7388 *
7389 * Return: 0 on success, negative errno on failure
7390 */
7391static int
7392__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7393 struct wireless_dev *wdev,
7394 const void *data,
7395 int data_len)
7396{
7397 struct net_device *dev = wdev->netdev;
7398 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7399 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7400 struct nlattr *tb[PARAM_MAX + 1];
7401 uint8_t control;
7402 int ret;
7403 static const struct nla_policy policy[PARAM_MAX + 1] =
7404 {
7405 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7406 [PARAM_CONTROL] = { .type = NLA_U32 },
7407 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7408 .len = VOS_MAC_ADDR_SIZE },
7409 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7410 .len = VOS_MAC_ADDR_SIZE },
7411 [PARAM_PERIOD] = { .type = NLA_U32 },
7412 };
7413
7414 ENTER();
7415
7416 ret = wlan_hdd_validate_context(hdd_ctx);
7417 if (0 != ret)
7418 {
7419 hddLog(LOGE, FL("HDD context is not valid"));
7420 return ret;
7421 }
7422
7423 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7424 {
7425 hddLog(LOGE,
7426 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7427 return -ENOTSUPP;
7428 }
7429
7430 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7431 {
7432 hddLog(LOGE, FL("Invalid ATTR"));
7433 return -EINVAL;
7434 }
7435
7436 if (!tb[PARAM_CONTROL])
7437 {
7438 hddLog(LOGE, FL("attr control failed"));
7439 return -EINVAL;
7440 }
7441 control = nla_get_u32(tb[PARAM_CONTROL]);
7442 hddLog(LOG1, FL("Control: %d"), control);
7443
7444 if (control == WLAN_START_OFFLOADED_PACKETS)
7445 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7446 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7447 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7448 else
7449 {
7450 hddLog(LOGE, FL("Invalid control: %d"), control);
7451 return -EINVAL;
7452 }
7453}
7454
7455/*
7456 * done with short names for the global vendor params
7457 * used by __wlan_hdd_cfg80211_offloaded_packets()
7458 */
7459#undef PARAM_MAX
7460#undef PARAM_REQUEST_ID
7461#undef PARAM_CONTROL
7462#undef PARAM_IP_PACKET
7463#undef PARAM_SRC_MAC_ADDR
7464#undef PARAM_DST_MAC_ADDR
7465#undef PARAM_PERIOD
7466
7467/**
7468 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7469 * @wiphy: wiphy structure pointer
7470 * @wdev: Wireless device structure pointer
7471 * @data: Pointer to the data received
7472 * @data_len: Length of @data
7473 *
7474 * Return: 0 on success; errno on failure
7475 */
7476static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7477 struct wireless_dev *wdev,
7478 const void *data,
7479 int data_len)
7480{
7481 int ret = 0;
7482
7483 vos_ssr_protect(__func__);
7484 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7485 wdev, data, data_len);
7486 vos_ssr_unprotect(__func__);
7487
7488 return ret;
7489}
7490#endif
7491
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307492static const struct
7493nla_policy
7494qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307495 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7496 .type = NLA_BINARY,
7497 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307498};
7499
7500/**
7501 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7502 * get link properties like nss, rate flags and operating frequency for
7503 * the connection with the given peer.
7504 * @wiphy: WIPHY structure pointer
7505 * @wdev: Wireless device structure pointer
7506 * @data: Pointer to the data received
7507 * @data_len: Length of the data received
7508 *
7509 * This function return the above link properties on success.
7510 *
7511 * Return: 0 on success and errno on failure
7512 */
7513static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7514 struct wireless_dev *wdev,
7515 const void *data,
7516 int data_len)
7517{
7518 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7519 struct net_device *dev = wdev->netdev;
7520 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7521 hdd_station_ctx_t *hdd_sta_ctx;
7522 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7523 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7524 uint32_t sta_id;
7525 struct sk_buff *reply_skb;
7526 uint32_t rate_flags = 0;
7527 uint8_t nss;
7528 uint8_t final_rate_flags = 0;
7529 uint32_t freq;
7530 v_CONTEXT_t pVosContext = NULL;
7531 ptSapContext pSapCtx = NULL;
7532
7533 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7535 return -EINVAL;
7536 }
7537
7538 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7539 qca_wlan_vendor_attr_policy)) {
7540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7541 return -EINVAL;
7542 }
7543
7544 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7545 hddLog(VOS_TRACE_LEVEL_ERROR,
7546 FL("Attribute peerMac not provided for mode=%d"),
7547 adapter->device_mode);
7548 return -EINVAL;
7549 }
7550
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307551 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7552 hddLog(VOS_TRACE_LEVEL_ERROR,
7553 FL("Attribute peerMac is invalid=%d"),
7554 adapter->device_mode);
7555 return -EINVAL;
7556 }
7557
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307558 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7559 sizeof(peer_mac));
7560 hddLog(VOS_TRACE_LEVEL_INFO,
7561 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7562 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7563
7564 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7565 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7566 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7567 if ((hdd_sta_ctx->conn_info.connState !=
7568 eConnectionState_Associated) ||
7569 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7570 VOS_MAC_ADDRESS_LEN)) {
7571 hddLog(VOS_TRACE_LEVEL_ERROR,
7572 FL("Not Associated to mac "MAC_ADDRESS_STR),
7573 MAC_ADDR_ARRAY(peer_mac));
7574 return -EINVAL;
7575 }
7576
7577 nss = 1; //pronto supports only one spatial stream
7578 freq = vos_chan_to_freq(
7579 hdd_sta_ctx->conn_info.operationChannel);
7580 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7581
7582 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7583 adapter->device_mode == WLAN_HDD_SOFTAP) {
7584
7585 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7586 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7587 if(pSapCtx == NULL){
7588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7589 FL("psapCtx is NULL"));
7590 return -ENOENT;
7591 }
7592
7593
7594 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7595 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7596 !vos_is_macaddr_broadcast(
7597 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7598 vos_mem_compare(
7599 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7600 peer_mac, VOS_MAC_ADDRESS_LEN))
7601 break;
7602 }
7603
7604 if (WLAN_MAX_STA_COUNT == sta_id) {
7605 hddLog(VOS_TRACE_LEVEL_ERROR,
7606 FL("No active peer with mac="MAC_ADDRESS_STR),
7607 MAC_ADDR_ARRAY(peer_mac));
7608 return -EINVAL;
7609 }
7610
7611 nss = 1; //pronto supports only one spatial stream
7612 freq = vos_chan_to_freq(
7613 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7614 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7615 } else {
7616 hddLog(VOS_TRACE_LEVEL_ERROR,
7617 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7618 MAC_ADDR_ARRAY(peer_mac));
7619 return -EINVAL;
7620 }
7621
7622 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7623 if (rate_flags & eHAL_TX_RATE_VHT80) {
7624 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7625 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7626 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7627 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7628 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7629 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7630 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7631 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7632 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7633 if (rate_flags & eHAL_TX_RATE_HT40)
7634 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7635 }
7636
7637 if (rate_flags & eHAL_TX_RATE_SGI) {
7638 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7639 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7640 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7641 }
7642 }
7643
7644 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7645 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7646
7647 if (NULL == reply_skb) {
7648 hddLog(VOS_TRACE_LEVEL_ERROR,
7649 FL("getLinkProperties: skb alloc failed"));
7650 return -EINVAL;
7651 }
7652
7653 if (nla_put_u8(reply_skb,
7654 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7655 nss) ||
7656 nla_put_u8(reply_skb,
7657 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7658 final_rate_flags) ||
7659 nla_put_u32(reply_skb,
7660 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7661 freq)) {
7662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7663 kfree_skb(reply_skb);
7664 return -EINVAL;
7665 }
7666
7667 return cfg80211_vendor_cmd_reply(reply_skb);
7668}
7669
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307670#define BEACON_MISS_THRESH_2_4 \
7671 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7672#define BEACON_MISS_THRESH_5_0 \
7673 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307674#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7675#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7676#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7677#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307678#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7679 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307680
7681/**
7682 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7683 * vendor command
7684 *
7685 * @wiphy: wiphy device pointer
7686 * @wdev: wireless device pointer
7687 * @data: Vendor command data buffer
7688 * @data_len: Buffer length
7689 *
7690 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7691 *
7692 * Return: EOK or other error codes.
7693 */
7694
7695static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7696 struct wireless_dev *wdev,
7697 const void *data,
7698 int data_len)
7699{
7700 struct net_device *dev = wdev->netdev;
7701 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7702 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7703 hdd_station_ctx_t *pHddStaCtx;
7704 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7705 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307706 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307707 eHalStatus status;
7708 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307709 uint8_t hb_thresh_val;
7710
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307711 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7712 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7713 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307714 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7715 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7716 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307717 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7718 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307719 };
7720
7721 ENTER();
7722
7723 if (VOS_FTM_MODE == hdd_get_conparam()) {
7724 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7725 return -EINVAL;
7726 }
7727
7728 ret_val = wlan_hdd_validate_context(pHddCtx);
7729 if (ret_val) {
7730 return ret_val;
7731 }
7732
7733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7734
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307735 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7736 hddLog(LOGE, FL("Invalid ATTR"));
7737 return -EINVAL;
7738 }
7739
7740 /* check the Wifi Capability */
7741 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7742 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7743 {
7744 hddLog(VOS_TRACE_LEVEL_ERROR,
7745 FL("WIFICONFIG not supported by Firmware"));
7746 return -EINVAL;
7747 }
7748
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307749 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7750 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7751 modifyRoamParamsReq.value =
7752 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7753
7754 if (eHAL_STATUS_SUCCESS !=
7755 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7756 {
7757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7758 ret_val = -EINVAL;
7759 }
7760 return ret_val;
7761 }
7762
7763 /* Moved this down in order to provide provision to set beacon
7764 * miss penalty count irrespective of connection state.
7765 */
7766 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7767 hddLog(LOGE, FL("Not in Connected state!"));
7768 return -ENOTSUPP;
7769 }
7770
7771 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307772
7773 if (!pReq) {
7774 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7775 "%s: Not able to allocate memory for tSetWifiConfigParams",
7776 __func__);
7777 return eHAL_STATUS_E_MALLOC_FAILED;
7778 }
7779
7780 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7781
7782 pReq->sessionId = pAdapter->sessionId;
7783 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7784
7785 if (tb[PARAM_MODULATED_DTIM]) {
7786 pReq->paramValue = nla_get_u32(
7787 tb[PARAM_MODULATED_DTIM]);
7788 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7789 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307790 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307791 hdd_set_pwrparams(pHddCtx);
7792 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7793 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7794
7795 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7796 iw_full_power_cbfn, pAdapter,
7797 eSME_FULL_PWR_NEEDED_BY_HDD);
7798 }
7799 else
7800 {
7801 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7802 }
7803 }
7804
7805 if (tb[PARAM_STATS_AVG_FACTOR]) {
7806 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7807 pReq->paramValue = nla_get_u16(
7808 tb[PARAM_STATS_AVG_FACTOR]);
7809 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7810 pReq->paramType, pReq->paramValue);
7811 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7812
7813 if (eHAL_STATUS_SUCCESS != status)
7814 {
7815 vos_mem_free(pReq);
7816 pReq = NULL;
7817 ret_val = -EPERM;
7818 return ret_val;
7819 }
7820 }
7821
7822
7823 if (tb[PARAM_GUARD_TIME]) {
7824 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7825 pReq->paramValue = nla_get_u32(
7826 tb[PARAM_GUARD_TIME]);
7827 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7828 pReq->paramType, pReq->paramValue);
7829 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7830
7831 if (eHAL_STATUS_SUCCESS != status)
7832 {
7833 vos_mem_free(pReq);
7834 pReq = NULL;
7835 ret_val = -EPERM;
7836 return ret_val;
7837 }
7838
7839 }
7840
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7842 hb_thresh_val = nla_get_u8(
7843 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7844
7845 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7846 hb_thresh_val);
7847 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7848 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7849 NULL, eANI_BOOLEAN_FALSE);
7850
7851 status = sme_update_hb_threshold(
7852 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7853 WNI_CFG_HEART_BEAT_THRESHOLD,
7854 hb_thresh_val, eCSR_BAND_24);
7855 if (eHAL_STATUS_SUCCESS != status) {
7856 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7857 vos_mem_free(pReq);
7858 pReq = NULL;
7859 return -EPERM;
7860 }
7861 }
7862
7863 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7864 hb_thresh_val = nla_get_u8(
7865 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7866
7867 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7868 hb_thresh_val);
7869 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7870 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7871 NULL, eANI_BOOLEAN_FALSE);
7872
7873 status = sme_update_hb_threshold(
7874 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7875 WNI_CFG_HEART_BEAT_THRESHOLD,
7876 hb_thresh_val, eCSR_BAND_5G);
7877 if (eHAL_STATUS_SUCCESS != status) {
7878 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7879 vos_mem_free(pReq);
7880 pReq = NULL;
7881 return -EPERM;
7882 }
7883 }
7884
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307885 EXIT();
7886 return ret_val;
7887}
7888
7889/**
7890 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7891 * vendor command
7892 *
7893 * @wiphy: wiphy device pointer
7894 * @wdev: wireless device pointer
7895 * @data: Vendor command data buffer
7896 * @data_len: Buffer length
7897 *
7898 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7899 *
7900 * Return: EOK or other error codes.
7901 */
7902static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7903 struct wireless_dev *wdev,
7904 const void *data,
7905 int data_len)
7906{
7907 int ret;
7908
7909 vos_ssr_protect(__func__);
7910 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7911 data, data_len);
7912 vos_ssr_unprotect(__func__);
7913
7914 return ret;
7915}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307916
7917/*
7918 * define short names for the global vendor params
7919 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7920 */
7921#define STATS_SET_INVALID \
7922 QCA_ATTR_NUD_STATS_SET_INVALID
7923#define STATS_SET_START \
7924 QCA_ATTR_NUD_STATS_SET_START
7925#define STATS_GW_IPV4 \
7926 QCA_ATTR_NUD_STATS_GW_IPV4
7927#define STATS_SET_MAX \
7928 QCA_ATTR_NUD_STATS_SET_MAX
7929
7930const struct nla_policy
7931qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7932{
7933 [STATS_SET_START] = {.type = NLA_FLAG },
7934 [STATS_GW_IPV4] = {.type = NLA_U32 },
7935};
7936
7937/**
7938 * hdd_set_nud_stats_cb() - hdd callback api to get status
7939 * @data: pointer to adapter
7940 * @rsp: status
7941 *
7942 * Return: None
7943 */
7944static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7945{
7946
7947 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7948
7949 if (NULL == adapter)
7950 return;
7951
7952 if (VOS_STATUS_SUCCESS == rsp) {
7953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7954 "%s success received STATS_SET_START", __func__);
7955 } else {
7956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7957 "%s STATS_SET_START Failed!!", __func__);
7958 }
7959 return;
7960}
7961
7962/**
7963 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7964 * @wiphy: pointer to wireless wiphy structure.
7965 * @wdev: pointer to wireless_dev structure.
7966 * @data: pointer to apfind configuration data.
7967 * @data_len: the length in byte of apfind data.
7968 *
7969 * This is called when wlan driver needs to send arp stats to
7970 * firmware.
7971 *
7972 * Return: An error code or 0 on success.
7973 */
7974static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7975 struct wireless_dev *wdev,
7976 const void *data, int data_len)
7977{
7978 struct nlattr *tb[STATS_SET_MAX + 1];
7979 struct net_device *dev = wdev->netdev;
7980 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7981 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307982 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307983 setArpStatsParams arp_stats_params;
7984 int err = 0;
7985
7986 ENTER();
7987
7988 err = wlan_hdd_validate_context(hdd_ctx);
7989 if (0 != err)
7990 return err;
7991
7992 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7994 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7995 return -EINVAL;
7996 }
7997
7998 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7999 qca_wlan_vendor_set_nud_stats);
8000 if (err)
8001 {
8002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8003 "%s STATS_SET_START ATTR", __func__);
8004 return err;
8005 }
8006
8007 if (tb[STATS_SET_START])
8008 {
8009 if (!tb[STATS_GW_IPV4]) {
8010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8011 "%s STATS_SET_START CMD", __func__);
8012 return -EINVAL;
8013 }
8014 arp_stats_params.flag = true;
8015 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8016 } else {
8017 arp_stats_params.flag = false;
8018 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308019 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8021 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308022 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8023 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308024
8025 arp_stats_params.pkt_type = 1; // ARP packet type
8026
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308027 if (arp_stats_params.flag) {
8028 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8029 WLANTL_SetARPFWDatapath(pVosContext, true);
8030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8031 "%s Set FW in data path for ARP with tgt IP :%d",
8032 __func__, hdd_ctx->track_arp_ip);
8033 }
8034 else {
8035 WLANTL_SetARPFWDatapath(pVosContext, false);
8036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8037 "%s Remove FW from data path", __func__);
8038 }
8039
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308040 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8041 arp_stats_params.data_ctx = adapter;
8042
8043 if (eHAL_STATUS_SUCCESS !=
8044 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8046 "%s STATS_SET_START CMD Failed!!", __func__);
8047 return -EINVAL;
8048 }
8049
8050 EXIT();
8051
8052 return err;
8053}
8054
8055/**
8056 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8057 * @wiphy: pointer to wireless wiphy structure.
8058 * @wdev: pointer to wireless_dev structure.
8059 * @data: pointer to apfind configuration data.
8060 * @data_len: the length in byte of apfind data.
8061 *
8062 * This is called when wlan driver needs to send arp stats to
8063 * firmware.
8064 *
8065 * Return: An error code or 0 on success.
8066 */
8067static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8068 struct wireless_dev *wdev,
8069 const void *data, int data_len)
8070{
8071 int ret;
8072
8073 vos_ssr_protect(__func__);
8074 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8075 vos_ssr_unprotect(__func__);
8076
8077 return ret;
8078}
8079#undef STATS_SET_INVALID
8080#undef STATS_SET_START
8081#undef STATS_GW_IPV4
8082#undef STATS_SET_MAX
8083
8084/*
8085 * define short names for the global vendor params
8086 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8087 */
8088#define STATS_GET_INVALID \
8089 QCA_ATTR_NUD_STATS_SET_INVALID
8090#define COUNT_FROM_NETDEV \
8091 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8092#define COUNT_TO_LOWER_MAC \
8093 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8094#define RX_COUNT_BY_LOWER_MAC \
8095 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8096#define COUNT_TX_SUCCESS \
8097 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8098#define RSP_RX_COUNT_BY_LOWER_MAC \
8099 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8100#define RSP_RX_COUNT_BY_UPPER_MAC \
8101 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8102#define RSP_COUNT_TO_NETDEV \
8103 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8104#define RSP_COUNT_OUT_OF_ORDER_DROP \
8105 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8106#define AP_LINK_ACTIVE \
8107 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8108#define AP_LINK_DAD \
8109 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8110#define STATS_GET_MAX \
8111 QCA_ATTR_NUD_STATS_GET_MAX
8112
8113const struct nla_policy
8114qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8115{
8116 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8117 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8118 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8119 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8120 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8121 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8122 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8123 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8124 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8125 [AP_LINK_DAD] = {.type = NLA_FLAG },
8126};
8127
8128static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8129{
8130
8131 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8132 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8133 struct hdd_nud_stats_context *context;
8134 int status;
8135
8136 ENTER();
8137
8138 if (NULL == adapter)
8139 return;
8140
8141 status = wlan_hdd_validate_context(hdd_ctx);
8142 if (0 != status) {
8143 return;
8144 }
8145
8146 if (!rsp) {
8147 hddLog(LOGE, FL("data is null"));
8148 return;
8149 }
8150
8151 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8152 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8153 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8154 adapter->dad |= rsp->dad;
8155
8156 spin_lock(&hdd_context_lock);
8157 context = &hdd_ctx->nud_stats_context;
8158 complete(&context->response_event);
8159 spin_unlock(&hdd_context_lock);
8160
8161 return;
8162}
8163static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8164 struct wireless_dev *wdev,
8165 const void *data, int data_len)
8166{
8167 int err = 0;
8168 unsigned long rc;
8169 struct hdd_nud_stats_context *context;
8170 struct net_device *dev = wdev->netdev;
8171 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8172 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8173 getArpStatsParams arp_stats_params;
8174 struct sk_buff *skb;
8175
8176 ENTER();
8177
8178 err = wlan_hdd_validate_context(hdd_ctx);
8179 if (0 != err)
8180 return err;
8181
8182 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8183 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8184 arp_stats_params.data_ctx = adapter;
8185
8186 spin_lock(&hdd_context_lock);
8187 context = &hdd_ctx->nud_stats_context;
8188 INIT_COMPLETION(context->response_event);
8189 spin_unlock(&hdd_context_lock);
8190
8191 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8193 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8194 return -EINVAL;
8195 }
8196
8197 if (eHAL_STATUS_SUCCESS !=
8198 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8200 "%s STATS_SET_START CMD Failed!!", __func__);
8201 return -EINVAL;
8202 }
8203
8204 rc = wait_for_completion_timeout(&context->response_event,
8205 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8206 if (!rc)
8207 {
8208 hddLog(LOGE,
8209 FL("Target response timed out request "));
8210 return -ETIMEDOUT;
8211 }
8212
8213 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8214 WLAN_NUD_STATS_LEN);
8215 if (!skb)
8216 {
8217 hddLog(VOS_TRACE_LEVEL_ERROR,
8218 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8219 __func__);
8220 return -ENOMEM;
8221 }
8222
8223 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8224 adapter->hdd_stats.hddArpStats.txCount) ||
8225 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8226 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8227 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8228 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8229 nla_put_u16(skb, COUNT_TX_SUCCESS,
8230 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8231 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8232 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8233 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8234 adapter->hdd_stats.hddArpStats.rxCount) ||
8235 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8236 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8237 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8238 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8239 hddLog(LOGE, FL("nla put fail"));
8240 kfree_skb(skb);
8241 return -EINVAL;
8242 }
8243 if (adapter->con_status)
8244 nla_put_flag(skb, AP_LINK_ACTIVE);
8245 if (adapter->dad)
8246 nla_put_flag(skb, AP_LINK_DAD);
8247
8248 cfg80211_vendor_cmd_reply(skb);
8249 return err;
8250}
8251
8252static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8253 struct wireless_dev *wdev,
8254 const void *data, int data_len)
8255{
8256 int ret;
8257
8258 vos_ssr_protect(__func__);
8259 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8260 vos_ssr_unprotect(__func__);
8261
8262 return ret;
8263}
8264
8265#undef QCA_ATTR_NUD_STATS_SET_INVALID
8266#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8267#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8268#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8269#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8270#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8271#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8272#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8273#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8274#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8275#undef QCA_ATTR_NUD_STATS_GET_MAX
8276
8277
8278
Kapil Guptaee33bf12016-12-20 18:27:37 +05308279#ifdef WLAN_FEATURE_APFIND
8280/**
8281 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8282 * @wiphy: pointer to wireless wiphy structure.
8283 * @wdev: pointer to wireless_dev structure.
8284 * @data: pointer to apfind configuration data.
8285 * @data_len: the length in byte of apfind data.
8286 *
8287 * This is called when wlan driver needs to send APFIND configurations to
8288 * firmware.
8289 *
8290 * Return: An error code or 0 on success.
8291 */
8292static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8293 struct wireless_dev *wdev,
8294 const void *data, int data_len)
8295{
8296 struct sme_ap_find_request_req apfind_req;
8297 VOS_STATUS status;
8298 int ret_val;
8299 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8300
8301 ENTER();
8302
8303 ret_val = wlan_hdd_validate_context(hdd_ctx);
8304 if (ret_val)
8305 return ret_val;
8306
8307 if (VOS_FTM_MODE == hdd_get_conparam()) {
8308 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8309 return -EPERM;
8310 }
8311
8312 apfind_req.request_data_len = data_len;
8313 apfind_req.request_data = data;
8314
8315 status = sme_apfind_set_cmd(&apfind_req);
8316 if (VOS_STATUS_SUCCESS != status) {
8317 ret_val = -EIO;
8318 }
8319 return ret_val;
8320}
8321
8322/**
8323 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8324 * @wiphy: pointer to wireless wiphy structure.
8325 * @wdev: pointer to wireless_dev structure.
8326 * @data: pointer to apfind configuration data.
8327 * @data_len: the length in byte of apfind data.
8328 *
8329 * This is called when wlan driver needs to send APFIND configurations to
8330 * firmware.
8331 *
8332 * Return: An error code or 0 on success.
8333 */
8334static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8335 struct wireless_dev *wdev,
8336 const void *data, int data_len)
8337{
8338 int ret;
8339
8340 vos_ssr_protect(__func__);
8341 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8342 vos_ssr_unprotect(__func__);
8343
8344 return ret;
8345}
8346#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308347const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8348{
Mukul Sharma2a271632014-10-13 14:59:01 +05308349 {
8350 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8351 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8352 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8353 WIPHY_VENDOR_CMD_NEED_NETDEV |
8354 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308355 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308356 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308357
8358 {
8359 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8360 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8361 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8362 WIPHY_VENDOR_CMD_NEED_NETDEV |
8363 WIPHY_VENDOR_CMD_NEED_RUNNING,
8364 .doit = wlan_hdd_cfg80211_nan_request
8365 },
8366
Sunil Duttc69bccb2014-05-26 21:30:20 +05308367#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8368 {
8369 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8370 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8371 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8372 WIPHY_VENDOR_CMD_NEED_NETDEV |
8373 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308374 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308375 },
8376
8377 {
8378 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8379 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8380 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8381 WIPHY_VENDOR_CMD_NEED_NETDEV |
8382 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308383 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308384 },
8385
8386 {
8387 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8388 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8389 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8390 WIPHY_VENDOR_CMD_NEED_NETDEV |
8391 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308392 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308393 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308394#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308395#ifdef WLAN_FEATURE_EXTSCAN
8396 {
8397 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8398 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8399 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8400 WIPHY_VENDOR_CMD_NEED_NETDEV |
8401 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308402 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308403 },
8404 {
8405 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8406 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8407 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8408 WIPHY_VENDOR_CMD_NEED_NETDEV |
8409 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308410 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308411 },
8412 {
8413 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8414 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8415 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8416 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308417 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308418 },
8419 {
8420 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8421 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
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_get_capabilities
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_GET_CACHED_RESULTS,
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_get_cached_results
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_SET_BSSID_HOTLIST,
8438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8439 WIPHY_VENDOR_CMD_NEED_NETDEV |
8440 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308441 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308442 },
8443 {
8444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8447 WIPHY_VENDOR_CMD_NEED_NETDEV |
8448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308449 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308450 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308451#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308452/*EXT TDLS*/
8453 {
8454 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8455 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8456 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8457 WIPHY_VENDOR_CMD_NEED_NETDEV |
8458 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308459 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308460 },
8461 {
8462 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8463 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8464 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8465 WIPHY_VENDOR_CMD_NEED_NETDEV |
8466 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308467 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308468 },
8469 {
8470 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8471 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8472 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8473 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308474 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308475 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308476 {
8477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8480 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308481 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308482 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308483 {
8484 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8485 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8486 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8487 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308489 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308490 {
8491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8494 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308495 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308496 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308497 {
8498 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8499 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8500 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8501 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308502 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308503 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308504 {
8505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8508 WIPHY_VENDOR_CMD_NEED_NETDEV |
8509 WIPHY_VENDOR_CMD_NEED_RUNNING,
8510 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8511 },
8512 {
8513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8516 WIPHY_VENDOR_CMD_NEED_NETDEV |
8517 WIPHY_VENDOR_CMD_NEED_RUNNING,
8518 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308519 },
8520 {
8521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8524 WIPHY_VENDOR_CMD_NEED_NETDEV,
8525 .doit = wlan_hdd_cfg80211_wifi_logger_start
8526 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308527 {
8528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
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_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308534 },
8535 {
8536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8539 WIPHY_VENDOR_CMD_NEED_NETDEV |
8540 WIPHY_VENDOR_CMD_NEED_RUNNING,
8541 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308542 },
8543 {
8544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8547 WIPHY_VENDOR_CMD_NEED_NETDEV |
8548 WIPHY_VENDOR_CMD_NEED_RUNNING,
8549 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308550 },
8551#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
8558 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308559 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308560#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308561 {
8562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8565 WIPHY_VENDOR_CMD_NEED_NETDEV |
8566 WIPHY_VENDOR_CMD_NEED_RUNNING,
8567 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308568 },
8569 {
8570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8573 WIPHY_VENDOR_CMD_NEED_NETDEV |
8574 WIPHY_VENDOR_CMD_NEED_RUNNING,
8575 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308576 },
8577#ifdef WLAN_FEATURE_APFIND
8578 {
8579 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8580 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8581 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8582 WIPHY_VENDOR_CMD_NEED_NETDEV,
8583 .doit = wlan_hdd_cfg80211_apfind_cmd
8584 },
8585#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
8592 .doit = wlan_hdd_cfg80211_set_nud_stats
8593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
8600 .doit = wlan_hdd_cfg80211_get_nud_stats
8601 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV |
8607 WIPHY_VENDOR_CMD_NEED_RUNNING,
8608 .doit = hdd_cfg80211_get_station_cmd
8609 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308610};
8611
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008612/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308613static const
8614struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008615{
8616#ifdef FEATURE_WLAN_CH_AVOID
8617 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308618 .vendor_id = QCA_NL80211_VENDOR_ID,
8619 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008620 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308621#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8622#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8623 {
8624 /* Index = 1*/
8625 .vendor_id = QCA_NL80211_VENDOR_ID,
8626 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8627 },
8628 {
8629 /* Index = 2*/
8630 .vendor_id = QCA_NL80211_VENDOR_ID,
8631 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8632 },
8633 {
8634 /* Index = 3*/
8635 .vendor_id = QCA_NL80211_VENDOR_ID,
8636 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8637 },
8638 {
8639 /* Index = 4*/
8640 .vendor_id = QCA_NL80211_VENDOR_ID,
8641 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8642 },
8643 {
8644 /* Index = 5*/
8645 .vendor_id = QCA_NL80211_VENDOR_ID,
8646 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8647 },
8648 {
8649 /* Index = 6*/
8650 .vendor_id = QCA_NL80211_VENDOR_ID,
8651 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8652 },
8653#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308654#ifdef WLAN_FEATURE_EXTSCAN
8655 {
8656 .vendor_id = QCA_NL80211_VENDOR_ID,
8657 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8658 },
8659 {
8660 .vendor_id = QCA_NL80211_VENDOR_ID,
8661 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8662 },
8663 {
8664 .vendor_id = QCA_NL80211_VENDOR_ID,
8665 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8666 },
8667 {
8668 .vendor_id = QCA_NL80211_VENDOR_ID,
8669 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8670 },
8671 {
8672 .vendor_id = QCA_NL80211_VENDOR_ID,
8673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8674 },
8675 {
8676 .vendor_id = QCA_NL80211_VENDOR_ID,
8677 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8678 },
8679 {
8680 .vendor_id = QCA_NL80211_VENDOR_ID,
8681 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8682 },
8683 {
8684 .vendor_id = QCA_NL80211_VENDOR_ID,
8685 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8686 },
8687 {
8688 .vendor_id = QCA_NL80211_VENDOR_ID,
8689 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8690 },
8691 {
8692 .vendor_id = QCA_NL80211_VENDOR_ID,
8693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8694 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308695#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308696/*EXT TDLS*/
8697 {
8698 .vendor_id = QCA_NL80211_VENDOR_ID,
8699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8700 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308701 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8702 .vendor_id = QCA_NL80211_VENDOR_ID,
8703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8704 },
8705
Srinivas Dasari030bad32015-02-18 23:23:54 +05308706
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308707 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308708 .vendor_id = QCA_NL80211_VENDOR_ID,
8709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8710 },
8711
Sushant Kaushik084f6592015-09-10 13:11:56 +05308712 {
8713 .vendor_id = QCA_NL80211_VENDOR_ID,
8714 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308715 },
8716 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8717 .vendor_id = QCA_NL80211_VENDOR_ID,
8718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8719 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308720 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8721 .vendor_id = QCA_NL80211_VENDOR_ID,
8722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8723 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308724 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8725 .vendor_id = QCA_NL80211_VENDOR_ID,
8726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8727 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008728};
8729
Jeff Johnson295189b2012-06-20 16:38:30 -07008730/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308731 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308732 * This function is called by hdd_wlan_startup()
8733 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308734 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308736struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008737{
8738 struct wiphy *wiphy;
8739 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308740 /*
8741 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 */
8743 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8744
8745 if (!wiphy)
8746 {
8747 /* Print error and jump into err label and free the memory */
8748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8749 return NULL;
8750 }
8751
Sunil Duttc69bccb2014-05-26 21:30:20 +05308752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 return wiphy;
8754}
8755
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308756#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8757 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8758/**
8759 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8760 * @wiphy: pointer to wiphy
8761 * @config: pointer to config
8762 *
8763 * Return: None
8764 */
8765static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8766 hdd_config_t *config)
8767{
8768 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8769 if (config->max_sched_scan_plan_interval)
8770 wiphy->max_sched_scan_plan_interval =
8771 config->max_sched_scan_plan_interval;
8772 if (config->max_sched_scan_plan_iterations)
8773 wiphy->max_sched_scan_plan_iterations =
8774 config->max_sched_scan_plan_iterations;
8775}
8776#else
8777static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8778 hdd_config_t *config)
8779{
8780}
8781#endif
8782
Jeff Johnson295189b2012-06-20 16:38:30 -07008783/*
8784 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308785 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 * private ioctl to change the band value
8787 */
8788int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8789{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308790 int i, j;
8791 eNVChannelEnabledType channelEnabledState;
8792
Jeff Johnsone7245742012-09-05 17:12:55 -07008793 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308794
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308795 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308797
8798 if (NULL == wiphy->bands[i])
8799 {
8800 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8801 __func__, i);
8802 continue;
8803 }
8804
8805 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8806 {
8807 struct ieee80211_supported_band *band = wiphy->bands[i];
8808
8809 channelEnabledState = vos_nv_getChannelEnabledState(
8810 band->channels[j].hw_value);
8811
8812 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8813 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308814 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308815 continue;
8816 }
8817 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8818 {
8819 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8820 continue;
8821 }
8822
8823 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8824 NV_CHANNEL_INVALID == channelEnabledState)
8825 {
8826 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8827 }
8828 else if (NV_CHANNEL_DFS == channelEnabledState)
8829 {
8830 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8831 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8832 }
8833 else
8834 {
8835 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8836 |IEEE80211_CHAN_RADAR);
8837 }
8838 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 }
8840 return 0;
8841}
8842/*
8843 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308844 * This function is called by hdd_wlan_startup()
8845 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 * This function is used to initialize and register wiphy structure.
8847 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308848int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 struct wiphy *wiphy,
8850 hdd_config_t *pCfg
8851 )
8852{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308853 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308854 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8855
Jeff Johnsone7245742012-09-05 17:12:55 -07008856 ENTER();
8857
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 /* Now bind the underlying wlan device with wiphy */
8859 set_wiphy_dev(wiphy, dev);
8860
8861 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008862
Kiet Lam6c583332013-10-14 05:37:09 +05308863#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008864 /* the flag for the other case would be initialzed in
8865 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8867 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8868#else
Amar Singhal0a402232013-10-11 20:57:16 -07008869 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308870#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308871#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008872
Amar Singhalfddc28c2013-09-05 13:03:40 -07008873 /* This will disable updating of NL channels from passive to
8874 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8876 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8877#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008878 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308879#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008880
Amar Singhala49cbc52013-10-08 18:37:44 -07008881
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008882#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008883 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8884 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8885 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008886 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308888 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308889#else
8890 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8891#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008892#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008893
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008894#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008895 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008896#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008897 || pCfg->isFastRoamIniFeatureEnabled
8898#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008899#ifdef FEATURE_WLAN_ESE
8900 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008901#endif
8902 )
8903 {
8904 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8905 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008906#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008907#ifdef FEATURE_WLAN_TDLS
8908 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8909 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8910#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308911#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308912 if (pCfg->configPNOScanSupport)
8913 {
8914 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8915 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8916 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8917 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8918 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308919#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008920
Abhishek Singh10d85972015-04-17 10:27:23 +05308921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8922 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8923#endif
8924
Amar Singhalfddc28c2013-09-05 13:03:40 -07008925#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008926 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8927 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008928 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008929 driver need to determine what to do with both
8930 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008931
8932 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008933#else
8934 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008935#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008936
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308937 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8938
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308939 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008940
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308941 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8942
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308944 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8945 | BIT(NL80211_IFTYPE_ADHOC)
8946 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8947 | BIT(NL80211_IFTYPE_P2P_GO)
8948 | BIT(NL80211_IFTYPE_AP);
8949
8950 if (VOS_MONITOR_MODE == hdd_get_conparam())
8951 {
8952 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008954
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308955 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008956 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8958 if( pCfg->enableMCC )
8959 {
8960 /* Currently, supports up to two channels */
8961 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008962
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308963 if( !pCfg->allowMCCGODiffBI )
8964 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008965
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308966 }
8967 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8968 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008969#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308970 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008971
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 /* Before registering we need to update the ht capabilitied based
8973 * on ini values*/
8974 if( !pCfg->ShortGI20MhzEnable )
8975 {
8976 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8977 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 }
8979
8980 if( !pCfg->ShortGI40MhzEnable )
8981 {
8982 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8983 }
8984
8985 if( !pCfg->nChannelBondingMode5GHz )
8986 {
8987 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8988 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308989 /*
8990 * In case of static linked driver at the time of driver unload,
8991 * module exit doesn't happens. Module cleanup helps in cleaning
8992 * of static memory.
8993 * If driver load happens statically, at the time of driver unload,
8994 * wiphy flags don't get reset because of static memory.
8995 * It's better not to store channel in static memory.
8996 */
8997 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8998 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8999 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
9000 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
9001 {
9002 hddLog(VOS_TRACE_LEVEL_ERROR,
9003 FL("Not enough memory to allocate channels"));
9004 return -ENOMEM;
9005 }
9006 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
9007 &hdd_channels_2_4_GHZ[0],
9008 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009009
Agrawal Ashish97dec502015-11-26 20:20:58 +05309010 if (true == hdd_is_5g_supported(pHddCtx))
9011 {
9012 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9013 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
9014 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
9015 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
9016 {
9017 hddLog(VOS_TRACE_LEVEL_ERROR,
9018 FL("Not enough memory to allocate channels"));
9019 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
9020 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
9021 return -ENOMEM;
9022 }
9023 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
9024 &hdd_channels_5_GHZ[0],
9025 sizeof(hdd_channels_5_GHZ));
9026 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309027
9028 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9029 {
9030
9031 if (NULL == wiphy->bands[i])
9032 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309033 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309034 __func__, i);
9035 continue;
9036 }
9037
9038 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9039 {
9040 struct ieee80211_supported_band *band = wiphy->bands[i];
9041
9042 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
9043 {
9044 // Enable social channels for P2P
9045 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9046 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9047 else
9048 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9049 continue;
9050 }
9051 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
9052 {
9053 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9054 continue;
9055 }
9056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 }
9058 /*Initialise the supported cipher suite details*/
9059 wiphy->cipher_suites = hdd_cipher_suites;
9060 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9061
9062 /*signal strength in mBm (100*dBm) */
9063 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9064
9065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309066 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009067#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009068
Sunil Duttc69bccb2014-05-26 21:30:20 +05309069 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9070 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009071 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9072 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9073
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309074 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9075
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309076 EXIT();
9077 return 0;
9078}
9079
9080/* In this function we are registering wiphy. */
9081int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9082{
9083 ENTER();
9084 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 if (0 > wiphy_register(wiphy))
9086 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309087 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9089 return -EIO;
9090 }
9091
9092 EXIT();
9093 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309094}
Jeff Johnson295189b2012-06-20 16:38:30 -07009095
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309096/* In this function we are updating channel list when,
9097 regulatory domain is FCC and country code is US.
9098 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9099 As per FCC smart phone is not a indoor device.
9100 GO should not opeate on indoor channels */
9101void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9102{
9103 int j;
9104 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9105 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9106 //Default counrtycode from NV at the time of wiphy initialization.
9107 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9108 &defaultCountryCode[0]))
9109 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009110 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309111 }
9112 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9113 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309114 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
9117 return;
9118 }
9119 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
9120 {
9121 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
9122 // Mark UNII -1 band channel as passive
9123 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9124 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9125 }
9126 }
9127}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309128/* This function registers for all frame which supplicant is interested in */
9129void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009130{
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9132 /* Register for all P2P action, public action etc frames */
9133 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009134 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309135 /* Register frame indication call back */
9136 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 /* Right now we are registering these frame when driver is getting
9138 initialized. Once we will move to 2.6.37 kernel, in which we have
9139 frame register ops, we will move this code as a part of that */
9140 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309141 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9143
9144 /* GAS Initial Response */
9145 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9146 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309147
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 /* GAS Comeback Request */
9149 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9150 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9151
9152 /* GAS Comeback Response */
9153 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9154 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9155
9156 /* P2P Public Action */
9157 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309158 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 P2P_PUBLIC_ACTION_FRAME_SIZE );
9160
9161 /* P2P Action */
9162 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9163 (v_U8_t*)P2P_ACTION_FRAME,
9164 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009165
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309166 /* WNM BSS Transition Request frame */
9167 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9168 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9169 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009170
9171 /* WNM-Notification */
9172 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9173 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9174 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009175}
9176
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309177void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009178{
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9180 /* Register for all P2P action, public action etc frames */
9181 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9182
Jeff Johnsone7245742012-09-05 17:12:55 -07009183 ENTER();
9184
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 /* Right now we are registering these frame when driver is getting
9186 initialized. Once we will move to 2.6.37 kernel, in which we have
9187 frame register ops, we will move this code as a part of that */
9188 /* GAS Initial Request */
9189
9190 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9191 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9192
9193 /* GAS Initial Response */
9194 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9195 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309196
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 /* GAS Comeback Request */
9198 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9199 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9200
9201 /* GAS Comeback Response */
9202 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9203 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9204
9205 /* P2P Public Action */
9206 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309207 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 P2P_PUBLIC_ACTION_FRAME_SIZE );
9209
9210 /* P2P Action */
9211 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9212 (v_U8_t*)P2P_ACTION_FRAME,
9213 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009214 /* WNM-Notification */
9215 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9216 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9217 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009218}
9219
9220#ifdef FEATURE_WLAN_WAPI
9221void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309222 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009223{
9224 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9225 tCsrRoamSetKey setKey;
9226 v_BOOL_t isConnected = TRUE;
9227 int status = 0;
9228 v_U32_t roamId= 0xFF;
9229 tANI_U8 *pKeyPtr = NULL;
9230 int n = 0;
9231
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9233 __func__, hdd_device_modetoString(pAdapter->device_mode),
9234 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009235
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309236 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 setKey.keyId = key_index; // Store Key ID
9238 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9239 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9240 setKey.paeRole = 0 ; // the PAE role
9241 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9242 {
9243 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9244 }
9245 else
9246 {
9247 isConnected = hdd_connIsConnected(pHddStaCtx);
9248 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9249 }
9250 setKey.keyLength = key_Len;
9251 pKeyPtr = setKey.Key;
9252 memcpy( pKeyPtr, key, key_Len);
9253
Arif Hussain6d2a3322013-11-17 19:50:10 -08009254 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 __func__, key_Len);
9256 for (n = 0 ; n < key_Len; n++)
9257 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9258 __func__,n,setKey.Key[n]);
9259
9260 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9261 if ( isConnected )
9262 {
9263 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9264 pAdapter->sessionId, &setKey, &roamId );
9265 }
9266 if ( status != 0 )
9267 {
9268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9269 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9270 __LINE__, status );
9271 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9272 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309273 /* Need to clear any trace of key value in the memory.
9274 * Thus zero out the memory even though it is local
9275 * variable.
9276 */
9277 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009278}
9279#endif /* FEATURE_WLAN_WAPI*/
9280
9281#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309282int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 beacon_data_t **ppBeacon,
9284 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009285#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309286int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009287 beacon_data_t **ppBeacon,
9288 struct cfg80211_beacon_data *params,
9289 int dtim_period)
9290#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309291{
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 int size;
9293 beacon_data_t *beacon = NULL;
9294 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309295 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9296 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009297
Jeff Johnsone7245742012-09-05 17:12:55 -07009298 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309300 {
9301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9302 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009305
9306 old = pAdapter->sessionCtx.ap.beacon;
9307
9308 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309309 {
9310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9311 FL("session(%d) old and new heads points to NULL"),
9312 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309314 }
9315
9316 if (params->tail && !params->tail_len)
9317 {
9318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9319 FL("tail_len is zero but tail is not NULL"));
9320 return -EINVAL;
9321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009322
Jeff Johnson295189b2012-06-20 16:38:30 -07009323#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9324 /* Kernel 3.0 is not updating dtim_period for set beacon */
9325 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309326 {
9327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9328 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009331#endif
9332
Kapil Gupta137ef892016-12-13 19:38:00 +05309333 if (params->head)
9334 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309336 head = params->head;
9337 } else
9338 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309340 head = old->head;
9341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009342
Kapil Gupta137ef892016-12-13 19:38:00 +05309343 if (params->tail || !old)
9344 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309346 tail = params->tail;
9347 } else
9348 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309350 tail = old->tail;
9351 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009352
Kapil Gupta137ef892016-12-13 19:38:00 +05309353 if (params->proberesp_ies || !old)
9354 {
9355 proberesp_ies_len = params->proberesp_ies_len;
9356 proberesp_ies = params->proberesp_ies;
9357 } else
9358 {
9359 proberesp_ies_len = old->proberesp_ies_len;
9360 proberesp_ies = old->proberesp_ies;
9361 }
9362
9363 if (params->assocresp_ies || !old)
9364 {
9365 assocresp_ies_len = params->assocresp_ies_len;
9366 assocresp_ies = params->assocresp_ies;
9367 } else
9368 {
9369 assocresp_ies_len = old->assocresp_ies_len;
9370 assocresp_ies = old->assocresp_ies;
9371 }
9372
9373 size = sizeof(beacon_data_t) + head_len + tail_len +
9374 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
9376 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309378 {
9379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9380 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009383
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009384#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309385 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 beacon->dtim_period = params->dtim_period;
9387 else
9388 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009389#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309390 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009391 beacon->dtim_period = dtim_period;
9392 else
9393 beacon->dtim_period = old->dtim_period;
9394#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309395
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9397 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309398 beacon->proberesp_ies = beacon->tail + tail_len;
9399 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9400
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 beacon->head_len = head_len;
9402 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309403 beacon->proberesp_ies_len = proberesp_ies_len;
9404 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009405
c_manjee527ecac2017-01-25 12:25:27 +05309406 if (head && head_len)
9407 memcpy(beacon->head, head, head_len);
9408 if (tail && tail_len)
9409 memcpy(beacon->tail, tail, tail_len);
9410 if (proberesp_ies && proberesp_ies_len)
9411 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9412 if (assocresp_ies && assocresp_ies_len)
9413 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009414
9415 *ppBeacon = beacon;
9416
9417 kfree(old);
9418
9419 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420}
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309422v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9424 const v_U8_t *pIes,
9425#else
9426 v_U8_t *pIes,
9427#endif
9428 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009429{
9430 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309431 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309433
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 elem_id = ptr[0];
9437 elem_len = ptr[1];
9438 left -= 2;
9439 if(elem_len > left)
9440 {
9441 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009442 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 eid,elem_len,left);
9444 return NULL;
9445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309446 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 {
9448 return ptr;
9449 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 left -= elem_len;
9452 ptr += (elem_len + 2);
9453 }
9454 return NULL;
9455}
9456
Jeff Johnson295189b2012-06-20 16:38:30 -07009457/* Check if rate is 11g rate or not */
9458static int wlan_hdd_rate_is_11g(u8 rate)
9459{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009460 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 u8 i;
9462 for (i = 0; i < 8; i++)
9463 {
9464 if(rate == gRateArray[i])
9465 return TRUE;
9466 }
9467 return FALSE;
9468}
9469
9470/* Check for 11g rate and set proper 11g only mode */
9471static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9472 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9473{
9474 u8 i, num_rates = pIe[0];
9475
9476 pIe += 1;
9477 for ( i = 0; i < num_rates; i++)
9478 {
9479 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9480 {
9481 /* If rate set have 11g rate than change the mode to 11G */
9482 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9483 if (pIe[i] & BASIC_RATE_MASK)
9484 {
9485 /* If we have 11g rate as basic rate, it means mode
9486 is 11g only mode.
9487 */
9488 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9489 *pCheckRatesfor11g = FALSE;
9490 }
9491 }
9492 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9493 {
9494 *require_ht = TRUE;
9495 }
9496 }
9497 return;
9498}
9499
9500static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9501{
9502 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9503 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9504 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9505 u8 checkRatesfor11g = TRUE;
9506 u8 require_ht = FALSE;
9507 u8 *pIe=NULL;
9508
9509 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9510
9511 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9512 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9513 if (pIe != NULL)
9514 {
9515 pIe += 1;
9516 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9517 &pConfig->SapHw_mode);
9518 }
9519
9520 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9521 WLAN_EID_EXT_SUPP_RATES);
9522 if (pIe != NULL)
9523 {
9524
9525 pIe += 1;
9526 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9527 &pConfig->SapHw_mode);
9528 }
9529
9530 if( pConfig->channel > 14 )
9531 {
9532 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9533 }
9534
9535 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9536 WLAN_EID_HT_CAPABILITY);
9537
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 {
9540 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9541 if(require_ht)
9542 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9543 }
9544}
9545
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309546static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9547 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9548{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009549 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309550 v_U8_t *pIe = NULL;
9551 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9552
9553 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9554 pBeacon->tail, pBeacon->tail_len);
9555
9556 if (pIe)
9557 {
9558 ielen = pIe[1] + 2;
9559 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9560 {
9561 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9562 }
9563 else
9564 {
9565 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9566 return -EINVAL;
9567 }
9568 *total_ielen += ielen;
9569 }
9570 return 0;
9571}
9572
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009573static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9574 v_U8_t *genie, v_U8_t *total_ielen)
9575{
9576 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9577 int left = pBeacon->tail_len;
9578 v_U8_t *ptr = pBeacon->tail;
9579 v_U8_t elem_id, elem_len;
9580 v_U16_t ielen = 0;
9581
9582 if ( NULL == ptr || 0 == left )
9583 return;
9584
9585 while (left >= 2)
9586 {
9587 elem_id = ptr[0];
9588 elem_len = ptr[1];
9589 left -= 2;
9590 if (elem_len > left)
9591 {
9592 hddLog( VOS_TRACE_LEVEL_ERROR,
9593 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9594 elem_id, elem_len, left);
9595 return;
9596 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309597 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009598 {
9599 /* skipping the VSIE's which we don't want to include or
9600 * it will be included by existing code
9601 */
9602 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9603#ifdef WLAN_FEATURE_WFD
9604 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9605#endif
9606 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9607 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9608 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9609 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9610 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9611 {
9612 ielen = ptr[1] + 2;
9613 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9614 {
9615 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9616 *total_ielen += ielen;
9617 }
9618 else
9619 {
9620 hddLog( VOS_TRACE_LEVEL_ERROR,
9621 "IE Length is too big "
9622 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9623 elem_id, elem_len, *total_ielen);
9624 }
9625 }
9626 }
9627
9628 left -= elem_len;
9629 ptr += (elem_len + 2);
9630 }
9631 return;
9632}
9633
Kapil Gupta137ef892016-12-13 19:38:00 +05309634int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009635{
9636 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309637 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009639 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309640 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009641
9642 genie = vos_mem_malloc(MAX_GENIE_LEN);
9643
9644 if(genie == NULL) {
9645
9646 return -ENOMEM;
9647 }
9648
Kapil Gupta137ef892016-12-13 19:38:00 +05309649 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309650 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9651 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309653 hddLog(LOGE,
9654 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309655 ret = -EINVAL;
9656 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 }
9658
9659#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309660 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9661 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9662 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309663 hddLog(LOGE,
9664 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309665 ret = -EINVAL;
9666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 }
9668#endif
9669
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309670 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9671 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309673 hddLog(LOGE,
9674 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309675 ret = -EINVAL;
9676 goto done;
9677 }
9678
9679 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9680 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009681 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
9684 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9685 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9686 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9687 {
9688 hddLog(LOGE,
9689 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009690 ret = -EINVAL;
9691 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 }
9693
9694 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9695 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9696 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9697 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9698 ==eHAL_STATUS_FAILURE)
9699 {
9700 hddLog(LOGE,
9701 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009702 ret = -EINVAL;
9703 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 }
9705
9706 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309707 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 u8 probe_rsp_ie_len[3] = {0};
9711 u8 counter = 0;
9712 /* Check Probe Resp Length if it is greater then 255 then Store
9713 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9714 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9715 Store More then 255 bytes into One Variable.
9716 */
9717 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9718 {
9719 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9720 {
9721 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9722 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9723 }
9724 else
9725 {
9726 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9727 rem_probe_resp_ie_len = 0;
9728 }
9729 }
9730
9731 rem_probe_resp_ie_len = 0;
9732
9733 if (probe_rsp_ie_len[0] > 0)
9734 {
9735 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9736 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309737 (tANI_U8*)&pBeacon->
9738 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 probe_rsp_ie_len[0], NULL,
9740 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9741 {
9742 hddLog(LOGE,
9743 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009744 ret = -EINVAL;
9745 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 }
9747 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9748 }
9749
9750 if (probe_rsp_ie_len[1] > 0)
9751 {
9752 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9753 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309754 (tANI_U8*)&pBeacon->
9755 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 probe_rsp_ie_len[1], NULL,
9757 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9758 {
9759 hddLog(LOGE,
9760 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009761 ret = -EINVAL;
9762 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 }
9764 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9765 }
9766
9767 if (probe_rsp_ie_len[2] > 0)
9768 {
9769 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9770 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309771 (tANI_U8*)&pBeacon->
9772 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 probe_rsp_ie_len[2], NULL,
9774 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9775 {
9776 hddLog(LOGE,
9777 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009778 ret = -EINVAL;
9779 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009780 }
9781 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9782 }
9783
9784 if (probe_rsp_ie_len[1] == 0 )
9785 {
9786 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9787 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9788 eANI_BOOLEAN_FALSE) )
9789 {
9790 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009791 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 }
9793 }
9794
9795 if (probe_rsp_ie_len[2] == 0 )
9796 {
9797 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9798 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9799 eANI_BOOLEAN_FALSE) )
9800 {
9801 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009802 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 }
9804 }
9805
9806 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9807 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9808 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9809 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9810 == eHAL_STATUS_FAILURE)
9811 {
9812 hddLog(LOGE,
9813 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009814 ret = -EINVAL;
9815 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 }
9817 }
9818 else
9819 {
9820 // Reset WNI_CFG_PROBE_RSP Flags
9821 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9822
9823 hddLog(VOS_TRACE_LEVEL_INFO,
9824 "%s: No Probe Response IE received in set beacon",
9825 __func__);
9826 }
9827
9828 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309829 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 {
9831 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309832 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9833 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9835 {
9836 hddLog(LOGE,
9837 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009838 ret = -EINVAL;
9839 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 }
9841
9842 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9843 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9844 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9845 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9846 == eHAL_STATUS_FAILURE)
9847 {
9848 hddLog(LOGE,
9849 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009850 ret = -EINVAL;
9851 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 }
9853 }
9854 else
9855 {
9856 hddLog(VOS_TRACE_LEVEL_INFO,
9857 "%s: No Assoc Response IE received in set beacon",
9858 __func__);
9859
9860 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9861 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9862 eANI_BOOLEAN_FALSE) )
9863 {
9864 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009865 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 }
9867 }
9868
Jeff Johnsone7245742012-09-05 17:12:55 -07009869done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309871 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009872}
Jeff Johnson295189b2012-06-20 16:38:30 -07009873
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309874/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 * FUNCTION: wlan_hdd_validate_operation_channel
9876 * called by wlan_hdd_cfg80211_start_bss() and
9877 * wlan_hdd_cfg80211_set_channel()
9878 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309879 * channel list.
9880 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009881VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009882{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 v_U32_t num_ch = 0;
9885 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9886 u32 indx = 0;
9887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309888 v_U8_t fValidChannel = FALSE, count = 0;
9889 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309890
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9892
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309893 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309895 /* Validate the channel */
9896 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309898 if ( channel == rfChannels[count].channelNum )
9899 {
9900 fValidChannel = TRUE;
9901 break;
9902 }
9903 }
9904 if (fValidChannel != TRUE)
9905 {
9906 hddLog(VOS_TRACE_LEVEL_ERROR,
9907 "%s: Invalid Channel [%d]", __func__, channel);
9908 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 }
9910 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309911 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309913 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9914 valid_ch, &num_ch))
9915 {
9916 hddLog(VOS_TRACE_LEVEL_ERROR,
9917 "%s: failed to get valid channel list", __func__);
9918 return VOS_STATUS_E_FAILURE;
9919 }
9920 for (indx = 0; indx < num_ch; indx++)
9921 {
9922 if (channel == valid_ch[indx])
9923 {
9924 break;
9925 }
9926 }
9927
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309928 if (indx >= num_ch)
9929 {
9930 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9931 {
9932 eCsrBand band;
9933 unsigned int freq;
9934
9935 sme_GetFreqBand(hHal, &band);
9936
9937 if (eCSR_BAND_5G == band)
9938 {
9939#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9940 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9941 {
9942 freq = ieee80211_channel_to_frequency(channel,
9943 IEEE80211_BAND_2GHZ);
9944 }
9945 else
9946 {
9947 freq = ieee80211_channel_to_frequency(channel,
9948 IEEE80211_BAND_5GHZ);
9949 }
9950#else
9951 freq = ieee80211_channel_to_frequency(channel);
9952#endif
9953 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9954 return VOS_STATUS_SUCCESS;
9955 }
9956 }
9957
9958 hddLog(VOS_TRACE_LEVEL_ERROR,
9959 "%s: Invalid Channel [%d]", __func__, channel);
9960 return VOS_STATUS_E_FAILURE;
9961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309963
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965
Jeff Johnson295189b2012-06-20 16:38:30 -07009966}
9967
Viral Modi3a32cc52013-02-08 11:14:52 -08009968/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309969 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009970 * This function is used to set the channel number
9971 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309972static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009973 struct ieee80211_channel *chan,
9974 enum nl80211_channel_type channel_type
9975 )
9976{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309977 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009978 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009979 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009980 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309981 hdd_context_t *pHddCtx;
9982 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009983
9984 ENTER();
9985
9986 if( NULL == dev )
9987 {
9988 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009989 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009990 return -ENODEV;
9991 }
9992 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309993
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9995 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9996 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009997 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309998 "%s: device_mode = %s (%d) freq = %d", __func__,
9999 hdd_device_modetoString(pAdapter->device_mode),
10000 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010001
10002 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10003 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010004 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010005 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010006 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010007 }
10008
10009 /*
10010 * Do freq to chan conversion
10011 * TODO: for 11a
10012 */
10013
10014 channel = ieee80211_frequency_to_channel(freq);
10015
10016 /* Check freq range */
10017 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10018 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10019 {
10020 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010021 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010022 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10023 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10024 return -EINVAL;
10025 }
10026
10027 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10028
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010029 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10030 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010031 {
10032 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10033 {
10034 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010035 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010036 return -EINVAL;
10037 }
10038 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10039 "%s: set channel to [%d] for device mode =%d",
10040 __func__, channel,pAdapter->device_mode);
10041 }
10042 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010043 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010044 )
10045 {
10046 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10047 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10048 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10049
10050 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10051 {
10052 /* Link is up then return cant set channel*/
10053 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010054 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010055 return -EINVAL;
10056 }
10057
10058 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10059 pHddStaCtx->conn_info.operationChannel = channel;
10060 pRoamProfile->ChannelInfo.ChannelList =
10061 &pHddStaCtx->conn_info.operationChannel;
10062 }
10063 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010064 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010065 )
10066 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10068 {
10069 if(VOS_STATUS_SUCCESS !=
10070 wlan_hdd_validate_operation_channel(pAdapter,channel))
10071 {
10072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010073 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010074 return -EINVAL;
10075 }
10076 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10077 }
10078 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010079 {
10080 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10081
10082 /* If auto channel selection is configured as enable/ 1 then ignore
10083 channel set by supplicant
10084 */
10085 if ( cfg_param->apAutoChannelSelection )
10086 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010087 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10088 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010089 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010090 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10091 __func__, hdd_device_modetoString(pAdapter->device_mode),
10092 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010093 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010094 else
10095 {
10096 if(VOS_STATUS_SUCCESS !=
10097 wlan_hdd_validate_operation_channel(pAdapter,channel))
10098 {
10099 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010100 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010101 return -EINVAL;
10102 }
10103 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10104 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010105 }
10106 }
10107 else
10108 {
10109 hddLog(VOS_TRACE_LEVEL_FATAL,
10110 "%s: Invalid device mode failed to set valid channel", __func__);
10111 return -EINVAL;
10112 }
10113 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010114 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010115}
10116
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010117static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10118 struct net_device *dev,
10119 struct ieee80211_channel *chan,
10120 enum nl80211_channel_type channel_type
10121 )
10122{
10123 int ret;
10124
10125 vos_ssr_protect(__func__);
10126 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10127 vos_ssr_unprotect(__func__);
10128
10129 return ret;
10130}
10131
Anurag Chouhan83026002016-12-13 22:46:21 +053010132#ifdef DHCP_SERVER_OFFLOAD
10133void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10134 VOS_STATUS status)
10135{
10136 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10137
10138 ENTER();
10139
10140 if (NULL == adapter)
10141 {
10142 hddLog(VOS_TRACE_LEVEL_ERROR,
10143 "%s: adapter is NULL",__func__);
10144 return;
10145 }
10146
10147 adapter->dhcp_status.dhcp_offload_status = status;
10148 vos_event_set(&adapter->dhcp_status.vos_event);
10149 return;
10150}
10151
10152/**
10153 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10154 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010155 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010156 *
10157 * Return: None
10158 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010159VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10160 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010161{
10162 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10163 sir_dhcp_srv_offload_info dhcp_srv_info;
10164 tANI_U8 num_entries = 0;
10165 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10166 tANI_U8 num;
10167 tANI_U32 temp;
10168 VOS_STATUS ret;
10169
10170 ENTER();
10171
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010172 if (!re_init) {
10173 ret = wlan_hdd_validate_context(hdd_ctx);
10174 if (0 != ret)
10175 return VOS_STATUS_E_INVAL;
10176 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010177
10178 /* Prepare the request to send to SME */
10179 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10180 if (NULL == dhcp_srv_info) {
10181 hddLog(VOS_TRACE_LEVEL_ERROR,
10182 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10183 return VOS_STATUS_E_NOMEM;
10184 }
10185
10186 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10187
10188 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10189 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10190 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10191 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10192 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10193 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10194
10195 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10196 srv_ip,
10197 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +053010198 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +053010199 if (num_entries != IPADDR_NUM_ENTRIES) {
10200 hddLog(VOS_TRACE_LEVEL_ERROR,
10201 "%s: incorrect IP address (%s) assigned for DHCP server!",
10202 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10203 vos_mem_free(dhcp_srv_info);
10204 return VOS_STATUS_E_FAILURE;
10205 }
10206
10207 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10208 hddLog(VOS_TRACE_LEVEL_ERROR,
10209 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10210 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10211 vos_mem_free(dhcp_srv_info);
10212 return VOS_STATUS_E_FAILURE;
10213 }
10214
10215 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10216 hddLog(VOS_TRACE_LEVEL_ERROR,
10217 "%s: invalid IP address (%s)! The last field must be less than 100!",
10218 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10219 vos_mem_free(dhcp_srv_info);
10220 return VOS_STATUS_E_FAILURE;
10221 }
10222
10223 for (num = 0; num < num_entries; num++) {
10224 temp = srv_ip[num];
10225 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10226 }
10227
10228 if (eHAL_STATUS_SUCCESS !=
10229 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10230 hddLog(VOS_TRACE_LEVEL_ERROR,
10231 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10232 vos_mem_free(dhcp_srv_info);
10233 return VOS_STATUS_E_FAILURE;
10234 }
10235
10236 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10237 "%s: enable DHCP Server offload successfully!", __func__);
10238
10239 vos_mem_free(dhcp_srv_info);
10240 return 0;
10241}
10242#endif /* DHCP_SERVER_OFFLOAD */
10243
Jeff Johnson295189b2012-06-20 16:38:30 -070010244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10245static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10246 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010247#else
10248static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10249 struct cfg80211_beacon_data *params,
10250 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010251 enum nl80211_hidden_ssid hidden_ssid,
10252 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010254{
10255 tsap_Config_t *pConfig;
10256 beacon_data_t *pBeacon = NULL;
10257 struct ieee80211_mgmt *pMgmt_frame;
10258 v_U8_t *pIe=NULL;
10259 v_U16_t capab_info;
10260 eCsrAuthType RSNAuthType;
10261 eCsrEncryptionType RSNEncryptType;
10262 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010263 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 tpWLAN_SAPEventCB pSapEventCallback;
10265 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010267 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010269 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010271 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010272 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010273 v_BOOL_t MFPCapable = VOS_FALSE;
10274 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010275 v_BOOL_t sapEnable11AC =
10276 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010277 u_int16_t prev_rsn_length = 0;
10278
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 ENTER();
10280
Nitesh Shah9b066282017-06-06 18:05:52 +053010281 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010282 iniConfig = pHddCtx->cfg_ini;
10283
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10285
10286 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10287
10288 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10289
10290 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10291
10292 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10293
10294 //channel is already set in the set_channel Call back
10295 //pConfig->channel = pCommitConfig->channel;
10296
10297 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010298 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10300
10301 pConfig->dtim_period = pBeacon->dtim_period;
10302
Arif Hussain6d2a3322013-11-17 19:50:10 -080010303 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 pConfig->dtim_period);
10305
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010306 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010307 {
10308 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010310 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10311 {
10312 tANI_BOOLEAN restartNeeded;
10313 pConfig->ieee80211d = 1;
10314 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10315 sme_setRegInfo(hHal, pConfig->countryCode);
10316 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10317 }
10318 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010320 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010321 pConfig->ieee80211d = 1;
10322 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10323 sme_setRegInfo(hHal, pConfig->countryCode);
10324 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010326 else
10327 {
10328 pConfig->ieee80211d = 0;
10329 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010330 /*
10331 * If auto channel is configured i.e. channel is 0,
10332 * so skip channel validation.
10333 */
10334 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10335 {
10336 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10337 {
10338 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010339 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010340 return -EINVAL;
10341 }
10342 }
10343 else
10344 {
10345 if(1 != pHddCtx->is_dynamic_channel_range_set)
10346 {
10347 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10348 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10349 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10350 }
10351 pHddCtx->is_dynamic_channel_range_set = 0;
10352 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010354 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 {
10356 pConfig->ieee80211d = 0;
10357 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010358
10359#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10360 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10361 pConfig->authType = eSAP_OPEN_SYSTEM;
10362 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10363 pConfig->authType = eSAP_SHARED_KEY;
10364 else
10365 pConfig->authType = eSAP_AUTO_SWITCH;
10366#else
10367 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10368 pConfig->authType = eSAP_OPEN_SYSTEM;
10369 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10370 pConfig->authType = eSAP_SHARED_KEY;
10371 else
10372 pConfig->authType = eSAP_AUTO_SWITCH;
10373#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010374
10375 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010376
10377 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010379#ifdef SAP_AUTH_OFFLOAD
10380 /* In case of sap offload, hostapd.conf is configuted with open mode and
10381 * security is configured from ini file. Due to open mode in hostapd.conf
10382 * privacy bit is set to false which will result in not sending,
10383 * data packets as encrypted.
10384 * If enable_sap_auth_offload is enabled in ini and
10385 * sap_auth_offload_sec_type is type of WPA2-PSK,
10386 * driver will set privacy bit to 1.
10387 */
10388 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10389 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10390 pConfig->privacy = VOS_TRUE;
10391#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010392
10393 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10394
10395 /*Set wps station to configured*/
10396 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10397
10398 if(pIe)
10399 {
10400 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10401 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010402 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 return -EINVAL;
10404 }
10405 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10406 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010407 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 /* Check 15 bit of WPS IE as it contain information for wps state
10409 * WPS state
10410 */
10411 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10412 {
10413 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10414 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10415 {
10416 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10417 }
10418 }
10419 }
10420 else
10421 {
10422 pConfig->wps_state = SAP_WPS_DISABLED;
10423 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010425
c_hpothufe599e92014-06-16 11:38:55 +053010426 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10427 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10428 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10429 eCSR_ENCRYPT_TYPE_NONE;
10430
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010432 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010433 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 WLAN_EID_RSN);
10435 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010438 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10439 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10440 pConfig->RSNWPAReqIELength);
10441 else
10442 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10443 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010444 /* The actual processing may eventually be more extensive than
10445 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 * by the app.
10447 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010448 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10450 &RSNEncryptType,
10451 &mcRSNEncryptType,
10452 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010453 &MFPCapable,
10454 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010455 pConfig->RSNWPAReqIE[1]+2,
10456 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010457
10458 if( VOS_STATUS_SUCCESS == status )
10459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010460 /* Now copy over all the security attributes you have
10461 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 * */
10463 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10464 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10465 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10466 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010467 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010468 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10470 }
10471 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10474 pBeacon->tail, pBeacon->tail_len);
10475
10476 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10477 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010478 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 {
10480 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010481 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010483 if (pConfig->RSNWPAReqIELength <=
10484 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10485 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10486 pIe[1] + 2);
10487 else
10488 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10489 pConfig->RSNWPAReqIELength);
10490
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 }
10492 else
10493 {
10494 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010495 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10496 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10497 pConfig->RSNWPAReqIELength);
10498 else
10499 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10500 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010501 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10503 &RSNEncryptType,
10504 &mcRSNEncryptType,
10505 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010506 &MFPCapable,
10507 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010508 pConfig->RSNWPAReqIE[1]+2,
10509 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510
10511 if( VOS_STATUS_SUCCESS == status )
10512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010513 /* Now copy over all the security attributes you have
10514 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 * */
10516 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10517 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10518 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10519 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010520 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010521 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10523 }
10524 }
10525 }
10526
Kapil Gupta137ef892016-12-13 19:38:00 +053010527 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010528 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10529 return -EINVAL;
10530 }
10531
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10533
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010534#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 if (params->ssid != NULL)
10536 {
10537 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10538 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10539 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10540 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10541 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010542#else
10543 if (ssid != NULL)
10544 {
10545 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10546 pConfig->SSIDinfo.ssid.length = ssid_len;
10547 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10548 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10549 }
10550#endif
10551
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010552 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010554
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 /* default value */
10556 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10557 pConfig->num_accept_mac = 0;
10558 pConfig->num_deny_mac = 0;
10559
10560 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10561 pBeacon->tail, pBeacon->tail_len);
10562
10563 /* pIe for black list is following form:
10564 type : 1 byte
10565 length : 1 byte
10566 OUI : 4 bytes
10567 acl type : 1 byte
10568 no of mac addr in black list: 1 byte
10569 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010570 */
10571 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 {
10573 pConfig->SapMacaddr_acl = pIe[6];
10574 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010575 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010576 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010577 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10578 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10580 for (i = 0; i < pConfig->num_deny_mac; i++)
10581 {
10582 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10583 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 }
10586 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10587 pBeacon->tail, pBeacon->tail_len);
10588
10589 /* pIe for white list is following form:
10590 type : 1 byte
10591 length : 1 byte
10592 OUI : 4 bytes
10593 acl type : 1 byte
10594 no of mac addr in white list: 1 byte
10595 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010596 */
10597 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 {
10599 pConfig->SapMacaddr_acl = pIe[6];
10600 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010601 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010603 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10604 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10606 for (i = 0; i < pConfig->num_accept_mac; i++)
10607 {
10608 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10609 acl_entry++;
10610 }
10611 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010612
Jeff Johnson295189b2012-06-20 16:38:30 -070010613 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10614
Jeff Johnsone7245742012-09-05 17:12:55 -070010615#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010616 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010617 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10618 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010619 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10620 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010621 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10622 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010623 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10624 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010625 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010626 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010627 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010628 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010629
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010630 /* If ACS disable and selected channel <= 14
10631 * OR
10632 * ACS enabled and ACS operating band is choosen as 2.4
10633 * AND
10634 * VHT in 2.4G Disabled
10635 * THEN
10636 * Fallback to 11N mode
10637 */
10638 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10639 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010640 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010641 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010642 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010643 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10644 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010645 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10646 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010647 }
10648#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010649
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 // ht_capab is not what the name conveys,this is used for protection bitmap
10651 pConfig->ht_capab =
10652 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10653
Kapil Gupta137ef892016-12-13 19:38:00 +053010654 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 {
10656 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10657 return -EINVAL;
10658 }
10659
10660 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010661 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010662 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10663 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010664 pConfig->obssProtEnabled =
10665 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010666
Chet Lanctot8cecea22014-02-11 19:09:36 -080010667#ifdef WLAN_FEATURE_11W
10668 pConfig->mfpCapable = MFPCapable;
10669 pConfig->mfpRequired = MFPRequired;
10670 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10671 pConfig->mfpCapable, pConfig->mfpRequired);
10672#endif
10673
Arif Hussain6d2a3322013-11-17 19:50:10 -080010674 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010676 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10677 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10678 (int)pConfig->channel);
10679 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10680 pConfig->SapHw_mode, pConfig->privacy,
10681 pConfig->authType);
10682 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10683 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10684 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10685 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010686
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010687 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 {
10689 //Bss already started. just return.
10690 //TODO Probably it should update some beacon params.
10691 hddLog( LOGE, "Bss Already started...Ignore the request");
10692 EXIT();
10693 return 0;
10694 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010695
Agarwal Ashish51325b52014-06-16 16:50:49 +053010696 if (vos_max_concurrent_connections_reached()) {
10697 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10698 return -EINVAL;
10699 }
10700
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 pConfig->persona = pHostapdAdapter->device_mode;
10702
Peng Xu2446a892014-09-05 17:21:18 +053010703 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10704 if ( NULL != psmeConfig)
10705 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010706 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010707 sme_GetConfigParam(hHal, psmeConfig);
10708 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010709#ifdef WLAN_FEATURE_AP_HT40_24G
10710 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10711 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10712 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10713 {
10714 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10715 sme_UpdateConfig (hHal, psmeConfig);
10716 }
10717#endif
Peng Xu2446a892014-09-05 17:21:18 +053010718 vos_mem_free(psmeConfig);
10719 }
Peng Xuafc34e32014-09-25 13:23:55 +053010720 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010721
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010722 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10723
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 pSapEventCallback = hdd_hostapd_SAPEventCB;
10725 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10726 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10727 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010728 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010729 ret = -EINVAL;
10730 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 }
10732
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010733 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10735
10736 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010737
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010739 {
10740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010741 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010742 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 VOS_ASSERT(0);
10744 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010745
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010747 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10748 VOS_STATUS_SUCCESS)
10749 {
10750 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10751 VOS_ASSERT(0);
10752 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010753 /* Initialize WMM configuation */
10754 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010755 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010756
Anurag Chouhan83026002016-12-13 22:46:21 +053010757#ifdef DHCP_SERVER_OFFLOAD
10758 /* set dhcp server offload */
10759 if (iniConfig->enable_dhcp_srv_offload &&
10760 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010761 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010762 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010763 if (!VOS_IS_STATUS_SUCCESS(status))
10764 {
10765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10766 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010767 vos_event_reset(&pHostapdState->vosEvent);
10768 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10769 status = vos_wait_single_event(&pHostapdState->vosEvent,
10770 10000);
10771 if (!VOS_IS_STATUS_SUCCESS(status)) {
10772 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010773 ret = -EINVAL;
10774 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010775 }
10776 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010777 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010778 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10779 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10780 {
10781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10782 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10783 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010784 vos_event_reset(&pHostapdState->vosEvent);
10785 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10786 status = vos_wait_single_event(&pHostapdState->vosEvent,
10787 10000);
10788 if (!VOS_IS_STATUS_SUCCESS(status)) {
10789 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010790 ret = -EINVAL;
10791 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010792 }
10793 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010794 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010795#ifdef MDNS_OFFLOAD
10796 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010797 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010798 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10799 if (VOS_IS_STATUS_SUCCESS(status))
10800 {
10801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10802 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010803 vos_event_reset(&pHostapdState->vosEvent);
10804 if (VOS_STATUS_SUCCESS ==
10805 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10806 status = vos_wait_single_event(&pHostapdState->vosEvent,
10807 10000);
10808 if (!VOS_IS_STATUS_SUCCESS(status)) {
10809 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010810 ret = -EINVAL;
10811 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010812 }
10813 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010814 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010815 status = vos_wait_single_event(&pHostapdAdapter->
10816 mdns_status.vos_event, 2000);
10817 if (!VOS_IS_STATUS_SUCCESS(status) ||
10818 pHostapdAdapter->mdns_status.mdns_enable_status ||
10819 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10820 pHostapdAdapter->mdns_status.mdns_resp_status)
10821 {
10822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10823 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10824 pHostapdAdapter->mdns_status.mdns_enable_status,
10825 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10826 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010827 vos_event_reset(&pHostapdState->vosEvent);
10828 if (VOS_STATUS_SUCCESS ==
10829 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10830 status = vos_wait_single_event(&pHostapdState->vosEvent,
10831 10000);
10832 if (!VOS_IS_STATUS_SUCCESS(status)) {
10833 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010834 ret = -EINVAL;
10835 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010836 }
10837 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010838 }
10839 }
10840#endif /* MDNS_OFFLOAD */
10841 } else {
10842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10843 ("DHCP Disabled ini %d, FW %d"),
10844 iniConfig->enable_dhcp_srv_offload,
10845 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010846 }
10847#endif /* DHCP_SERVER_OFFLOAD */
10848
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010849#ifdef WLAN_FEATURE_P2P_DEBUG
10850 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10851 {
10852 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10853 {
10854 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10855 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010856 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010857 }
10858 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10859 {
10860 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10861 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010862 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010863 }
10864 }
10865#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010866 /* Check and restart SAP if it is on Unsafe channel */
10867 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010868
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 pHostapdState->bCommit = TRUE;
10870 EXIT();
10871
10872 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010873error:
10874 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10875 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010876}
10877
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010878#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010879static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010880 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 struct beacon_parameters *params)
10882{
10883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010884 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010885 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010886
10887 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010888
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10890 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10891 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010892 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10893 hdd_device_modetoString(pAdapter->device_mode),
10894 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010895
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010896 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10897 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010898 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010899 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010900 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010901 }
10902
Agarwal Ashish51325b52014-06-16 16:50:49 +053010903 if (vos_max_concurrent_connections_reached()) {
10904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10905 return -EINVAL;
10906 }
10907
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010908 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 )
10911 {
10912 beacon_data_t *old,*new;
10913
10914 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010915
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010917 {
10918 hddLog(VOS_TRACE_LEVEL_WARN,
10919 FL("already beacon info added to session(%d)"),
10920 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010922 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010923
10924 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10925
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010926 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 {
10928 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010929 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 return -EINVAL;
10931 }
10932
10933 pAdapter->sessionCtx.ap.beacon = new;
10934
10935 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10936 }
10937
10938 EXIT();
10939 return status;
10940}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010941
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010942static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10943 struct net_device *dev,
10944 struct beacon_parameters *params)
10945{
10946 int ret;
10947
10948 vos_ssr_protect(__func__);
10949 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10950 vos_ssr_unprotect(__func__);
10951
10952 return ret;
10953}
10954
10955static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 struct net_device *dev,
10957 struct beacon_parameters *params)
10958{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010960 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10961 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010962 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010963
10964 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010965
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010966 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10967 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10968 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10969 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10970 __func__, hdd_device_modetoString(pAdapter->device_mode),
10971 pAdapter->device_mode);
10972
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010973 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10974 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010975 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010976 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010977 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010978 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010979
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010980 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010982 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 {
10984 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010987
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010989 {
10990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10991 FL("session(%d) old and new heads points to NULL"),
10992 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010995
10996 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10997
10998 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010999 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011000 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 return -EINVAL;
11002 }
11003
11004 pAdapter->sessionCtx.ap.beacon = new;
11005
11006 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11007 }
11008
11009 EXIT();
11010 return status;
11011}
11012
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011013static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11014 struct net_device *dev,
11015 struct beacon_parameters *params)
11016{
11017 int ret;
11018
11019 vos_ssr_protect(__func__);
11020 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11021 vos_ssr_unprotect(__func__);
11022
11023 return ret;
11024}
11025
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011026#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11027
11028#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011029static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011030 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011031#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011032static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011033 struct net_device *dev)
11034#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011035{
11036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011037 hdd_context_t *pHddCtx = NULL;
11038 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011039 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011040 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011041
11042 ENTER();
11043
11044 if (NULL == pAdapter)
11045 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011047 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 return -ENODEV;
11049 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011050
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011051 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11052 TRACE_CODE_HDD_CFG80211_STOP_AP,
11053 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11055 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011056 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011058 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011059 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011060
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011061 pScanInfo = &pHddCtx->scan_info;
11062
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11064 __func__, hdd_device_modetoString(pAdapter->device_mode),
11065 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011066
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011067 ret = wlan_hdd_scan_abort(pAdapter);
11068
Girish Gowli4bf7a632014-06-12 13:42:11 +053011069 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011070 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11072 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011073
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011074 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011075 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11077 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011078
Jeff Johnsone7245742012-09-05 17:12:55 -070011079 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011080 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011081 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011082 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011083 }
11084
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011085 /* Delete all associated STAs before stopping AP/P2P GO */
11086 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011087 hdd_hostapd_stop(dev);
11088
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 )
11092 {
11093 beacon_data_t *old;
11094
11095 old = pAdapter->sessionCtx.ap.beacon;
11096
11097 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011098 {
11099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11100 FL("session(%d) beacon data points to NULL"),
11101 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011104
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011106
11107 mutex_lock(&pHddCtx->sap_lock);
11108 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11109 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011110 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 {
11112 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11113
11114 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11115
11116 if (!VOS_IS_STATUS_SUCCESS(status))
11117 {
11118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011119 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011121 }
11122 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011124 /* BSS stopped, clear the active sessions for this device mode */
11125 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 }
11127 mutex_unlock(&pHddCtx->sap_lock);
11128
11129 if(status != VOS_STATUS_SUCCESS)
11130 {
11131 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011132 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 return -EINVAL;
11134 }
11135
Jeff Johnson4416a782013-03-25 14:17:50 -070011136 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11138 ==eHAL_STATUS_FAILURE)
11139 {
11140 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011141 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 }
11143
Jeff Johnson4416a782013-03-25 14:17:50 -070011144 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11146 eANI_BOOLEAN_FALSE) )
11147 {
11148 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011149 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011150 }
11151
11152 // Reset WNI_CFG_PROBE_RSP Flags
11153 wlan_hdd_reset_prob_rspies(pAdapter);
11154
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011155 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11156
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 pAdapter->sessionCtx.ap.beacon = NULL;
11158 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011159#ifdef WLAN_FEATURE_P2P_DEBUG
11160 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11161 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11162 {
11163 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11164 "GO got removed");
11165 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11166 }
11167#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 }
11169 EXIT();
11170 return status;
11171}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011172
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011173#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11174static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11175 struct net_device *dev)
11176{
11177 int ret;
11178
11179 vos_ssr_protect(__func__);
11180 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11181 vos_ssr_unprotect(__func__);
11182
11183 return ret;
11184}
11185#else
11186static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11187 struct net_device *dev)
11188{
11189 int ret;
11190
11191 vos_ssr_protect(__func__);
11192 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11193 vos_ssr_unprotect(__func__);
11194
11195 return ret;
11196}
11197#endif
11198
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011199#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11200
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011201static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011202 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011203 struct cfg80211_ap_settings *params)
11204{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011205 hdd_adapter_t *pAdapter;
11206 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011208
11209 ENTER();
11210
Girish Gowlib143d7a2015-02-18 19:39:55 +053011211 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011212 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011214 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011215 return -ENODEV;
11216 }
11217
11218 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11219 if (NULL == pAdapter)
11220 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011222 "%s: HDD adapter is Null", __func__);
11223 return -ENODEV;
11224 }
11225
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011226 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11227 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11228 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011229 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11230 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011232 "%s: HDD adapter magic is invalid", __func__);
11233 return -ENODEV;
11234 }
11235
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011236 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11237
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011239 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011240 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011241 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011242 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011243 }
11244
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011245 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11246 __func__, hdd_device_modetoString(pAdapter->device_mode),
11247 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011248
11249 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011250 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011251 )
11252 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011253 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011254
11255 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011256
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011257 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011258 {
11259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11260 FL("already beacon info added to session(%d)"),
11261 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011262 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011263 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011264
Girish Gowlib143d7a2015-02-18 19:39:55 +053011265#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11266 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11267 &new,
11268 &params->beacon);
11269#else
11270 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11271 &new,
11272 &params->beacon,
11273 params->dtim_period);
11274#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011275
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011276 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011277 {
11278 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011279 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011280 return -EINVAL;
11281 }
11282 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011284 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11285#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11286 params->channel, params->channel_type);
11287#else
11288 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11289#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011290#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011291 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011292 params->ssid_len, params->hidden_ssid,
11293 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011294 }
11295
11296 EXIT();
11297 return status;
11298}
11299
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011300static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11301 struct net_device *dev,
11302 struct cfg80211_ap_settings *params)
11303{
11304 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011305
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011306 vos_ssr_protect(__func__);
11307 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11308 vos_ssr_unprotect(__func__);
11309
11310 return ret;
11311}
11312
11313static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011314 struct net_device *dev,
11315 struct cfg80211_beacon_data *params)
11316{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011318 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011319 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011320
11321 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011322
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11324 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11325 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011327 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011328
11329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11330 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011331 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011333 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011334 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011335
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011337 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011338 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011339 {
11340 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011341
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011342 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011343
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011344 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011345 {
11346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11347 FL("session(%d) beacon data points to NULL"),
11348 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011349 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011350 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011351
11352 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11353
11354 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011356 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011357 return -EINVAL;
11358 }
11359
11360 pAdapter->sessionCtx.ap.beacon = new;
11361
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011362 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11363 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011364 }
11365
11366 EXIT();
11367 return status;
11368}
11369
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011370static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11371 struct net_device *dev,
11372 struct cfg80211_beacon_data *params)
11373{
11374 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011375
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011376 vos_ssr_protect(__func__);
11377 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11378 vos_ssr_unprotect(__func__);
11379
11380 return ret;
11381}
11382
11383#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011384
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011385static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 struct net_device *dev,
11387 struct bss_parameters *params)
11388{
11389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011390 hdd_context_t *pHddCtx;
11391 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011392
11393 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011394
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011395 if (NULL == pAdapter)
11396 {
11397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11398 "%s: HDD adapter is Null", __func__);
11399 return -ENODEV;
11400 }
11401 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011402 ret = wlan_hdd_validate_context(pHddCtx);
11403 if (0 != ret)
11404 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011405 return ret;
11406 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011407 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11408 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11409 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11411 __func__, hdd_device_modetoString(pAdapter->device_mode),
11412 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011413
11414 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011416 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 {
11418 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11419 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 {
11422 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 }
11425
11426 EXIT();
11427 return 0;
11428}
11429
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011430static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11431 struct net_device *dev,
11432 struct bss_parameters *params)
11433{
11434 int ret;
11435
11436 vos_ssr_protect(__func__);
11437 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11438 vos_ssr_unprotect(__func__);
11439
11440 return ret;
11441}
Kiet Lam10841362013-11-01 11:36:50 +053011442/* FUNCTION: wlan_hdd_change_country_code_cd
11443* to wait for contry code completion
11444*/
11445void* wlan_hdd_change_country_code_cb(void *pAdapter)
11446{
11447 hdd_adapter_t *call_back_pAdapter = pAdapter;
11448 complete(&call_back_pAdapter->change_country_code);
11449 return NULL;
11450}
11451
Jeff Johnson295189b2012-06-20 16:38:30 -070011452/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011453 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11455 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011456int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 struct net_device *ndev,
11458 enum nl80211_iftype type,
11459 u32 *flags,
11460 struct vif_params *params
11461 )
11462{
11463 struct wireless_dev *wdev;
11464 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011465 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011466 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 tCsrRoamProfile *pRoamProfile = NULL;
11468 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011469 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 eMib_dot11DesiredBssType connectedBssType;
11471 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011472 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011473
11474 ENTER();
11475
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011476 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011477 {
11478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11479 "%s: Adapter context is null", __func__);
11480 return VOS_STATUS_E_FAILURE;
11481 }
11482
11483 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11484 if (!pHddCtx)
11485 {
11486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11487 "%s: HDD context is null", __func__);
11488 return VOS_STATUS_E_FAILURE;
11489 }
11490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11492 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11493 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011494 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011495 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011497 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 }
11499
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11501 __func__, hdd_device_modetoString(pAdapter->device_mode),
11502 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011503
Agarwal Ashish51325b52014-06-16 16:50:49 +053011504 if (vos_max_concurrent_connections_reached()) {
11505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11506 return -EINVAL;
11507 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011508 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 wdev = ndev->ieee80211_ptr;
11510
11511#ifdef WLAN_BTAMP_FEATURE
11512 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11513 (NL80211_IFTYPE_ADHOC == type)||
11514 (NL80211_IFTYPE_AP == type)||
11515 (NL80211_IFTYPE_P2P_GO == type))
11516 {
11517 pHddCtx->isAmpAllowed = VOS_FALSE;
11518 // stop AMP traffic
11519 status = WLANBAP_StopAmp();
11520 if(VOS_STATUS_SUCCESS != status )
11521 {
11522 pHddCtx->isAmpAllowed = VOS_TRUE;
11523 hddLog(VOS_TRACE_LEVEL_FATAL,
11524 "%s: Failed to stop AMP", __func__);
11525 return -EINVAL;
11526 }
11527 }
11528#endif //WLAN_BTAMP_FEATURE
11529 /* Reset the current device mode bit mask*/
11530 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11531
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011532 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11533 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11534 (type == NL80211_IFTYPE_P2P_GO)))
11535 {
11536 /* Notify Mode change in case of concurrency.
11537 * Below function invokes TDLS teardown Functionality Since TDLS is
11538 * not Supported in case of concurrency i.e Once P2P session
11539 * is detected disable offchannel and teardown TDLS links
11540 */
11541 hddLog(LOG1,
11542 FL("Device mode = %d Interface type = %d"),
11543 pAdapter->device_mode, type);
11544 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11545 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011546
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011549 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011550 )
11551 {
11552 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011553 if (!pWextState)
11554 {
11555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11556 "%s: pWextState is null", __func__);
11557 return VOS_STATUS_E_FAILURE;
11558 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011559 pRoamProfile = &pWextState->roamProfile;
11560 LastBSSType = pRoamProfile->BSSType;
11561
11562 switch (type)
11563 {
11564 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 hddLog(VOS_TRACE_LEVEL_INFO,
11567 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11568 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011569#ifdef WLAN_FEATURE_11AC
11570 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11571 {
11572 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11573 }
11574#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011575 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011576 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011578 //Check for sub-string p2p to confirm its a p2p interface
11579 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011580 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011581#ifdef FEATURE_WLAN_TDLS
11582 mutex_lock(&pHddCtx->tdls_lock);
11583 wlan_hdd_tdls_exit(pAdapter, TRUE);
11584 mutex_unlock(&pHddCtx->tdls_lock);
11585#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011586 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11587 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11588 }
11589 else
11590 {
11591 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011593 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011595
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 case NL80211_IFTYPE_ADHOC:
11597 hddLog(VOS_TRACE_LEVEL_INFO,
11598 "%s: setting interface Type to ADHOC", __func__);
11599 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11600 pRoamProfile->phyMode =
11601 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011602 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011604 hdd_set_ibss_ops( pAdapter );
11605 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011606
11607 status = hdd_sta_id_hash_attach(pAdapter);
11608 if (VOS_STATUS_SUCCESS != status) {
11609 hddLog(VOS_TRACE_LEVEL_ERROR,
11610 FL("Failed to initialize hash for IBSS"));
11611 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 break;
11613
11614 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 {
11617 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11618 "%s: setting interface Type to %s", __func__,
11619 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11620
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011621 //Cancel any remain on channel for GO mode
11622 if (NL80211_IFTYPE_P2P_GO == type)
11623 {
11624 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11625 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011626 if (NL80211_IFTYPE_AP == type)
11627 {
11628 /* As Loading WLAN Driver one interface being created for p2p device
11629 * address. This will take one HW STA and the max number of clients
11630 * that can connect to softAP will be reduced by one. so while changing
11631 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11632 * interface as it is not required in SoftAP mode.
11633 */
11634
11635 // Get P2P Adapter
11636 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11637
11638 if (pP2pAdapter)
11639 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011640 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011641 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011642 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11643 }
11644 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011645 //Disable IMPS & BMPS for SAP/GO
11646 if(VOS_STATUS_E_FAILURE ==
11647 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11648 {
11649 //Fail to Exit BMPS
11650 VOS_ASSERT(0);
11651 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011652
11653 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11654
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011655#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011656
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011657 /* A Mutex Lock is introduced while changing the mode to
11658 * protect the concurrent access for the Adapters by TDLS
11659 * module.
11660 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011661 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011662#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011664 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11667 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011668#ifdef FEATURE_WLAN_TDLS
11669 mutex_unlock(&pHddCtx->tdls_lock);
11670#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011671 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11672 (pConfig->apRandomBssidEnabled))
11673 {
11674 /* To meet Android requirements create a randomized
11675 MAC address of the form 02:1A:11:Fx:xx:xx */
11676 get_random_bytes(&ndev->dev_addr[3], 3);
11677 ndev->dev_addr[0] = 0x02;
11678 ndev->dev_addr[1] = 0x1A;
11679 ndev->dev_addr[2] = 0x11;
11680 ndev->dev_addr[3] |= 0xF0;
11681 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11682 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011683 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11684 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011685 }
11686
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 hdd_set_ap_ops( pAdapter->dev );
11688
Kiet Lam10841362013-11-01 11:36:50 +053011689 /* This is for only SAP mode where users can
11690 * control country through ini.
11691 * P2P GO follows station country code
11692 * acquired during the STA scanning. */
11693 if((NL80211_IFTYPE_AP == type) &&
11694 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11695 {
11696 int status = 0;
11697 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11698 "%s: setting country code from INI ", __func__);
11699 init_completion(&pAdapter->change_country_code);
11700 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11701 (void *)(tSmeChangeCountryCallback)
11702 wlan_hdd_change_country_code_cb,
11703 pConfig->apCntryCode, pAdapter,
11704 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011705 eSIR_FALSE,
11706 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011707 if (eHAL_STATUS_SUCCESS == status)
11708 {
11709 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011710 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011711 &pAdapter->change_country_code,
11712 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011713 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011714 {
11715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011716 FL("SME Timed out while setting country code %ld"),
11717 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011718
11719 if (pHddCtx->isLogpInProgress)
11720 {
11721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11722 "%s: LOGP in Progress. Ignore!!!", __func__);
11723 return -EAGAIN;
11724 }
Kiet Lam10841362013-11-01 11:36:50 +053011725 }
11726 }
11727 else
11728 {
11729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011730 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011731 return -EINVAL;
11732 }
11733 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011734 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 if(status != VOS_STATUS_SUCCESS)
11736 {
11737 hddLog(VOS_TRACE_LEVEL_FATAL,
11738 "%s: Error initializing the ap mode", __func__);
11739 return -EINVAL;
11740 }
11741 hdd_set_conparam(1);
11742
Nirav Shah7e3c8132015-06-22 23:51:42 +053011743 status = hdd_sta_id_hash_attach(pAdapter);
11744 if (VOS_STATUS_SUCCESS != status)
11745 {
11746 hddLog(VOS_TRACE_LEVEL_ERROR,
11747 FL("Failed to initialize hash for AP"));
11748 return -EINVAL;
11749 }
11750
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 /*interface type changed update in wiphy structure*/
11752 if(wdev)
11753 {
11754 wdev->iftype = type;
11755 pHddCtx->change_iface = type;
11756 }
11757 else
11758 {
11759 hddLog(VOS_TRACE_LEVEL_ERROR,
11760 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11761 return -EINVAL;
11762 }
11763 goto done;
11764 }
11765
11766 default:
11767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11768 __func__);
11769 return -EOPNOTSUPP;
11770 }
11771 }
11772 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 )
11775 {
11776 switch(type)
11777 {
11778 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011781
11782 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011783#ifdef FEATURE_WLAN_TDLS
11784
11785 /* A Mutex Lock is introduced while changing the mode to
11786 * protect the concurrent access for the Adapters by TDLS
11787 * module.
11788 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011789 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011790#endif
c_hpothu002231a2015-02-05 14:58:51 +053011791 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011793 //Check for sub-string p2p to confirm its a p2p interface
11794 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011795 {
11796 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11797 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11798 }
11799 else
11800 {
11801 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011803 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011804
11805 /* set con_mode to STA only when no SAP concurrency mode */
11806 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11807 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11810 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011811#ifdef FEATURE_WLAN_TDLS
11812 mutex_unlock(&pHddCtx->tdls_lock);
11813#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011814 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 if( VOS_STATUS_SUCCESS != status )
11816 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011817 /* In case of JB, for P2P-GO, only change interface will be called,
11818 * This is the right place to enable back bmps_imps()
11819 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011820 if (pHddCtx->hdd_wlan_suspended)
11821 {
11822 hdd_set_pwrparams(pHddCtx);
11823 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011824 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 goto done;
11826 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11830 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 goto done;
11832 default:
11833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11834 __func__);
11835 return -EOPNOTSUPP;
11836
11837 }
11838
11839 }
11840 else
11841 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011842 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11843 __func__, hdd_device_modetoString(pAdapter->device_mode),
11844 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 return -EOPNOTSUPP;
11846 }
11847
11848
11849 if(pRoamProfile)
11850 {
11851 if ( LastBSSType != pRoamProfile->BSSType )
11852 {
11853 /*interface type changed update in wiphy structure*/
11854 wdev->iftype = type;
11855
11856 /*the BSS mode changed, We need to issue disconnect
11857 if connected or in IBSS disconnect state*/
11858 if ( hdd_connGetConnectedBssType(
11859 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11860 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11861 {
11862 /*need to issue a disconnect to CSR.*/
11863 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11864 if( eHAL_STATUS_SUCCESS ==
11865 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11866 pAdapter->sessionId,
11867 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11868 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011869 ret = wait_for_completion_interruptible_timeout(
11870 &pAdapter->disconnect_comp_var,
11871 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11872 if (ret <= 0)
11873 {
11874 hddLog(VOS_TRACE_LEVEL_ERROR,
11875 FL("wait on disconnect_comp_var failed %ld"), ret);
11876 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 }
11878 }
11879 }
11880 }
11881
11882done:
11883 /*set bitmask based on updated value*/
11884 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011885
11886 /* Only STA mode support TM now
11887 * all other mode, TM feature should be disabled */
11888 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11889 (~VOS_STA & pHddCtx->concurrency_mode) )
11890 {
11891 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11892 }
11893
Jeff Johnson295189b2012-06-20 16:38:30 -070011894#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011896 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 {
11898 //we are ok to do AMP
11899 pHddCtx->isAmpAllowed = VOS_TRUE;
11900 }
11901#endif //WLAN_BTAMP_FEATURE
11902 EXIT();
11903 return 0;
11904}
11905
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011906/*
11907 * FUNCTION: wlan_hdd_cfg80211_change_iface
11908 * wrapper function to protect the actual implementation from SSR.
11909 */
11910int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11911 struct net_device *ndev,
11912 enum nl80211_iftype type,
11913 u32 *flags,
11914 struct vif_params *params
11915 )
11916{
11917 int ret;
11918
11919 vos_ssr_protect(__func__);
11920 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11921 vos_ssr_unprotect(__func__);
11922
11923 return ret;
11924}
11925
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011926#ifdef FEATURE_WLAN_TDLS
11927static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011928 struct net_device *dev,
11929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11930 const u8 *mac,
11931#else
11932 u8 *mac,
11933#endif
11934 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011935{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011936 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011937 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011938 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011939 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011940 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011941 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011942
11943 ENTER();
11944
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011945 if (!dev) {
11946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11947 return -EINVAL;
11948 }
11949
11950 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11951 if (!pAdapter) {
11952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11953 return -EINVAL;
11954 }
11955
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011956 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011957 {
11958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11959 "Invalid arguments");
11960 return -EINVAL;
11961 }
Hoonki Lee27511902013-03-14 18:19:06 -070011962
11963 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11964 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11965 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011967 "%s: TDLS mode is disabled OR not enabled in FW."
11968 MAC_ADDRESS_STR " Request declined.",
11969 __func__, MAC_ADDR_ARRAY(mac));
11970 return -ENOTSUPP;
11971 }
11972
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011973 if (pHddCtx->isLogpInProgress)
11974 {
11975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11976 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011977 wlan_hdd_tdls_set_link_status(pAdapter,
11978 mac,
11979 eTDLS_LINK_IDLE,
11980 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011981 return -EBUSY;
11982 }
11983
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011984 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011985 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011986
11987 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011989 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11990 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011991 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011992 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011993 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011994
11995 /* in add station, we accept existing valid staId if there is */
11996 if ((0 == update) &&
11997 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11998 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011999 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012001 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012002 " link_status %d. staId %d. add station ignored.",
12003 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012004 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012005 return 0;
12006 }
12007 /* in change station, we accept only when staId is valid */
12008 if ((1 == update) &&
12009 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12010 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12011 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012012 tANI_U16 staId = pTdlsPeer->staId;
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
12015 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012016 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12017 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12018 mutex_unlock(&pHddCtx->tdls_lock);
12019 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012020 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012021 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012022
12023 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012024 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012025 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12027 "%s: " MAC_ADDRESS_STR
12028 " TDLS setup is ongoing. Request declined.",
12029 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012030 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012031 }
12032
12033 /* first to check if we reached to maximum supported TDLS peer.
12034 TODO: for now, return -EPERM looks working fine,
12035 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012036 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12037 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012038 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12040 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012041 " TDLS Max peer already connected. Request declined."
12042 " Num of peers (%d), Max allowed (%d).",
12043 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12044 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012045 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012046 }
12047 else
12048 {
12049 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012050 mutex_lock(&pHddCtx->tdls_lock);
12051 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012052 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012053 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012054 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12056 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12057 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012058 return -EPERM;
12059 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012060 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012061 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012062 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012063 wlan_hdd_tdls_set_link_status(pAdapter,
12064 mac,
12065 eTDLS_LINK_CONNECTING,
12066 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012067
Jeff Johnsond75fe012013-04-06 10:53:06 -070012068 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012069 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012070 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012072 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012073 if(StaParams->htcap_present)
12074 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012076 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012078 "ht_capa->extended_capabilities: %0x",
12079 StaParams->HTCap.extendedHtCapInfo);
12080 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012082 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012084 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012085 if(StaParams->vhtcap_present)
12086 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012088 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12089 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12090 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12091 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012092 {
12093 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012095 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
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 "[%d]: %x ", i, StaParams->supported_rates[i]);
12098 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012099 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012100 else if ((1 == update) && (NULL == StaParams))
12101 {
12102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12103 "%s : update is true, but staParams is NULL. Error!", __func__);
12104 return -EPERM;
12105 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012106
12107 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12108
12109 if (!update)
12110 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012111 /*Before adding sta make sure that device exited from BMPS*/
12112 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12113 {
12114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12115 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12116 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12117 if (status != VOS_STATUS_SUCCESS) {
12118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12119 }
12120 }
12121
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012122 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012123 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012124 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012125 hddLog(VOS_TRACE_LEVEL_ERROR,
12126 FL("Failed to add TDLS peer STA. Enable Bmps"));
12127 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012128 return -EPERM;
12129 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012130 }
12131 else
12132 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012133 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012134 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012135 if (ret != eHAL_STATUS_SUCCESS) {
12136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12137 return -EPERM;
12138 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012139 }
12140
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012141 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012142 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12143
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012144 mutex_lock(&pHddCtx->tdls_lock);
12145 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12146
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012147 if ((pTdlsPeer != NULL) &&
12148 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012149 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012150 hddLog(VOS_TRACE_LEVEL_ERROR,
12151 FL("peer link status %u"), pTdlsPeer->link_status);
12152 mutex_unlock(&pHddCtx->tdls_lock);
12153 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012154 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012155 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012156
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012157 if (ret <= 0)
12158 {
12159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12160 "%s: timeout waiting for tdls add station indication %ld",
12161 __func__, ret);
12162 goto error;
12163 }
12164
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012165 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12166 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012168 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012169 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012170 }
12171
12172 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012173
12174error:
Atul Mittal115287b2014-07-08 13:26:33 +053012175 wlan_hdd_tdls_set_link_status(pAdapter,
12176 mac,
12177 eTDLS_LINK_IDLE,
12178 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012179 return -EPERM;
12180
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012181}
12182#endif
12183
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012184static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12187 const u8 *mac,
12188#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 struct station_parameters *params)
12192{
12193 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012194 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012195 hdd_context_t *pHddCtx;
12196 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012198 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012199#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012200 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012201 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012202 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012203 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012204#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012205
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012206 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012207
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012208 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012209 if ((NULL == pAdapter))
12210 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012212 "invalid adapter ");
12213 return -EINVAL;
12214 }
12215
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12217 TRACE_CODE_HDD_CHANGE_STATION,
12218 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012220
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012221 ret = wlan_hdd_validate_context(pHddCtx);
12222 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012223 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012224 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012225 }
12226
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012227 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12228
12229 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012230 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12232 "invalid HDD station context");
12233 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12236
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012237 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12238 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012240 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012242 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 WLANTL_STA_AUTHENTICATED);
12244
Gopichand Nakkala29149562013-05-10 21:43:41 +053012245 if (status != VOS_STATUS_SUCCESS)
12246 {
12247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12248 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12249 return -EINVAL;
12250 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 }
12252 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012253 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12254 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012255#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012256 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12257 StaParams.capability = params->capability;
12258 StaParams.uapsd_queues = params->uapsd_queues;
12259 StaParams.max_sp = params->max_sp;
12260
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012261 /* Convert (first channel , number of channels) tuple to
12262 * the total list of channels. This goes with the assumption
12263 * that if the first channel is < 14, then the next channels
12264 * are an incremental of 1 else an incremental of 4 till the number
12265 * of channels.
12266 */
12267 if (0 != params->supported_channels_len) {
12268 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12269 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12270 {
12271 int wifi_chan_index;
12272 StaParams.supported_channels[j] = params->supported_channels[i];
12273 wifi_chan_index =
12274 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12275 no_of_channels = params->supported_channels[i+1];
12276 for(k=1; k <= no_of_channels; k++)
12277 {
12278 StaParams.supported_channels[j+1] =
12279 StaParams.supported_channels[j] + wifi_chan_index;
12280 j+=1;
12281 }
12282 }
12283 StaParams.supported_channels_len = j;
12284 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012285 if (params->supported_oper_classes_len >
12286 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12288 "received oper classes:%d, resetting it to max supported %d",
12289 params->supported_oper_classes_len,
12290 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12291 params->supported_oper_classes_len =
12292 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12293 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012294 vos_mem_copy(StaParams.supported_oper_classes,
12295 params->supported_oper_classes,
12296 params->supported_oper_classes_len);
12297 StaParams.supported_oper_classes_len =
12298 params->supported_oper_classes_len;
12299
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012300 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12302 "received extn capabilities:%d, resetting it to max supported",
12303 params->ext_capab_len);
12304 params->ext_capab_len = sizeof(StaParams.extn_capability);
12305 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012306 if (0 != params->ext_capab_len)
12307 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012308 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012309
12310 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012311 {
12312 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012313 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012314 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012315
12316 StaParams.supported_rates_len = params->supported_rates_len;
12317
12318 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12319 * The supported_rates array , for all the structures propogating till Add Sta
12320 * to the firmware has to be modified , if the supplicant (ieee80211) is
12321 * modified to send more rates.
12322 */
12323
12324 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12325 */
12326 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12327 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12328
12329 if (0 != StaParams.supported_rates_len) {
12330 int i = 0;
12331 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12332 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012334 "Supported Rates with Length %d", StaParams.supported_rates_len);
12335 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012337 "[%d]: %0x", i, StaParams.supported_rates[i]);
12338 }
12339
12340 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012341 {
12342 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012343 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012344 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012345
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012346 if (0 != params->ext_capab_len ) {
12347 /*Define A Macro : TODO Sunil*/
12348 if ((1<<4) & StaParams.extn_capability[3]) {
12349 isBufSta = 1;
12350 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012351 /* TDLS Channel Switching Support */
12352 if ((1<<6) & StaParams.extn_capability[3]) {
12353 isOffChannelSupported = 1;
12354 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012355 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012356
12357 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012358 (params->ht_capa || params->vht_capa ||
12359 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012360 /* TDLS Peer is WME/QoS capable */
12361 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012362
12363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12364 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12365 __func__, isQosWmmSta, StaParams.htcap_present);
12366
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012367 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12368 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012369 isOffChannelSupported,
12370 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012371
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012372 if (VOS_STATUS_SUCCESS != status) {
12373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12374 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12375 return -EINVAL;
12376 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012377 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12378
12379 if (VOS_STATUS_SUCCESS != status) {
12380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12381 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12382 return -EINVAL;
12383 }
12384 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012385#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012386 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012387 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 return status;
12389}
12390
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12392static int wlan_hdd_change_station(struct wiphy *wiphy,
12393 struct net_device *dev,
12394 const u8 *mac,
12395 struct station_parameters *params)
12396#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012397static int wlan_hdd_change_station(struct wiphy *wiphy,
12398 struct net_device *dev,
12399 u8 *mac,
12400 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012401#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012402{
12403 int ret;
12404
12405 vos_ssr_protect(__func__);
12406 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12407 vos_ssr_unprotect(__func__);
12408
12409 return ret;
12410}
12411
Jeff Johnson295189b2012-06-20 16:38:30 -070012412/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012413 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 * This function is used to initialize the key information
12415 */
12416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012417static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 struct net_device *ndev,
12419 u8 key_index, bool pairwise,
12420 const u8 *mac_addr,
12421 struct key_params *params
12422 )
12423#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012424static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 struct net_device *ndev,
12426 u8 key_index, const u8 *mac_addr,
12427 struct key_params *params
12428 )
12429#endif
12430{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012431 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 tCsrRoamSetKey setKey;
12433 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012434 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012435 v_U32_t roamId= 0xFF;
12436 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 hdd_hostapd_state_t *pHostapdState;
12438 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012439 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012440 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012441 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012442 v_MACADDR_t *peerMacAddr;
12443 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012444 uint8_t staid = HDD_MAX_STA_COUNT;
12445 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012446
12447 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012448
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012449 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12450 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12451 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012452 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12453 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012454 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012455 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012456 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012457 }
12458
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12460 __func__, hdd_device_modetoString(pAdapter->device_mode),
12461 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012462
12463 if (CSR_MAX_NUM_KEY <= key_index)
12464 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 key_index);
12467
12468 return -EINVAL;
12469 }
12470
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012471 if (CSR_MAX_KEY_LEN < params->key_len)
12472 {
12473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12474 params->key_len);
12475
12476 return -EINVAL;
12477 }
12478
Jingxiang Gec438aea2017-10-26 16:44:00 +080012479 if (CSR_MAX_RSC_LEN < params->seq_len)
12480 {
12481 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12482 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012483
12484 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012485 }
12486
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012487 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012488 "%s: called with key index = %d & key length %d & seq length %d",
12489 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012490
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012491 peerMacAddr = (v_MACADDR_t *)mac_addr;
12492
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 /*extract key idx, key len and key*/
12494 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12495 setKey.keyId = key_index;
12496 setKey.keyLength = params->key_len;
12497 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012498 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012499
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012500 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012501 {
12502 case WLAN_CIPHER_SUITE_WEP40:
12503 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12504 break;
12505
12506 case WLAN_CIPHER_SUITE_WEP104:
12507 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12508 break;
12509
12510 case WLAN_CIPHER_SUITE_TKIP:
12511 {
12512 u8 *pKey = &setKey.Key[0];
12513 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12514
12515 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12516
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012517 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012518
12519 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012520 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 |--------------|----------|----------|
12522 <---16bytes---><--8bytes--><--8bytes-->
12523
12524 */
12525 /*Sme expects the 32 bytes key to be in the below order
12526
12527 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012528 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 |--------------|----------|----------|
12530 <---16bytes---><--8bytes--><--8bytes-->
12531 */
12532 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012533 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012534
12535 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012536 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012537
12538 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012539 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012540
12541
12542 break;
12543 }
12544
12545 case WLAN_CIPHER_SUITE_CCMP:
12546 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12547 break;
12548
12549#ifdef FEATURE_WLAN_WAPI
12550 case WLAN_CIPHER_SUITE_SMS4:
12551 {
12552 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12553 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12554 params->key, params->key_len);
12555 return 0;
12556 }
12557#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012558
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012559#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 case WLAN_CIPHER_SUITE_KRK:
12561 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12562 break;
12563#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012564
12565#ifdef WLAN_FEATURE_11W
12566 case WLAN_CIPHER_SUITE_AES_CMAC:
12567 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012568 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012569#endif
12570
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012574 status = -EOPNOTSUPP;
12575 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012576 }
12577
12578 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12579 __func__, setKey.encType);
12580
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012581 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12583 (!pairwise)
12584#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012585 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012586#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012587 )
12588 {
12589 /* set group key*/
12590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12591 "%s- %d: setting Broadcast key",
12592 __func__, __LINE__);
12593 setKey.keyDirection = eSIR_RX_ONLY;
12594 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12595 }
12596 else
12597 {
12598 /* set pairwise key*/
12599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12600 "%s- %d: setting pairwise key",
12601 __func__, __LINE__);
12602 setKey.keyDirection = eSIR_TX_RX;
12603 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012604 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012605 }
12606 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12607 {
12608 setKey.keyDirection = eSIR_TX_RX;
12609 /*Set the group key*/
12610 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12611 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012612
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012613 if ( 0 != status )
12614 {
12615 hddLog(VOS_TRACE_LEVEL_ERROR,
12616 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012617 status = -EINVAL;
12618 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012619 }
12620 /*Save the keys here and call sme_RoamSetKey for setting
12621 the PTK after peer joins the IBSS network*/
12622 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12623 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012624 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012625 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012626 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12627 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12628 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012630 if( pHostapdState->bssState == BSS_START )
12631 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012632 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12633 vos_status = wlan_hdd_check_ula_done(pAdapter);
12634
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012635 if (peerMacAddr && (pairwise_set_key == true))
12636 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012637
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012638 if ( vos_status != VOS_STATUS_SUCCESS )
12639 {
12640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12641 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12642 __LINE__, vos_status );
12643
12644 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12645
12646 status = -EINVAL;
12647 goto end;
12648 }
12649
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12651
12652 if ( status != eHAL_STATUS_SUCCESS )
12653 {
12654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12655 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12656 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012657 status = -EINVAL;
12658 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 }
12660 }
12661
12662 /* Saving WEP keys */
12663 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12664 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12665 {
12666 //Save the wep key in ap context. Issue setkey after the BSS is started.
12667 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12668 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12669 }
12670 else
12671 {
12672 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012673 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12675 }
12676 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012677 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12678 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 {
12680 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12681 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12682
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12684 if (!pairwise)
12685#else
12686 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12687#endif
12688 {
12689 /* set group key*/
12690 if (pHddStaCtx->roam_info.deferKeyComplete)
12691 {
12692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12693 "%s- %d: Perform Set key Complete",
12694 __func__, __LINE__);
12695 hdd_PerformRoamSetKeyComplete(pAdapter);
12696 }
12697 }
12698
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012699 if (pairwise_set_key == true)
12700 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012701
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12703
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012704 pWextState->roamProfile.Keys.defaultIndex = key_index;
12705
12706
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012707 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 params->key, params->key_len);
12709
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012710
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12712
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012713 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012715 __func__, setKey.peerMac[0], setKey.peerMac[1],
12716 setKey.peerMac[2], setKey.peerMac[3],
12717 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 setKey.keyDirection);
12719
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012720 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012721
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012722 if ( vos_status != VOS_STATUS_SUCCESS )
12723 {
12724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12726 __LINE__, vos_status );
12727
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012728 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012729
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012730 status = -EINVAL;
12731 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012732
12733 }
12734
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012735#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012736 /* The supplicant may attempt to set the PTK once pre-authentication
12737 is done. Save the key in the UMAC and include it in the ADD BSS
12738 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012739 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012740 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012741 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012742 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12743 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012744 status = 0;
12745 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012746 }
12747 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12748 {
12749 hddLog(VOS_TRACE_LEVEL_ERROR,
12750 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012751 status = -EINVAL;
12752 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012753 }
12754#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012755
12756 /* issue set key request to SME*/
12757 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12758 pAdapter->sessionId, &setKey, &roamId );
12759
12760 if ( 0 != status )
12761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012762 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012763 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12764 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012765 status = -EINVAL;
12766 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012767 }
12768
12769
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012770 /* in case of IBSS as there was no information available about WEP keys during
12771 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012773 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12774 !( ( IW_AUTH_KEY_MGMT_802_1X
12775 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012776 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12777 )
12778 &&
12779 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12780 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12781 )
12782 )
12783 {
12784 setKey.keyDirection = eSIR_RX_ONLY;
12785 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12786
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012789 __func__, setKey.peerMac[0], setKey.peerMac[1],
12790 setKey.peerMac[2], setKey.peerMac[3],
12791 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 setKey.keyDirection);
12793
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012794 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 pAdapter->sessionId, &setKey, &roamId );
12796
12797 if ( 0 != status )
12798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012799 hddLog(VOS_TRACE_LEVEL_ERROR,
12800 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 __func__, status);
12802 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012803 status = -EINVAL;
12804 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012805 }
12806 }
12807 }
12808
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012809 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012810 for (i = 0; i < params->seq_len; i++) {
12811 rsc_counter |= (params->seq[i] << i*8);
12812 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012813 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12814 }
12815
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012816end:
12817 /* Need to clear any trace of key value in the memory.
12818 * Thus zero out the memory even though it is local
12819 * variable.
12820 */
12821 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012822 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012823 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012824}
12825
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12827static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12828 struct net_device *ndev,
12829 u8 key_index, bool pairwise,
12830 const u8 *mac_addr,
12831 struct key_params *params
12832 )
12833#else
12834static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12835 struct net_device *ndev,
12836 u8 key_index, const u8 *mac_addr,
12837 struct key_params *params
12838 )
12839#endif
12840{
12841 int ret;
12842 vos_ssr_protect(__func__);
12843#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12844 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12845 mac_addr, params);
12846#else
12847 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12848 params);
12849#endif
12850 vos_ssr_unprotect(__func__);
12851
12852 return ret;
12853}
12854
Jeff Johnson295189b2012-06-20 16:38:30 -070012855/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012856 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012857 * This function is used to get the key information
12858 */
12859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012860static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012861 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012862 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012863 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012864 const u8 *mac_addr, void *cookie,
12865 void (*callback)(void *cookie, struct key_params*)
12866 )
12867#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012868static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012869 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012870 struct net_device *ndev,
12871 u8 key_index, const u8 *mac_addr, void *cookie,
12872 void (*callback)(void *cookie, struct key_params*)
12873 )
12874#endif
12875{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012877 hdd_wext_state_t *pWextState = NULL;
12878 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012879 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012880 hdd_context_t *pHddCtx;
12881 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012882
12883 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012884
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012885 if (NULL == pAdapter)
12886 {
12887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12888 "%s: HDD adapter is Null", __func__);
12889 return -ENODEV;
12890 }
12891
12892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12893 ret = wlan_hdd_validate_context(pHddCtx);
12894 if (0 != ret)
12895 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012896 return ret;
12897 }
12898
12899 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12900 pRoamProfile = &(pWextState->roamProfile);
12901
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12903 __func__, hdd_device_modetoString(pAdapter->device_mode),
12904 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012905
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 memset(&params, 0, sizeof(params));
12907
12908 if (CSR_MAX_NUM_KEY <= key_index)
12909 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012911 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012913
12914 switch(pRoamProfile->EncryptionType.encryptionType[0])
12915 {
12916 case eCSR_ENCRYPT_TYPE_NONE:
12917 params.cipher = IW_AUTH_CIPHER_NONE;
12918 break;
12919
12920 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12921 case eCSR_ENCRYPT_TYPE_WEP40:
12922 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12923 break;
12924
12925 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12926 case eCSR_ENCRYPT_TYPE_WEP104:
12927 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12928 break;
12929
12930 case eCSR_ENCRYPT_TYPE_TKIP:
12931 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12932 break;
12933
12934 case eCSR_ENCRYPT_TYPE_AES:
12935 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12936 break;
12937
12938 default:
12939 params.cipher = IW_AUTH_CIPHER_NONE;
12940 break;
12941 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012942
c_hpothuaaf19692014-05-17 17:01:48 +053012943 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12944 TRACE_CODE_HDD_CFG80211_GET_KEY,
12945 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012946
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12948 params.seq_len = 0;
12949 params.seq = NULL;
12950 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12951 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012952 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012953 return 0;
12954}
12955
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12957static int wlan_hdd_cfg80211_get_key(
12958 struct wiphy *wiphy,
12959 struct net_device *ndev,
12960 u8 key_index, bool pairwise,
12961 const u8 *mac_addr, void *cookie,
12962 void (*callback)(void *cookie, struct key_params*)
12963 )
12964#else
12965static int wlan_hdd_cfg80211_get_key(
12966 struct wiphy *wiphy,
12967 struct net_device *ndev,
12968 u8 key_index, const u8 *mac_addr, void *cookie,
12969 void (*callback)(void *cookie, struct key_params*)
12970 )
12971#endif
12972{
12973 int ret;
12974
12975 vos_ssr_protect(__func__);
12976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12977 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12978 mac_addr, cookie, callback);
12979#else
12980 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12981 callback);
12982#endif
12983 vos_ssr_unprotect(__func__);
12984
12985 return ret;
12986}
12987
Jeff Johnson295189b2012-06-20 16:38:30 -070012988/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012989 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012990 * This function is used to delete the key information
12991 */
12992#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012993static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012995 u8 key_index,
12996 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 const u8 *mac_addr
12998 )
12999#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013000static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013001 struct net_device *ndev,
13002 u8 key_index,
13003 const u8 *mac_addr
13004 )
13005#endif
13006{
13007 int status = 0;
13008
13009 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013010 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 //it is observed that this is invalidating peer
13012 //key index whenever re-key is done. This is affecting data link.
13013 //It should be ok to ignore del_key.
13014#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13016 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013017 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13018 tCsrRoamSetKey setKey;
13019 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 ENTER();
13022
13023 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13024 __func__,pAdapter->device_mode);
13025
13026 if (CSR_MAX_NUM_KEY <= key_index)
13027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013028 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 key_index);
13030
13031 return -EINVAL;
13032 }
13033
13034 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13035 setKey.keyId = key_index;
13036
13037 if (mac_addr)
13038 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13039 else
13040 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13041
13042 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13043
13044 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013046 )
13047 {
13048
13049 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013050 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13051 if( pHostapdState->bssState == BSS_START)
13052 {
13053 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013054
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 if ( status != eHAL_STATUS_SUCCESS )
13056 {
13057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13058 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13059 __LINE__, status );
13060 }
13061 }
13062 }
13063 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013064 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 )
13066 {
13067 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13068
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013069 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13070
13071 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013073 __func__, setKey.peerMac[0], setKey.peerMac[1],
13074 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 if(pAdapter->sessionCtx.station.conn_info.connState ==
13077 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013079 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013081
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 if ( 0 != status )
13083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013084 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 "%s: sme_RoamSetKey failure, returned %d",
13086 __func__, status);
13087 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13088 return -EINVAL;
13089 }
13090 }
13091 }
13092#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013093 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 return status;
13095}
13096
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13098static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13099 struct net_device *ndev,
13100 u8 key_index,
13101 bool pairwise,
13102 const u8 *mac_addr
13103 )
13104#else
13105static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13106 struct net_device *ndev,
13107 u8 key_index,
13108 const u8 *mac_addr
13109 )
13110#endif
13111{
13112 int ret;
13113
13114 vos_ssr_protect(__func__);
13115#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13116 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13117 mac_addr);
13118#else
13119 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13120#endif
13121 vos_ssr_unprotect(__func__);
13122
13123 return ret;
13124}
13125
Jeff Johnson295189b2012-06-20 16:38:30 -070013126/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013127 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 * This function is used to set the default tx key index
13129 */
13130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013131static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 struct net_device *ndev,
13133 u8 key_index,
13134 bool unicast, bool multicast)
13135#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013136static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 struct net_device *ndev,
13138 u8 key_index)
13139#endif
13140{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013142 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013143 hdd_wext_state_t *pWextState;
13144 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013145 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013146
13147 ENTER();
13148
Gopichand Nakkala29149562013-05-10 21:43:41 +053013149 if ((NULL == pAdapter))
13150 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013152 "invalid adapter");
13153 return -EINVAL;
13154 }
13155
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013156 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13157 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13158 pAdapter->sessionId, key_index));
13159
Gopichand Nakkala29149562013-05-10 21:43:41 +053013160 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13161 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13162
13163 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13164 {
13165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13166 "invalid Wext state or HDD context");
13167 return -EINVAL;
13168 }
13169
Arif Hussain6d2a3322013-11-17 19:50:10 -080013170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013172
Jeff Johnson295189b2012-06-20 16:38:30 -070013173 if (CSR_MAX_NUM_KEY <= key_index)
13174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013176 key_index);
13177
13178 return -EINVAL;
13179 }
13180
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013181 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13182 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013183 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013184 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013185 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013186 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013187
Jeff Johnson295189b2012-06-20 16:38:30 -070013188 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013190 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013192 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013193 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013194#ifdef FEATURE_WLAN_WAPI
13195 (eCSR_ENCRYPT_TYPE_WPI !=
13196 pHddStaCtx->conn_info.ucEncryptionType) &&
13197#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013198 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013199 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013201 {
13202 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013203 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 tCsrRoamSetKey setKey;
13206 v_U32_t roamId= 0xFF;
13207 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013208
13209 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013211
Jeff Johnson295189b2012-06-20 16:38:30 -070013212 Keys->defaultIndex = (u8)key_index;
13213 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13214 setKey.keyId = key_index;
13215 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013216
13217 vos_mem_copy(&setKey.Key[0],
13218 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220
Gopichand Nakkala29149562013-05-10 21:43:41 +053013221 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013222
13223 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 &pHddStaCtx->conn_info.bssId[0],
13225 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013226
Gopichand Nakkala29149562013-05-10 21:43:41 +053013227 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13228 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13229 eCSR_ENCRYPT_TYPE_WEP104)
13230 {
13231 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13232 even though ap is configured for WEP-40 encryption. In this canse the key length
13233 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13234 type(104) and switching encryption type to 40*/
13235 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13236 eCSR_ENCRYPT_TYPE_WEP40;
13237 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13238 eCSR_ENCRYPT_TYPE_WEP40;
13239 }
13240
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013241 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013243
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 if ( 0 != status )
13249 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013250 hddLog(VOS_TRACE_LEVEL_ERROR,
13251 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 status);
13253 return -EINVAL;
13254 }
13255 }
13256 }
13257
13258 /* In SoftAp mode setting key direction for default mode */
13259 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13260 {
13261 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13262 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13263 (eCSR_ENCRYPT_TYPE_AES !=
13264 pWextState->roamProfile.EncryptionType.encryptionType[0])
13265 )
13266 {
13267 /* Saving key direction for default key index to TX default */
13268 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13269 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13270 }
13271 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013272 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013273 return status;
13274}
13275
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13277static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13278 struct net_device *ndev,
13279 u8 key_index,
13280 bool unicast, bool multicast)
13281#else
13282static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13283 struct net_device *ndev,
13284 u8 key_index)
13285#endif
13286{
13287 int ret;
13288 vos_ssr_protect(__func__);
13289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13290 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13291 multicast);
13292#else
13293 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13294#endif
13295 vos_ssr_unprotect(__func__);
13296
13297 return ret;
13298}
13299
Jeff Johnson295189b2012-06-20 16:38:30 -070013300/*
13301 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13302 * This function is used to inform the BSS details to nl80211 interface.
13303 */
13304static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13305 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13306{
13307 struct net_device *dev = pAdapter->dev;
13308 struct wireless_dev *wdev = dev->ieee80211_ptr;
13309 struct wiphy *wiphy = wdev->wiphy;
13310 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13311 int chan_no;
13312 int ie_length;
13313 const char *ie;
13314 unsigned int freq;
13315 struct ieee80211_channel *chan;
13316 int rssi = 0;
13317 struct cfg80211_bss *bss = NULL;
13318
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 if( NULL == pBssDesc )
13320 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013321 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 return bss;
13323 }
13324
13325 chan_no = pBssDesc->channelId;
13326 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13327 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13328
13329 if( NULL == ie )
13330 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013331 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 return bss;
13333 }
13334
13335#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13336 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13337 {
13338 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13339 }
13340 else
13341 {
13342 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13343 }
13344#else
13345 freq = ieee80211_channel_to_frequency(chan_no);
13346#endif
13347
13348 chan = __ieee80211_get_channel(wiphy, freq);
13349
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013350 if (!chan) {
13351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13352 return NULL;
13353 }
13354
Abhishek Singhaee43942014-06-16 18:55:47 +053013355 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013356
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013357 return cfg80211_inform_bss(wiphy, chan,
13358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13359 CFG80211_BSS_FTYPE_UNKNOWN,
13360#endif
13361 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013362 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 pBssDesc->capabilityInfo,
13364 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013365 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013366}
13367
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013368/*
13369 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13370 * interface that BSS might have been lost.
13371 * @pAdapter: adaptor
13372 * @bssid: bssid which might have been lost
13373 *
13374 * Return: bss which is unlinked from kernel cache
13375 */
13376struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13377 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13378{
13379 struct net_device *dev = pAdapter->dev;
13380 struct wireless_dev *wdev = dev->ieee80211_ptr;
13381 struct wiphy *wiphy = wdev->wiphy;
13382 struct cfg80211_bss *bss = NULL;
13383
Abhishek Singh5a597e62016-12-05 15:16:30 +053013384 bss = hdd_get_bss_entry(wiphy,
13385 NULL, bssid,
13386 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013387 if (bss == NULL) {
13388 hddLog(LOGE, FL("BSS not present"));
13389 } else {
13390 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13391 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13392 cfg80211_unlink_bss(wiphy, bss);
13393 }
13394 return bss;
13395}
Jeff Johnson295189b2012-06-20 16:38:30 -070013396
13397
13398/*
13399 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13400 * This function is used to inform the BSS details to nl80211 interface.
13401 */
13402struct cfg80211_bss*
13403wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13404 tSirBssDescription *bss_desc
13405 )
13406{
13407 /*
13408 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13409 already exists in bss data base of cfg80211 for that particular BSS ID.
13410 Using cfg80211_inform_bss_frame to update the bss entry instead of
13411 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13412 now there is no possibility to get the mgmt(probe response) frame from PE,
13413 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13414 cfg80211_inform_bss_frame.
13415 */
13416 struct net_device *dev = pAdapter->dev;
13417 struct wireless_dev *wdev = dev->ieee80211_ptr;
13418 struct wiphy *wiphy = wdev->wiphy;
13419 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013420#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13421 qcom_ie_age *qie_age = NULL;
13422 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13423#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 const char *ie =
13427 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13428 unsigned int freq;
13429 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013430 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 struct cfg80211_bss *bss_status = NULL;
13432 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13433 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013434 hdd_context_t *pHddCtx;
13435 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013436#ifdef WLAN_OPEN_SOURCE
13437 struct timespec ts;
13438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013440
Wilson Yangf80a0542013-10-07 13:02:37 -070013441 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13442 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013443 if (0 != status)
13444 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013445 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013446 }
13447
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013448 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013449 if (!mgmt)
13450 {
13451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13452 "%s: memory allocation failed ", __func__);
13453 return NULL;
13454 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013455
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013457
13458#ifdef WLAN_OPEN_SOURCE
13459 /* Android does not want the timestamp from the frame.
13460 Instead it wants a monotonic increasing value */
13461 get_monotonic_boottime(&ts);
13462 mgmt->u.probe_resp.timestamp =
13463 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13464#else
13465 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013466 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13467 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013468
13469#endif
13470
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13472 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013473
13474#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13475 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13476 /* Assuming this is the last IE, copy at the end */
13477 ie_length -=sizeof(qcom_ie_age);
13478 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13479 qie_age->element_id = QCOM_VENDOR_IE_ID;
13480 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13481 qie_age->oui_1 = QCOM_OUI1;
13482 qie_age->oui_2 = QCOM_OUI2;
13483 qie_age->oui_3 = QCOM_OUI3;
13484 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013485 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13486 * bss related timestamp is in units of ms. Due to this when scan results
13487 * are sent to lowi the scan age is high.To address this, send age in units
13488 * of 1/10 ms.
13489 */
13490 qie_age->age = (vos_timer_get_system_time() -
13491 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013492#endif
13493
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013495 if (bss_desc->fProbeRsp)
13496 {
13497 mgmt->frame_control |=
13498 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13499 }
13500 else
13501 {
13502 mgmt->frame_control |=
13503 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13504 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013505
13506#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013507 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13509 {
13510 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13511 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013512 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13514
13515 {
13516 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13517 }
13518 else
13519 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13521 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 kfree(mgmt);
13523 return NULL;
13524 }
13525#else
13526 freq = ieee80211_channel_to_frequency(chan_no);
13527#endif
13528 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013529 /*when the band is changed on the fly using the GUI, three things are done
13530 * 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)
13531 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13532 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13533 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13534 * and discards the channels correponding to previous band and calls back with zero bss results.
13535 * 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
13536 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13537 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13538 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13539 * So drop the bss and continue to next bss.
13540 */
13541 if(chan == NULL)
13542 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013543 hddLog(VOS_TRACE_LEVEL_ERROR,
13544 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13545 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013546 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013547 return NULL;
13548 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013549 /*To keep the rssi icon of the connected AP in the scan window
13550 *and the rssi icon of the wireless networks in sync
13551 * */
13552 if (( eConnectionState_Associated ==
13553 pAdapter->sessionCtx.station.conn_info.connState ) &&
13554 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13555 pAdapter->sessionCtx.station.conn_info.bssId,
13556 WNI_CFG_BSSID_LEN)) &&
13557 (pHddCtx->hdd_wlan_suspended == FALSE))
13558 {
13559 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13560 rssi = (pAdapter->rssi * 100);
13561 }
13562 else
13563 {
13564 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013566
Nirav Shah20ac06f2013-12-12 18:14:06 +053013567 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013568 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13569 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013570
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13572 frame_len, rssi, GFP_KERNEL);
13573 kfree(mgmt);
13574 return bss_status;
13575}
13576
13577/*
13578 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13579 * This function is used to update the BSS data base of CFG8011
13580 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013581struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 tCsrRoamInfo *pRoamInfo
13583 )
13584{
13585 tCsrRoamConnectedProfile roamProfile;
13586 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13587 struct cfg80211_bss *bss = NULL;
13588
13589 ENTER();
13590
13591 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13592 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13593
13594 if (NULL != roamProfile.pBssDesc)
13595 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013596 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13597 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013598
13599 if (NULL == bss)
13600 {
13601 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13602 __func__);
13603 }
13604
13605 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13606 }
13607 else
13608 {
13609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13610 __func__);
13611 }
13612 return bss;
13613}
13614
13615/*
13616 * FUNCTION: wlan_hdd_cfg80211_update_bss
13617 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013618static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13619 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013621{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013622 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 tCsrScanResultInfo *pScanResult;
13624 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013625 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 tScanResultHandle pResult;
13627 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013628 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013629 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13633 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13634 NO_SESSION, pAdapter->sessionId));
13635
Wilson Yangf80a0542013-10-07 13:02:37 -070013636 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013637 ret = wlan_hdd_validate_context(pHddCtx);
13638 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013640 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013641 }
13642
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013643 if (pAdapter->request != NULL)
13644 {
13645 if ((pAdapter->request->n_ssids == 1)
13646 && (pAdapter->request->ssids != NULL)
13647 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13648 is_p2p_scan = true;
13649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 /*
13651 * start getting scan results and populate cgf80211 BSS database
13652 */
13653 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13654
13655 /* no scan results */
13656 if (NULL == pResult)
13657 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13659 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013660 wlan_hdd_get_frame_logs(pAdapter,
13661 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013662 return status;
13663 }
13664
13665 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13666
13667 while (pScanResult)
13668 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013669 /*
13670 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13671 * entry already exists in bss data base of cfg80211 for that
13672 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13673 * bss entry instead of cfg80211_inform_bss, But this call expects
13674 * mgmt packet as input. As of now there is no possibility to get
13675 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 * ieee80211_mgmt(probe response) and passing to c
13677 * fg80211_inform_bss_frame.
13678 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013679 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13680 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13681 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013682 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13683 continue; //Skip the non p2p bss entries
13684 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13686 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013687
Jeff Johnson295189b2012-06-20 16:38:30 -070013688
13689 if (NULL == bss_status)
13690 {
13691 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013692 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 }
13694 else
13695 {
Yue Maf49ba872013-08-19 12:04:25 -070013696 cfg80211_put_bss(
13697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13698 wiphy,
13699#endif
13700 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 }
13702
13703 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13704 }
13705
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013706 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013707 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013708 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013709}
13710
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013711void
13712hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13713{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013714 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013715 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013716} /****** end hddPrintMacAddr() ******/
13717
13718void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013719hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013720{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013721 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013722 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013723 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13724 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13725 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013726} /****** end hddPrintPmkId() ******/
13727
13728//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13729//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13730
13731//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13732//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13733
13734#define dump_bssid(bssid) \
13735 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013736 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13737 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013738 }
13739
13740#define dump_pmkid(pMac, pmkid) \
13741 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013742 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13743 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013744 }
13745
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013746#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013747/*
13748 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13749 * This function is used to notify the supplicant of a new PMKSA candidate.
13750 */
13751int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013752 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013753 int index, bool preauth )
13754{
Jeff Johnsone7245742012-09-05 17:12:55 -070013755#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013756 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013757 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013758
13759 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013760 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013761
13762 if( NULL == pRoamInfo )
13763 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013764 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013765 return -EINVAL;
13766 }
13767
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013768 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13769 {
13770 dump_bssid(pRoamInfo->bssid);
13771 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013772 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013773 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013774#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013775 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013776}
13777#endif //FEATURE_WLAN_LFR
13778
Yue Maef608272013-04-08 23:09:17 -070013779#ifdef FEATURE_WLAN_LFR_METRICS
13780/*
13781 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13782 * 802.11r/LFR metrics reporting function to report preauth initiation
13783 *
13784 */
13785#define MAX_LFR_METRICS_EVENT_LENGTH 100
13786VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13787 tCsrRoamInfo *pRoamInfo)
13788{
13789 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13790 union iwreq_data wrqu;
13791
13792 ENTER();
13793
13794 if (NULL == pAdapter)
13795 {
13796 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13797 return VOS_STATUS_E_FAILURE;
13798 }
13799
13800 /* create the event */
13801 memset(&wrqu, 0, sizeof(wrqu));
13802 memset(metrics_notification, 0, sizeof(metrics_notification));
13803
13804 wrqu.data.pointer = metrics_notification;
13805 wrqu.data.length = scnprintf(metrics_notification,
13806 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13807 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13808
13809 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13810
13811 EXIT();
13812
13813 return VOS_STATUS_SUCCESS;
13814}
13815
13816/*
13817 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13818 * 802.11r/LFR metrics reporting function to report preauth completion
13819 * or failure
13820 */
13821VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13822 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13823{
13824 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13825 union iwreq_data wrqu;
13826
13827 ENTER();
13828
13829 if (NULL == pAdapter)
13830 {
13831 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13832 return VOS_STATUS_E_FAILURE;
13833 }
13834
13835 /* create the event */
13836 memset(&wrqu, 0, sizeof(wrqu));
13837 memset(metrics_notification, 0, sizeof(metrics_notification));
13838
13839 scnprintf(metrics_notification, sizeof(metrics_notification),
13840 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13841 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13842
13843 if (1 == preauth_status)
13844 strncat(metrics_notification, " TRUE", 5);
13845 else
13846 strncat(metrics_notification, " FALSE", 6);
13847
13848 wrqu.data.pointer = metrics_notification;
13849 wrqu.data.length = strlen(metrics_notification);
13850
13851 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13852
13853 EXIT();
13854
13855 return VOS_STATUS_SUCCESS;
13856}
13857
13858/*
13859 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13860 * 802.11r/LFR metrics reporting function to report handover initiation
13861 *
13862 */
13863VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13864 tCsrRoamInfo *pRoamInfo)
13865{
13866 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13867 union iwreq_data wrqu;
13868
13869 ENTER();
13870
13871 if (NULL == pAdapter)
13872 {
13873 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13874 return VOS_STATUS_E_FAILURE;
13875 }
13876
13877 /* create the event */
13878 memset(&wrqu, 0, sizeof(wrqu));
13879 memset(metrics_notification, 0, sizeof(metrics_notification));
13880
13881 wrqu.data.pointer = metrics_notification;
13882 wrqu.data.length = scnprintf(metrics_notification,
13883 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13884 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13885
13886 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13887
13888 EXIT();
13889
13890 return VOS_STATUS_SUCCESS;
13891}
13892#endif
13893
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013894
13895/**
13896 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13897 * @scan_req: scan request to be checked
13898 *
13899 * Return: true or false
13900 */
13901#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13902static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13903 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013904 *scan_req, hdd_context_t
13905 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013906{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013907 if (!scan_req || !scan_req->wiphy ||
13908 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013909 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13910 return false;
13911 }
13912 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13913 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13914 return false;
13915 }
13916 return true;
13917}
13918#else
13919static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13920 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013921 *scan_req, hdd_context_t
13922 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013923{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013924 if (!scan_req || !scan_req->wiphy ||
13925 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013926 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13927 return false;
13928 }
13929 return true;
13930}
13931#endif
13932
Mukul Sharmab392b642017-08-17 17:45:29 +053013933#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013934/*
13935 * FUNCTION: hdd_cfg80211_scan_done_callback
13936 * scanning callback function, called after finishing scan
13937 *
13938 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13941{
13942 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013943 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013945 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 struct cfg80211_scan_request *req = NULL;
13947 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013948 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013949 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013950 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013951 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013952
13953 ENTER();
13954
c_manjee1b4ab9a2016-10-26 11:36:55 +053013955 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13956 !pAdapter->dev) {
13957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13958 return 0;
13959 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013960 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013961 if (NULL == pHddCtx) {
13962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013963 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013964 }
13965
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013966#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013967 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013968 {
13969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013970 }
13971#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013972 pScanInfo = &pHddCtx->scan_info;
13973
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013975 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080013976 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 __func__, halHandle, pContext, (int) scanId, (int) status);
13978
Kiet Lamac06e2c2013-10-23 16:25:07 +053013979 pScanInfo->mScanPendingCounter = 0;
13980
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013982 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 &pScanInfo->scan_req_completion_event,
13984 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013985 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013987 hddLog(VOS_TRACE_LEVEL_ERROR,
13988 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013990 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 }
13992
Yue Maef608272013-04-08 23:09:17 -070013993 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 {
13995 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013996 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 }
13998
13999 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 {
14002 hddLog(VOS_TRACE_LEVEL_INFO,
14003 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014004 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 (int) scanId);
14006 }
14007
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014009 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014010#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014011 {
14012 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14013 pAdapter);
14014 if (0 > ret)
14015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014016 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014017
Jeff Johnson295189b2012-06-20 16:38:30 -070014018 /* If any client wait scan result through WEXT
14019 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014020 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 {
14022 /* The other scan request waiting for current scan finish
14023 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014024 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014026 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 }
14028 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014029 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014030 {
14031 struct net_device *dev = pAdapter->dev;
14032 union iwreq_data wrqu;
14033 int we_event;
14034 char *msg;
14035
14036 memset(&wrqu, '\0', sizeof(wrqu));
14037 we_event = SIOCGIWSCAN;
14038 msg = NULL;
14039 wireless_send_event(dev, we_event, &wrqu, msg);
14040 }
14041 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014042 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014043
14044 /* Get the Scan Req */
14045 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014046 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014047
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014048 /* Scan is no longer pending */
14049 pScanInfo->mScanPending = VOS_FALSE;
14050
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014051 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014055 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014056#endif
14057
14058 if (pAdapter->dev) {
14059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14060 pAdapter->dev->name);
14061 }
mukul sharmae7041822015-12-03 15:09:21 +053014062 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014063 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 }
14065
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014066 /* last_scan_timestamp is used to decide if new scan
14067 * is needed or not on station interface. If last station
14068 * scan time and new station scan time is less then
14069 * last_scan_timestamp ; driver will return cached scan.
14070 */
14071 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14072 {
14073 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14074
14075 if ( req->n_channels )
14076 {
14077 for (i = 0; i < req->n_channels ; i++ )
14078 {
14079 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14080 }
14081 /* store no of channel scanned */
14082 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14083 }
14084
14085 }
14086
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014087 /*
14088 * cfg80211_scan_done informing NL80211 about completion
14089 * of scanning
14090 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014091 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14092 {
14093 aborted = true;
14094 }
mukul sharmae7041822015-12-03 15:09:21 +053014095
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014097 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14098 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014099#endif
14100 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014101
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014102 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014103
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014104allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014105 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14106 ) && (pHddCtx->spoofMacAddr.isEnabled
14107 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014108 /* Generate new random mac addr for next scan */
14109 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014110
14111 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14112 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014113 }
14114
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014115 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014116 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014117
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014118 /* Acquire wakelock to handle the case where APP's tries to suspend
14119 * immediatly after the driver gets connect request(i.e after scan)
14120 * from supplicant, this result in app's is suspending and not able
14121 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014122 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014123
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014125 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014126#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014127#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014128 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014129#endif
14130
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 EXIT();
14132 return 0;
14133}
14134
14135/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014136 * FUNCTION: hdd_isConnectionInProgress
14137 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014138 *
14139 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014140v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14141 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014142{
14143 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14144 hdd_station_ctx_t *pHddStaCtx = NULL;
14145 hdd_adapter_t *pAdapter = NULL;
14146 VOS_STATUS status = 0;
14147 v_U8_t staId = 0;
14148 v_U8_t *staMac = NULL;
14149
14150 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14151
14152 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14153 {
14154 pAdapter = pAdapterNode->pAdapter;
14155
14156 if( pAdapter )
14157 {
14158 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014159 "%s: Adapter with device mode %s (%d) exists",
14160 __func__, hdd_device_modetoString(pAdapter->device_mode),
14161 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014162 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014163 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14164 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14165 (eConnectionState_Connecting ==
14166 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14167 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014168 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014169 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014170 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014171 if (session_id && reason)
14172 {
14173 *session_id = pAdapter->sessionId;
14174 *reason = eHDD_CONNECTION_IN_PROGRESS;
14175 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014176 return VOS_TRUE;
14177 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014178 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014179 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014180 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014181 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014182 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014183 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014184 if (session_id && reason)
14185 {
14186 *session_id = pAdapter->sessionId;
14187 *reason = eHDD_REASSOC_IN_PROGRESS;
14188 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014189 return VOS_TRUE;
14190 }
14191 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014192 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14193 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014194 {
14195 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14196 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014197 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014198 {
14199 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014200 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014201 "%s: client " MAC_ADDRESS_STR
14202 " is in the middle of WPS/EAPOL exchange.", __func__,
14203 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014204 if (session_id && reason)
14205 {
14206 *session_id = pAdapter->sessionId;
14207 *reason = eHDD_EAPOL_IN_PROGRESS;
14208 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014209 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014210 }
14211 }
14212 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14213 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14214 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014215 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14216 ptSapContext pSapCtx = NULL;
14217 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14218 if(pSapCtx == NULL){
14219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14220 FL("psapCtx is NULL"));
14221 return VOS_FALSE;
14222 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014223 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14224 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014225 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14226 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014227 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014228 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014229
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014230 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014231 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14232 "middle of WPS/EAPOL exchange.", __func__,
14233 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014234 if (session_id && reason)
14235 {
14236 *session_id = pAdapter->sessionId;
14237 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14238 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014239 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014240 }
14241 }
14242 }
14243 }
14244 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14245 pAdapterNode = pNext;
14246 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014247 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014248}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014249
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014250/**
14251 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14252 * to the Scan request
14253 * @scanRequest: Pointer to the csr scan request
14254 * @request: Pointer to the scan request from supplicant
14255 *
14256 * Return: None
14257 */
14258#ifdef CFG80211_SCAN_BSSID
14259static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14260 struct cfg80211_scan_request *request)
14261{
14262 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14263}
14264#else
14265static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14266 struct cfg80211_scan_request *request)
14267{
14268}
14269#endif
14270
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014271/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014272 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 * this scan respond to scan trigger and update cfg80211 scan database
14274 * later, scan dump command can be used to recieve scan results
14275 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014276int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014277#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14278 struct net_device *dev,
14279#endif
14280 struct cfg80211_scan_request *request)
14281{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014282 hdd_adapter_t *pAdapter = NULL;
14283 hdd_context_t *pHddCtx = NULL;
14284 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014285 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014286 tCsrScanRequest scanRequest;
14287 tANI_U8 *channelList = NULL, i;
14288 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014289 int status;
14290 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014292 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014293 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014294 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014295 v_U8_t curr_session_id;
14296 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014297
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14299 struct net_device *dev = NULL;
14300 if (NULL == request)
14301 {
14302 hddLog(VOS_TRACE_LEVEL_ERROR,
14303 "%s: scan req param null", __func__);
14304 return -EINVAL;
14305 }
14306 dev = request->wdev->netdev;
14307#endif
14308
14309 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14310 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14311 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14312
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 ENTER();
14314
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014315 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14316 __func__, hdd_device_modetoString(pAdapter->device_mode),
14317 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014318
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014319 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014320 if (0 != status)
14321 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014322 return status;
14323 }
14324
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014325 if (NULL == pwextBuf)
14326 {
14327 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14328 __func__);
14329 return -EIO;
14330 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014331 cfg_param = pHddCtx->cfg_ini;
14332 pScanInfo = &pHddCtx->scan_info;
14333
Jeff Johnson295189b2012-06-20 16:38:30 -070014334#ifdef WLAN_BTAMP_FEATURE
14335 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014336 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014338 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 "%s: No scanning when AMP is on", __func__);
14340 return -EOPNOTSUPP;
14341 }
14342#endif
14343 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014344 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014345 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014346 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014347 "%s: Not scanning on device_mode = %s (%d)",
14348 __func__, hdd_device_modetoString(pAdapter->device_mode),
14349 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 return -EOPNOTSUPP;
14351 }
14352
14353 if (TRUE == pScanInfo->mScanPending)
14354 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014355 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14356 {
14357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14358 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014359 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 }
14361
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014362 // Don't allow scan if PNO scan is going on.
14363 if (pHddCtx->isPnoEnable)
14364 {
14365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14366 FL("pno scan in progress"));
14367 return -EBUSY;
14368 }
14369
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014370 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014371 //Channel and action frame is pending
14372 //Otherwise Cancel Remain On Channel and allow Scan
14373 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014374 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014375 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014376 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014377 return -EBUSY;
14378 }
14379
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14381 {
14382 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014383 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014384 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014386 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14387 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014388 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014389 "%s: MAX TM Level Scan not allowed", __func__);
14390 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014391 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 }
14393 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14394
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014395 /* Check if scan is allowed at this point of time.
14396 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014397 if (TRUE == pHddCtx->btCoexModeSet)
14398 {
14399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14400 FL("BTCoex Mode operation in progress"));
14401 return -EBUSY;
14402 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014403 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014404 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014405
14406 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14407 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14408 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014409 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14410 pHddCtx->last_scan_reject_reason != curr_reason ||
14411 !pHddCtx->last_scan_reject_timestamp)
14412 {
14413 pHddCtx->last_scan_reject_session_id = curr_session_id;
14414 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014415 pHddCtx->last_scan_reject_timestamp =
14416 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014417 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014418 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014419 else
14420 {
14421 pHddCtx->scan_reject_cnt++;
14422
Abhishek Singhe4b12562017-06-20 16:53:39 +053014423 if ((pHddCtx->scan_reject_cnt >=
14424 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014425 vos_system_time_after(jiffies_to_msecs(jiffies),
14426 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014427 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014428 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14429 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14430 vos_system_time_after(jiffies_to_msecs(jiffies),
14431 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014432 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014433 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014434 if (pHddCtx->cfg_ini->enableFatalEvent)
14435 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14436 WLAN_LOG_INDICATOR_HOST_DRIVER,
14437 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14438 FALSE, FALSE);
14439 else
14440 {
14441 hddLog(LOGE, FL("Triggering SSR"));
14442 vos_wlanRestart();
14443 }
14444 }
14445 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014446 return -EBUSY;
14447 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014448 pHddCtx->last_scan_reject_timestamp = 0;
14449 pHddCtx->last_scan_reject_session_id = 0xFF;
14450 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014451 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014452
Jeff Johnson295189b2012-06-20 16:38:30 -070014453 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14454
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014455 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14456 * Becasue of this, driver is assuming that this is not wildcard scan and so
14457 * is not aging out the scan results.
14458 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014459 if ((request->ssids) && (request->n_ssids == 1) &&
14460 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014461 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014463
14464 if ((request->ssids) && (0 < request->n_ssids))
14465 {
14466 tCsrSSIDInfo *SsidInfo;
14467 int j;
14468 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14469 /* Allocate num_ssid tCsrSSIDInfo structure */
14470 SsidInfo = scanRequest.SSIDs.SSIDList =
14471 ( tCsrSSIDInfo *)vos_mem_malloc(
14472 request->n_ssids*sizeof(tCsrSSIDInfo));
14473
14474 if(NULL == scanRequest.SSIDs.SSIDList)
14475 {
14476 hddLog(VOS_TRACE_LEVEL_ERROR,
14477 "%s: memory alloc failed SSIDInfo buffer", __func__);
14478 return -ENOMEM;
14479 }
14480
14481 /* copy all the ssid's and their length */
14482 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14483 {
14484 /* get the ssid length */
14485 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14486 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14487 SsidInfo->SSID.length);
14488 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14489 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14490 j, SsidInfo->SSID.ssId);
14491 }
14492 /* set the scan type to active */
14493 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14494 }
14495 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014497 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14498 TRACE_CODE_HDD_CFG80211_SCAN,
14499 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 /* set the scan type to active */
14501 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014503 else
14504 {
14505 /*Set the scan type to default type, in this case it is ACTIVE*/
14506 scanRequest.scanType = pScanInfo->scan_mode;
14507 }
14508 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14509 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014510
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014511 csr_scan_request_assign_bssid(&scanRequest, request);
14512
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 /* set BSSType to default type */
14514 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14515
14516 /*TODO: scan the requested channels only*/
14517
14518 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014519 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014520 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014521 hddLog(VOS_TRACE_LEVEL_WARN,
14522 "No of Scan Channels exceeded limit: %d", request->n_channels);
14523 request->n_channels = MAX_CHANNEL;
14524 }
14525
14526 hddLog(VOS_TRACE_LEVEL_INFO,
14527 "No of Scan Channels: %d", request->n_channels);
14528
14529
14530 if( request->n_channels )
14531 {
14532 char chList [(request->n_channels*5)+1];
14533 int len;
14534 channelList = vos_mem_malloc( request->n_channels );
14535 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014536 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014537 hddLog(VOS_TRACE_LEVEL_ERROR,
14538 "%s: memory alloc failed channelList", __func__);
14539 status = -ENOMEM;
14540 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014541 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014542
14543 for( i = 0, len = 0; i < request->n_channels ; i++ )
14544 {
14545 channelList[i] = request->channels[i]->hw_value;
14546 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14547 }
14548
Nirav Shah20ac06f2013-12-12 18:14:06 +053014549 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014550 "Channel-List: %s ", chList);
14551 }
c_hpothu53512302014-04-15 18:49:53 +053014552
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014553 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14554 scanRequest.ChannelInfo.ChannelList = channelList;
14555
14556 /* set requestType to full scan */
14557 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14558
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014559 /* if there is back to back scan happening in driver with in
14560 * nDeferScanTimeInterval interval driver should defer new scan request
14561 * and should provide last cached scan results instead of new channel list.
14562 * This rule is not applicable if scan is p2p scan.
14563 * This condition will work only in case when last request no of channels
14564 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014565 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014566 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014567 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014568
Sushant Kaushik86592172015-04-27 16:35:03 +053014569 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14570 /* if wps ie is NULL , then only defer scan */
14571 if ( pWpsIe == NULL &&
14572 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014573 {
14574 if ( pScanInfo->last_scan_timestamp !=0 &&
14575 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14576 {
14577 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14578 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14579 vos_mem_compare(pScanInfo->last_scan_channelList,
14580 channelList, pScanInfo->last_scan_numChannels))
14581 {
14582 hddLog(VOS_TRACE_LEVEL_WARN,
14583 " New and old station scan time differ is less then %u",
14584 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14585
14586 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014587 pAdapter);
14588
Agarwal Ashish57e84372014-12-05 18:26:53 +053014589 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014590 "Return old cached scan as all channels and no of channels are same");
14591
Agarwal Ashish57e84372014-12-05 18:26:53 +053014592 if (0 > ret)
14593 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014594
Agarwal Ashish57e84372014-12-05 18:26:53 +053014595 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014596
14597 status = eHAL_STATUS_SUCCESS;
14598 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014599 }
14600 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014601 }
14602
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014603 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14604 * search (Flush on both full scan and social scan but not on single
14605 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14606 */
14607
14608 /* Supplicant does single channel scan after 8-way handshake
14609 * and in that case driver shoudnt flush scan results. If
14610 * driver flushes the scan results here and unfortunately if
14611 * the AP doesnt respond to our probe req then association
14612 * fails which is not desired
14613 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014614 if ((request->n_ssids == 1)
14615 && (request->ssids != NULL)
14616 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14617 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014618
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014619 if( is_p2p_scan ||
14620 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014621 {
14622 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14623 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14624 pAdapter->sessionId );
14625 }
14626
14627 if( request->ie_len )
14628 {
14629 /* save this for future association (join requires this) */
14630 /*TODO: Array needs to be converted to dynamic allocation,
14631 * as multiple ie.s can be sent in cfg80211_scan_request structure
14632 * CR 597966
14633 */
14634 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14635 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14636 pScanInfo->scanAddIE.length = request->ie_len;
14637
14638 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14639 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14640 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014642 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014643 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014644 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14645 memcpy( pwextBuf->roamProfile.addIEScan,
14646 request->ie, request->ie_len);
14647 }
14648 else
14649 {
14650 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14651 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014652 }
14653
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014654 }
14655 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14656 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14657
14658 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14659 request->ie_len);
14660 if (pP2pIe != NULL)
14661 {
14662#ifdef WLAN_FEATURE_P2P_DEBUG
14663 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14664 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14665 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014666 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014667 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14668 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14669 "Go nego completed to Connection is started");
14670 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14671 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014672 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014673 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14674 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014676 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14677 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14678 "Disconnected state to Connection is started");
14679 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14680 "for 4way Handshake");
14681 }
14682#endif
14683
14684 /* no_cck will be set during p2p find to disable 11b rates */
14685 if(TRUE == request->no_cck)
14686 {
14687 hddLog(VOS_TRACE_LEVEL_INFO,
14688 "%s: This is a P2P Search", __func__);
14689 scanRequest.p2pSearch = 1;
14690
14691 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014692 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014693 /* set requestType to P2P Discovery */
14694 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14695 }
14696
14697 /*
14698 Skip Dfs Channel in case of P2P Search
14699 if it is set in ini file
14700 */
14701 if(cfg_param->skipDfsChnlInP2pSearch)
14702 {
14703 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014704 }
14705 else
14706 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014707 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014709
Agarwal Ashish4f616132013-12-30 23:32:50 +053014710 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 }
14712 }
14713
14714 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14715
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014716#ifdef FEATURE_WLAN_TDLS
14717 /* if tdls disagree scan right now, return immediately.
14718 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14719 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14720 */
14721 status = wlan_hdd_tdls_scan_callback (pAdapter,
14722 wiphy,
14723#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14724 dev,
14725#endif
14726 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014727 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014728 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014729 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14731 "scan rejected %d", __func__, status);
14732 else
14733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14734 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014735 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014736 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014737 }
14738#endif
14739
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014740 /* acquire the wakelock to avoid the apps suspend during the scan. To
14741 * address the following issues.
14742 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14743 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14744 * for long time, this result in apps running at full power for long time.
14745 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14746 * be stuck in full power because of resume BMPS
14747 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014748 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014749
Nirav Shah20ac06f2013-12-12 18:14:06 +053014750 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14751 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014752 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14753 scanRequest.requestType, scanRequest.scanType,
14754 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014755 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14756
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014757 if (pHddCtx->spoofMacAddr.isEnabled &&
14758 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014759 {
14760 hddLog(VOS_TRACE_LEVEL_INFO,
14761 "%s: MAC Spoofing enabled for current scan", __func__);
14762 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14763 * to fill TxBds for probe request during current scan
14764 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014765 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014766 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014767
14768 if(status != VOS_STATUS_SUCCESS)
14769 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014770 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014771 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014772#ifdef FEATURE_WLAN_TDLS
14773 wlan_hdd_tdls_scan_done_callback(pAdapter);
14774#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014775 goto free_mem;
14776 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014777 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014778 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014779 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 pAdapter->sessionId, &scanRequest, &scanId,
14781 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014782
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 if (eHAL_STATUS_SUCCESS != status)
14784 {
14785 hddLog(VOS_TRACE_LEVEL_ERROR,
14786 "%s: sme_ScanRequest returned error %d", __func__, status);
14787 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014788 if(eHAL_STATUS_RESOURCES == status)
14789 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14791 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014792 status = -EBUSY;
14793 } else {
14794 status = -EIO;
14795 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014796 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014797
14798#ifdef FEATURE_WLAN_TDLS
14799 wlan_hdd_tdls_scan_done_callback(pAdapter);
14800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014801 goto free_mem;
14802 }
14803
14804 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014805 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014806 pAdapter->request = request;
14807 pScanInfo->scanId = scanId;
14808
14809 complete(&pScanInfo->scan_req_completion_event);
14810
14811free_mem:
14812 if( scanRequest.SSIDs.SSIDList )
14813 {
14814 vos_mem_free(scanRequest.SSIDs.SSIDList);
14815 }
14816
14817 if( channelList )
14818 vos_mem_free( channelList );
14819
14820 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014821 return status;
14822}
14823
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014824int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14825#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14826 struct net_device *dev,
14827#endif
14828 struct cfg80211_scan_request *request)
14829{
14830 int ret;
14831
14832 vos_ssr_protect(__func__);
14833 ret = __wlan_hdd_cfg80211_scan(wiphy,
14834#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14835 dev,
14836#endif
14837 request);
14838 vos_ssr_unprotect(__func__);
14839
14840 return ret;
14841}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014842
14843void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14844{
14845 v_U8_t iniDot11Mode =
14846 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14847 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14848
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014849 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14850 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014851 switch ( iniDot11Mode )
14852 {
14853 case eHDD_DOT11_MODE_AUTO:
14854 case eHDD_DOT11_MODE_11ac:
14855 case eHDD_DOT11_MODE_11ac_ONLY:
14856#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014857 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14858 sme_IsFeatureSupportedByFW(DOT11AC) )
14859 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14860 else
14861 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014862#else
14863 hddDot11Mode = eHDD_DOT11_MODE_11n;
14864#endif
14865 break;
14866 case eHDD_DOT11_MODE_11n:
14867 case eHDD_DOT11_MODE_11n_ONLY:
14868 hddDot11Mode = eHDD_DOT11_MODE_11n;
14869 break;
14870 default:
14871 hddDot11Mode = iniDot11Mode;
14872 break;
14873 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014874#ifdef WLAN_FEATURE_AP_HT40_24G
14875 if (operationChannel > SIR_11B_CHANNEL_END)
14876#endif
14877 {
14878 /* This call decides required channel bonding mode */
14879 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014880 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053014881 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014882 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014883}
14884
Jeff Johnson295189b2012-06-20 16:38:30 -070014885/*
14886 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014887 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014888 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014889int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014890 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14891 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014892{
14893 int status = 0;
14894 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014895 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014896 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 v_U32_t roamId;
14898 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014899 eCsrAuthType RSNAuthType;
14900
14901 ENTER();
14902
14903 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014904 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014905 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014906
14907 status = wlan_hdd_validate_context(pHddCtx);
14908 if (status)
14909 {
Yue Mae36e3552014-03-05 17:06:20 -080014910 return status;
14911 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014912
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14914 {
14915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14916 return -EINVAL;
14917 }
14918
Nitesh Shah9b066282017-06-06 18:05:52 +053014919 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14920
Jeff Johnson295189b2012-06-20 16:38:30 -070014921 pRoamProfile = &pWextState->roamProfile;
14922
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014923 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014925 hdd_station_ctx_t *pHddStaCtx;
14926 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014927 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014928
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014929 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14933 {
14934 /*QoS not enabled in cfg file*/
14935 pRoamProfile->uapsd_mask = 0;
14936 }
14937 else
14938 {
14939 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014940 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14942 }
14943
14944 pRoamProfile->SSIDs.numOfSSIDs = 1;
14945 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14946 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014947 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14949 ssid, ssid_len);
14950
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014951 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14952 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14953
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 if (bssid)
14955 {
14956 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014957 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014959 /* Save BSSID in seperate variable as well, as RoamProfile
14960 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 case of join failure we should send valid BSSID to supplicant
14962 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014963 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014964 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014965
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014967 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014968 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014969 /* Store bssid_hint to use in the scan filter. */
14970 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
14971 WNI_CFG_BSSID_LEN);
14972 /*
14973 * Save BSSID in seperate variable as well, as RoamProfile
14974 * BSSID is getting zeroed out in the association process. And in
14975 * case of join failure we should send valid BSSID to supplicant
14976 */
14977 vos_mem_copy(pWextState->req_bssId, bssid_hint,
14978 WNI_CFG_BSSID_LEN);
14979 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
14980 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070014981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014982
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014983
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014984 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
14985 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
14987 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014988 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 /*set gen ie*/
14990 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14991 /*set auth*/
14992 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14993 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014994#ifdef FEATURE_WLAN_WAPI
14995 if (pAdapter->wapi_info.nWapiMode)
14996 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014997 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 switch (pAdapter->wapi_info.wapiAuthMode)
14999 {
15000 case WAPI_AUTH_MODE_PSK:
15001 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015002 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 pAdapter->wapi_info.wapiAuthMode);
15004 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15005 break;
15006 }
15007 case WAPI_AUTH_MODE_CERT:
15008 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015009 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015010 pAdapter->wapi_info.wapiAuthMode);
15011 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15012 break;
15013 }
15014 } // End of switch
15015 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15016 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15017 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015018 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 pRoamProfile->AuthType.numEntries = 1;
15020 pRoamProfile->EncryptionType.numEntries = 1;
15021 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15022 pRoamProfile->mcEncryptionType.numEntries = 1;
15023 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15024 }
15025 }
15026#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015027#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015028 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015029 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15030 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15031 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015032 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15033 sizeof (tSirGtkOffloadParams));
15034 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015035 }
15036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 pRoamProfile->csrPersona = pAdapter->device_mode;
15038
Jeff Johnson32d95a32012-09-10 13:15:23 -070015039 if( operatingChannel )
15040 {
15041 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15042 pRoamProfile->ChannelInfo.numOfChannels = 1;
15043 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015044 else
15045 {
15046 pRoamProfile->ChannelInfo.ChannelList = NULL;
15047 pRoamProfile->ChannelInfo.numOfChannels = 0;
15048 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015049 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15050 {
15051 hdd_select_cbmode(pAdapter,operatingChannel);
15052 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015053
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015054 /*
15055 * Change conn_state to connecting before sme_RoamConnect(),
15056 * because sme_RoamConnect() has a direct path to call
15057 * hdd_smeRoamCallback(), which will change the conn_state
15058 * If direct path, conn_state will be accordingly changed
15059 * to NotConnected or Associated by either
15060 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15061 * in sme_RoamCallback()
15062 * if sme_RomConnect is to be queued,
15063 * Connecting state will remain until it is completed.
15064 * If connection state is not changed,
15065 * connection state will remain in eConnectionState_NotConnected state.
15066 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15067 * if conn state is eConnectionState_NotConnected.
15068 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15069 * informed of connect result indication which is an issue.
15070 */
15071
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015072 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15073 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015074 {
15075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015076 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015077 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15078 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015079 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015080 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 pAdapter->sessionId, pRoamProfile, &roamId);
15082
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015083 if ((eHAL_STATUS_SUCCESS != status) &&
15084 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15085 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015086
15087 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015088 hddLog(VOS_TRACE_LEVEL_ERROR,
15089 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15090 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015091 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015092 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015093 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015094 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015095
15096 pRoamProfile->ChannelInfo.ChannelList = NULL;
15097 pRoamProfile->ChannelInfo.numOfChannels = 0;
15098
Jeff Johnson295189b2012-06-20 16:38:30 -070015099 }
15100 else
15101 {
15102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15103 return -EINVAL;
15104 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015105 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015106 return status;
15107}
15108
15109/*
15110 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15111 * This function is used to set the authentication type (OPEN/SHARED).
15112 *
15113 */
15114static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15115 enum nl80211_auth_type auth_type)
15116{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015117 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015118 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15119
15120 ENTER();
15121
15122 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015123 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015125 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015126 hddLog(VOS_TRACE_LEVEL_INFO,
15127 "%s: set authentication type to AUTOSWITCH", __func__);
15128 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15129 break;
15130
15131 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015132#ifdef WLAN_FEATURE_VOWIFI_11R
15133 case NL80211_AUTHTYPE_FT:
15134#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015135 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 "%s: set authentication type to OPEN", __func__);
15137 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15138 break;
15139
15140 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015141 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015142 "%s: set authentication type to SHARED", __func__);
15143 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15144 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015145#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015146 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015147 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015148 "%s: set authentication type to CCKM WPA", __func__);
15149 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15150 break;
15151#endif
15152
15153
15154 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015155 hddLog(VOS_TRACE_LEVEL_ERROR,
15156 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015157 auth_type);
15158 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15159 return -EINVAL;
15160 }
15161
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015162 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 pHddStaCtx->conn_info.authType;
15164 return 0;
15165}
15166
15167/*
15168 * FUNCTION: wlan_hdd_set_akm_suite
15169 * This function is used to set the key mgmt type(PSK/8021x).
15170 *
15171 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015172static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015173 u32 key_mgmt
15174 )
15175{
15176 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15177 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015178 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015179#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015180#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015181#endif
15182#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015183#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015184#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015185 /*set key mgmt type*/
15186 switch(key_mgmt)
15187 {
15188 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015189 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015190#ifdef WLAN_FEATURE_VOWIFI_11R
15191 case WLAN_AKM_SUITE_FT_PSK:
15192#endif
15193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015194 __func__);
15195 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15196 break;
15197
15198 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015199 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015200#ifdef WLAN_FEATURE_VOWIFI_11R
15201 case WLAN_AKM_SUITE_FT_8021X:
15202#endif
15203 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015204 __func__);
15205 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15206 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015207#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015208#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15209#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15210 case WLAN_AKM_SUITE_CCKM:
15211 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15212 __func__);
15213 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15214 break;
15215#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015216#ifndef WLAN_AKM_SUITE_OSEN
15217#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15218 case WLAN_AKM_SUITE_OSEN:
15219 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15220 __func__);
15221 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15222 break;
15223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015224
15225 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015227 __func__, key_mgmt);
15228 return -EINVAL;
15229
15230 }
15231 return 0;
15232}
15233
15234/*
15235 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015236 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015237 * (NONE/WEP40/WEP104/TKIP/CCMP).
15238 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015239static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15240 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015241 bool ucast
15242 )
15243{
15244 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015245 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015246 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15247
15248 ENTER();
15249
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015250 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015251 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 __func__, cipher);
15254 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15255 }
15256 else
15257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015258
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015260 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015261 {
15262 case IW_AUTH_CIPHER_NONE:
15263 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15264 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015265
Jeff Johnson295189b2012-06-20 16:38:30 -070015266 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015267 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015269
Jeff Johnson295189b2012-06-20 16:38:30 -070015270 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015271 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015273
Jeff Johnson295189b2012-06-20 16:38:30 -070015274 case WLAN_CIPHER_SUITE_TKIP:
15275 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15276 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015277
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 case WLAN_CIPHER_SUITE_CCMP:
15279 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15280 break;
15281#ifdef FEATURE_WLAN_WAPI
15282 case WLAN_CIPHER_SUITE_SMS4:
15283 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15284 break;
15285#endif
15286
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015287#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 case WLAN_CIPHER_SUITE_KRK:
15289 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15290 break;
15291#endif
15292 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 __func__, cipher);
15295 return -EOPNOTSUPP;
15296 }
15297 }
15298
15299 if (ucast)
15300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 __func__, encryptionType);
15303 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15304 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015305 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 encryptionType;
15307 }
15308 else
15309 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015310 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015311 __func__, encryptionType);
15312 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15313 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15314 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15315 }
15316
15317 return 0;
15318}
15319
15320
15321/*
15322 * FUNCTION: wlan_hdd_cfg80211_set_ie
15323 * This function is used to parse WPA/RSN IE's.
15324 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015325int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015326#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15327 const u8 *ie,
15328#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015329 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015330#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015331 size_t ie_len
15332 )
15333{
15334 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15336 const u8 *genie = ie;
15337#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015338 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015339#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 v_U16_t remLen = ie_len;
15341#ifdef FEATURE_WLAN_WAPI
15342 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15343 u16 *tmp;
15344 v_U16_t akmsuiteCount;
15345 int *akmlist;
15346#endif
15347 ENTER();
15348
15349 /* clear previous assocAddIE */
15350 pWextState->assocAddIE.length = 0;
15351 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015352 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015353
15354 while (remLen >= 2)
15355 {
15356 v_U16_t eLen = 0;
15357 v_U8_t elementId;
15358 elementId = *genie++;
15359 eLen = *genie++;
15360 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015361
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015362 /* Sanity check on eLen */
15363 if (eLen > remLen) {
15364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15365 __func__, eLen, elementId);
15366 VOS_ASSERT(0);
15367 return -EINVAL;
15368 }
15369
Arif Hussain6d2a3322013-11-17 19:50:10 -080015370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015372
15373 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015375 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015376 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 -070015377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015378 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015379 "%s: Invalid WPA IE", __func__);
15380 return -EINVAL;
15381 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015382 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015383 {
15384 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015385 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015386 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015387
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015388 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015389 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015390 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15391 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 VOS_ASSERT(0);
15393 return -ENOMEM;
15394 }
15395 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15396 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15397 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015398
Jeff Johnson295189b2012-06-20 16:38:30 -070015399 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15400 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15401 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15402 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015403 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15404 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015405 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15406 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15407 __func__, eLen);
15408 VOS_ASSERT(0);
15409 return -EINVAL;
15410 }
15411
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15413 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15414 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15415 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15416 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15417 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015418 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015419 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015420 {
15421 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015422 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015424
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015425 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015426 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015427 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15428 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 VOS_ASSERT(0);
15430 return -ENOMEM;
15431 }
15432 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15433 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15434 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015435
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15437 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15438 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015439#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015440 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15441 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 /*Consider WFD IE, only for P2P Client */
15443 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15444 {
15445 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015446 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015448
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015449 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015450 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015451 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15452 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 VOS_ASSERT(0);
15454 return -ENOMEM;
15455 }
15456 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15457 // WPS IE + P2P IE + WFD IE
15458 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15459 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15462 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15463 }
15464#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015465 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015466 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015467 HS20_OUI_TYPE_SIZE)) )
15468 {
15469 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015470 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015471 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015472
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015473 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015474 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015475 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15476 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015477 VOS_ASSERT(0);
15478 return -ENOMEM;
15479 }
15480 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15481 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015482
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015483 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15484 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15485 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015486 /* Appending OSEN Information Element in Assiciation Request */
15487 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15488 OSEN_OUI_TYPE_SIZE)) )
15489 {
15490 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15491 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15492 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015493
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015494 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015495 {
15496 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15497 "Need bigger buffer space");
15498 VOS_ASSERT(0);
15499 return -ENOMEM;
15500 }
15501 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15502 pWextState->assocAddIE.length += eLen + 2;
15503
15504 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15505 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15506 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15507 }
15508
Abhishek Singh4322e622015-06-10 15:42:54 +053015509 /* Update only for WPA IE */
15510 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15511 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015512
15513 /* populating as ADDIE in beacon frames */
15514 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015515 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015516 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15517 {
15518 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15519 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15520 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15521 {
15522 hddLog(LOGE,
15523 "Coldn't pass "
15524 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15525 }
15526 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15527 else
15528 hddLog(LOGE,
15529 "Could not pass on "
15530 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15531
15532 /* IBSS mode doesn't contain params->proberesp_ies still
15533 beaconIE's need to be populated in probe response frames */
15534 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15535 {
15536 u16 rem_probe_resp_ie_len = eLen + 2;
15537 u8 probe_rsp_ie_len[3] = {0};
15538 u8 counter = 0;
15539
15540 /* Check Probe Resp Length if it is greater then 255 then
15541 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15542 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15543 not able Store More then 255 bytes into One Variable */
15544
15545 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15546 {
15547 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15548 {
15549 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15550 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15551 }
15552 else
15553 {
15554 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15555 rem_probe_resp_ie_len = 0;
15556 }
15557 }
15558
15559 rem_probe_resp_ie_len = 0;
15560
15561 if (probe_rsp_ie_len[0] > 0)
15562 {
15563 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15564 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15565 (tANI_U8*)(genie - 2),
15566 probe_rsp_ie_len[0], NULL,
15567 eANI_BOOLEAN_FALSE)
15568 == eHAL_STATUS_FAILURE)
15569 {
15570 hddLog(LOGE,
15571 "Could not pass"
15572 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15573 }
15574 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15575 }
15576
15577 if (probe_rsp_ie_len[1] > 0)
15578 {
15579 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15580 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15581 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15582 probe_rsp_ie_len[1], NULL,
15583 eANI_BOOLEAN_FALSE)
15584 == eHAL_STATUS_FAILURE)
15585 {
15586 hddLog(LOGE,
15587 "Could not pass"
15588 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15589 }
15590 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15591 }
15592
15593 if (probe_rsp_ie_len[2] > 0)
15594 {
15595 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15596 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15597 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15598 probe_rsp_ie_len[2], NULL,
15599 eANI_BOOLEAN_FALSE)
15600 == eHAL_STATUS_FAILURE)
15601 {
15602 hddLog(LOGE,
15603 "Could not pass"
15604 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15605 }
15606 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15607 }
15608
15609 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15610 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15611 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15612 {
15613 hddLog(LOGE,
15614 "Could not pass"
15615 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15616 }
15617 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015618 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015619 break;
15620 case DOT11F_EID_RSN:
15621 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15622 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15623 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15624 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15625 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15626 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015627
Abhishek Singhb16f3562016-01-20 11:08:32 +053015628 /* Appending extended capabilities with Interworking or
15629 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015630 *
15631 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015632 * interworkingService or bsstransition bit is set to 1.
15633 * Driver is only interested in interworkingService and
15634 * bsstransition capability from supplicant.
15635 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015636 * required from supplicat, it needs to be handled while
15637 * sending Assoc Req in LIM.
15638 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015639 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015640 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015641 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015642 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015643 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015644
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015645 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015646 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015647 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15648 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015649 VOS_ASSERT(0);
15650 return -ENOMEM;
15651 }
15652 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15653 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015654
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015655 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15656 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15657 break;
15658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015659#ifdef FEATURE_WLAN_WAPI
15660 case WLAN_EID_WAPI:
15661 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015662 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015663 pAdapter->wapi_info.nWapiMode);
15664 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015665 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 akmsuiteCount = WPA_GET_LE16(tmp);
15667 tmp = tmp + 1;
15668 akmlist = (int *)(tmp);
15669 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15670 {
15671 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15672 }
15673 else
15674 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015675 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015676 VOS_ASSERT(0);
15677 return -EINVAL;
15678 }
15679
15680 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15681 {
15682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015683 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015684 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015685 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015686 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015687 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015689 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15691 }
15692 break;
15693#endif
15694 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015695 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015696 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015697 /* when Unknown IE is received we should break and continue
15698 * to the next IE in the buffer instead we were returning
15699 * so changing this to break */
15700 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015701 }
15702 genie += eLen;
15703 remLen -= eLen;
15704 }
15705 EXIT();
15706 return 0;
15707}
15708
15709/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015710 * FUNCTION: hdd_isWPAIEPresent
15711 * Parse the received IE to find the WPA IE
15712 *
15713 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015714static bool hdd_isWPAIEPresent(
15715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15716 const u8 *ie,
15717#else
15718 u8 *ie,
15719#endif
15720 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015721{
15722 v_U8_t eLen = 0;
15723 v_U16_t remLen = ie_len;
15724 v_U8_t elementId = 0;
15725
15726 while (remLen >= 2)
15727 {
15728 elementId = *ie++;
15729 eLen = *ie++;
15730 remLen -= 2;
15731 if (eLen > remLen)
15732 {
15733 hddLog(VOS_TRACE_LEVEL_ERROR,
15734 "%s: IE length is wrong %d", __func__, eLen);
15735 return FALSE;
15736 }
15737 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15738 {
15739 /* OUI - 0x00 0X50 0XF2
15740 WPA Information Element - 0x01
15741 WPA version - 0x01*/
15742 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15743 return TRUE;
15744 }
15745 ie += eLen;
15746 remLen -= eLen;
15747 }
15748 return FALSE;
15749}
15750
15751/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015753 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 * parameters during connect operation.
15755 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015756int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015757 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015758 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015759{
15760 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015761 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015762 ENTER();
15763
15764 /*set wpa version*/
15765 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15766
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015767 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015768 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015769 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015770 {
15771 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15772 }
15773 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15774 {
15775 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15776 }
15777 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015778
15779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015780 pWextState->wpaVersion);
15781
15782 /*set authentication type*/
15783 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15784
15785 if (0 > status)
15786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015787 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015788 "%s: failed to set authentication type ", __func__);
15789 return status;
15790 }
15791
15792 /*set key mgmt type*/
15793 if (req->crypto.n_akm_suites)
15794 {
15795 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15796 if (0 > status)
15797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 __func__);
15800 return status;
15801 }
15802 }
15803
15804 /*set pairwise cipher type*/
15805 if (req->crypto.n_ciphers_pairwise)
15806 {
15807 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15808 req->crypto.ciphers_pairwise[0], true);
15809 if (0 > status)
15810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015811 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015812 "%s: failed to set unicast cipher type", __func__);
15813 return status;
15814 }
15815 }
15816 else
15817 {
15818 /*Reset previous cipher suite to none*/
15819 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15820 if (0 > status)
15821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015822 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 "%s: failed to set unicast cipher type", __func__);
15824 return status;
15825 }
15826 }
15827
15828 /*set group cipher type*/
15829 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15830 false);
15831
15832 if (0 > status)
15833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015835 __func__);
15836 return status;
15837 }
15838
Chet Lanctot186b5732013-03-18 10:26:30 -070015839#ifdef WLAN_FEATURE_11W
15840 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15841#endif
15842
Jeff Johnson295189b2012-06-20 16:38:30 -070015843 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15844 if (req->ie_len)
15845 {
15846 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15847 if ( 0 > status)
15848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015850 __func__);
15851 return status;
15852 }
15853 }
15854
15855 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015856 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 {
15858 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15859 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15860 )
15861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015862 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015863 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15864 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015865 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 __func__);
15867 return -EOPNOTSUPP;
15868 }
15869 else
15870 {
15871 u8 key_len = req->key_len;
15872 u8 key_idx = req->key_idx;
15873
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015874 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 && (CSR_MAX_NUM_KEY > key_idx)
15876 )
15877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015878 hddLog(VOS_TRACE_LEVEL_INFO,
15879 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 __func__, key_idx, key_len);
15881 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015882 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015883 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 (u8)key_len;
15886 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15887 }
15888 }
15889 }
15890 }
15891
15892 return status;
15893}
15894
15895/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015896 * FUNCTION: wlan_hdd_try_disconnect
15897 * This function is used to disconnect from previous
15898 * connection
15899 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015900int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015901{
15902 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015903 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015904 hdd_station_ctx_t *pHddStaCtx;
15905 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015906 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015907
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015908 ret = wlan_hdd_validate_context(pHddCtx);
15909 if (0 != ret)
15910 {
15911 return ret;
15912 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015913 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15914
15915 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15916
15917 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15918 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015919 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015920 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15921 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015922 /* Indicate disconnect to SME so that in-progress connection or preauth
15923 * can be aborted
15924 */
15925 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15926 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015927 spin_lock_bh(&pAdapter->lock_for_active_session);
15928 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15929 {
15930 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15931 }
15932 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015933 hdd_connSetConnectionState(pHddStaCtx,
15934 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015935 /* Issue disconnect to CSR */
15936 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015937 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015938 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015939 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15940 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15941 hddLog(LOG1,
15942 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15943 } else if ( 0 != status ) {
15944 hddLog(LOGE,
15945 FL("csrRoamDisconnect failure, returned %d"),
15946 (int)status );
15947 result = -EINVAL;
15948 goto disconnected;
15949 }
15950 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015951 &pAdapter->disconnect_comp_var,
15952 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015953 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15954 hddLog(LOGE,
15955 "%s: Failed to disconnect, timed out", __func__);
15956 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015957 }
15958 }
15959 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15960 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015961 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015962 &pAdapter->disconnect_comp_var,
15963 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015964 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015965 {
15966 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015967 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015968 }
15969 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015970disconnected:
15971 hddLog(LOG1,
15972 FL("Set HDD connState to eConnectionState_NotConnected"));
15973 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
15974 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015975}
15976
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015977/**
15978 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
15979 * @adapter: Pointer to the HDD adapter
15980 * @req: Pointer to the structure cfg_connect_params receieved from user space
15981 *
15982 * This function will start reassociation if bssid hint, channel hint and
15983 * previous bssid parameters are present in the connect request
15984 *
15985 * Return: success if reassociation is happening
15986 * Error code if reassociation is not permitted or not happening
15987 */
15988#ifdef CFG80211_CONNECT_PREV_BSSID
15989static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15990 struct cfg80211_connect_params *req)
15991{
15992 int status = -EPERM;
15993 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15994 hddLog(VOS_TRACE_LEVEL_INFO,
15995 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15996 req->channel_hint->hw_value,
15997 MAC_ADDR_ARRAY(req->bssid_hint));
15998 status = hdd_reassoc(adapter, req->bssid_hint,
15999 req->channel_hint->hw_value,
16000 CONNECT_CMD_USERSPACE);
16001 }
16002 return status;
16003}
16004#else
16005static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16006 struct cfg80211_connect_params *req)
16007{
16008 return -EPERM;
16009}
16010#endif
16011
Abhishek Singhe3beee22017-07-31 15:35:40 +053016012/**
16013 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16014 * connect in HT20 mode
16015 * @hdd_ctx: hdd context
16016 * @adapter: Pointer to the HDD adapter
16017 * @req: Pointer to the structure cfg_connect_params receieved from user space
16018 *
16019 * This function will check if supplicant has indicated to to connect in HT20
16020 * mode. this is currently applicable only for 2.4Ghz mode only.
16021 * if feature is enabled and supplicant indicate HT20 set
16022 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16023 *
16024 * Return: void
16025 */
16026#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16027static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16028 hdd_adapter_t *adapter,
16029 struct cfg80211_connect_params *req)
16030{
16031 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16032 tCsrRoamProfile *roam_profile;
16033
16034 roam_profile = &wext_state->roamProfile;
16035 roam_profile->force_24ghz_in_ht20 = false;
16036 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16037 !(req->ht_capa.cap_info &
16038 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16039 roam_profile->force_24ghz_in_ht20 = true;
16040
16041 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16042 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16043}
16044#else
16045static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16046 hdd_adapter_t *adapter,
16047 struct cfg80211_connect_params *req)
16048{
16049 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16050 tCsrRoamProfile *roam_profile;
16051
16052 roam_profile = &wext_state->roamProfile;
16053 roam_profile->force_24ghz_in_ht20 = false;
16054}
16055#endif
16056
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016057/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016058 * FUNCTION: __wlan_hdd_cfg80211_connect
16059 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016061static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 struct net_device *ndev,
16063 struct cfg80211_connect_params *req
16064 )
16065{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016066 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016067 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16069 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016070 const u8 *bssid_hint = req->bssid_hint;
16071#else
16072 const u8 *bssid_hint = NULL;
16073#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016075 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016076 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016077
16078 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16081 TRACE_CODE_HDD_CFG80211_CONNECT,
16082 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016083 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016084 "%s: device_mode = %s (%d)", __func__,
16085 hdd_device_modetoString(pAdapter->device_mode),
16086 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016087
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016089 if (!pHddCtx)
16090 {
16091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16092 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016093 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016094 }
16095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016096 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016097 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016099 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 }
16101
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016102 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16103 if (0 == status)
16104 return status;
16105
Agarwal Ashish51325b52014-06-16 16:50:49 +053016106
Jeff Johnson295189b2012-06-20 16:38:30 -070016107#ifdef WLAN_BTAMP_FEATURE
16108 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016109 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016111 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016113 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 }
16115#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016116
16117 //If Device Mode is Station Concurrent Sessions Exit BMps
16118 //P2P Mode will be taken care in Open/close adapter
16119 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016120 (vos_concurrent_open_sessions_running())) {
16121 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16122 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016123 }
16124
16125 /*Try disconnecting if already in connected state*/
16126 status = wlan_hdd_try_disconnect(pAdapter);
16127 if ( 0 > status)
16128 {
16129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16130 " connection"));
16131 return -EALREADY;
16132 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016133 /* Check for max concurrent connections after doing disconnect if any*/
16134 if (vos_max_concurrent_connections_reached()) {
16135 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16136 return -ECONNREFUSED;
16137 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016138
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016140 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016141
16142 if ( 0 > status)
16143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016145 __func__);
16146 return status;
16147 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016148
16149 if (pHddCtx->spoofMacAddr.isEnabled)
16150 {
16151 hddLog(VOS_TRACE_LEVEL_INFO,
16152 "%s: MAC Spoofing enabled ", __func__);
16153 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16154 * to fill TxBds for probe request during SSID scan which may happen
16155 * as part of connect command
16156 */
16157 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16158 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16159 if (status != VOS_STATUS_SUCCESS)
16160 return -ECONNREFUSED;
16161 }
16162
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016163 if (req->channel)
16164 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016165 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016166 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016167
16168 /* Abort if any scan is going on */
16169 status = wlan_hdd_scan_abort(pAdapter);
16170 if (0 != status)
16171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16172
Abhishek Singhe3beee22017-07-31 15:35:40 +053016173 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16174
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016175 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16176 req->ssid_len, req->bssid,
16177 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016178
Sushant Kaushikd7083982015-03-18 14:33:24 +053016179 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 {
16181 //ReEnable BMPS if disabled
16182 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16183 (NULL != pHddCtx))
16184 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016185 if (pHddCtx->hdd_wlan_suspended)
16186 {
16187 hdd_set_pwrparams(pHddCtx);
16188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016189 //ReEnable Bmps and Imps back
16190 hdd_enable_bmps_imps(pHddCtx);
16191 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 return status;
16194 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016195 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016196 EXIT();
16197 return status;
16198}
16199
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016200static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16201 struct net_device *ndev,
16202 struct cfg80211_connect_params *req)
16203{
16204 int ret;
16205 vos_ssr_protect(__func__);
16206 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16207 vos_ssr_unprotect(__func__);
16208
16209 return ret;
16210}
Jeff Johnson295189b2012-06-20 16:38:30 -070016211
16212/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016213 * FUNCTION: wlan_hdd_disconnect
16214 * This function is used to issue a disconnect request to SME
16215 */
16216int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
16217{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016218 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016219 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016220 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016221 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016222 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016223
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016224 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016225
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016226 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016227 if (0 != status)
16228 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016229 return status;
16230 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053016231 /* Indicate sme of disconnect so that in progress connection or preauth
16232 * can be aborted
16233 */
16234 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053016235 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016236 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016237
Agarwal Ashish47d18112014-08-04 19:55:07 +053016238 /* Need to apply spin lock before decreasing active sessions
16239 * as there can be chance for double decrement if context switch
16240 * Calls hdd_DisConnectHandler.
16241 */
16242
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016243 prev_conn_state = pHddStaCtx->conn_info.connState;
16244
Agarwal Ashish47d18112014-08-04 19:55:07 +053016245 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016246 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16247 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016248 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16249 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053016250 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
16251 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053016252 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016253
Abhishek Singhf4669da2014-05-26 15:07:49 +053016254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053016255 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
16256
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016257 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016258
Mihir Shete182a0b22014-08-18 16:08:48 +053016259 /*
16260 * stop tx queues before deleting STA/BSS context from the firmware.
16261 * tx has to be disabled because the firmware can get busy dropping
16262 * the tx frames after BSS/STA has been deleted and will not send
16263 * back a response resulting in WDI timeout
16264 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053016265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053016266 netif_tx_disable(pAdapter->dev);
16267 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016268
Mihir Shete182a0b22014-08-18 16:08:48 +053016269 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016270 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
16271 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016272 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
16273 prev_conn_state != eConnectionState_Connecting)
16274 {
16275 hddLog(LOG1,
16276 FL("status = %d, already disconnected"), status);
16277 result = 0;
16278 goto disconnected;
16279 }
16280 /*
16281 * Wait here instead of returning directly, this will block the next
16282 * connect command and allow processing of the scan for ssid and
16283 * the previous connect command in CSR. Else we might hit some
16284 * race conditions leading to SME and HDD out of sync.
16285 */
16286 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016287 {
16288 hddLog(LOG1,
16289 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016290 }
16291 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016292 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016293 hddLog(LOGE,
16294 FL("csrRoamDisconnect failure, returned %d"),
16295 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016296 result = -EINVAL;
16297 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016298 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016299 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016300 &pAdapter->disconnect_comp_var,
16301 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016302 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016303 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016304 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016305 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016306 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016307 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016308disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016309 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016310 FL("Set HDD connState to eConnectionState_NotConnected"));
16311 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016312#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
16313 /* Sending disconnect event to userspace for kernel version < 3.11
16314 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
16315 */
16316 hddLog(LOG1, FL("Send disconnected event to userspace"));
16317
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053016318 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016319 WLAN_REASON_UNSPECIFIED);
16320#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016322 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016323 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016324}
16325
16326
16327/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016328 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016329 * This function is used to issue a disconnect request to SME
16330 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016331static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 struct net_device *dev,
16333 u16 reason
16334 )
16335{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016336 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016337 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016338 tCsrRoamProfile *pRoamProfile;
16339 hdd_station_ctx_t *pHddStaCtx;
16340 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016341#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016342 tANI_U8 staIdx;
16343#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016344
Jeff Johnson295189b2012-06-20 16:38:30 -070016345 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016346
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016347 if (!pAdapter) {
16348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16349 return -EINVAL;
16350 }
16351
16352 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16353 if (!pHddStaCtx) {
16354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16355 return -EINVAL;
16356 }
16357
16358 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16359 status = wlan_hdd_validate_context(pHddCtx);
16360 if (0 != status)
16361 {
16362 return status;
16363 }
16364
16365 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16366
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016367 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16368 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16369 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16371 __func__, hdd_device_modetoString(pAdapter->device_mode),
16372 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016373
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16375 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016376
Jeff Johnson295189b2012-06-20 16:38:30 -070016377 if (NULL != pRoamProfile)
16378 {
16379 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016380 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16381 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016383 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016385 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016386 switch(reason)
16387 {
16388 case WLAN_REASON_MIC_FAILURE:
16389 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16390 break;
16391
16392 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16393 case WLAN_REASON_DISASSOC_AP_BUSY:
16394 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16395 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16396 break;
16397
16398 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16399 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016400 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16402 break;
16403
Jeff Johnson295189b2012-06-20 16:38:30 -070016404 default:
16405 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16406 break;
16407 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016408 pScanInfo = &pHddCtx->scan_info;
16409 if (pScanInfo->mScanPending)
16410 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016411 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016412 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016413 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016414 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016415 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016416 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016417#ifdef FEATURE_WLAN_TDLS
16418 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016419 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016420 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016421 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16422 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016423 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016424 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016425 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016427 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016428 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016429 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016430 status = sme_DeleteTdlsPeerSta(
16431 WLAN_HDD_GET_HAL_CTX(pAdapter),
16432 pAdapter->sessionId,
16433 mac);
16434 if (status != eHAL_STATUS_SUCCESS) {
16435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16436 return -EPERM;
16437 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016438 }
16439 }
16440#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016441
16442 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16443 reasonCode,
16444 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016445 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16446 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016447 {
16448 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016449 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016450 __func__, (int)status );
16451 return -EINVAL;
16452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016453 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016454 else
16455 {
16456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16457 "called while in %d state", __func__,
16458 pHddStaCtx->conn_info.connState);
16459 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016460 }
16461 else
16462 {
16463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16464 }
16465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016466 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016467 return status;
16468}
16469
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016470static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16471 struct net_device *dev,
16472 u16 reason
16473 )
16474{
16475 int ret;
16476 vos_ssr_protect(__func__);
16477 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16478 vos_ssr_unprotect(__func__);
16479
16480 return ret;
16481}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016482
Jeff Johnson295189b2012-06-20 16:38:30 -070016483/*
16484 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016485 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016486 * settings in IBSS mode.
16487 */
16488static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016489 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016490 struct cfg80211_ibss_params *params
16491 )
16492{
16493 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016494 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016495 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16496 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016497
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 ENTER();
16499
16500 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016501 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016502
16503 if (params->ie_len && ( NULL != params->ie) )
16504 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016505 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16506 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016507 {
16508 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16509 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16510 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016511 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016512 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016513 tDot11fIEWPA dot11WPAIE;
16514 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016515 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016516
Wilson Yang00256342013-10-10 23:13:38 -070016517 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016518 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16519 params->ie_len, DOT11F_EID_WPA);
16520 if ( NULL != ie )
16521 {
16522 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16523 // Unpack the WPA IE
16524 //Skip past the EID byte and length byte - and four byte WiFi OUI
16525 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16526 &ie[2+4],
16527 ie[1] - 4,
16528 &dot11WPAIE);
16529 /*Extract the multicast cipher, the encType for unicast
16530 cipher for wpa-none is none*/
16531 encryptionType =
16532 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16533 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016534 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016535
Jeff Johnson295189b2012-06-20 16:38:30 -070016536 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16537
16538 if (0 > status)
16539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016541 __func__);
16542 return status;
16543 }
16544 }
16545
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016546 pWextState->roamProfile.AuthType.authType[0] =
16547 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016548 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16549
16550 if (params->privacy)
16551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016552 /* Security enabled IBSS, At this time there is no information available
16553 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016554 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016555 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016556 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016557 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016558 *enable privacy bit in beacons */
16559
16560 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16561 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016562 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16563 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016564 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16565 pWextState->roamProfile.EncryptionType.numEntries = 1;
16566 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016567 return status;
16568}
16569
16570/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016571 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016572 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016574static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016575 struct net_device *dev,
16576 struct cfg80211_ibss_params *params
16577 )
16578{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16581 tCsrRoamProfile *pRoamProfile;
16582 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016583 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16584 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016585 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016586
16587 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016588
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016589 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16590 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16591 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016592 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016593 "%s: device_mode = %s (%d)", __func__,
16594 hdd_device_modetoString(pAdapter->device_mode),
16595 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016596
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016597 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016598 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016600 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 }
16602
16603 if (NULL == pWextState)
16604 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016605 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016606 __func__);
16607 return -EIO;
16608 }
16609
Agarwal Ashish51325b52014-06-16 16:50:49 +053016610 if (vos_max_concurrent_connections_reached()) {
16611 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16612 return -ECONNREFUSED;
16613 }
16614
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016615 /*Try disconnecting if already in connected state*/
16616 status = wlan_hdd_try_disconnect(pAdapter);
16617 if ( 0 > status)
16618 {
16619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16620 " IBSS connection"));
16621 return -EALREADY;
16622 }
16623
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 pRoamProfile = &pWextState->roamProfile;
16625
16626 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16627 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016629 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 return -EINVAL;
16631 }
16632
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016633 /* BSSID is provided by upper layers hence no need to AUTO generate */
16634 if (NULL != params->bssid) {
16635 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16636 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16637 hddLog (VOS_TRACE_LEVEL_ERROR,
16638 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16639 return -EIO;
16640 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016641 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016642 }
krunal sonie9002db2013-11-25 14:24:17 -080016643 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16644 {
16645 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16646 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16647 {
16648 hddLog (VOS_TRACE_LEVEL_ERROR,
16649 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16650 return -EIO;
16651 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016652
16653 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016654 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016655 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016656 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016657
Jeff Johnson295189b2012-06-20 16:38:30 -070016658 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016659 if (NULL !=
16660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16661 params->chandef.chan)
16662#else
16663 params->channel)
16664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016665 {
16666 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016667 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16668 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16669 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16670 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016671
16672 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016673 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016674 ieee80211_frequency_to_channel(
16675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16676 params->chandef.chan->center_freq);
16677#else
16678 params->channel->center_freq);
16679#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016680
16681 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16682 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016683 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16685 __func__);
16686 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016687 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016688
16689 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016690 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016691 if (channelNum == validChan[indx])
16692 {
16693 break;
16694 }
16695 }
16696 if (indx >= numChans)
16697 {
16698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016699 __func__, channelNum);
16700 return -EINVAL;
16701 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016702 /* Set the Operational Channel */
16703 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16704 channelNum);
16705 pRoamProfile->ChannelInfo.numOfChannels = 1;
16706 pHddStaCtx->conn_info.operationChannel = channelNum;
16707 pRoamProfile->ChannelInfo.ChannelList =
16708 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016709 }
16710
16711 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016712 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016713 if (status < 0)
16714 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016716 __func__);
16717 return status;
16718 }
16719
16720 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016721 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016722 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016723 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016724
16725 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016728 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016729 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016730}
16731
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016732static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16733 struct net_device *dev,
16734 struct cfg80211_ibss_params *params
16735 )
16736{
16737 int ret = 0;
16738
16739 vos_ssr_protect(__func__);
16740 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16741 vos_ssr_unprotect(__func__);
16742
16743 return ret;
16744}
16745
Jeff Johnson295189b2012-06-20 16:38:30 -070016746/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016747 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016748 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016749 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016750static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016751 struct net_device *dev
16752 )
16753{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016754 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016755 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16756 tCsrRoamProfile *pRoamProfile;
16757 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016758 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016759 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016760#ifdef WLAN_FEATURE_RMC
16761 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016763
16764 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016765
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016766 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16767 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16768 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016769 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016770 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016771 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016772 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016773 }
16774
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016775 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16776 hdd_device_modetoString(pAdapter->device_mode),
16777 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 if (NULL == pWextState)
16779 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016780 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016781 __func__);
16782 return -EIO;
16783 }
16784
16785 pRoamProfile = &pWextState->roamProfile;
16786
16787 /* Issue disconnect only if interface type is set to IBSS */
16788 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016790 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016791 __func__);
16792 return -EINVAL;
16793 }
16794
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016795#ifdef WLAN_FEATURE_RMC
16796 /* Clearing add IE of beacon */
16797 if (ccmCfgSetStr(pHddCtx->hHal,
16798 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16799 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16800 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16801 {
16802 hddLog (VOS_TRACE_LEVEL_ERROR,
16803 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16804 return -EINVAL;
16805 }
16806 if (ccmCfgSetInt(pHddCtx->hHal,
16807 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16808 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16809 {
16810 hddLog (VOS_TRACE_LEVEL_ERROR,
16811 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16812 __func__);
16813 return -EINVAL;
16814 }
16815
16816 // Reset WNI_CFG_PROBE_RSP Flags
16817 wlan_hdd_reset_prob_rspies(pAdapter);
16818
16819 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16820 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16821 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16822 {
16823 hddLog (VOS_TRACE_LEVEL_ERROR,
16824 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16825 __func__);
16826 return -EINVAL;
16827 }
16828#endif
16829
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 /* Issue Disconnect request */
16831 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016832 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16833 pAdapter->sessionId,
16834 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16835 if (!HAL_STATUS_SUCCESS(hal_status)) {
16836 hddLog(LOGE,
16837 FL("sme_RoamDisconnect failed hal_status(%d)"),
16838 hal_status);
16839 return -EAGAIN;
16840 }
16841 status = wait_for_completion_timeout(
16842 &pAdapter->disconnect_comp_var,
16843 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16844 if (!status) {
16845 hddLog(LOGE,
16846 FL("wait on disconnect_comp_var failed"));
16847 return -ETIMEDOUT;
16848 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016850 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016851 return 0;
16852}
16853
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016854static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16855 struct net_device *dev
16856 )
16857{
16858 int ret = 0;
16859
16860 vos_ssr_protect(__func__);
16861 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16862 vos_ssr_unprotect(__func__);
16863
16864 return ret;
16865}
16866
Jeff Johnson295189b2012-06-20 16:38:30 -070016867/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016868 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016869 * This function is used to set the phy parameters
16870 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16871 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016872static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016873 u32 changed)
16874{
16875 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16876 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016877 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016878
16879 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016880
16881 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016882 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16883 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016885 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016886 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016887 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016888 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016889 }
16890
Jeff Johnson295189b2012-06-20 16:38:30 -070016891 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16892 {
16893 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16894 WNI_CFG_RTS_THRESHOLD_STAMAX :
16895 wiphy->rts_threshold;
16896
16897 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016898 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016900 hddLog(VOS_TRACE_LEVEL_ERROR,
16901 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016902 __func__, rts_threshold);
16903 return -EINVAL;
16904 }
16905
16906 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16907 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016908 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016909 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016910 hddLog(VOS_TRACE_LEVEL_ERROR,
16911 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016912 __func__, rts_threshold);
16913 return -EIO;
16914 }
16915
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016916 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016917 rts_threshold);
16918 }
16919
16920 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16921 {
16922 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16923 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16924 wiphy->frag_threshold;
16925
16926 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016927 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016928 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016929 hddLog(VOS_TRACE_LEVEL_ERROR,
16930 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016931 frag_threshold);
16932 return -EINVAL;
16933 }
16934
16935 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16936 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016937 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016939 hddLog(VOS_TRACE_LEVEL_ERROR,
16940 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016941 __func__, frag_threshold);
16942 return -EIO;
16943 }
16944
16945 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16946 frag_threshold);
16947 }
16948
16949 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16950 || (changed & WIPHY_PARAM_RETRY_LONG))
16951 {
16952 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16953 wiphy->retry_short :
16954 wiphy->retry_long;
16955
16956 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
16957 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
16958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016960 __func__, retry_value);
16961 return -EINVAL;
16962 }
16963
16964 if (changed & WIPHY_PARAM_RETRY_SHORT)
16965 {
16966 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
16967 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016968 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016969 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016970 hddLog(VOS_TRACE_LEVEL_ERROR,
16971 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 __func__, retry_value);
16973 return -EIO;
16974 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016975 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016976 __func__, retry_value);
16977 }
16978 else if (changed & WIPHY_PARAM_RETRY_SHORT)
16979 {
16980 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
16981 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016982 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016984 hddLog(VOS_TRACE_LEVEL_ERROR,
16985 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016986 __func__, retry_value);
16987 return -EIO;
16988 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016989 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016990 __func__, retry_value);
16991 }
16992 }
16993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016994 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016995 return 0;
16996}
16997
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016998static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
16999 u32 changed)
17000{
17001 int ret;
17002
17003 vos_ssr_protect(__func__);
17004 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17005 vos_ssr_unprotect(__func__);
17006
17007 return ret;
17008}
17009
Jeff Johnson295189b2012-06-20 16:38:30 -070017010/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017011 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 * This function is used to set the txpower
17013 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017014static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017015#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17016 struct wireless_dev *wdev,
17017#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017018#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017019 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017020#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017021 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017022#endif
17023 int dbm)
17024{
17025 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017026 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17028 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017029 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017030
17031 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17034 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17035 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017037 if (0 != status)
17038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017039 return status;
17040 }
17041
17042 hHal = pHddCtx->hHal;
17043
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017044 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17045 dbm, ccmCfgSetCallback,
17046 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017047 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017048 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017049 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17050 return -EIO;
17051 }
17052
17053 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17054 dbm);
17055
17056 switch(type)
17057 {
17058 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17059 /* Fall through */
17060 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17061 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17064 __func__);
17065 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017066 }
17067 break;
17068 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 __func__);
17071 return -EOPNOTSUPP;
17072 break;
17073 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17075 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 return -EIO;
17077 }
17078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017079 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017080 return 0;
17081}
17082
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017083static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17084#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17085 struct wireless_dev *wdev,
17086#endif
17087#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17088 enum tx_power_setting type,
17089#else
17090 enum nl80211_tx_power_setting type,
17091#endif
17092 int dbm)
17093{
17094 int ret;
17095 vos_ssr_protect(__func__);
17096 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17097#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17098 wdev,
17099#endif
17100#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17101 type,
17102#else
17103 type,
17104#endif
17105 dbm);
17106 vos_ssr_unprotect(__func__);
17107
17108 return ret;
17109}
17110
Jeff Johnson295189b2012-06-20 16:38:30 -070017111/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017112 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017113 * This function is used to read the txpower
17114 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017115static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017116#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17117 struct wireless_dev *wdev,
17118#endif
17119 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017120{
17121
17122 hdd_adapter_t *pAdapter;
17123 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017124 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017125
Jeff Johnsone7245742012-09-05 17:12:55 -070017126 ENTER();
17127
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017128 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017129 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017130 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017131 *dbm = 0;
17132 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017133 }
17134
Jeff Johnson295189b2012-06-20 16:38:30 -070017135 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17136 if (NULL == pAdapter)
17137 {
17138 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17139 return -ENOENT;
17140 }
17141
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017142 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17143 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17144 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017145 wlan_hdd_get_classAstats(pAdapter);
17146 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17147
Jeff Johnsone7245742012-09-05 17:12:55 -070017148 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017149 return 0;
17150}
17151
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017152static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17153#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17154 struct wireless_dev *wdev,
17155#endif
17156 int *dbm)
17157{
17158 int ret;
17159
17160 vos_ssr_protect(__func__);
17161 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17162#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17163 wdev,
17164#endif
17165 dbm);
17166 vos_ssr_unprotect(__func__);
17167
17168 return ret;
17169}
17170
Dustin Brown8c1d4092017-07-28 18:08:01 +053017171/*
17172 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17173 * @stats: summary stats to use as a source
17174 * @info: kernel station_info struct to use as a destination
17175 *
17176 * Return: None
17177 */
17178static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17179 struct station_info *info)
17180{
17181 int i;
17182
17183 info->rx_packets = stats->rx_frm_cnt;
17184 info->tx_packets = 0;
17185 info->tx_retries = 0;
17186 info->tx_failed = 0;
17187
17188 for (i = 0; i < 4; ++i) {
17189 info->tx_packets += stats->tx_frm_cnt[i];
17190 info->tx_retries += stats->multiple_retry_cnt[i];
17191 info->tx_failed += stats->fail_cnt[i];
17192 }
17193
17194 info->filled |= STATION_INFO_TX_PACKETS |
17195 STATION_INFO_TX_RETRIES |
17196 STATION_INFO_TX_FAILED |
17197 STATION_INFO_RX_PACKETS;
17198}
17199
17200/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017201 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17202 * @adapter: sap adapter pointer
17203 * @staid: station id of the client
17204 * @rssi: rssi value to fill
17205 *
17206 * Return: None
17207 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017208void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017209wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17210{
17211 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17212
17213 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17214}
17215
17216/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017217 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17218 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017219 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017220 * @info: kernel station_info struct to populate
17221 *
17222 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17223 * support "station dump" and "station get" for SAP vdevs, even though they
17224 * aren't technically stations.
17225 *
17226 * Return: errno
17227 */
17228static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017229wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17231 const u8* mac,
17232#else
17233 u8* mac,
17234#endif
17235 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017236{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017237 v_MACADDR_t *peerMacAddr;
17238 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017239 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017240 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017241
17242 status = wlan_hdd_get_station_stats(adapter);
17243 if (!VOS_IS_STATUS_SUCCESS(status)) {
17244 hddLog(VOS_TRACE_LEVEL_ERROR,
17245 "Failed to get SAP stats; status:%d", status);
17246 return 0;
17247 }
17248
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017249 peerMacAddr = (v_MACADDR_t *)mac;
17250 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17251 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17252 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17253
17254 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17255 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
17256 info->filled |= STATION_INFO_SIGNAL;
17257 }
17258
Dustin Brown8c1d4092017-07-28 18:08:01 +053017259 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17260
17261 return 0;
17262}
17263
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017264static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17266 const u8* mac,
17267#else
17268 u8* mac,
17269#endif
17270 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017271{
17272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17273 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17274 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017275 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017276
17277 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17278 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017279
17280 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17281 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17282 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17283 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17284 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17285 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17286 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017287 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017288 tANI_U16 myRate;
17289 tANI_U16 currentRate = 0;
17290 tANI_U8 maxSpeedMCS = 0;
17291 tANI_U8 maxMCSIdx = 0;
17292 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017293 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017294 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017295 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017296
Leo Chang6f8870f2013-03-26 18:11:36 -070017297#ifdef WLAN_FEATURE_11AC
17298 tANI_U32 vht_mcs_map;
17299 eDataRate11ACMaxMcs vhtMaxMcs;
17300#endif /* WLAN_FEATURE_11AC */
17301
Jeff Johnsone7245742012-09-05 17:12:55 -070017302 ENTER();
17303
Dustin Brown8c1d4092017-07-28 18:08:01 +053017304 status = wlan_hdd_validate_context(pHddCtx);
17305 if (0 != status)
17306 {
17307 return status;
17308 }
17309
17310 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017311 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017312
Jeff Johnson295189b2012-06-20 16:38:30 -070017313 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17314 (0 == ssidlen))
17315 {
17316 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17317 " Invalid ssidlen, %d", __func__, ssidlen);
17318 /*To keep GUI happy*/
17319 return 0;
17320 }
17321
Mukul Sharma811205f2014-07-09 21:07:30 +053017322 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17323 {
17324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17325 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017326 /* return a cached value */
17327 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017328 return 0;
17329 }
17330
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017331 wlan_hdd_get_station_stats(pAdapter);
17332 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017333
Kiet Lam3b17fc82013-09-27 05:24:08 +053017334 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017335 wlan_hdd_get_snr(pAdapter, &snr);
17336 pHddStaCtx->conn_info.signal = sinfo->signal;
17337 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053017338 sinfo->filled |= STATION_INFO_SIGNAL;
17339
c_hpothu09f19542014-05-30 21:53:31 +053017340 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017341 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17342 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017343 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017344 {
17345 rate_flags = pAdapter->maxRateFlags;
17346 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017347
Jeff Johnson295189b2012-06-20 16:38:30 -070017348 //convert to the UI units of 100kbps
17349 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17350
17351#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017352 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 -070017353 sinfo->signal,
17354 pCfg->reportMaxLinkSpeed,
17355 myRate,
17356 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017357 (int) pCfg->linkSpeedRssiMid,
17358 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017359 (int) rate_flags,
17360 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017361#endif //LINKSPEED_DEBUG_ENABLED
17362
17363 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17364 {
17365 // we do not want to necessarily report the current speed
17366 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17367 {
17368 // report the max possible speed
17369 rssidx = 0;
17370 }
17371 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17372 {
17373 // report the max possible speed with RSSI scaling
17374 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17375 {
17376 // report the max possible speed
17377 rssidx = 0;
17378 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017379 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017380 {
17381 // report middle speed
17382 rssidx = 1;
17383 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017384 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17385 {
17386 // report middle speed
17387 rssidx = 2;
17388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017389 else
17390 {
17391 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017392 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017393 }
17394 }
17395 else
17396 {
17397 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17398 hddLog(VOS_TRACE_LEVEL_ERROR,
17399 "%s: Invalid value for reportMaxLinkSpeed: %u",
17400 __func__, pCfg->reportMaxLinkSpeed);
17401 rssidx = 0;
17402 }
17403
17404 maxRate = 0;
17405
17406 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017407 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17408 OperationalRates, &ORLeng))
17409 {
17410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17411 /*To keep GUI happy*/
17412 return 0;
17413 }
17414
Jeff Johnson295189b2012-06-20 16:38:30 -070017415 for (i = 0; i < ORLeng; i++)
17416 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017417 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 {
17419 /* Validate Rate Set */
17420 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17421 {
17422 currentRate = supported_data_rate[j].supported_rate[rssidx];
17423 break;
17424 }
17425 }
17426 /* Update MAX rate */
17427 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17428 }
17429
17430 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017431 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17432 ExtendedRates, &ERLeng))
17433 {
17434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17435 /*To keep GUI happy*/
17436 return 0;
17437 }
17438
Jeff Johnson295189b2012-06-20 16:38:30 -070017439 for (i = 0; i < ERLeng; i++)
17440 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017441 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017442 {
17443 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17444 {
17445 currentRate = supported_data_rate[j].supported_rate[rssidx];
17446 break;
17447 }
17448 }
17449 /* Update MAX rate */
17450 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17451 }
c_hpothu79aab322014-07-14 21:11:01 +053017452
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017453 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017454 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017455 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017456 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017457 {
c_hpothu79aab322014-07-14 21:11:01 +053017458 if (rate_flags & eHAL_TX_RATE_VHT80)
17459 mode = 2;
17460 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17461 mode = 1;
17462 else
17463 mode = 0;
17464
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017465 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17466 MCSRates, &MCSLeng))
17467 {
17468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17469 /*To keep GUI happy*/
17470 return 0;
17471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017472 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017473#ifdef WLAN_FEATURE_11AC
17474 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017475 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017476 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017477 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017478 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017479 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017480 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017481 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017482 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017483 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017484 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017485 maxMCSIdx = 7;
17486 }
17487 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17488 {
17489 maxMCSIdx = 8;
17490 }
17491 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17492 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017493 //VHT20 is supporting 0~8
17494 if (rate_flags & eHAL_TX_RATE_VHT20)
17495 maxMCSIdx = 8;
17496 else
17497 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017498 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017499
c_hpothu79aab322014-07-14 21:11:01 +053017500 if (0 != rssidx)/*check for scaled */
17501 {
17502 //get middle rate MCS index if rssi=1/2
17503 for (i=0; i <= maxMCSIdx; i++)
17504 {
17505 if (sinfo->signal <= rssiMcsTbl[mode][i])
17506 {
17507 maxMCSIdx = i;
17508 break;
17509 }
17510 }
17511 }
17512
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017513 if (rate_flags & eHAL_TX_RATE_VHT80)
17514 {
17515 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17516 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17517 }
17518 else if (rate_flags & eHAL_TX_RATE_VHT40)
17519 {
17520 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17521 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17522 }
17523 else if (rate_flags & eHAL_TX_RATE_VHT20)
17524 {
17525 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17526 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17527 }
17528
Leo Chang6f8870f2013-03-26 18:11:36 -070017529 maxSpeedMCS = 1;
17530 if (currentRate > maxRate)
17531 {
17532 maxRate = currentRate;
17533 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017534
Leo Chang6f8870f2013-03-26 18:11:36 -070017535 }
17536 else
17537#endif /* WLAN_FEATURE_11AC */
17538 {
17539 if (rate_flags & eHAL_TX_RATE_HT40)
17540 {
17541 rateFlag |= 1;
17542 }
17543 if (rate_flags & eHAL_TX_RATE_SGI)
17544 {
17545 rateFlag |= 2;
17546 }
17547
Girish Gowli01abcee2014-07-31 20:18:55 +053017548 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017549 if (rssidx == 1 || rssidx == 2)
17550 {
17551 //get middle rate MCS index if rssi=1/2
17552 for (i=0; i <= 7; i++)
17553 {
17554 if (sinfo->signal <= rssiMcsTbl[mode][i])
17555 {
17556 temp = i+1;
17557 break;
17558 }
17559 }
17560 }
c_hpothu79aab322014-07-14 21:11:01 +053017561
17562 for (i = 0; i < MCSLeng; i++)
17563 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017564 for (j = 0; j < temp; j++)
17565 {
17566 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17567 {
17568 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017569 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017570 break;
17571 }
17572 }
17573 if ((j < temp) && (currentRate > maxRate))
17574 {
17575 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017576 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017577 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017578 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017579 }
17580 }
17581
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017582 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17583 {
17584 maxRate = myRate;
17585 maxSpeedMCS = 1;
17586 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017588 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017589 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017590 {
17591 maxRate = myRate;
17592 if (rate_flags & eHAL_TX_RATE_LEGACY)
17593 {
17594 maxSpeedMCS = 0;
17595 }
17596 else
17597 {
17598 maxSpeedMCS = 1;
17599 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17600 }
17601 }
17602
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017603 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017604 {
17605 sinfo->txrate.legacy = maxRate;
17606#ifdef LINKSPEED_DEBUG_ENABLED
17607 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17608#endif //LINKSPEED_DEBUG_ENABLED
17609 }
17610 else
17611 {
17612 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017613#ifdef WLAN_FEATURE_11AC
17614 sinfo->txrate.nss = 1;
17615 if (rate_flags & eHAL_TX_RATE_VHT80)
17616 {
17617 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017618 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017619 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017620 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017621 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017622 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17623 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17624 }
17625 else if (rate_flags & eHAL_TX_RATE_VHT20)
17626 {
17627 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17628 }
17629#endif /* WLAN_FEATURE_11AC */
17630 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17631 {
17632 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17633 if (rate_flags & eHAL_TX_RATE_HT40)
17634 {
17635 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17636 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017637 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017638 if (rate_flags & eHAL_TX_RATE_SGI)
17639 {
17640 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17641 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017642
Jeff Johnson295189b2012-06-20 16:38:30 -070017643#ifdef LINKSPEED_DEBUG_ENABLED
17644 pr_info("Reporting MCS rate %d flags %x\n",
17645 sinfo->txrate.mcs,
17646 sinfo->txrate.flags );
17647#endif //LINKSPEED_DEBUG_ENABLED
17648 }
17649 }
17650 else
17651 {
17652 // report current rate instead of max rate
17653
17654 if (rate_flags & eHAL_TX_RATE_LEGACY)
17655 {
17656 //provide to the UI in units of 100kbps
17657 sinfo->txrate.legacy = myRate;
17658#ifdef LINKSPEED_DEBUG_ENABLED
17659 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17660#endif //LINKSPEED_DEBUG_ENABLED
17661 }
17662 else
17663 {
17664 //must be MCS
17665 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017666#ifdef WLAN_FEATURE_11AC
17667 sinfo->txrate.nss = 1;
17668 if (rate_flags & eHAL_TX_RATE_VHT80)
17669 {
17670 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17671 }
17672 else
17673#endif /* WLAN_FEATURE_11AC */
17674 {
17675 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017677 if (rate_flags & eHAL_TX_RATE_SGI)
17678 {
17679 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17680 }
17681 if (rate_flags & eHAL_TX_RATE_HT40)
17682 {
17683 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17684 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017685#ifdef WLAN_FEATURE_11AC
17686 else if (rate_flags & eHAL_TX_RATE_VHT80)
17687 {
17688 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17689 }
17690#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017691#ifdef LINKSPEED_DEBUG_ENABLED
17692 pr_info("Reporting actual MCS rate %d flags %x\n",
17693 sinfo->txrate.mcs,
17694 sinfo->txrate.flags );
17695#endif //LINKSPEED_DEBUG_ENABLED
17696 }
17697 }
17698 sinfo->filled |= STATION_INFO_TX_BITRATE;
17699
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017700 sinfo->tx_packets =
17701 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17702 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17703 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17704 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17705
17706 sinfo->tx_retries =
17707 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17708 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17709 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17710 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17711
17712 sinfo->tx_failed =
17713 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17714 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17715 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17716 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17717
17718 sinfo->filled |=
17719 STATION_INFO_TX_PACKETS |
17720 STATION_INFO_TX_RETRIES |
17721 STATION_INFO_TX_FAILED;
17722
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017723 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17724 sinfo->filled |= STATION_INFO_RX_PACKETS;
17725
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017726 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17727 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017728 if (rate_flags & eHAL_TX_RATE_LEGACY)
17729 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17730 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17731 sinfo->rx_packets);
17732 else
17733 hddLog(LOG1,
17734 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17735 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17736 sinfo->tx_packets, sinfo->rx_packets);
17737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17739 TRACE_CODE_HDD_CFG80211_GET_STA,
17740 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017741 EXIT();
17742 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017743}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17745static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17746 const u8* mac, struct station_info *sinfo)
17747#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017748static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17749 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017750#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017751{
17752 int ret;
17753
17754 vos_ssr_protect(__func__);
17755 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17756 vos_ssr_unprotect(__func__);
17757
17758 return ret;
17759}
17760
17761static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017762 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017763{
17764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017765 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017766 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017767 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017768
Jeff Johnsone7245742012-09-05 17:12:55 -070017769 ENTER();
17770
Jeff Johnson295189b2012-06-20 16:38:30 -070017771 if (NULL == pAdapter)
17772 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017774 return -ENODEV;
17775 }
17776
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017777 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17778 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17779 pAdapter->sessionId, timeout));
17780
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017781 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017782 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017783 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017784 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017785 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017786 }
17787
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017788 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17789 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17790 (pHddCtx->cfg_ini->fhostArpOffload) &&
17791 (eConnectionState_Associated ==
17792 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17793 {
Amar Singhald53568e2013-09-26 11:03:45 -070017794
17795 hddLog(VOS_TRACE_LEVEL_INFO,
17796 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017797 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017798 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17799 {
17800 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017801 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017802 __func__, vos_status);
17803 }
17804 }
17805
Jeff Johnson295189b2012-06-20 16:38:30 -070017806 /**The get power cmd from the supplicant gets updated by the nl only
17807 *on successful execution of the function call
17808 *we are oppositely mapped w.r.t mode in the driver
17809 **/
17810 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17811
17812 if (VOS_STATUS_E_FAILURE == vos_status)
17813 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17815 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017816 return -EINVAL;
17817 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017818 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017819 return 0;
17820}
17821
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017822static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17823 struct net_device *dev, bool mode, int timeout)
17824{
17825 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017826
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017827 vos_ssr_protect(__func__);
17828 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17829 vos_ssr_unprotect(__func__);
17830
17831 return ret;
17832}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017833
Jeff Johnson295189b2012-06-20 16:38:30 -070017834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017835static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17836 struct net_device *netdev,
17837 u8 key_index)
17838{
17839 ENTER();
17840 return 0;
17841}
17842
Jeff Johnson295189b2012-06-20 16:38:30 -070017843static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017844 struct net_device *netdev,
17845 u8 key_index)
17846{
17847 int ret;
17848 vos_ssr_protect(__func__);
17849 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17850 vos_ssr_unprotect(__func__);
17851 return ret;
17852}
17853#endif //LINUX_VERSION_CODE
17854
17855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17856static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17857 struct net_device *dev,
17858 struct ieee80211_txq_params *params)
17859{
17860 ENTER();
17861 return 0;
17862}
17863#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17864static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17865 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017866{
Jeff Johnsone7245742012-09-05 17:12:55 -070017867 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017868 return 0;
17869}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017870#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017871
17872#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17873static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017874 struct net_device *dev,
17875 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017876{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017877 int ret;
17878
17879 vos_ssr_protect(__func__);
17880 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17881 vos_ssr_unprotect(__func__);
17882 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017883}
17884#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17885static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17886 struct ieee80211_txq_params *params)
17887{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017888 int ret;
17889
17890 vos_ssr_protect(__func__);
17891 ret = __wlan_hdd_set_txq_params(wiphy, params);
17892 vos_ssr_unprotect(__func__);
17893 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017894}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017896
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017897static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017898 struct net_device *dev,
17899 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017900{
17901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017902 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017903 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017904 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017905 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017906 v_CONTEXT_t pVosContext = NULL;
17907 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017908
Jeff Johnsone7245742012-09-05 17:12:55 -070017909 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017910
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017911 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017912 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017914 return -EINVAL;
17915 }
17916
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017917 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17918 TRACE_CODE_HDD_CFG80211_DEL_STA,
17919 pAdapter->sessionId, pAdapter->device_mode));
17920
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017923 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017925 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017926 }
17927
Jeff Johnson295189b2012-06-20 16:38:30 -070017928 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017929 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017930 )
17931 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017932 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17933 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17934 if(pSapCtx == NULL){
17935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17936 FL("psapCtx is NULL"));
17937 return -ENOENT;
17938 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017939 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17940 {
17941 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17942 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17943 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17944 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017945 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017946 {
17947 v_U16_t i;
17948 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17949 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017950 if ((pSapCtx->aStaInfo[i].isUsed) &&
17951 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017952 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017953 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017954 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017955 ETHER_ADDR_LEN);
17956
Jeff Johnson295189b2012-06-20 16:38:30 -070017957 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017958 "%s: Delete STA with MAC::"
17959 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017960 __func__,
17961 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
17962 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070017963 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017964 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017965 }
17966 }
17967 }
17968 else
17969 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017970
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017971 vos_status = hdd_softap_GetStaId(pAdapter,
17972 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017973 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17974 {
17975 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017976 "%s: Skip this DEL STA as this is not used::"
17977 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017978 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017979 return -ENOENT;
17980 }
17981
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017982 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017983 {
17984 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080017985 "%s: Skip this DEL STA as deauth is in progress::"
17986 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017987 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017988 return -ENOENT;
17989 }
17990
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017991 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017992
Jeff Johnson295189b2012-06-20 16:38:30 -070017993 hddLog(VOS_TRACE_LEVEL_INFO,
17994 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080017995 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017997 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017998
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017999 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018000 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18001 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018002 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018003 hddLog(VOS_TRACE_LEVEL_INFO,
18004 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018005 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018006 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018007 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018008 return -ENOENT;
18009 }
18010
Jeff Johnson295189b2012-06-20 16:38:30 -070018011 }
18012 }
18013
18014 EXIT();
18015
18016 return 0;
18017}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018018
18019#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018020int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018021 struct net_device *dev,
18022 struct station_del_parameters *param)
18023#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018025int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018026 struct net_device *dev, const u8 *mac)
18027#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018028int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018029 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018030#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018031#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018032{
18033 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018034 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018035
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018036 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018037
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018038#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018039 if (NULL == param) {
18040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018041 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018042 return -EINVAL;
18043 }
18044
18045 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18046 param->subtype, &delStaParams);
18047
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018048#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018049 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018050 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018051#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018052 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18053
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018054 vos_ssr_unprotect(__func__);
18055
18056 return ret;
18057}
18058
18059static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018060 struct net_device *dev,
18061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18062 const u8 *mac,
18063#else
18064 u8 *mac,
18065#endif
18066 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018067{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018068 hdd_adapter_t *pAdapter;
18069 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018070 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018071#ifdef FEATURE_WLAN_TDLS
18072 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018073
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018074 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018075
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018076 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18077 if (NULL == pAdapter)
18078 {
18079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18080 "%s: Adapter is NULL",__func__);
18081 return -EINVAL;
18082 }
18083 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18084 status = wlan_hdd_validate_context(pHddCtx);
18085 if (0 != status)
18086 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018087 return status;
18088 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18091 TRACE_CODE_HDD_CFG80211_ADD_STA,
18092 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018093 mask = params->sta_flags_mask;
18094
18095 set = params->sta_flags_set;
18096
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018098 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18099 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018100
18101 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18102 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018103 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018104 }
18105 }
18106#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018107 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018108 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018109}
18110
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18112static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18113 struct net_device *dev, const u8 *mac,
18114 struct station_parameters *params)
18115#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018116static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18117 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018118#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018119{
18120 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018121
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018122 vos_ssr_protect(__func__);
18123 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18124 vos_ssr_unprotect(__func__);
18125
18126 return ret;
18127}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018128#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018129
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018130static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018131 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018132{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18134 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018135 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018136 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018137 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018138 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018139
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018140 ENTER();
18141
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018142 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018143 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018146 return -EINVAL;
18147 }
18148
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018149 if (!pmksa) {
18150 hddLog(LOGE, FL("pmksa is NULL"));
18151 return -EINVAL;
18152 }
18153
18154 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018155 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018156 pmksa->bssid, pmksa->pmkid);
18157 return -EINVAL;
18158 }
18159
18160 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18161 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18162
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018163 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18164 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018165 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018166 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018167 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018168 }
18169
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018170 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018171 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18172
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018173 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18174 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018175
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018176 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018177 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018178 &pmk_id, 1, FALSE);
18179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18181 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18182 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018183
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018184 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018185 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018186}
18187
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018188static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18189 struct cfg80211_pmksa *pmksa)
18190{
18191 int ret;
18192
18193 vos_ssr_protect(__func__);
18194 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18195 vos_ssr_unprotect(__func__);
18196
18197 return ret;
18198}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018199
Wilson Yang6507c4e2013-10-01 20:11:19 -070018200
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018201static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018202 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018203{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18205 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018206 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018207 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018209 ENTER();
18210
Wilson Yang6507c4e2013-10-01 20:11:19 -070018211 /* Validate pAdapter */
18212 if (NULL == pAdapter)
18213 {
18214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18215 return -EINVAL;
18216 }
18217
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018218 if (!pmksa) {
18219 hddLog(LOGE, FL("pmksa is NULL"));
18220 return -EINVAL;
18221 }
18222
18223 if (!pmksa->bssid) {
18224 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18225 return -EINVAL;
18226 }
18227
Kiet Lam98c46a12014-10-31 15:34:57 -070018228 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18229 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18230
Wilson Yang6507c4e2013-10-01 20:11:19 -070018231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18232 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018233 if (0 != status)
18234 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018235 return status;
18236 }
18237
18238 /*Retrieve halHandle*/
18239 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18240
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018241 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18242 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18243 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018244 /* Delete the PMKID CSR cache */
18245 if (eHAL_STATUS_SUCCESS !=
18246 sme_RoamDelPMKIDfromCache(halHandle,
18247 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18248 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18249 MAC_ADDR_ARRAY(pmksa->bssid));
18250 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018251 }
18252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018253 EXIT();
18254 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018255}
18256
Wilson Yang6507c4e2013-10-01 20:11:19 -070018257
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018258static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18259 struct cfg80211_pmksa *pmksa)
18260{
18261 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018262
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018263 vos_ssr_protect(__func__);
18264 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18265 vos_ssr_unprotect(__func__);
18266
18267 return ret;
18268
18269}
18270
18271static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018272{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018273 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18274 tHalHandle halHandle;
18275 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018276 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018277
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018278 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018279
18280 /* Validate pAdapter */
18281 if (NULL == pAdapter)
18282 {
18283 hddLog(VOS_TRACE_LEVEL_ERROR,
18284 "%s: Invalid Adapter" ,__func__);
18285 return -EINVAL;
18286 }
18287
18288 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18289 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018290 if (0 != status)
18291 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018292 return status;
18293 }
18294
18295 /*Retrieve halHandle*/
18296 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18297
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018298 /* Flush the PMKID cache in CSR */
18299 if (eHAL_STATUS_SUCCESS !=
18300 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18302 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018303 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018304 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018305 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018306}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018307
18308static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18309{
18310 int ret;
18311
18312 vos_ssr_protect(__func__);
18313 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18314 vos_ssr_unprotect(__func__);
18315
18316 return ret;
18317}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018318#endif
18319
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018320#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018321static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18322 struct net_device *dev,
18323 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018324{
18325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18326 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018327 hdd_context_t *pHddCtx;
18328 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018330 ENTER();
18331
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018332 if (NULL == pAdapter)
18333 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018335 return -ENODEV;
18336 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18338 ret = wlan_hdd_validate_context(pHddCtx);
18339 if (0 != ret)
18340 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018341 return ret;
18342 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018343 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018344 if (NULL == pHddStaCtx)
18345 {
18346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18347 return -EINVAL;
18348 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018349
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018350 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18351 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18352 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018353 // Added for debug on reception of Re-assoc Req.
18354 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18355 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018356 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018357 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018358 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018359 }
18360
18361#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018362 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018363 ftie->ie_len);
18364#endif
18365
18366 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018367 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18368 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018369 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018370
18371 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018372 return 0;
18373}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018374
18375static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18376 struct net_device *dev,
18377 struct cfg80211_update_ft_ies_params *ftie)
18378{
18379 int ret;
18380
18381 vos_ssr_protect(__func__);
18382 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18383 vos_ssr_unprotect(__func__);
18384
18385 return ret;
18386}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018387#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018388
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018389#ifdef FEATURE_WLAN_SCAN_PNO
18390
18391void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18392 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18393{
18394 int ret;
18395 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18396 hdd_context_t *pHddCtx;
18397
Nirav Shah80830bf2013-12-31 16:35:12 +053018398 ENTER();
18399
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018400 if (NULL == pAdapter)
18401 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018403 "%s: HDD adapter is Null", __func__);
18404 return ;
18405 }
18406
18407 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18408 if (NULL == pHddCtx)
18409 {
18410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18411 "%s: HDD context is Null!!!", __func__);
18412 return ;
18413 }
18414
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018415 spin_lock(&pHddCtx->schedScan_lock);
18416 if (TRUE == pHddCtx->isWiphySuspended)
18417 {
18418 pHddCtx->isSchedScanUpdatePending = TRUE;
18419 spin_unlock(&pHddCtx->schedScan_lock);
18420 hddLog(VOS_TRACE_LEVEL_INFO,
18421 "%s: Update cfg80211 scan database after it resume", __func__);
18422 return ;
18423 }
18424 spin_unlock(&pHddCtx->schedScan_lock);
18425
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018426 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18427
18428 if (0 > ret)
18429 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018430 else
18431 {
18432 /* Acquire wakelock to handle the case where APP's tries to suspend
18433 * immediatly after the driver gets connect request(i.e after pno)
18434 * from supplicant, this result in app's is suspending and not able
18435 * to process the connect request to AP */
18436 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18437 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018438 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18440 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018441}
18442
18443/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018444 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018445 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018446 */
18447static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18448{
18449 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18450 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018451 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18453 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018454
18455 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18456 {
18457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18458 "%s: PNO is allowed only in STA interface", __func__);
18459 return eHAL_STATUS_FAILURE;
18460 }
18461
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018462 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18463
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018464 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018465 * active sessions. PNO is allowed only in case when sap session
18466 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018467 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018468 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18469 {
18470 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018471 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018472
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018473 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18474 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18475 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18476 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018477 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18478 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018479 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018480 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018481 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018482 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018483 }
18484 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18485 pAdapterNode = pNext;
18486 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018487 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018488}
18489
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018490void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18491{
18492 hdd_adapter_t *pAdapter = callbackContext;
18493 hdd_context_t *pHddCtx;
18494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018495 ENTER();
18496
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018497 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18498 {
18499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18500 FL("Invalid adapter or adapter has invalid magic"));
18501 return;
18502 }
18503
18504 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18505 if (0 != wlan_hdd_validate_context(pHddCtx))
18506 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018507 return;
18508 }
18509
c_hpothub53c45d2014-08-18 16:53:14 +053018510 if (VOS_STATUS_SUCCESS != status)
18511 {
18512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018513 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018514 pHddCtx->isPnoEnable = FALSE;
18515 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018516
18517 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18518 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018519 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018520}
18521
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18523 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18524/**
18525 * hdd_config_sched_scan_plan() - configures the sched scan plans
18526 * from the framework.
18527 * @pno_req: pointer to PNO scan request
18528 * @request: pointer to scan request from framework
18529 *
18530 * Return: None
18531 */
18532static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18533 struct cfg80211_sched_scan_request *request,
18534 hdd_context_t *hdd_ctx)
18535{
18536 v_U32_t i = 0;
18537
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018538 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018539 for (i = 0; i < request->n_scan_plans; i++)
18540 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018541 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18542 request->scan_plans[i].iterations;
18543 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18544 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018545 }
18546}
18547#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018548static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018549 struct cfg80211_sched_scan_request *request,
18550 hdd_context_t *hdd_ctx)
18551{
18552 v_U32_t i, temp_int;
18553 /* Driver gets only one time interval which is hardcoded in
18554 * supplicant for 10000ms. Taking power consumption into account 6
18555 * timers will be used, Timervalue is increased exponentially
18556 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18557 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18558 * If it is set to 0 only one timer will be used and PNO scan cycle
18559 * will be repeated after each interval specified by supplicant
18560 * till PNO is disabled.
18561 */
18562 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018563 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018564 HDD_PNO_SCAN_TIMERS_SET_ONE;
18565 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018566 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018567 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18568
18569 temp_int = (request->interval)/1000;
18570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18571 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18572 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018573 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018574 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018575 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018576 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018577 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018578 temp_int *= 2;
18579 }
18580 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018581 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018582}
18583#endif
18584
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018585/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018586 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18587 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018588 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018589static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018590 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18591{
18592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018593 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018594 hdd_context_t *pHddCtx;
18595 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018596 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018597 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18598 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018599 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18600 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018601 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018602 hdd_config_t *pConfig = NULL;
18603 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018604
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018605 ENTER();
18606
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018607 if (NULL == pAdapter)
18608 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018610 "%s: HDD adapter is Null", __func__);
18611 return -ENODEV;
18612 }
18613
18614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018615 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018616
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018617 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018618 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018619 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018620 }
18621
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018622 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018623 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18624 if (NULL == hHal)
18625 {
18626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18627 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018628 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018629 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018630 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18631 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18632 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018633 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018634 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018635 {
18636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18637 "%s: aborting the existing scan is unsuccessfull", __func__);
18638 return -EBUSY;
18639 }
18640
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018641 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018642 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018644 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018645 return -EBUSY;
18646 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018647
c_hpothu37f21312014-04-09 21:49:54 +053018648 if (TRUE == pHddCtx->isPnoEnable)
18649 {
18650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18651 FL("already PNO is enabled"));
18652 return -EBUSY;
18653 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018654
18655 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18656 {
18657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18658 "%s: abort ROC failed ", __func__);
18659 return -EBUSY;
18660 }
18661
c_hpothu37f21312014-04-09 21:49:54 +053018662 pHddCtx->isPnoEnable = TRUE;
18663
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018664 pnoRequest.enable = 1; /*Enable PNO */
18665 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018666
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018667 if (( !pnoRequest.ucNetworksCount ) ||
18668 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018669 {
18670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018671 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018672 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018673 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018674 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018675 goto error;
18676 }
18677
18678 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18679 {
18680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018681 "%s: Incorrect number of channels %d",
18682 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018683 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018684 goto error;
18685 }
18686
18687 /* Framework provides one set of channels(all)
18688 * common for all saved profile */
18689 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18690 channels_allowed, &num_channels_allowed))
18691 {
18692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18693 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018694 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018695 goto error;
18696 }
18697 /* Checking each channel against allowed channel list */
18698 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018699 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018700 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018701 char chList [(request->n_channels*5)+1];
18702 int len;
18703 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018704 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018705 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018706 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018707 if (request->channels[i]->hw_value == channels_allowed[indx])
18708 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018709 if ((!pConfig->enableDFSPnoChnlScan) &&
18710 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18711 {
18712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18713 "%s : Dropping DFS channel : %d",
18714 __func__,channels_allowed[indx]);
18715 num_ignore_dfs_ch++;
18716 break;
18717 }
18718
Nirav Shah80830bf2013-12-31 16:35:12 +053018719 valid_ch[num_ch++] = request->channels[i]->hw_value;
18720 len += snprintf(chList+len, 5, "%d ",
18721 request->channels[i]->hw_value);
18722 break ;
18723 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018724 }
18725 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018726 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018727
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018728 /*If all channels are DFS and dropped, then ignore the PNO request*/
18729 if (num_ignore_dfs_ch == request->n_channels)
18730 {
18731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18732 "%s : All requested channels are DFS channels", __func__);
18733 ret = -EINVAL;
18734 goto error;
18735 }
18736 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018737
18738 pnoRequest.aNetworks =
18739 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18740 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018741 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018742 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18743 FL("failed to allocate memory aNetworks %u"),
18744 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18745 goto error;
18746 }
18747 vos_mem_zero(pnoRequest.aNetworks,
18748 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18749
18750 /* Filling per profile params */
18751 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18752 {
18753 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018754 request->match_sets[i].ssid.ssid_len;
18755
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018756 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18757 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018758 {
18759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018760 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018761 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018762 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018763 goto error;
18764 }
18765
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018766 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018767 request->match_sets[i].ssid.ssid,
18768 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18770 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018771 i, pnoRequest.aNetworks[i].ssId.ssId);
18772 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18773 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18774 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018775
18776 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018777 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18778 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018779
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018780 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018781 }
18782
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018783 for (i = 0; i < request->n_ssids; i++)
18784 {
18785 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018786 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018787 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018788 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018789 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018790 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018791 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018792 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018793 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018794 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018795 break;
18796 }
18797 j++;
18798 }
18799 }
18800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18801 "Number of hidden networks being Configured = %d",
18802 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018804 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018805
18806 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18807 if (pnoRequest.p24GProbeTemplate == NULL)
18808 {
18809 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18810 FL("failed to allocate memory p24GProbeTemplate %u"),
18811 SIR_PNO_MAX_PB_REQ_SIZE);
18812 goto error;
18813 }
18814
18815 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18816 if (pnoRequest.p5GProbeTemplate == NULL)
18817 {
18818 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18819 FL("failed to allocate memory p5GProbeTemplate %u"),
18820 SIR_PNO_MAX_PB_REQ_SIZE);
18821 goto error;
18822 }
18823
18824 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18825 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18826
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018827 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18828 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018829 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018830 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18831 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18832 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018833
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018834 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18835 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18836 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018837 }
18838
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018839 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018840
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018841 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018842
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018843 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018844 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18845 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018846 pAdapter->pno_req_status = 0;
18847
Nirav Shah80830bf2013-12-31 16:35:12 +053018848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18849 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018850 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18851 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018852
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018853 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018854 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018855 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18856 if (eHAL_STATUS_SUCCESS != status)
18857 {
18858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018859 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018860 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018861 goto error;
18862 }
18863
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018864 ret = wait_for_completion_timeout(
18865 &pAdapter->pno_comp_var,
18866 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18867 if (0 >= ret)
18868 {
18869 // Did not receive the response for PNO enable in time.
18870 // Assuming the PNO enable was success.
18871 // Returning error from here, because we timeout, results
18872 // in side effect of Wifi (Wifi Setting) not to work.
18873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18874 FL("Timed out waiting for PNO to be Enabled"));
18875 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018876 }
18877
18878 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018879 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018880
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018881error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18883 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018884 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018885 if (pnoRequest.aNetworks)
18886 vos_mem_free(pnoRequest.aNetworks);
18887 if (pnoRequest.p24GProbeTemplate)
18888 vos_mem_free(pnoRequest.p24GProbeTemplate);
18889 if (pnoRequest.p5GProbeTemplate)
18890 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018891
18892 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018893 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018894}
18895
18896/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018897 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18898 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018899 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018900static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18901 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18902{
18903 int ret;
18904
18905 vos_ssr_protect(__func__);
18906 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18907 vos_ssr_unprotect(__func__);
18908
18909 return ret;
18910}
18911
18912/*
18913 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18914 * Function to disable PNO
18915 */
18916static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018917 struct net_device *dev)
18918{
18919 eHalStatus status = eHAL_STATUS_FAILURE;
18920 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18921 hdd_context_t *pHddCtx;
18922 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018923 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018924 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018925
18926 ENTER();
18927
18928 if (NULL == pAdapter)
18929 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018931 "%s: HDD adapter is Null", __func__);
18932 return -ENODEV;
18933 }
18934
18935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018936
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018937 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018938 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018940 "%s: HDD context is Null", __func__);
18941 return -ENODEV;
18942 }
18943
18944 /* The return 0 is intentional when isLogpInProgress and
18945 * isLoadUnloadInProgress. We did observe a crash due to a return of
18946 * failure in sched_scan_stop , especially for a case where the unload
18947 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18948 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18949 * success. If it returns a failure , then its next invocation due to the
18950 * clean up of the second interface will have the dev pointer corresponding
18951 * to the first one leading to a crash.
18952 */
18953 if (pHddCtx->isLogpInProgress)
18954 {
18955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18956 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053018957 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018958 return ret;
18959 }
18960
Mihir Shete18156292014-03-11 15:38:30 +053018961 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018962 {
18963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18964 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
18965 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018966 }
18967
18968 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18969 if (NULL == hHal)
18970 {
18971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18972 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018973 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018974 }
18975
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018976 pnoRequest.enable = 0; /* Disable PNO */
18977 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018978
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018979 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18980 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
18981 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018982
18983 INIT_COMPLETION(pAdapter->pno_comp_var);
18984 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18985 pnoRequest.callbackContext = pAdapter;
18986 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018987 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018988 pAdapter->sessionId,
18989 NULL, pAdapter);
18990 if (eHAL_STATUS_SUCCESS != status)
18991 {
18992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18993 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018994 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018995 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018996 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053018997 ret = wait_for_completion_timeout(
18998 &pAdapter->pno_comp_var,
18999 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19000 if (0 >= ret)
19001 {
19002 // Did not receive the response for PNO disable in time.
19003 // Assuming the PNO disable was success.
19004 // Returning error from here, because we timeout, results
19005 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019007 FL("Timed out waiting for PNO to be disabled"));
19008 ret = 0;
19009 }
19010
19011 ret = pAdapter->pno_req_status;
19012 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019013
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019014error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019016 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019017
19018 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019019 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019020}
19021
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019022/*
19023 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19024 * NL interface to disable PNO
19025 */
19026static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19027 struct net_device *dev)
19028{
19029 int ret;
19030
19031 vos_ssr_protect(__func__);
19032 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19033 vos_ssr_unprotect(__func__);
19034
19035 return ret;
19036}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019037#endif /*FEATURE_WLAN_SCAN_PNO*/
19038
19039
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019040#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019041#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019042static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19043 struct net_device *dev,
19044 u8 *peer, u8 action_code,
19045 u8 dialog_token,
19046 u16 status_code, u32 peer_capability,
19047 const u8 *buf, size_t len)
19048#else /* TDLS_MGMT_VERSION2 */
19049#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19050static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19051 struct net_device *dev,
19052 const u8 *peer, u8 action_code,
19053 u8 dialog_token, u16 status_code,
19054 u32 peer_capability, bool initiator,
19055 const u8 *buf, size_t len)
19056#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19057static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19058 struct net_device *dev,
19059 const u8 *peer, u8 action_code,
19060 u8 dialog_token, u16 status_code,
19061 u32 peer_capability, const u8 *buf,
19062 size_t len)
19063#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19064static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19065 struct net_device *dev,
19066 u8 *peer, u8 action_code,
19067 u8 dialog_token,
19068 u16 status_code, u32 peer_capability,
19069 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019070#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019071static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19072 struct net_device *dev,
19073 u8 *peer, u8 action_code,
19074 u8 dialog_token,
19075 u16 status_code, const u8 *buf,
19076 size_t len)
19077#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019078#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019079{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019080 hdd_adapter_t *pAdapter;
19081 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019082 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019083 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019084 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019085 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019086 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019087 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019088#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019089 u32 peer_capability = 0;
19090#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019091 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019092 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019093 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019094
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019095 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19096 if (NULL == pAdapter)
19097 {
19098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19099 "%s: Adapter is NULL",__func__);
19100 return -EINVAL;
19101 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019102 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19103 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19104 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019105
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019106 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019107 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019110 "Invalid arguments");
19111 return -EINVAL;
19112 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019113
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019114 if (pHddCtx->isLogpInProgress)
19115 {
19116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19117 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019118 wlan_hdd_tdls_set_link_status(pAdapter,
19119 peer,
19120 eTDLS_LINK_IDLE,
19121 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019122 return -EBUSY;
19123 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019124
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019125 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19126 {
19127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19128 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19129 return -EAGAIN;
19130 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019131
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019132 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19133 if (!pHddTdlsCtx) {
19134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19135 "%s: pHddTdlsCtx not valid.", __func__);
19136 }
19137
Hoonki Lee27511902013-03-14 18:19:06 -070019138 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019139 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019141 "%s: TDLS mode is disabled OR not enabled in FW."
19142 MAC_ADDRESS_STR " action %d declined.",
19143 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019144 return -ENOTSUPP;
19145 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019146
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019147 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19148
19149 if( NULL == pHddStaCtx )
19150 {
19151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19152 "%s: HDD station context NULL ",__func__);
19153 return -EINVAL;
19154 }
19155
19156 /* STA should be connected and authenticated
19157 * before sending any TDLS frames
19158 */
19159 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19160 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19161 {
19162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19163 "STA is not connected or unauthenticated. "
19164 "connState %u, uIsAuthenticated %u",
19165 pHddStaCtx->conn_info.connState,
19166 pHddStaCtx->conn_info.uIsAuthenticated);
19167 return -EAGAIN;
19168 }
19169
Hoonki Lee27511902013-03-14 18:19:06 -070019170 /* other than teardown frame, other mgmt frames are not sent if disabled */
19171 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19172 {
19173 /* if tdls_mode is disabled to respond to peer's request */
19174 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19175 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019177 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019178 " TDLS mode is disabled. action %d declined.",
19179 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019180
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019181 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019182 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019183
19184 if (vos_max_concurrent_connections_reached())
19185 {
19186 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19187 return -EINVAL;
19188 }
Hoonki Lee27511902013-03-14 18:19:06 -070019189 }
19190
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019191 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19192 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019193 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019194 {
19195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019196 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019197 " TDLS setup is ongoing. action %d declined.",
19198 __func__, MAC_ADDR_ARRAY(peer), action_code);
19199 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019200 }
19201 }
19202
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019203 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19204 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019205 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019206 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19207 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019208 {
19209 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19210 we return error code at 'add_station()'. Hence we have this
19211 check again in addtion to add_station().
19212 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019213 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019214 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19216 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019217 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19218 __func__, MAC_ADDR_ARRAY(peer), action_code,
19219 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019220 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019221 }
19222 else
19223 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019224 /* maximum reached. tweak to send error code to peer and return
19225 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019226 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19228 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019229 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19230 __func__, MAC_ADDR_ARRAY(peer), status_code,
19231 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019232 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019233 /* fall through to send setup resp with failure status
19234 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019235 }
19236 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019237 else
19238 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019239 mutex_lock(&pHddCtx->tdls_lock);
19240 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019241 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019242 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019243 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019245 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19246 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019247 return -EPERM;
19248 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019249 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019250 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019251 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019252
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019254 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019255 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19256 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019257
Hoonki Leea34dd892013-02-05 22:56:02 -080019258 /*Except teardown responder will not be used so just make 0*/
19259 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019260 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019261 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019262
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019263 mutex_lock(&pHddCtx->tdls_lock);
19264 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019265
19266 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19267 responder = pTdlsPeer->is_responder;
19268 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019269 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019271 "%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 -070019272 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19273 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019274 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019275 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019276 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019277 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019278 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019279
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019280 /* Discard TDLS setup if peer is removed by user app */
19281 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19282 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19283 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19284 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19285
19286 mutex_lock(&pHddCtx->tdls_lock);
19287 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19288 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19289 mutex_unlock(&pHddCtx->tdls_lock);
19290 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19291 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19292 MAC_ADDR_ARRAY(peer), action_code);
19293 return -EINVAL;
19294 }
19295 mutex_unlock(&pHddCtx->tdls_lock);
19296 }
19297
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019298 /* For explicit trigger of DIS_REQ come out of BMPS for
19299 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019300 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019301 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019302 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19303 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019304 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019305 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019307 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19308 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019309 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19310 if (status != VOS_STATUS_SUCCESS) {
19311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019312 } else {
19313 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019314 }
Hoonki Lee14621352013-04-16 17:51:19 -070019315 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019316 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019317 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19319 }
19320 }
Hoonki Lee14621352013-04-16 17:51:19 -070019321 }
19322
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019323 /* make sure doesn't call send_mgmt() while it is pending */
19324 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19325 {
19326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019327 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019328 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019329 ret = -EBUSY;
19330 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019331 }
19332
19333 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019334 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19335
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019336 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19337 pAdapter->sessionId, peer, action_code, dialog_token,
19338 status_code, peer_capability, (tANI_U8 *)buf, len,
19339 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019340
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019341 if (VOS_STATUS_SUCCESS != status)
19342 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19344 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019345 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019346 ret = -EINVAL;
19347 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019348 }
19349
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19351 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19352 WAIT_TIME_TDLS_MGMT);
19353
Hoonki Leed37cbb32013-04-20 00:31:14 -070019354 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19355 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19356
19357 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019358 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019360 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019361 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019362 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019363
19364 if (pHddCtx->isLogpInProgress)
19365 {
19366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19367 "%s: LOGP in Progress. Ignore!!!", __func__);
19368 return -EAGAIN;
19369 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019370 if (rc <= 0)
19371 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19372 WLAN_LOG_INDICATOR_HOST_DRIVER,
19373 WLAN_LOG_REASON_HDD_TIME_OUT,
19374 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019375
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019376 ret = -EINVAL;
19377 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019378 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019379 else
19380 {
19381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19382 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19383 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19384 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019385
Gopichand Nakkala05922802013-03-14 12:23:19 -070019386 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019387 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019388 ret = max_sta_failed;
19389 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019390 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019391
Hoonki Leea34dd892013-02-05 22:56:02 -080019392 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19393 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019394 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19396 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019397 }
19398 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19399 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019400 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19402 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019403 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019404
19405 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019406
19407tx_failed:
19408 /* add_station will be called before sending TDLS_SETUP_REQ and
19409 * TDLS_SETUP_RSP and as part of add_station driver will enable
19410 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19411 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19412 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19413 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19414 */
19415
19416 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19417 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19418 wlan_hdd_tdls_check_bmps(pAdapter);
19419 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019420}
19421
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019422#if TDLS_MGMT_VERSION2
19423static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19424 u8 *peer, u8 action_code, u8 dialog_token,
19425 u16 status_code, u32 peer_capability,
19426 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019427#else /* TDLS_MGMT_VERSION2 */
19428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19429static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19430 struct net_device *dev,
19431 const u8 *peer, u8 action_code,
19432 u8 dialog_token, u16 status_code,
19433 u32 peer_capability, bool initiator,
19434 const u8 *buf, size_t len)
19435#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19436static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19437 struct net_device *dev,
19438 const u8 *peer, u8 action_code,
19439 u8 dialog_token, u16 status_code,
19440 u32 peer_capability, const u8 *buf,
19441 size_t len)
19442#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19443static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19444 struct net_device *dev,
19445 u8 *peer, u8 action_code,
19446 u8 dialog_token,
19447 u16 status_code, u32 peer_capability,
19448 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019449#else
19450static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19451 u8 *peer, u8 action_code, u8 dialog_token,
19452 u16 status_code, const u8 *buf, size_t len)
19453#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019454#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019455{
19456 int ret;
19457
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019458 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019459#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019460 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19461 dialog_token, status_code,
19462 peer_capability, buf, len);
19463#else /* TDLS_MGMT_VERSION2 */
19464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19465 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19466 dialog_token, status_code,
19467 peer_capability, initiator,
19468 buf, len);
19469#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19470 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19471 dialog_token, status_code,
19472 peer_capability, buf, len);
19473#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19474 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19475 dialog_token, status_code,
19476 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019477#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019478 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19479 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019480#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019481#endif
19482 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019483
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019484 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019485}
Atul Mittal115287b2014-07-08 13:26:33 +053019486
19487int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19489 const u8 *peer,
19490#else
Atul Mittal115287b2014-07-08 13:26:33 +053019491 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019492#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019493 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019494 cfg80211_exttdls_callback callback)
19495{
19496
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019497 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019498 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19501 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19502 __func__, MAC_ADDR_ARRAY(peer));
19503
19504 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19505 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19506
19507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019508 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19509 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19510 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019511 return -ENOTSUPP;
19512 }
19513
19514 /* To cater the requirement of establishing the TDLS link
19515 * irrespective of the data traffic , get an entry of TDLS peer.
19516 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019517 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019518 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19519 if (pTdlsPeer == NULL) {
19520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19521 "%s: peer " MAC_ADDRESS_STR " not existing",
19522 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019523 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019524 return -EINVAL;
19525 }
19526
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019527 /* check FW TDLS Off Channel capability */
19528 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019529 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019530 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019531 {
19532 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19533 pTdlsPeer->peerParams.global_operating_class =
19534 tdls_peer_params->global_operating_class;
19535 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19536 pTdlsPeer->peerParams.min_bandwidth_kbps =
19537 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019538 /* check configured channel is valid, non dfs and
19539 * not current operating channel */
19540 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19541 tdls_peer_params->channel)) &&
19542 (pHddStaCtx) &&
19543 (tdls_peer_params->channel !=
19544 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019545 {
19546 pTdlsPeer->isOffChannelConfigured = TRUE;
19547 }
19548 else
19549 {
19550 pTdlsPeer->isOffChannelConfigured = FALSE;
19551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19552 "%s: Configured Tdls Off Channel is not valid", __func__);
19553
19554 }
19555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019556 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19557 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019558 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019559 pTdlsPeer->isOffChannelConfigured,
19560 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019561 }
19562 else
19563 {
19564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019565 "%s: TDLS off channel FW capability %d, "
19566 "host capab %d or Invalid TDLS Peer Params", __func__,
19567 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19568 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019569 }
19570
Atul Mittal115287b2014-07-08 13:26:33 +053019571 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19572
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019573 mutex_unlock(&pHddCtx->tdls_lock);
19574
Atul Mittal115287b2014-07-08 13:26:33 +053019575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19576 " %s TDLS Add Force Peer Failed",
19577 __func__);
19578 return -EINVAL;
19579 }
19580 /*EXT TDLS*/
19581
19582 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019583 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19585 " %s TDLS set callback Failed",
19586 __func__);
19587 return -EINVAL;
19588 }
19589
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019590 mutex_unlock(&pHddCtx->tdls_lock);
19591
Atul Mittal115287b2014-07-08 13:26:33 +053019592 return(0);
19593
19594}
19595
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019596int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19598 const u8 *peer
19599#else
19600 u8 *peer
19601#endif
19602)
Atul Mittal115287b2014-07-08 13:26:33 +053019603{
19604
19605 hddTdlsPeer_t *pTdlsPeer;
19606 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019607
Atul Mittal115287b2014-07-08 13:26:33 +053019608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19609 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19610 __func__, MAC_ADDR_ARRAY(peer));
19611
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019612 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19614 return -EINVAL;
19615 }
19616
Atul Mittal115287b2014-07-08 13:26:33 +053019617 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19618 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19619
19620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019621 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19622 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19623 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019624 return -ENOTSUPP;
19625 }
19626
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019627 mutex_lock(&pHddCtx->tdls_lock);
19628 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019629
19630 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019631 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019633 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019634 __func__, MAC_ADDR_ARRAY(peer));
19635 return -EINVAL;
19636 }
19637 else {
19638 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19639 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019640 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19641 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019642 /* if channel switch is configured, reset
19643 the channel for this peer */
19644 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19645 {
19646 pTdlsPeer->peerParams.channel = 0;
19647 pTdlsPeer->isOffChannelConfigured = FALSE;
19648 }
Atul Mittal115287b2014-07-08 13:26:33 +053019649 }
19650
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019651 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019652 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019654 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019655 }
Atul Mittal115287b2014-07-08 13:26:33 +053019656
19657 /*EXT TDLS*/
19658
19659 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019660 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19662 " %s TDLS set callback Failed",
19663 __func__);
19664 return -EINVAL;
19665 }
Atul Mittal115287b2014-07-08 13:26:33 +053019666
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019667 mutex_unlock(&pHddCtx->tdls_lock);
19668
19669 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019670}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019671static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19673 const u8 *peer,
19674#else
19675 u8 *peer,
19676#endif
19677 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019678{
19679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019681 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019682 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019684 ENTER();
19685
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019686 if (!pAdapter) {
19687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19688 return -EINVAL;
19689 }
19690
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19692 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19693 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019694 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019695 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019697 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019698 return -EINVAL;
19699 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019700
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019701 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019702 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019703 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019704 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019705 }
19706
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019707
19708 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019709 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019710 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019712 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19713 "Cannot process TDLS commands",
19714 pHddCtx->cfg_ini->fEnableTDLSSupport,
19715 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019716 return -ENOTSUPP;
19717 }
19718
19719 switch (oper) {
19720 case NL80211_TDLS_ENABLE_LINK:
19721 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019722 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019723 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019724 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19725 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019726 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019727 tANI_U16 numCurrTdlsPeers = 0;
19728 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019729 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019730 tSirMacAddr peerMac;
19731 int channel;
19732 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019733
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19735 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19736 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019737
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019738 mutex_lock(&pHddCtx->tdls_lock);
19739 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019740 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019741 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019742 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19744 " (oper %d) not exsting. ignored",
19745 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19746 return -EINVAL;
19747 }
19748
19749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19750 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19751 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19752 "NL80211_TDLS_ENABLE_LINK");
19753
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019754 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19755 {
19756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19757 MAC_ADDRESS_STR " failed",
19758 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019759 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019760 return -EINVAL;
19761 }
19762
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019763 /* before starting tdls connection, set tdls
19764 * off channel established status to default value */
19765 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019766
19767 mutex_unlock(&pHddCtx->tdls_lock);
19768
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019769 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019770 /* TDLS Off Channel, Disable tdls channel switch,
19771 when there are more than one tdls link */
19772 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019773 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019774 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019775 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019776 /* get connected peer and send disable tdls off chan */
19777 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019778 if ((connPeer) &&
19779 (connPeer->isOffChannelSupported == TRUE) &&
19780 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019781 {
19782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19783 "%s: More then one peer connected, Disable "
19784 "TDLS channel switch", __func__);
19785
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019786 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019787 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19788 channel = connPeer->peerParams.channel;
19789
19790 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019791
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019792 ret = sme_SendTdlsChanSwitchReq(
19793 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019794 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019795 peerMac,
19796 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019797 TDLS_OFF_CHANNEL_BW_OFFSET,
19798 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019799 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019800 hddLog(VOS_TRACE_LEVEL_ERROR,
19801 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019802 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019803 }
19804 else
19805 {
19806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19807 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019808 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019809 "isOffChannelConfigured %d",
19810 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019811 (connPeer ? (connPeer->isOffChannelSupported)
19812 : -1),
19813 (connPeer ? (connPeer->isOffChannelConfigured)
19814 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019815 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019816 }
19817 }
19818
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019819 mutex_lock(&pHddCtx->tdls_lock);
19820 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19821 if ( NULL == pTdlsPeer ) {
19822 mutex_unlock(&pHddCtx->tdls_lock);
19823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19824 "%s: " MAC_ADDRESS_STR
19825 " (oper %d) peer got freed in other context. ignored",
19826 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19827 return -EINVAL;
19828 }
19829 peer_status = pTdlsPeer->link_status;
19830 mutex_unlock(&pHddCtx->tdls_lock);
19831
19832 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019833 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019834 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019835
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019836 if (0 != wlan_hdd_tdls_get_link_establish_params(
19837 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019839 return -EINVAL;
19840 }
19841 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019842
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019843 ret = sme_SendTdlsLinkEstablishParams(
19844 WLAN_HDD_GET_HAL_CTX(pAdapter),
19845 pAdapter->sessionId, peer,
19846 &tdlsLinkEstablishParams);
19847 if (ret != VOS_STATUS_SUCCESS) {
19848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19849 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019850 /* Send TDLS peer UAPSD capabilities to the firmware and
19851 * register with the TL on after the response for this operation
19852 * is received .
19853 */
19854 ret = wait_for_completion_interruptible_timeout(
19855 &pAdapter->tdls_link_establish_req_comp,
19856 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019857
19858 mutex_lock(&pHddCtx->tdls_lock);
19859 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19860 if ( NULL == pTdlsPeer ) {
19861 mutex_unlock(&pHddCtx->tdls_lock);
19862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19863 "%s %d: " MAC_ADDRESS_STR
19864 " (oper %d) peer got freed in other context. ignored",
19865 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19866 (int)oper);
19867 return -EINVAL;
19868 }
19869 peer_status = pTdlsPeer->link_status;
19870 mutex_unlock(&pHddCtx->tdls_lock);
19871
19872 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019873 {
19874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019875 FL("Link Establish Request Failed Status %ld"),
19876 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019877 return -EINVAL;
19878 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019879 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019880
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019881 mutex_lock(&pHddCtx->tdls_lock);
19882 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19883 if ( NULL == pTdlsPeer ) {
19884 mutex_unlock(&pHddCtx->tdls_lock);
19885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19886 "%s: " MAC_ADDRESS_STR
19887 " (oper %d) peer got freed in other context. ignored",
19888 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19889 return -EINVAL;
19890 }
19891
Atul Mittal115287b2014-07-08 13:26:33 +053019892 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19893 eTDLS_LINK_CONNECTED,
19894 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019895 staDesc.ucSTAId = pTdlsPeer->staId;
19896 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019897
19898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19899 "%s: tdlsLinkEstablishParams of peer "
19900 MAC_ADDRESS_STR "uapsdQueues: %d"
19901 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19902 "isResponder: %d peerstaId: %d",
19903 __func__,
19904 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19905 tdlsLinkEstablishParams.uapsdQueues,
19906 tdlsLinkEstablishParams.qos,
19907 tdlsLinkEstablishParams.maxSp,
19908 tdlsLinkEstablishParams.isBufSta,
19909 tdlsLinkEstablishParams.isOffChannelSupported,
19910 tdlsLinkEstablishParams.isResponder,
19911 pTdlsPeer->staId);
19912
19913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19914 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19915 __func__,
19916 staDesc.ucSTAId,
19917 staDesc.ucQosEnabled);
19918
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019919 ret = WLANTL_UpdateTdlsSTAClient(
19920 pHddCtx->pvosContext,
19921 &staDesc);
19922 if (ret != VOS_STATUS_SUCCESS) {
19923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19924 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019925
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019926 /* Mark TDLS client Authenticated .*/
19927 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19928 pTdlsPeer->staId,
19929 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019930 if (VOS_STATUS_SUCCESS == status)
19931 {
Hoonki Lee14621352013-04-16 17:51:19 -070019932 if (pTdlsPeer->is_responder == 0)
19933 {
19934 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019935 tdlsConnInfo_t *tdlsInfo;
19936
19937 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19938
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019939 if (!vos_timer_is_initialized(
19940 &pTdlsPeer->initiatorWaitTimeoutTimer))
19941 {
19942 /* Initialize initiator wait callback */
19943 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019944 &pTdlsPeer->initiatorWaitTimeoutTimer,
19945 VOS_TIMER_TYPE_SW,
19946 wlan_hdd_tdls_initiator_wait_cb,
19947 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019948 }
Hoonki Lee14621352013-04-16 17:51:19 -070019949 wlan_hdd_tdls_timer_restart(pAdapter,
19950 &pTdlsPeer->initiatorWaitTimeoutTimer,
19951 WAIT_TIME_TDLS_INITIATOR);
19952 /* suspend initiator TX until it receives direct packet from the
19953 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019954 ret = WLANTL_SuspendDataTx(
19955 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19956 &staId, NULL);
19957 if (ret != VOS_STATUS_SUCCESS) {
19958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
19959 }
Hoonki Lee14621352013-04-16 17:51:19 -070019960 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019961
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019962 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019963 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019964 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019965 suppChannelLen =
19966 tdlsLinkEstablishParams.supportedChannelsLen;
19967
19968 if ((suppChannelLen > 0) &&
19969 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
19970 {
19971 tANI_U8 suppPeerChannel = 0;
19972 int i = 0;
19973 for (i = 0U; i < suppChannelLen; i++)
19974 {
19975 suppPeerChannel =
19976 tdlsLinkEstablishParams.supportedChannels[i];
19977
19978 pTdlsPeer->isOffChannelSupported = FALSE;
19979 if (suppPeerChannel ==
19980 pTdlsPeer->peerParams.channel)
19981 {
19982 pTdlsPeer->isOffChannelSupported = TRUE;
19983 break;
19984 }
19985 }
19986 }
19987 else
19988 {
19989 pTdlsPeer->isOffChannelSupported = FALSE;
19990 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019991 }
19992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19993 "%s: TDLS channel switch request for channel "
19994 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019995 "%d isOffChannelSupported %d", __func__,
19996 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019997 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019998 suppChannelLen,
19999 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020000
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020001 /* TDLS Off Channel, Enable tdls channel switch,
20002 when their is only one tdls link and it supports */
20003 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20004 if ((numCurrTdlsPeers == 1) &&
20005 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20006 (TRUE == pTdlsPeer->isOffChannelConfigured))
20007 {
20008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20009 "%s: Send TDLS channel switch request for channel %d",
20010 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020011
20012 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020013 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20014 channel = pTdlsPeer->peerParams.channel;
20015
20016 mutex_unlock(&pHddCtx->tdls_lock);
20017
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020018 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20019 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020020 peerMac,
20021 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020022 TDLS_OFF_CHANNEL_BW_OFFSET,
20023 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020024 if (ret != VOS_STATUS_SUCCESS) {
20025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20026 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020027 }
20028 else
20029 {
20030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20031 "%s: TDLS channel switch request not sent"
20032 " numCurrTdlsPeers %d "
20033 "isOffChannelSupported %d "
20034 "isOffChannelConfigured %d",
20035 __func__, numCurrTdlsPeers,
20036 pTdlsPeer->isOffChannelSupported,
20037 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020038 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020039 }
20040
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020041 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020042 else
20043 mutex_unlock(&pHddCtx->tdls_lock);
20044
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020045 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020046
20047 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020048 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20049 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020050 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020051 int ac;
20052 uint8 ucAc[4] = { WLANTL_AC_VO,
20053 WLANTL_AC_VI,
20054 WLANTL_AC_BK,
20055 WLANTL_AC_BE };
20056 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20057 for(ac=0; ac < 4; ac++)
20058 {
20059 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20060 pTdlsPeer->staId, ucAc[ac],
20061 tlTid[ac], tlTid[ac], 0, 0,
20062 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020063 if (status != VOS_STATUS_SUCCESS) {
20064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20065 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020066 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020067 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020068 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020069
Bhargav Shah66896792015-10-01 18:17:37 +053020070 /* stop TCP delack timer if TDLS is enable */
20071 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20072 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020073 hdd_wlan_tdls_enable_link_event(peer,
20074 pTdlsPeer->isOffChannelSupported,
20075 pTdlsPeer->isOffChannelConfigured,
20076 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020077 }
20078 break;
20079 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020080 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020081 tANI_U16 numCurrTdlsPeers = 0;
20082 hddTdlsPeer_t *connPeer = NULL;
20083
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20085 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20086 __func__, MAC_ADDR_ARRAY(peer));
20087
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020088 mutex_lock(&pHddCtx->tdls_lock);
20089 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020090
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020091
Sunil Dutt41de4e22013-11-14 18:09:02 +053020092 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020093 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20095 " (oper %d) not exsting. ignored",
20096 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20097 return -EINVAL;
20098 }
20099
20100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20101 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20102 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20103 "NL80211_TDLS_DISABLE_LINK");
20104
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020105 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020106 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020107 long status;
20108
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020109 /* set tdls off channel status to false for this peer */
20110 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020111 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20112 eTDLS_LINK_TEARING,
20113 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20114 eTDLS_LINK_UNSPECIFIED:
20115 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020116 mutex_unlock(&pHddCtx->tdls_lock);
20117
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020118 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20119
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020120 status = sme_DeleteTdlsPeerSta(
20121 WLAN_HDD_GET_HAL_CTX(pAdapter),
20122 pAdapter->sessionId, peer );
20123 if (status != VOS_STATUS_SUCCESS) {
20124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20125 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020126
20127 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20128 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020129
20130 mutex_lock(&pHddCtx->tdls_lock);
20131 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20132 if ( NULL == pTdlsPeer ) {
20133 mutex_unlock(&pHddCtx->tdls_lock);
20134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20135 " peer was freed in other context",
20136 __func__, MAC_ADDR_ARRAY(peer));
20137 return -EINVAL;
20138 }
20139
Atul Mittal271a7652014-09-12 13:18:22 +053020140 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020141 eTDLS_LINK_IDLE,
20142 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020143 mutex_unlock(&pHddCtx->tdls_lock);
20144
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020145 if (status <= 0)
20146 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20148 "%s: Del station failed status %ld",
20149 __func__, status);
20150 return -EPERM;
20151 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020152
20153 /* TDLS Off Channel, Enable tdls channel switch,
20154 when their is only one tdls link and it supports */
20155 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20156 if (numCurrTdlsPeers == 1)
20157 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020158 tSirMacAddr peerMac;
20159 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020160
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020161 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020162 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020163
20164 if (connPeer == NULL) {
20165 mutex_unlock(&pHddCtx->tdls_lock);
20166 hddLog(VOS_TRACE_LEVEL_ERROR,
20167 "%s connPeer is NULL", __func__);
20168 return -EINVAL;
20169 }
20170
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020171 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20172 channel = connPeer->peerParams.channel;
20173
20174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20175 "%s: TDLS channel switch "
20176 "isOffChannelSupported %d "
20177 "isOffChannelConfigured %d "
20178 "isOffChannelEstablished %d",
20179 __func__,
20180 (connPeer ? connPeer->isOffChannelSupported : -1),
20181 (connPeer ? connPeer->isOffChannelConfigured : -1),
20182 (connPeer ? connPeer->isOffChannelEstablished : -1));
20183
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020184 if ((connPeer) &&
20185 (connPeer->isOffChannelSupported == TRUE) &&
20186 (connPeer->isOffChannelConfigured == TRUE))
20187 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020188 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020189 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020190 status = sme_SendTdlsChanSwitchReq(
20191 WLAN_HDD_GET_HAL_CTX(pAdapter),
20192 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020193 peerMac,
20194 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020195 TDLS_OFF_CHANNEL_BW_OFFSET,
20196 TDLS_CHANNEL_SWITCH_ENABLE);
20197 if (status != VOS_STATUS_SUCCESS) {
20198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20199 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020200 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020201 else
20202 mutex_unlock(&pHddCtx->tdls_lock);
20203 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020204 else
20205 {
20206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20207 "%s: TDLS channel switch request not sent "
20208 "numCurrTdlsPeers %d ",
20209 __func__, numCurrTdlsPeers);
20210 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020211 }
20212 else
20213 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020214 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20216 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020217 }
Bhargav Shah66896792015-10-01 18:17:37 +053020218 if (numCurrTdlsPeers == 0) {
20219 /* start TCP delack timer if TDLS is disable */
20220 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20221 hdd_manage_delack_timer(pHddCtx);
20222 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020223 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020224 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020225 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020226 {
Atul Mittal115287b2014-07-08 13:26:33 +053020227 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020228
Atul Mittal115287b2014-07-08 13:26:33 +053020229 if (0 != status)
20230 {
20231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020232 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020233 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020234 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020235 break;
20236 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020237 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020238 {
Atul Mittal115287b2014-07-08 13:26:33 +053020239 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20240 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020241 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020242 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020243
Atul Mittal115287b2014-07-08 13:26:33 +053020244 if (0 != status)
20245 {
20246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020247 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020248 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020249 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020250 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020251 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020252 case NL80211_TDLS_DISCOVERY_REQ:
20253 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020255 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020256 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020257 return -ENOTSUPP;
20258 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20260 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020261 return -ENOTSUPP;
20262 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020263
20264 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020265 return 0;
20266}
Chilam NG571c65a2013-01-19 12:27:36 +053020267
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020268static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020269#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20270 const u8 *peer,
20271#else
20272 u8 *peer,
20273#endif
20274 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020275{
20276 int ret;
20277
20278 vos_ssr_protect(__func__);
20279 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20280 vos_ssr_unprotect(__func__);
20281
20282 return ret;
20283}
20284
Chilam NG571c65a2013-01-19 12:27:36 +053020285int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20286 struct net_device *dev, u8 *peer)
20287{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020288 hddLog(VOS_TRACE_LEVEL_INFO,
20289 "tdls send discover req: "MAC_ADDRESS_STR,
20290 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020291#if TDLS_MGMT_VERSION2
20292 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20293 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20294#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20296 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20297 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20298#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20299 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20300 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20301#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20302 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20303 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20304#else
Chilam NG571c65a2013-01-19 12:27:36 +053020305 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20306 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020307#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020308#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020309}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020310#endif
20311
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020312#ifdef WLAN_FEATURE_GTK_OFFLOAD
20313/*
20314 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20315 * Callback rountine called upon receiving response for
20316 * get offload info
20317 */
20318void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20319 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20320{
20321
20322 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020323 tANI_U8 tempReplayCounter[8];
20324 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020325
20326 ENTER();
20327
20328 if (NULL == pAdapter)
20329 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020331 "%s: HDD adapter is Null", __func__);
20332 return ;
20333 }
20334
20335 if (NULL == pGtkOffloadGetInfoRsp)
20336 {
20337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20338 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20339 return ;
20340 }
20341
20342 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20343 {
20344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20345 "%s: wlan Failed to get replay counter value",
20346 __func__);
20347 return ;
20348 }
20349
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020350 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20351 /* Update replay counter */
20352 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20353 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20354
20355 {
20356 /* changing from little to big endian since supplicant
20357 * works on big endian format
20358 */
20359 int i;
20360 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20361
20362 for (i = 0; i < 8; i++)
20363 {
20364 tempReplayCounter[7-i] = (tANI_U8)p[i];
20365 }
20366 }
20367
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020368 /* Update replay counter to NL */
20369 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020370 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020371}
20372
20373/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020374 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020375 * This function is used to offload GTK rekeying job to the firmware.
20376 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020377int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020378 struct cfg80211_gtk_rekey_data *data)
20379{
20380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20381 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20382 hdd_station_ctx_t *pHddStaCtx;
20383 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020384 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020385 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020386 eHalStatus status = eHAL_STATUS_FAILURE;
20387
20388 ENTER();
20389
20390 if (NULL == pAdapter)
20391 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020393 "%s: HDD adapter is Null", __func__);
20394 return -ENODEV;
20395 }
20396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20398 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20399 pAdapter->sessionId, pAdapter->device_mode));
20400
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020401 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020402 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020403 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020404 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020405 }
20406
20407 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20408 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20409 if (NULL == hHal)
20410 {
20411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20412 "%s: HAL context is Null!!!", __func__);
20413 return -EAGAIN;
20414 }
20415
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020416 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20417 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20418 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20419 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020420 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020421 {
20422 /* changing from big to little endian since driver
20423 * works on little endian format
20424 */
20425 tANI_U8 *p =
20426 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20427 int i;
20428
20429 for (i = 0; i < 8; i++)
20430 {
20431 p[7-i] = data->replay_ctr[i];
20432 }
20433 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020434
20435 if (TRUE == pHddCtx->hdd_wlan_suspended)
20436 {
20437 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020438 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20439 sizeof (tSirGtkOffloadParams));
20440 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020441 pAdapter->sessionId);
20442
20443 if (eHAL_STATUS_SUCCESS != status)
20444 {
20445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20446 "%s: sme_SetGTKOffload failed, returned %d",
20447 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020448
20449 /* Need to clear any trace of key value in the memory.
20450 * Thus zero out the memory even though it is local
20451 * variable.
20452 */
20453 vos_mem_zero(&hddGtkOffloadReqParams,
20454 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020455 return status;
20456 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20458 "%s: sme_SetGTKOffload successfull", __func__);
20459 }
20460 else
20461 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20463 "%s: wlan not suspended GTKOffload request is stored",
20464 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020465 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020466
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020467 /* Need to clear any trace of key value in the memory.
20468 * Thus zero out the memory even though it is local
20469 * variable.
20470 */
20471 vos_mem_zero(&hddGtkOffloadReqParams,
20472 sizeof(hddGtkOffloadReqParams));
20473
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020474 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020475 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020476}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020477
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020478int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20479 struct cfg80211_gtk_rekey_data *data)
20480{
20481 int ret;
20482
20483 vos_ssr_protect(__func__);
20484 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20485 vos_ssr_unprotect(__func__);
20486
20487 return ret;
20488}
20489#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020490/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020491 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020492 * This function is used to set access control policy
20493 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020494static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20495 struct net_device *dev,
20496 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020497{
20498 int i;
20499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20500 hdd_hostapd_state_t *pHostapdState;
20501 tsap_Config_t *pConfig;
20502 v_CONTEXT_t pVosContext = NULL;
20503 hdd_context_t *pHddCtx;
20504 int status;
20505
20506 ENTER();
20507
20508 if (NULL == pAdapter)
20509 {
20510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20511 "%s: HDD adapter is Null", __func__);
20512 return -ENODEV;
20513 }
20514
20515 if (NULL == params)
20516 {
20517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20518 "%s: params is Null", __func__);
20519 return -EINVAL;
20520 }
20521
20522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20523 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020524 if (0 != status)
20525 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020526 return status;
20527 }
20528
20529 pVosContext = pHddCtx->pvosContext;
20530 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20531
20532 if (NULL == pHostapdState)
20533 {
20534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20535 "%s: pHostapdState is Null", __func__);
20536 return -EINVAL;
20537 }
20538
20539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20540 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020541 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20542 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20543 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020544
20545 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20546 {
20547 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20548
20549 /* default value */
20550 pConfig->num_accept_mac = 0;
20551 pConfig->num_deny_mac = 0;
20552
20553 /**
20554 * access control policy
20555 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20556 * listed in hostapd.deny file.
20557 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20558 * listed in hostapd.accept file.
20559 */
20560 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20561 {
20562 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20563 }
20564 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20565 {
20566 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20567 }
20568 else
20569 {
20570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20571 "%s:Acl Policy : %d is not supported",
20572 __func__, params->acl_policy);
20573 return -ENOTSUPP;
20574 }
20575
20576 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20577 {
20578 pConfig->num_accept_mac = params->n_acl_entries;
20579 for (i = 0; i < params->n_acl_entries; i++)
20580 {
20581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20582 "** Add ACL MAC entry %i in WhiletList :"
20583 MAC_ADDRESS_STR, i,
20584 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20585
20586 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20587 sizeof(qcmacaddr));
20588 }
20589 }
20590 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20591 {
20592 pConfig->num_deny_mac = params->n_acl_entries;
20593 for (i = 0; i < params->n_acl_entries; i++)
20594 {
20595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20596 "** Add ACL MAC entry %i in BlackList :"
20597 MAC_ADDRESS_STR, i,
20598 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20599
20600 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20601 sizeof(qcmacaddr));
20602 }
20603 }
20604
20605 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20606 {
20607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20608 "%s: SAP Set Mac Acl fail", __func__);
20609 return -EINVAL;
20610 }
20611 }
20612 else
20613 {
20614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020615 "%s: Invalid device_mode = %s (%d)",
20616 __func__, hdd_device_modetoString(pAdapter->device_mode),
20617 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020618 return -EINVAL;
20619 }
20620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020621 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020622 return 0;
20623}
20624
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020625static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20626 struct net_device *dev,
20627 const struct cfg80211_acl_data *params)
20628{
20629 int ret;
20630 vos_ssr_protect(__func__);
20631 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20632 vos_ssr_unprotect(__func__);
20633
20634 return ret;
20635}
20636
Leo Chang9056f462013-08-01 19:21:11 -070020637#ifdef WLAN_NL80211_TESTMODE
20638#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020639void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020640(
20641 void *pAdapter,
20642 void *indCont
20643)
20644{
Leo Changd9df8aa2013-09-26 13:32:26 -070020645 tSirLPHBInd *lphbInd;
20646 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020647 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020648
20649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020650 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020651
c_hpothu73f35e62014-04-18 13:40:08 +053020652 if (pAdapter == NULL)
20653 {
20654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20655 "%s: pAdapter is NULL\n",__func__);
20656 return;
20657 }
20658
Leo Chang9056f462013-08-01 19:21:11 -070020659 if (NULL == indCont)
20660 {
20661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020662 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020663 return;
20664 }
20665
c_hpothu73f35e62014-04-18 13:40:08 +053020666 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020667 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020668 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020669 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020670 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020671 GFP_ATOMIC);
20672 if (!skb)
20673 {
20674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20675 "LPHB timeout, NL buffer alloc fail");
20676 return;
20677 }
20678
Leo Changac3ba772013-10-07 09:47:04 -070020679 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020680 {
20681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20682 "WLAN_HDD_TM_ATTR_CMD put fail");
20683 goto nla_put_failure;
20684 }
Leo Changac3ba772013-10-07 09:47:04 -070020685 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020686 {
20687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20688 "WLAN_HDD_TM_ATTR_TYPE put fail");
20689 goto nla_put_failure;
20690 }
Leo Changac3ba772013-10-07 09:47:04 -070020691 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020692 sizeof(tSirLPHBInd), lphbInd))
20693 {
20694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20695 "WLAN_HDD_TM_ATTR_DATA put fail");
20696 goto nla_put_failure;
20697 }
Leo Chang9056f462013-08-01 19:21:11 -070020698 cfg80211_testmode_event(skb, GFP_ATOMIC);
20699 return;
20700
20701nla_put_failure:
20702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20703 "NLA Put fail");
20704 kfree_skb(skb);
20705
20706 return;
20707}
20708#endif /* FEATURE_WLAN_LPHB */
20709
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020710static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020711{
20712 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20713 int err = 0;
20714#ifdef FEATURE_WLAN_LPHB
20715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020716 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020717
20718 ENTER();
20719
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020720 err = wlan_hdd_validate_context(pHddCtx);
20721 if (0 != err)
20722 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020723 return err;
20724 }
Leo Chang9056f462013-08-01 19:21:11 -070020725#endif /* FEATURE_WLAN_LPHB */
20726
20727 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20728 if (err)
20729 {
20730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20731 "%s Testmode INV ATTR", __func__);
20732 return err;
20733 }
20734
20735 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20736 {
20737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20738 "%s Testmode INV CMD", __func__);
20739 return -EINVAL;
20740 }
20741
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20743 TRACE_CODE_HDD_CFG80211_TESTMODE,
20744 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020745 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20746 {
20747#ifdef FEATURE_WLAN_LPHB
20748 /* Low Power Heartbeat configuration request */
20749 case WLAN_HDD_TM_CMD_WLAN_HB:
20750 {
20751 int buf_len;
20752 void *buf;
20753 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020754 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020755
20756 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20757 {
20758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20759 "%s Testmode INV DATA", __func__);
20760 return -EINVAL;
20761 }
20762
20763 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20764 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020765
Manjeet Singh3c577442017-02-10 19:03:38 +053020766 if (buf_len > sizeof(*hb_params)) {
20767 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20768 buf_len);
20769 return -ERANGE;
20770 }
20771
Amar Singhal05852702014-02-04 14:40:00 -080020772 hb_params_temp =(tSirLPHBReq *)buf;
20773 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20774 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20775 return -EINVAL;
20776
Leo Chang9056f462013-08-01 19:21:11 -070020777 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20778 if (NULL == hb_params)
20779 {
20780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20781 "%s Request Buffer Alloc Fail", __func__);
20782 return -EINVAL;
20783 }
20784
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020785 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020786 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020787 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20788 hb_params,
20789 wlan_hdd_cfg80211_lphb_ind_handler);
20790 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020791 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20793 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020794 vos_mem_free(hb_params);
20795 }
Leo Chang9056f462013-08-01 19:21:11 -070020796 return 0;
20797 }
20798#endif /* FEATURE_WLAN_LPHB */
20799 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20801 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020802 return -EOPNOTSUPP;
20803 }
20804
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020805 EXIT();
20806 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020807}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020808
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020809static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20810#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20811 struct wireless_dev *wdev,
20812#endif
20813 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020814{
20815 int ret;
20816
20817 vos_ssr_protect(__func__);
20818 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20819 vos_ssr_unprotect(__func__);
20820
20821 return ret;
20822}
Leo Chang9056f462013-08-01 19:21:11 -070020823#endif /* CONFIG_NL80211_TESTMODE */
20824
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020825extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020826static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020827 struct net_device *dev,
20828 int idx, struct survey_info *survey)
20829{
20830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20831 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020832 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020833 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020834 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020835 v_S7_t snr,rssi;
20836 int status, i, j, filled = 0;
20837
20838 ENTER();
20839
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020840 if (NULL == pAdapter)
20841 {
20842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20843 "%s: HDD adapter is Null", __func__);
20844 return -ENODEV;
20845 }
20846
20847 if (NULL == wiphy)
20848 {
20849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20850 "%s: wiphy is Null", __func__);
20851 return -ENODEV;
20852 }
20853
20854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20855 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020856 if (0 != status)
20857 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020858 return status;
20859 }
20860
Mihir Sheted9072e02013-08-21 17:02:29 +053020861 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20862
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020863 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020864 0 != pAdapter->survey_idx ||
20865 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020866 {
20867 /* The survey dump ops when implemented completely is expected to
20868 * return a survey of all channels and the ops is called by the
20869 * kernel with incremental values of the argument 'idx' till it
20870 * returns -ENONET. But we can only support the survey for the
20871 * operating channel for now. survey_idx is used to track
20872 * that the ops is called only once and then return -ENONET for
20873 * the next iteration
20874 */
20875 pAdapter->survey_idx = 0;
20876 return -ENONET;
20877 }
20878
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020879 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20880 {
20881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20882 "%s: Roaming in progress, hence return ", __func__);
20883 return -ENONET;
20884 }
20885
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020886 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20887
20888 wlan_hdd_get_snr(pAdapter, &snr);
20889 wlan_hdd_get_rssi(pAdapter, &rssi);
20890
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20892 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20893 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020894 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20895 hdd_wlan_get_freq(channel, &freq);
20896
20897
20898 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20899 {
20900 if (NULL == wiphy->bands[i])
20901 {
20902 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20903 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20904 continue;
20905 }
20906
20907 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20908 {
20909 struct ieee80211_supported_band *band = wiphy->bands[i];
20910
20911 if (band->channels[j].center_freq == (v_U16_t)freq)
20912 {
20913 survey->channel = &band->channels[j];
20914 /* The Rx BDs contain SNR values in dB for the received frames
20915 * while the supplicant expects noise. So we calculate and
20916 * return the value of noise (dBm)
20917 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20918 */
20919 survey->noise = rssi - snr;
20920 survey->filled = SURVEY_INFO_NOISE_DBM;
20921 filled = 1;
20922 }
20923 }
20924 }
20925
20926 if (filled)
20927 pAdapter->survey_idx = 1;
20928 else
20929 {
20930 pAdapter->survey_idx = 0;
20931 return -ENONET;
20932 }
20933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020934 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020935 return 0;
20936}
20937
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020938static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20939 struct net_device *dev,
20940 int idx, struct survey_info *survey)
20941{
20942 int ret;
20943
20944 vos_ssr_protect(__func__);
20945 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20946 vos_ssr_unprotect(__func__);
20947
20948 return ret;
20949}
20950
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020951/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020952 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020953 * this is called when cfg80211 driver resume
20954 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20955 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020956int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020957{
20958 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20959 hdd_adapter_t *pAdapter;
20960 hdd_adapter_list_node_t *pAdapterNode, *pNext;
20961 VOS_STATUS status = VOS_STATUS_SUCCESS;
20962
20963 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020964
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020965 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020966 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020967 return 0;
20968 }
20969
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020970 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
20971 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020972
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053020973 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020974 {
20975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20976 "%s: Resume SoftAP", __func__);
20977 hdd_set_wlan_suspend_mode(false);
20978 }
20979
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020980 spin_lock(&pHddCtx->schedScan_lock);
20981 pHddCtx->isWiphySuspended = FALSE;
20982 if (TRUE != pHddCtx->isSchedScanUpdatePending)
20983 {
20984 spin_unlock(&pHddCtx->schedScan_lock);
20985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20986 "%s: Return resume is not due to PNO indication", __func__);
20987 return 0;
20988 }
20989 // Reset flag to avoid updatating cfg80211 data old results again
20990 pHddCtx->isSchedScanUpdatePending = FALSE;
20991 spin_unlock(&pHddCtx->schedScan_lock);
20992
20993 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
20994
20995 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
20996 {
20997 pAdapter = pAdapterNode->pAdapter;
20998 if ( (NULL != pAdapter) &&
20999 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21000 {
21001 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021002 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21004 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021005 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021006 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021007 {
21008 /* Acquire wakelock to handle the case where APP's tries to
21009 * suspend immediately after updating the scan results. Whis
21010 * results in app's is in suspended state and not able to
21011 * process the connect request to AP
21012 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021013 hdd_prevent_suspend_timeout(2000,
21014 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021015 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021016 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021017
21018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21019 "%s : cfg80211 scan result database updated", __func__);
21020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021021 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021022 return 0;
21023
21024 }
21025 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21026 pAdapterNode = pNext;
21027 }
21028
21029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21030 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021031 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021032 return 0;
21033}
21034
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021035int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21036{
21037 int ret;
21038
21039 vos_ssr_protect(__func__);
21040 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21041 vos_ssr_unprotect(__func__);
21042
21043 return ret;
21044}
21045
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021046/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021047 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021048 * this is called when cfg80211 driver suspends
21049 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021050int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021051 struct cfg80211_wowlan *wow)
21052{
21053 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021054 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021055
21056 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021057
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021058 ret = wlan_hdd_validate_context(pHddCtx);
21059 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021060 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021061 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021062 }
21063
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021064 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21066 "%s: Suspend SoftAP", __func__);
21067 hdd_set_wlan_suspend_mode(true);
21068 }
21069
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021070
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21072 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21073 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021074 pHddCtx->isWiphySuspended = TRUE;
21075
21076 EXIT();
21077
21078 return 0;
21079}
21080
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021081int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21082 struct cfg80211_wowlan *wow)
21083{
21084 int ret;
21085
21086 vos_ssr_protect(__func__);
21087 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21088 vos_ssr_unprotect(__func__);
21089
21090 return ret;
21091}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021092
21093#ifdef FEATURE_OEM_DATA_SUPPORT
21094static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021095 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021096{
21097 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21098
21099 ENTER();
21100
21101 if (wlan_hdd_validate_context(pHddCtx)) {
21102 return;
21103 }
21104 if (!pMsg)
21105 {
21106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21107 return;
21108 }
21109
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021110 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021111
21112 EXIT();
21113 return;
21114
21115}
21116
21117void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021118 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021119{
21120 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21121
21122 ENTER();
21123
21124 if (wlan_hdd_validate_context(pHddCtx)) {
21125 return;
21126 }
21127
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021128 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021129
21130 switch(evType) {
21131 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021132 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021133 break;
21134 default:
21135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21136 break;
21137 }
21138 EXIT();
21139}
21140#endif
21141
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21143 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021144/**
21145 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21146 * @wiphy: Pointer to wiphy
21147 * @wdev: Pointer to wireless device structure
21148 *
21149 * This function is used to abort an ongoing scan
21150 *
21151 * Return: None
21152 */
21153static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21154 struct wireless_dev *wdev)
21155{
21156 struct net_device *dev = wdev->netdev;
21157 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21158 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21159 int ret;
21160
21161 ENTER();
21162
21163 if (NULL == adapter) {
21164 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21165 return;
21166 }
21167
21168 ret = wlan_hdd_validate_context(hdd_ctx);
21169 if (0 != ret)
21170 return;
21171
21172 wlan_hdd_scan_abort(adapter);
21173
21174 return;
21175}
21176
21177/**
21178 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21179 * @wiphy: Pointer to wiphy
21180 * @wdev: Pointer to wireless device structure
21181 *
21182 * Return: None
21183 */
21184void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21185 struct wireless_dev *wdev)
21186{
21187 vos_ssr_protect(__func__);
21188 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21189 vos_ssr_unprotect(__func__);
21190
21191 return;
21192}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021193#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021194
Abhishek Singh936c6932017-11-07 17:28:23 +053021195#ifdef CHANNEL_SWITCH_SUPPORTED
21196/**
21197 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21198 * channel in SAP/GO
21199 * @wiphy: wiphy pointer
21200 * @dev: dev pointer.
21201 * @csa_params: Change channel params
21202 *
21203 * This function is called to switch channel in SAP/GO
21204 *
21205 * Return: 0 if success else return non zero
21206 */
21207static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21208 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21209{
21210 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21211 hdd_context_t *hdd_ctx;
21212 uint8_t channel;
21213 int ret;
21214 v_CONTEXT_t vos_ctx;
21215
21216 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21217
21218 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21219 ret = wlan_hdd_validate_context(hdd_ctx);
21220 if (ret)
21221 return ret;
21222
21223 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21224 if (!vos_ctx) {
21225 hddLog(LOGE, FL("Vos ctx is null"));
21226 return -EINVAL;
21227 }
21228
21229 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21230 (WLAN_HDD_P2P_GO != adapter->device_mode))
21231 return -ENOTSUPP;
21232
21233 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021234 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021235
21236 return ret;
21237}
21238
21239/**
21240 * wlan_hdd_cfg80211_channel_switch()- function to switch
21241 * channel in SAP/GO
21242 * @wiphy: wiphy pointer
21243 * @dev: dev pointer.
21244 * @csa_params: Change channel params
21245 *
21246 * This function is called to switch channel in SAP/GO
21247 *
21248 * Return: 0 if success else return non zero
21249 */
21250static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21251 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21252{
21253 int ret;
21254
21255 vos_ssr_protect(__func__);
21256 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21257 vos_ssr_unprotect(__func__);
21258
21259 return ret;
21260}
21261#endif
21262
Jeff Johnson295189b2012-06-20 16:38:30 -070021263/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021264static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021265{
21266 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21267 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21268 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21269 .change_station = wlan_hdd_change_station,
21270#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21271 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21272 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21273 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021274#else
21275 .start_ap = wlan_hdd_cfg80211_start_ap,
21276 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21277 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021278#endif
21279 .change_bss = wlan_hdd_cfg80211_change_bss,
21280 .add_key = wlan_hdd_cfg80211_add_key,
21281 .get_key = wlan_hdd_cfg80211_get_key,
21282 .del_key = wlan_hdd_cfg80211_del_key,
21283 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021285 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021287 .scan = wlan_hdd_cfg80211_scan,
21288 .connect = wlan_hdd_cfg80211_connect,
21289 .disconnect = wlan_hdd_cfg80211_disconnect,
21290 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21291 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21292 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21293 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21294 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021295 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21296 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021297 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21299 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21300 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21301 .set_txq_params = wlan_hdd_set_txq_params,
21302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021303 .get_station = wlan_hdd_cfg80211_get_station,
21304 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21305 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021306 .add_station = wlan_hdd_cfg80211_add_station,
21307#ifdef FEATURE_WLAN_LFR
21308 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21309 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21310 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21311#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021312#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21313 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21314#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021315#ifdef FEATURE_WLAN_TDLS
21316 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21317 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21318#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021319#ifdef WLAN_FEATURE_GTK_OFFLOAD
21320 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21321#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021322#ifdef FEATURE_WLAN_SCAN_PNO
21323 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21324 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21325#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021326 .resume = wlan_hdd_cfg80211_resume_wlan,
21327 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021328 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021329#ifdef WLAN_NL80211_TESTMODE
21330 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21331#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021332 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21334 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021335 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021336#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021337#ifdef CHANNEL_SWITCH_SUPPORTED
21338 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21339#endif
21340
Jeff Johnson295189b2012-06-20 16:38:30 -070021341};
21342