blob: ec45a43fd7292f30d47acbcd20ac36c852aaca5b [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
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530424/* interface limits for sta + monitor SCC */
425static const struct ieee80211_iface_limit
426wlan_hdd_iface_sta_mon_limit[] = {
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_STATION),
430 },
431 {
432 .max = 1, /* Monitor interface */
433 .types = BIT(NL80211_IFTYPE_MONITOR),
434 },
435};
436
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800437/* By default, only single channel concurrency is allowed */
438static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530439wlan_hdd_iface_combination[] = {
440 {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456 },
457 {
458 .limits = wlan_hdd_iface_sta_mon_limit,
459 .num_different_channels = 1,
460 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
461 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
462 .beacon_int_infra_match = false,
463 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800464};
465#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800466
Jeff Johnson295189b2012-06-20 16:38:30 -0700467static struct cfg80211_ops wlan_hdd_cfg80211_ops;
468
469/* Data rate 100KBPS based on IE Index */
470struct index_data_rate_type
471{
472 v_U8_t beacon_rate_index;
473 v_U16_t supported_rate[4];
474};
475
476/* 11B, 11G Rate table include Basic rate and Extended rate
477 The IDX field is the rate index
478 The HI field is the rate when RSSI is strong or being ignored
479 (in this case we report actual rate)
480 The MID field is the rate when RSSI is moderate
481 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
482 The LO field is the rate when RSSI is low
483 (in this case we don't report rates, actual current rate used)
484 */
485static const struct
486{
487 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700488 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700489} supported_data_rate[] =
490{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700491/* IDX HI HM LM LO (RSSI-based index */
492 {2, { 10, 10, 10, 0}},
493 {4, { 20, 20, 10, 0}},
494 {11, { 55, 20, 10, 0}},
495 {12, { 60, 55, 20, 0}},
496 {18, { 90, 55, 20, 0}},
497 {22, {110, 55, 20, 0}},
498 {24, {120, 90, 60, 0}},
499 {36, {180, 120, 60, 0}},
500 {44, {220, 180, 60, 0}},
501 {48, {240, 180, 90, 0}},
502 {66, {330, 180, 90, 0}},
503 {72, {360, 240, 90, 0}},
504 {96, {480, 240, 120, 0}},
505 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700506};
507
508/* MCS Based rate table */
509static struct index_data_rate_type supported_mcs_rate[] =
510{
511/* MCS L20 L40 S20 S40 */
512 {0, {65, 135, 72, 150}},
513 {1, {130, 270, 144, 300}},
514 {2, {195, 405, 217, 450}},
515 {3, {260, 540, 289, 600}},
516 {4, {390, 810, 433, 900}},
517 {5, {520, 1080, 578, 1200}},
518 {6, {585, 1215, 650, 1350}},
519 {7, {650, 1350, 722, 1500}}
520};
521
Leo Chang6f8870f2013-03-26 18:11:36 -0700522#ifdef WLAN_FEATURE_11AC
523
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700525
526struct index_vht_data_rate_type
527{
528 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530529 v_U16_t supported_VHT80_rate[2];
530 v_U16_t supported_VHT40_rate[2];
531 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700532};
533
534typedef enum
535{
536 DATA_RATE_11AC_MAX_MCS_7,
537 DATA_RATE_11AC_MAX_MCS_8,
538 DATA_RATE_11AC_MAX_MCS_9,
539 DATA_RATE_11AC_MAX_MCS_NA
540} eDataRate11ACMaxMcs;
541
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530542/* SSID broadcast type */
543typedef enum eSSIDBcastType
544{
545 eBCAST_UNKNOWN = 0,
546 eBCAST_NORMAL = 1,
547 eBCAST_HIDDEN = 2,
548} tSSIDBcastType;
549
Leo Chang6f8870f2013-03-26 18:11:36 -0700550/* MCS Based VHT rate table */
551static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
552{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530553/* MCS L80 S80 L40 S40 L20 S40*/
554 {0, {293, 325}, {135, 150}, {65, 72}},
555 {1, {585, 650}, {270, 300}, {130, 144}},
556 {2, {878, 975}, {405, 450}, {195, 217}},
557 {3, {1170, 1300}, {540, 600}, {260, 289}},
558 {4, {1755, 1950}, {810, 900}, {390, 433}},
559 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
560 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
561 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
562 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
563 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700564};
565#endif /* WLAN_FEATURE_11AC */
566
c_hpothu79aab322014-07-14 21:11:01 +0530567/*array index points to MCS and array value points respective rssi*/
568static int rssiMcsTbl[][10] =
569{
570/*MCS 0 1 2 3 4 5 6 7 8 9*/
571 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
572 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
573 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
574};
575
Jeff Johnson295189b2012-06-20 16:38:30 -0700576extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530577#ifdef FEATURE_WLAN_SCAN_PNO
578static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
Leo Chang9056f462013-08-01 19:21:11 -0700581#ifdef WLAN_NL80211_TESTMODE
582enum wlan_hdd_tm_attr
583{
584 WLAN_HDD_TM_ATTR_INVALID = 0,
585 WLAN_HDD_TM_ATTR_CMD = 1,
586 WLAN_HDD_TM_ATTR_DATA = 2,
587 WLAN_HDD_TM_ATTR_TYPE = 3,
588 /* keep last */
589 WLAN_HDD_TM_ATTR_AFTER_LAST,
590 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
591};
592
593enum wlan_hdd_tm_cmd
594{
595 WLAN_HDD_TM_CMD_WLAN_HB = 1,
596};
597
598#define WLAN_HDD_TM_DATA_MAX_LEN 5000
599
600static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
601{
602 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
603 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
604 .len = WLAN_HDD_TM_DATA_MAX_LEN },
605};
606#endif /* WLAN_NL80211_TESTMODE */
607
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800608#ifdef FEATURE_WLAN_CH_AVOID
609/*
610 * FUNCTION: wlan_hdd_send_avoid_freq_event
611 * This is called when wlan driver needs to send vendor specific
612 * avoid frequency range event to userspace
613 */
614int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
615 tHddAvoidFreqList *pAvoidFreqList)
616{
617 struct sk_buff *vendor_event;
618
619 ENTER();
620
621 if (!pHddCtx)
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
624 "%s: HDD context is null", __func__);
625 return -1;
626 }
627
628 if (!pAvoidFreqList)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: pAvoidFreqList is null", __func__);
632 return -1;
633 }
634
635 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
637 NULL,
638#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800639 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530640 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800641 GFP_KERNEL);
642 if (!vendor_event)
643 {
644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
645 "%s: cfg80211_vendor_event_alloc failed", __func__);
646 return -1;
647 }
648
649 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
650 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
651
652 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
653
654 EXIT();
655 return 0;
656}
657#endif /* FEATURE_WLAN_CH_AVOID */
658
Srinivas Dasari030bad32015-02-18 23:23:54 +0530659/*
660 * FUNCTION: __wlan_hdd_cfg80211_nan_request
661 * This is called when wlan driver needs to send vendor specific
662 * nan request event.
663 */
664static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
665 struct wireless_dev *wdev,
666 const void *data, int data_len)
667{
668 tNanRequestReq nan_req;
669 VOS_STATUS status;
670 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530671 struct net_device *dev = wdev->netdev;
672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
673 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530674 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
675
676 if (0 == data_len)
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN - Invalid Request, length = 0"));
680 return ret_val;
681 }
682
683 if (NULL == data)
684 {
685 hddLog(VOS_TRACE_LEVEL_ERROR,
686 FL("NAN - Invalid Request, data is NULL"));
687 return ret_val;
688 }
689
690 status = wlan_hdd_validate_context(pHddCtx);
691 if (0 != status)
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("HDD context is not valid"));
695 return -EINVAL;
696 }
697
698 hddLog(LOG1, FL("Received NAN command"));
699 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
700 (tANI_U8 *)data, data_len);
701
702 /* check the NAN Capability */
703 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
704 {
705 hddLog(VOS_TRACE_LEVEL_ERROR,
706 FL("NAN is not supported by Firmware"));
707 return -EINVAL;
708 }
709
710 nan_req.request_data_len = data_len;
711 nan_req.request_data = data;
712
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530713 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530714 if (VOS_STATUS_SUCCESS == status)
715 {
716 ret_val = 0;
717 }
718 return ret_val;
719}
720
721/*
722 * FUNCTION: wlan_hdd_cfg80211_nan_request
723 * Wrapper to protect the nan vendor command from ssr
724 */
725static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
726 struct wireless_dev *wdev,
727 const void *data, int data_len)
728{
729 int ret;
730
731 vos_ssr_protect(__func__);
732 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
733 vos_ssr_unprotect(__func__);
734
735 return ret;
736}
737
738/*
739 * FUNCTION: wlan_hdd_cfg80211_nan_callback
740 * This is a callback function and it gets called
741 * when we need to report nan response event to
742 * upper layers.
743 */
744static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
745{
746 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
747 struct sk_buff *vendor_event;
748 int status;
749 tSirNanEvent *data;
750
751 ENTER();
752 if (NULL == msg)
753 {
754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
755 FL(" msg received here is null"));
756 return;
757 }
758 data = msg;
759
760 status = wlan_hdd_validate_context(pHddCtx);
761
762 if (0 != status)
763 {
764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
765 FL("HDD context is not valid"));
766 return;
767 }
768
769 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
771 NULL,
772#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 data->event_data_len +
774 NLMSG_HDRLEN,
775 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
776 GFP_KERNEL);
777
778 if (!vendor_event)
779 {
780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
781 FL("cfg80211_vendor_event_alloc failed"));
782 return;
783 }
784 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
785 data->event_data_len, data->event_data))
786 {
787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
788 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
789 kfree_skb(vendor_event);
790 return;
791 }
792 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
793 EXIT();
794}
795
796/*
797 * FUNCTION: wlan_hdd_cfg80211_nan_init
798 * This function is called to register the callback to sme layer
799 */
800inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
801{
802 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
803}
804
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530805/*
806 * define short names for the global vendor params
807 * used by __wlan_hdd_cfg80211_get_station_cmd()
808 */
809#define STATION_INVALID \
810 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
811#define STATION_INFO \
812 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
813#define STATION_ASSOC_FAIL_REASON \
814 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530815#define STATION_REMOTE \
816 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530817#define STATION_MAX \
818 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
819
820static const struct nla_policy
821hdd_get_station_policy[STATION_MAX + 1] = {
822 [STATION_INFO] = {.type = NLA_FLAG},
823 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
824};
825
826/**
827 * hdd_get_station_assoc_fail() - Handle get station assoc fail
828 * @hdd_ctx: HDD context within host driver
829 * @wdev: wireless device
830 *
831 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
832 * Validate cmd attributes and send the station info to upper layers.
833 *
834 * Return: Success(0) or reason code for failure
835 */
836static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
837 hdd_adapter_t *adapter)
838{
839 struct sk_buff *skb = NULL;
840 uint32_t nl_buf_len;
841 hdd_station_ctx_t *hdd_sta_ctx;
842
843 nl_buf_len = NLMSG_HDRLEN;
844 nl_buf_len += sizeof(uint32_t);
845 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
846
847 if (!skb) {
848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
849 return -ENOMEM;
850 }
851
852 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
853
854 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
855 hdd_sta_ctx->conn_info.assoc_status_code)) {
856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
857 goto fail;
858 }
859 return cfg80211_vendor_cmd_reply(skb);
860fail:
861 if (skb)
862 kfree_skb(skb);
863 return -EINVAL;
864}
865
866/**
867 * hdd_map_auth_type() - transform auth type specific to
868 * vendor command
869 * @auth_type: csr auth type
870 *
871 * Return: Success(0) or reason code for failure
872 */
873static int hdd_convert_auth_type(uint32_t auth_type)
874{
875 uint32_t ret_val;
876
877 switch (auth_type) {
878 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
879 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
880 break;
881 case eCSR_AUTH_TYPE_SHARED_KEY:
882 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
883 break;
884 case eCSR_AUTH_TYPE_WPA:
885 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
886 break;
887 case eCSR_AUTH_TYPE_WPA_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
889 break;
890 case eCSR_AUTH_TYPE_AUTOSWITCH:
891 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
892 break;
893 case eCSR_AUTH_TYPE_WPA_NONE:
894 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
895 break;
896 case eCSR_AUTH_TYPE_RSN:
897 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
898 break;
899 case eCSR_AUTH_TYPE_RSN_PSK:
900 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
901 break;
902 case eCSR_AUTH_TYPE_FT_RSN:
903 ret_val = QCA_WLAN_AUTH_TYPE_FT;
904 break;
905 case eCSR_AUTH_TYPE_FT_RSN_PSK:
906 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
907 break;
908 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
909 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
910 break;
911 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
912 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
913 break;
914#ifdef FEATURE_WLAN_ESE
915 case eCSR_AUTH_TYPE_CCKM_WPA:
916 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
917 break;
918 case eCSR_AUTH_TYPE_CCKM_RSN:
919 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
920 break;
921#endif
922 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
923 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
924 break;
925 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
926 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
927 break;
928 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
929 case eCSR_AUTH_TYPE_FAILED:
930 case eCSR_AUTH_TYPE_NONE:
931 default:
932 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
933 break;
934 }
935 return ret_val;
936}
937
938/**
939 * hdd_map_dot_11_mode() - transform dot11mode type specific to
940 * vendor command
941 * @dot11mode: dot11mode
942 *
943 * Return: Success(0) or reason code for failure
944 */
945static int hdd_convert_dot11mode(uint32_t dot11mode)
946{
947 uint32_t ret_val;
948
949 switch (dot11mode) {
950 case eCSR_CFG_DOT11_MODE_11A:
951 ret_val = QCA_WLAN_802_11_MODE_11A;
952 break;
953 case eCSR_CFG_DOT11_MODE_11B:
954 ret_val = QCA_WLAN_802_11_MODE_11B;
955 break;
956 case eCSR_CFG_DOT11_MODE_11G:
957 ret_val = QCA_WLAN_802_11_MODE_11G;
958 break;
959 case eCSR_CFG_DOT11_MODE_11N:
960 ret_val = QCA_WLAN_802_11_MODE_11N;
961 break;
962 case eCSR_CFG_DOT11_MODE_11AC:
963 ret_val = QCA_WLAN_802_11_MODE_11AC;
964 break;
965 case eCSR_CFG_DOT11_MODE_AUTO:
966 case eCSR_CFG_DOT11_MODE_ABG:
967 default:
968 ret_val = QCA_WLAN_802_11_MODE_INVALID;
969 }
970 return ret_val;
971}
972
973/**
974 * hdd_add_tx_bitrate() - add tx bitrate attribute
975 * @skb: pointer to sk buff
976 * @hdd_sta_ctx: pointer to hdd station context
977 * @idx: attribute index
978 *
979 * Return: Success(0) or reason code for failure
980 */
981static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
982 hdd_station_ctx_t *hdd_sta_ctx,
983 int idx)
984{
985 struct nlattr *nla_attr;
986 uint32_t bitrate, bitrate_compat;
987
988 nla_attr = nla_nest_start(skb, idx);
989 if (!nla_attr)
990 goto fail;
991 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
992 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
993
994 /* report 16-bit bitrate only if we can */
995 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
996 if (bitrate > 0 &&
997 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
999 goto fail;
1000 }
1001 if (bitrate_compat > 0 &&
1002 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1004 goto fail;
1005 }
1006 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1007 hdd_sta_ctx->conn_info.txrate.nss)) {
1008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1009 goto fail;
1010 }
1011 nla_nest_end(skb, nla_attr);
1012 return 0;
1013fail:
1014 return -EINVAL;
1015}
1016
1017/**
1018 * hdd_add_sta_info() - add station info attribute
1019 * @skb: pointer to sk buff
1020 * @hdd_sta_ctx: pointer to hdd station context
1021 * @idx: attribute index
1022 *
1023 * Return: Success(0) or reason code for failure
1024 */
1025static int32_t hdd_add_sta_info(struct sk_buff *skb,
1026 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1027{
1028 struct nlattr *nla_attr;
1029
1030 nla_attr = nla_nest_start(skb, idx);
1031 if (!nla_attr)
1032 goto fail;
1033 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1034 (hdd_sta_ctx->conn_info.signal + 100))) {
1035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1036 goto fail;
1037 }
1038 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1039 goto fail;
1040 nla_nest_end(skb, nla_attr);
1041 return 0;
1042fail:
1043 return -EINVAL;
1044}
1045
1046/**
1047 * hdd_add_survey_info() - add survey info attribute
1048 * @skb: pointer to sk buff
1049 * @hdd_sta_ctx: pointer to hdd station context
1050 * @idx: attribute index
1051 *
1052 * Return: Success(0) or reason code for failure
1053 */
1054static int32_t hdd_add_survey_info(struct sk_buff *skb,
1055 hdd_station_ctx_t *hdd_sta_ctx,
1056 int idx)
1057{
1058 struct nlattr *nla_attr;
1059
1060 nla_attr = nla_nest_start(skb, idx);
1061 if (!nla_attr)
1062 goto fail;
1063 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1064 hdd_sta_ctx->conn_info.freq) ||
1065 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1066 (hdd_sta_ctx->conn_info.noise + 100))) {
1067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1068 goto fail;
1069 }
1070 nla_nest_end(skb, nla_attr);
1071 return 0;
1072fail:
1073 return -EINVAL;
1074}
1075
1076/**
1077 * hdd_add_link_standard_info() - add link info attribute
1078 * @skb: pointer to sk buff
1079 * @hdd_sta_ctx: pointer to hdd station context
1080 * @idx: attribute index
1081 *
1082 * Return: Success(0) or reason code for failure
1083 */
1084static int32_t
1085hdd_add_link_standard_info(struct sk_buff *skb,
1086 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1087{
1088 struct nlattr *nla_attr;
1089
1090 nla_attr = nla_nest_start(skb, idx);
1091 if (!nla_attr)
1092 goto fail;
1093 if (nla_put(skb,
1094 NL80211_ATTR_SSID,
1095 hdd_sta_ctx->conn_info.SSID.SSID.length,
1096 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1098 goto fail;
1099 }
1100 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1101 goto fail;
1102 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1103 goto fail;
1104 nla_nest_end(skb, nla_attr);
1105 return 0;
1106fail:
1107 return -EINVAL;
1108}
1109
1110/**
1111 * hdd_add_ap_standard_info() - add ap info attribute
1112 * @skb: pointer to sk buff
1113 * @hdd_sta_ctx: pointer to hdd station context
1114 * @idx: attribute index
1115 *
1116 * Return: Success(0) or reason code for failure
1117 */
1118static int32_t
1119hdd_add_ap_standard_info(struct sk_buff *skb,
1120 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1121{
1122 struct nlattr *nla_attr;
1123
1124 nla_attr = nla_nest_start(skb, idx);
1125 if (!nla_attr)
1126 goto fail;
1127 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1128 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1129 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1130 &hdd_sta_ctx->conn_info.vht_caps)) {
1131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1132 goto fail;
1133 }
1134 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1135 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1136 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1137 &hdd_sta_ctx->conn_info.ht_caps)) {
1138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1139 goto fail;
1140 }
1141 nla_nest_end(skb, nla_attr);
1142 return 0;
1143fail:
1144 return -EINVAL;
1145}
1146
1147/**
1148 * hdd_get_station_info() - send BSS information to supplicant
1149 * @hdd_ctx: pointer to hdd context
1150 * @adapter: pointer to adapter
1151 *
1152 * Return: 0 if success else error status
1153 */
1154static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1155 hdd_adapter_t *adapter)
1156{
1157 struct sk_buff *skb = NULL;
1158 uint8_t *tmp_hs20 = NULL;
1159 uint32_t nl_buf_len;
1160 hdd_station_ctx_t *hdd_sta_ctx;
1161
1162 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1163
1164 nl_buf_len = NLMSG_HDRLEN;
1165 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1166 sizeof(hdd_sta_ctx->conn_info.freq) +
1167 sizeof(hdd_sta_ctx->conn_info.noise) +
1168 sizeof(hdd_sta_ctx->conn_info.signal) +
1169 (sizeof(uint32_t) * 2) +
1170 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1171 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1172 sizeof(hdd_sta_ctx->conn_info.authType) +
1173 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1174 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1175 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1176 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1177 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1178 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1179 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1180 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1181 1);
1182 }
1183 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1184 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1185 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1186 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1187
1188
1189 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1190 if (!skb) {
1191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1192 __func__, __LINE__);
1193 return -ENOMEM;
1194 }
1195
1196 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1197 LINK_INFO_STANDARD_NL80211_ATTR)) {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
1201 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1202 AP_INFO_STANDARD_NL80211_ATTR)) {
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1204 goto fail;
1205 }
1206 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1207 hdd_sta_ctx->conn_info.roam_count) ||
1208 nla_put_u32(skb, INFO_AKM,
1209 hdd_convert_auth_type(
1210 hdd_sta_ctx->conn_info.authType)) ||
1211 nla_put_u32(skb, WLAN802_11_MODE,
1212 hdd_convert_dot11mode(
1213 hdd_sta_ctx->conn_info.dot11Mode))) {
1214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1215 goto fail;
1216 }
1217 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1218 if (nla_put(skb, HT_OPERATION,
1219 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1220 &hdd_sta_ctx->conn_info.ht_operation)) {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1222 goto fail;
1223 }
1224 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1225 if (nla_put(skb, VHT_OPERATION,
1226 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1227 &hdd_sta_ctx->conn_info.vht_operation)) {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1229 goto fail;
1230 }
1231 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1232 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1233 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1234 tmp_hs20 + 1)) {
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1236 goto fail;
1237 }
1238
1239 return cfg80211_vendor_cmd_reply(skb);
1240fail:
1241 if (skb)
1242 kfree_skb(skb);
1243 return -EINVAL;
1244}
1245
1246/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301247 * hdd_add_survey_info_sap_get_len - get data length used in
1248 * hdd_add_survey_info_sap()
1249 *
1250 * This function calculates the data length used in hdd_add_survey_info_sap()
1251 *
1252 * Return: total data length used in hdd_add_survey_info_sap()
1253 */
1254static uint32_t hdd_add_survey_info_sap_get_len(void)
1255{
1256 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1257}
1258
1259/**
1260 * hdd_add_survey_info - add survey info attribute
1261 * @skb: pointer to response skb buffer
1262 * @stainfo: station information
1263 * @idx: attribute type index for nla_next_start()
1264 *
1265 * This function adds survey info attribute to response skb buffer
1266 *
1267 * Return : 0 on success and errno on failure
1268 */
1269static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1270 struct hdd_cache_sta_info *stainfo,
1271 int idx)
1272{
1273 struct nlattr *nla_attr;
1274
1275 nla_attr = nla_nest_start(skb, idx);
1276 if (!nla_attr)
1277 goto fail;
1278 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1279 stainfo->freq)) {
1280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1281 FL("put fail"));
1282 goto fail;
1283 }
1284 nla_nest_end(skb, nla_attr);
1285 return 0;
1286fail:
1287 return -EINVAL;
1288}
1289
1290/**
1291 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1292 * hdd_add_tx_bitrate_sap()
1293 *
1294 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1295 *
1296 * Return: total data length used in hdd_add_tx_bitrate_sap()
1297 */
1298static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1299{
1300 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1301}
1302
1303/**
1304 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1305 * @skb: pointer to response skb buffer
1306 * @stainfo: station information
1307 * @idx: attribute type index for nla_next_start()
1308 *
1309 * This function adds vht nss attribute to response skb buffer
1310 *
1311 * Return : 0 on success and errno on failure
1312 */
1313static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1314 struct hdd_cache_sta_info *stainfo,
1315 int idx)
1316{
1317 struct nlattr *nla_attr;
1318
1319 nla_attr = nla_nest_start(skb, idx);
1320 if (!nla_attr)
1321 goto fail;
1322
1323 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1324 stainfo->nss)) {
1325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1326 FL("put fail"));
1327 goto fail;
1328 }
1329 nla_nest_end(skb, nla_attr);
1330 return 0;
1331fail:
1332 return -EINVAL;
1333}
1334
1335/**
1336 * hdd_add_sta_info_sap_get_len - get data length used in
1337 * hdd_add_sta_info_sap()
1338 *
1339 * This function calculates the data length used in hdd_add_sta_info_sap()
1340 *
1341 * Return: total data length used in hdd_add_sta_info_sap()
1342 */
1343static uint32_t hdd_add_sta_info_sap_get_len(void)
1344{
1345 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1346 hdd_add_tx_bitrate_sap_get_len());
1347}
1348
1349/**
1350 * hdd_add_sta_info_sap - add sta signal info attribute
1351 * @skb: pointer to response skb buffer
1352 * @rssi: peer rssi value
1353 * @stainfo: station information
1354 * @idx: attribute type index for nla_next_start()
1355 *
1356 * This function adds sta signal attribute to response skb buffer
1357 *
1358 * Return : 0 on success and errno on failure
1359 */
1360static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1361 struct hdd_cache_sta_info *stainfo, int idx)
1362{
1363 struct nlattr *nla_attr;
1364
1365 nla_attr = nla_nest_start(skb, idx);
1366 if (!nla_attr)
1367 goto fail;
1368
1369 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, rssi)) {
1370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1371 FL("put fail"));
1372 goto fail;
1373 }
1374 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1376 FL("put fail"));
1377 goto fail;
1378 }
1379
1380 nla_nest_end(skb, nla_attr);
1381 return 0;
1382fail:
1383 return -EINVAL;
1384}
1385
1386/**
1387 * hdd_add_link_standard_info_sap_get_len - get data length used in
1388 * hdd_add_link_standard_info_sap()
1389 *
1390 * This function calculates the data length used in
1391 * hdd_add_link_standard_info_sap()
1392 *
1393 * Return: total data length used in hdd_add_link_standard_info_sap()
1394 */
1395static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1396{
1397 return ((NLA_HDRLEN) +
1398 hdd_add_survey_info_sap_get_len() +
1399 hdd_add_sta_info_sap_get_len() +
1400 (sizeof(uint32_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_link_standard_info_sap - add add link info attribut
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds link info attribut to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1423 goto fail;
1424 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1425 goto fail;
1426
1427 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1429 FL("put fail"));
1430 goto fail;
1431 }
1432
1433 nla_nest_end(skb, nla_attr);
1434 return 0;
1435fail:
1436 return -EINVAL;
1437}
1438
1439/**
1440 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1441 * hdd_add_ap_standard_info_sap()
1442 * @stainfo: station information
1443 *
1444 * This function calculates the data length used in
1445 * hdd_add_ap_standard_info_sap()
1446 *
1447 * Return: total data length used in hdd_add_ap_standard_info_sap()
1448 */
1449static uint32_t hdd_add_ap_standard_info_sap_get_len(
1450 struct hdd_cache_sta_info *stainfo)
1451{
1452 uint32_t len;
1453
1454 len = NLA_HDRLEN;
1455 if (stainfo->vht_present)
1456 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1457 if (stainfo->ht_present)
1458 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1459
1460 return len;
1461}
1462
1463/**
1464 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1465 * @skb: pointer to response skb buffer
1466 * @stainfo: station information
1467 * @idx: attribute type index for nla_next_start()
1468 *
1469 * This function adds HT and VHT info attributes to response skb buffer
1470 *
1471 * Return : 0 on success and errno on failure
1472 */
1473static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1474 struct hdd_cache_sta_info *stainfo,
1475 int idx)
1476{
1477 struct nlattr *nla_attr;
1478
1479 nla_attr = nla_nest_start(skb, idx);
1480 if (!nla_attr)
1481 goto fail;
1482
1483 if (stainfo->vht_present) {
1484 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1485 sizeof(stainfo->vht_caps),
1486 &stainfo->vht_caps)) {
1487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1488 FL("put fail"));
1489 goto fail;
1490 }
1491 }
1492 if (stainfo->ht_present) {
1493 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1494 sizeof(stainfo->ht_caps),
1495 &stainfo->ht_caps)) {
1496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1497 FL("put fail"));
1498 goto fail;
1499 }
1500 }
1501 nla_nest_end(skb, nla_attr);
1502 return 0;
1503fail:
1504 return -EINVAL;
1505}
1506
1507/**
1508 * hdd_decode_ch_width - decode channel band width based
1509 * @ch_width: encoded enum value holding channel band width
1510 *
1511 * This function decodes channel band width from the given encoded enum value.
1512 *
1513 * Returns: decoded channel band width.
1514 */
1515static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1516{
1517 switch (ch_width) {
1518 case 0:
1519 return 20;
1520 case 1:
1521 return 40;
1522 case 2:
1523 return 80;
1524 default:
1525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1526 "invalid enum: %d", ch_width);
1527 return 20;
1528 }
1529}
1530
1531/**
1532 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1533 * @hdd_ctx: hdd context
1534 * @adapter: hostapd interface
1535 * @mac_addr: mac address of requested peer
1536 *
1537 * This function collect and indicate the cached(deleted) peer's info
1538 *
1539 * Return: 0 on success, otherwise error value
1540 */
1541static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1542 hdd_adapter_t *adapter,
1543 v_MACADDR_t mac_addr)
1544{
1545 struct hdd_cache_sta_info *stainfo;
1546 struct sk_buff *skb = NULL;
1547 uint32_t nl_buf_len;
1548 uint8_t cw;
1549 ptSapContext sap_ctx;
1550 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1551
1552 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1553 if(sap_ctx == NULL){
1554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1555 FL("psapCtx is NULL"));
1556 return -ENOENT;
1557 }
1558
1559 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1560 mac_addr.bytes);
1561 if (!stainfo) {
1562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1563 "peer " MAC_ADDRESS_STR " not found",
1564 MAC_ADDR_ARRAY(mac_addr.bytes));
1565 return -EINVAL;
1566 }
1567 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1569 "peer " MAC_ADDRESS_STR " is in connected state",
1570 MAC_ADDR_ARRAY(mac_addr.bytes));
1571 return -EINVAL;
1572 }
1573
1574
1575 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1576 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1577 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1578 (sizeof(cw) + NLA_HDRLEN) +
1579 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1580
1581 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1582 if (!skb) {
1583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1584 return -ENOMEM;
1585 }
1586
1587 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1588 LINK_INFO_STANDARD_NL80211_ATTR)) {
1589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1590 goto fail;
1591 }
1592
1593 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1594 AP_INFO_STANDARD_NL80211_ATTR)) {
1595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1596 goto fail;
1597 }
1598
1599 /* upper layer expects decoded channel BW */
1600 cw = hdd_decode_ch_width(stainfo->ch_width);
1601 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1602 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1604 goto fail;
1605 }
1606 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
1607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1608 goto fail;
1609 }
1610
1611 vos_mem_zero(stainfo, sizeof(*stainfo));
1612
1613 return cfg80211_vendor_cmd_reply(skb);
1614fail:
1615 if (skb)
1616 kfree_skb(skb);
1617
1618 return -EINVAL;
1619}
1620
1621/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301622 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1623 * @wiphy: corestack handler
1624 * @wdev: wireless device
1625 * @data: data
1626 * @data_len: data length
1627 *
1628 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1629 * Validate cmd attributes and send the station info to upper layers.
1630 *
1631 * Return: Success(0) or reason code for failure
1632 */
1633static int32_t
1634__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1635 struct wireless_dev *wdev,
1636 const void *data,
1637 int data_len)
1638{
1639 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1640 struct net_device *dev = wdev->netdev;
1641 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1642 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1643 int32_t status;
1644
1645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1646 if (VOS_FTM_MODE == hdd_get_conparam()) {
1647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1648 status = -EPERM;
1649 goto out;
1650 }
1651
1652 status = wlan_hdd_validate_context(hdd_ctx);
1653 if (0 != status)
1654 goto out;
1655
1656
1657 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1658 data, data_len, NULL);
1659 if (status) {
1660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1661 goto out;
1662 }
1663
1664 /* Parse and fetch Command Type*/
1665 if (tb[STATION_INFO]) {
1666 status = hdd_get_station_info(hdd_ctx, adapter);
1667 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1668 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301669 } else if (tb[STATION_REMOTE]) {
1670 v_MACADDR_t mac_addr;
1671
1672 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1673 adapter->device_mode != WLAN_HDD_P2P_GO) {
1674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1675 adapter->device_mode);
1676 status = -EINVAL;
1677 goto out;
1678 }
1679
1680 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1681 VOS_MAC_ADDRESS_LEN);
1682
1683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1684 MAC_ADDR_ARRAY(mac_addr.bytes));
1685
1686 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1687 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301688 } else {
1689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1690 status = -EINVAL;
1691 goto out;
1692 }
1693 EXIT();
1694out:
1695 return status;
1696}
1697
1698/**
1699 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1700 * @wiphy: corestack handler
1701 * @wdev: wireless device
1702 * @data: data
1703 * @data_len: data length
1704 *
1705 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1706 * Validate cmd attributes and send the station info to upper layers.
1707 *
1708 * Return: Success(0) or reason code for failure
1709 */
1710static int32_t
1711hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1712 struct wireless_dev *wdev,
1713 const void *data,
1714 int data_len)
1715{
1716 int ret;
1717
1718 vos_ssr_protect(__func__);
1719 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1720 vos_ssr_unprotect(__func__);
1721
1722 return ret;
1723}
1724
1725/*
1726 * undef short names defined for get station command
1727 * used by __wlan_hdd_cfg80211_get_station_cmd()
1728 */
1729#undef STATION_INVALID
1730#undef STATION_INFO
1731#undef STATION_ASSOC_FAIL_REASON
1732#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301733
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1735
1736static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1737 struct sk_buff *vendor_event)
1738{
1739 if (nla_put_u8(vendor_event,
1740 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1741 stats->rate.preamble) ||
1742 nla_put_u8(vendor_event,
1743 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1744 stats->rate.nss) ||
1745 nla_put_u8(vendor_event,
1746 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1747 stats->rate.bw) ||
1748 nla_put_u8(vendor_event,
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1750 stats->rate.rateMcsIdx) ||
1751 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1752 stats->rate.bitrate ) ||
1753 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1754 stats->txMpdu ) ||
1755 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1756 stats->rxMpdu ) ||
1757 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1758 stats->mpduLost ) ||
1759 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1760 stats->retries) ||
1761 nla_put_u32(vendor_event,
1762 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1763 stats->retriesShort ) ||
1764 nla_put_u32(vendor_event,
1765 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1766 stats->retriesLong))
1767 {
1768 hddLog(VOS_TRACE_LEVEL_ERROR,
1769 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1770 return FALSE;
1771 }
1772 return TRUE;
1773}
1774
1775static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1776 struct sk_buff *vendor_event)
1777{
1778 u32 i = 0;
1779 struct nlattr *rateInfo;
1780 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1781 stats->type) ||
1782 nla_put(vendor_event,
1783 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1784 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1785 nla_put_u32(vendor_event,
1786 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1787 stats->capabilities) ||
1788 nla_put_u32(vendor_event,
1789 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1790 stats->numRate))
1791 {
1792 hddLog(VOS_TRACE_LEVEL_ERROR,
1793 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1794 goto error;
1795 }
1796
1797 rateInfo = nla_nest_start(vendor_event,
1798 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301799 if(!rateInfo)
1800 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 for (i = 0; i < stats->numRate; i++)
1802 {
1803 struct nlattr *rates;
1804 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1805 stats->rateStats +
1806 (i * sizeof(tSirWifiRateStat)));
1807 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301808 if(!rates)
1809 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810
1811 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1812 {
1813 hddLog(VOS_TRACE_LEVEL_ERROR,
1814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1815 return FALSE;
1816 }
1817 nla_nest_end(vendor_event, rates);
1818 }
1819 nla_nest_end(vendor_event, rateInfo);
1820
1821 return TRUE;
1822error:
1823 return FALSE;
1824}
1825
1826static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1827 struct sk_buff *vendor_event)
1828{
1829 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1830 stats->ac ) ||
1831 nla_put_u32(vendor_event,
1832 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1833 stats->txMpdu ) ||
1834 nla_put_u32(vendor_event,
1835 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1836 stats->rxMpdu ) ||
1837 nla_put_u32(vendor_event,
1838 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1839 stats->txMcast ) ||
1840 nla_put_u32(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1842 stats->rxMcast ) ||
1843 nla_put_u32(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1845 stats->rxAmpdu ) ||
1846 nla_put_u32(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1848 stats->txAmpdu ) ||
1849 nla_put_u32(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1851 stats->mpduLost )||
1852 nla_put_u32(vendor_event,
1853 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1854 stats->retries ) ||
1855 nla_put_u32(vendor_event,
1856 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1857 stats->retriesShort ) ||
1858 nla_put_u32(vendor_event,
1859 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1860 stats->retriesLong ) ||
1861 nla_put_u32(vendor_event,
1862 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1863 stats->contentionTimeMin ) ||
1864 nla_put_u32(vendor_event,
1865 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1866 stats->contentionTimeMax ) ||
1867 nla_put_u32(vendor_event,
1868 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1869 stats->contentionTimeAvg ) ||
1870 nla_put_u32(vendor_event,
1871 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1872 stats->contentionNumSamples ))
1873 {
1874 hddLog(VOS_TRACE_LEVEL_ERROR,
1875 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1876 return FALSE;
1877 }
1878 return TRUE;
1879}
1880
1881static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1882 struct sk_buff *vendor_event)
1883{
Dino Myclec8f3f332014-07-21 16:48:27 +05301884 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301885 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1886 nla_put(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1888 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1891 stats->state ) ||
1892 nla_put_u32(vendor_event,
1893 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1894 stats->roaming ) ||
1895 nla_put_u32(vendor_event,
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1897 stats->capabilities ) ||
1898 nla_put(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1900 strlen(stats->ssid), stats->ssid) ||
1901 nla_put(vendor_event,
1902 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1903 WNI_CFG_BSSID_LEN, stats->bssid) ||
1904 nla_put(vendor_event,
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1906 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1907 nla_put(vendor_event,
1908 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1909 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1910 )
1911 {
1912 hddLog(VOS_TRACE_LEVEL_ERROR,
1913 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1914 return FALSE;
1915 }
1916 return TRUE;
1917}
1918
Dino Mycle3b9536d2014-07-09 22:05:24 +05301919static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1920 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921 struct sk_buff *vendor_event)
1922{
1923 int i = 0;
1924 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1926 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301927 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301928
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 if (FALSE == put_wifi_interface_info(
1930 &pWifiIfaceStat->info,
1931 vendor_event))
1932 {
1933 hddLog(VOS_TRACE_LEVEL_ERROR,
1934 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1935 return FALSE;
1936
1937 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301938 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1939 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1940 if (NULL == pWifiIfaceStatTL)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1943 return FALSE;
1944 }
1945
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301946 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1947 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1948 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1949 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1950
1951 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1952 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1953 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1954 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301955
1956 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1957 {
1958 if (VOS_STATUS_SUCCESS ==
1959 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1960 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1961 {
1962 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1963 * obtained from TL structure
1964 */
1965
1966 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1967 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301968 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1969
Srinivas Dasari98947432014-11-07 19:41:24 +05301970 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1971 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1972 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1973 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1974 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1975 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1976 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1977 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301978
Srinivas Dasari98947432014-11-07 19:41:24 +05301979 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1980 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1981 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1982 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1983 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1984 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1985 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1986 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301987
Srinivas Dasari98947432014-11-07 19:41:24 +05301988 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1989 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1990 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1991 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1993 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1995 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301996 }
1997 else
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2000 }
2001
Dino Mycle3b9536d2014-07-09 22:05:24 +05302002 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2003 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2004 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2005 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2007 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2009 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2010 }
2011 else
2012 {
2013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2014 }
2015
2016
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017
2018 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302019 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2020 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2021 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2023 pWifiIfaceStat->beaconRx) ||
2024 nla_put_u32(vendor_event,
2025 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2026 pWifiIfaceStat->mgmtRx) ||
2027 nla_put_u32(vendor_event,
2028 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2029 pWifiIfaceStat->mgmtActionRx) ||
2030 nla_put_u32(vendor_event,
2031 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2032 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302033 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302034 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2035 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302036 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302037 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2038 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2041 pWifiIfaceStat->rssiAck))
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302044 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2045 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046 return FALSE;
2047 }
2048
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302049#ifdef FEATURE_EXT_LL_STAT
2050 /*
2051 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2052 * then host should send Leaky AP stats to upper layer,
2053 * otherwise no need to send these stats.
2054 */
2055 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2056 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2057 )
2058 {
2059 hddLog(VOS_TRACE_LEVEL_INFO,
2060 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2061 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2062 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2063 pWifiIfaceStat->leakyApStat.rx_leak_window,
2064 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2065 if (nla_put_u32(vendor_event,
2066 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2067 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2068 nla_put_u32(vendor_event,
2069 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2070 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2071 nla_put_u32(vendor_event,
2072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2073 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
2074 nla_put_u64(vendor_event,
2075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2076 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2077 {
2078 hddLog(VOS_TRACE_LEVEL_ERROR,
2079 FL("EXT_LL_STAT put fail"));
2080 vos_mem_free(pWifiIfaceStatTL);
2081 return FALSE;
2082 }
2083 }
2084#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302085 wmmInfo = nla_nest_start(vendor_event,
2086 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302087 if(!wmmInfo)
2088 {
2089 vos_mem_free(pWifiIfaceStatTL);
2090 return FALSE;
2091 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092 for (i = 0; i < WIFI_AC_MAX; i++)
2093 {
2094 struct nlattr *wmmStats;
2095 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302096 if(!wmmStats)
2097 {
2098 vos_mem_free(pWifiIfaceStatTL);
2099 return FALSE;
2100 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 if (FALSE == put_wifi_wmm_ac_stat(
2102 &pWifiIfaceStat->AccessclassStats[i],
2103 vendor_event))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR,
2106 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302107 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302108 return FALSE;
2109 }
2110
2111 nla_nest_end(vendor_event, wmmStats);
2112 }
2113 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302114 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302115 return TRUE;
2116}
2117
2118static tSirWifiInterfaceMode
2119 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2120{
2121 switch (deviceMode)
2122 {
2123 case WLAN_HDD_INFRA_STATION:
2124 return WIFI_INTERFACE_STA;
2125 case WLAN_HDD_SOFTAP:
2126 return WIFI_INTERFACE_SOFTAP;
2127 case WLAN_HDD_P2P_CLIENT:
2128 return WIFI_INTERFACE_P2P_CLIENT;
2129 case WLAN_HDD_P2P_GO:
2130 return WIFI_INTERFACE_P2P_GO;
2131 case WLAN_HDD_IBSS:
2132 return WIFI_INTERFACE_IBSS;
2133 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302134 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 }
2136}
2137
2138static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2139 tpSirWifiInterfaceInfo pInfo)
2140{
2141 v_U8_t *staMac = NULL;
2142 hdd_station_ctx_t *pHddStaCtx;
2143 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2144 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2145
2146 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2147
2148 vos_mem_copy(pInfo->macAddr,
2149 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2150
2151 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2152 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2153 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2154 {
2155 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2156 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2157 {
2158 pInfo->state = WIFI_DISCONNECTED;
2159 }
2160 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2161 {
2162 hddLog(VOS_TRACE_LEVEL_ERROR,
2163 "%s: Session ID %d, Connection is in progress", __func__,
2164 pAdapter->sessionId);
2165 pInfo->state = WIFI_ASSOCIATING;
2166 }
2167 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2168 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2169 {
2170 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2171 hddLog(VOS_TRACE_LEVEL_ERROR,
2172 "%s: client " MAC_ADDRESS_STR
2173 " is in the middle of WPS/EAPOL exchange.", __func__,
2174 MAC_ADDR_ARRAY(staMac));
2175 pInfo->state = WIFI_AUTHENTICATING;
2176 }
2177 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2178 {
2179 pInfo->state = WIFI_ASSOCIATED;
2180 vos_mem_copy(pInfo->bssid,
2181 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2182 vos_mem_copy(pInfo->ssid,
2183 pHddStaCtx->conn_info.SSID.SSID.ssId,
2184 pHddStaCtx->conn_info.SSID.SSID.length);
2185 //NULL Terminate the string.
2186 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2187 }
2188 }
2189 vos_mem_copy(pInfo->countryStr,
2190 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2191
2192 vos_mem_copy(pInfo->apCountryStr,
2193 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2194
2195 return TRUE;
2196}
2197
2198/*
2199 * hdd_link_layer_process_peer_stats () - This function is called after
2200 * receiving Link Layer Peer statistics from FW.This function converts
2201 * the firmware data to the NL data and sends the same to the kernel/upper
2202 * layers.
2203 */
2204static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2205 v_VOID_t *pData)
2206{
2207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208 tpSirWifiPeerStat pWifiPeerStat;
2209 tpSirWifiPeerInfo pWifiPeerInfo;
2210 struct nlattr *peerInfo;
2211 struct sk_buff *vendor_event;
2212 int status, i;
2213
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302214 ENTER();
2215
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 status = wlan_hdd_validate_context(pHddCtx);
2217 if (0 != status)
2218 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219 return;
2220 }
2221
2222 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2223
2224 hddLog(VOS_TRACE_LEVEL_INFO,
2225 "LL_STATS_PEER_ALL : numPeers %u",
2226 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 /*
2228 * Allocate a size of 4096 for the peer stats comprising
2229 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2230 * sizeof (tSirWifiRateStat).Each field is put with an
2231 * NL attribute.The size of 4096 is considered assuming
2232 * that number of rates shall not exceed beyond 50 with
2233 * the sizeof (tSirWifiRateStat) being 32.
2234 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302235 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2236 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302237 if (!vendor_event)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302240 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302241 __func__);
2242 return;
2243 }
2244 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302245 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2246 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2247 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2249 pWifiPeerStat->numPeers))
2250 {
2251 hddLog(VOS_TRACE_LEVEL_ERROR,
2252 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2253 kfree_skb(vendor_event);
2254 return;
2255 }
2256
2257 peerInfo = nla_nest_start(vendor_event,
2258 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302259 if(!peerInfo)
2260 {
2261 hddLog(VOS_TRACE_LEVEL_ERROR,
2262 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2263 __func__);
2264 kfree_skb(vendor_event);
2265 return;
2266 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302267
2268 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2269 pWifiPeerStat->peerInfo);
2270
2271 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2272 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302273 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302274 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302275
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302276 if(!peers)
2277 {
2278 hddLog(VOS_TRACE_LEVEL_ERROR,
2279 "%s: peer stats put fail",
2280 __func__);
2281 kfree_skb(vendor_event);
2282 return;
2283 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302284 if (FALSE == put_wifi_peer_info(
2285 pWifiPeerInfo, vendor_event))
2286 {
2287 hddLog(VOS_TRACE_LEVEL_ERROR,
2288 "%s: put_wifi_peer_info put fail", __func__);
2289 kfree_skb(vendor_event);
2290 return;
2291 }
2292
2293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2294 pWifiPeerStat->peerInfo +
2295 (i * sizeof(tSirWifiPeerInfo)) +
2296 (numRate * sizeof (tSirWifiRateStat)));
2297 nla_nest_end(vendor_event, peers);
2298 }
2299 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302300 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302301 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302302}
2303
2304/*
2305 * hdd_link_layer_process_iface_stats () - This function is called after
2306 * receiving Link Layer Interface statistics from FW.This function converts
2307 * the firmware data to the NL data and sends the same to the kernel/upper
2308 * layers.
2309 */
2310static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2311 v_VOID_t *pData)
2312{
2313 tpSirWifiIfaceStat pWifiIfaceStat;
2314 struct sk_buff *vendor_event;
2315 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2316 int status;
2317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302318 ENTER();
2319
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 status = wlan_hdd_validate_context(pHddCtx);
2321 if (0 != status)
2322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302323 return;
2324 }
2325 /*
2326 * Allocate a size of 4096 for the interface stats comprising
2327 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2328 * assuming that all these fit with in the limit.Please take
2329 * a call on the limit based on the data requirements on
2330 * interface statistics.
2331 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302332 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2333 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302334 if (!vendor_event)
2335 {
2336 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302337 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 return;
2339 }
2340
2341 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2342
Dino Mycle3b9536d2014-07-09 22:05:24 +05302343
2344 if (FALSE == hdd_get_interface_info( pAdapter,
2345 &pWifiIfaceStat->info))
2346 {
2347 hddLog(VOS_TRACE_LEVEL_ERROR,
2348 FL("hdd_get_interface_info get fail") );
2349 kfree_skb(vendor_event);
2350 return;
2351 }
2352
2353 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2354 vendor_event))
2355 {
2356 hddLog(VOS_TRACE_LEVEL_ERROR,
2357 FL("put_wifi_iface_stats fail") );
2358 kfree_skb(vendor_event);
2359 return;
2360 }
2361
Sunil Duttc69bccb2014-05-26 21:30:20 +05302362 hddLog(VOS_TRACE_LEVEL_INFO,
2363 "WMI_LINK_STATS_IFACE Data");
2364
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302365 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302366
2367 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368}
2369
2370/*
2371 * hdd_link_layer_process_radio_stats () - This function is called after
2372 * receiving Link Layer Radio statistics from FW.This function converts
2373 * the firmware data to the NL data and sends the same to the kernel/upper
2374 * layers.
2375 */
2376static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2377 v_VOID_t *pData)
2378{
2379 int status, i;
2380 tpSirWifiRadioStat pWifiRadioStat;
2381 tpSirWifiChannelStats pWifiChannelStats;
2382 struct sk_buff *vendor_event;
2383 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2384 struct nlattr *chList;
2385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302386 ENTER();
2387
Sunil Duttc69bccb2014-05-26 21:30:20 +05302388 status = wlan_hdd_validate_context(pHddCtx);
2389 if (0 != status)
2390 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302391 return;
2392 }
2393 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2394
2395 hddLog(VOS_TRACE_LEVEL_INFO,
2396 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302397 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302398 " radio is %d onTime is %u "
2399 " txTime is %u rxTime is %u "
2400 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302401 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302402 " onTimePnoScan is %u onTimeHs20 is %u "
2403 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302404 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302405 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2406 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2407 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302409 pWifiRadioStat->onTimeRoamScan,
2410 pWifiRadioStat->onTimePnoScan,
2411 pWifiRadioStat->onTimeHs20,
2412 pWifiRadioStat->numChannels);
2413 /*
2414 * Allocate a size of 4096 for the Radio stats comprising
2415 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2416 * (tSirWifiChannelStats).Each channel data is put with an
2417 * NL attribute.The size of 4096 is considered assuming that
2418 * number of channels shall not exceed beyond 60 with the
2419 * sizeof (tSirWifiChannelStats) being 24 bytes.
2420 */
2421
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302422 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2423 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 if (!vendor_event)
2425 {
2426 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302427 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302428 return;
2429 }
2430
2431 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302432 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2433 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2434 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2436 pWifiRadioStat->radio) ||
2437 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302438 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2439 NUM_RADIOS) ||
2440 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302441 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2442 pWifiRadioStat->onTime) ||
2443 nla_put_u32(vendor_event,
2444 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2445 pWifiRadioStat->txTime) ||
2446 nla_put_u32(vendor_event,
2447 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2448 pWifiRadioStat->rxTime) ||
2449 nla_put_u32(vendor_event,
2450 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2451 pWifiRadioStat->onTimeScan) ||
2452 nla_put_u32(vendor_event,
2453 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2454 pWifiRadioStat->onTimeNbd) ||
2455 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2457 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302458 nla_put_u32(vendor_event,
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2460 pWifiRadioStat->onTimeRoamScan) ||
2461 nla_put_u32(vendor_event,
2462 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2463 pWifiRadioStat->onTimePnoScan) ||
2464 nla_put_u32(vendor_event,
2465 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2466 pWifiRadioStat->onTimeHs20) ||
2467 nla_put_u32(vendor_event,
2468 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2469 pWifiRadioStat->numChannels))
2470 {
2471 hddLog(VOS_TRACE_LEVEL_ERROR,
2472 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2473 kfree_skb(vendor_event);
2474 return ;
2475 }
2476
2477 chList = nla_nest_start(vendor_event,
2478 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302479 if(!chList)
2480 {
2481 hddLog(VOS_TRACE_LEVEL_ERROR,
2482 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2483 __func__);
2484 kfree_skb(vendor_event);
2485 return;
2486 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302487 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2488 {
2489 struct nlattr *chInfo;
2490
2491 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2492 pWifiRadioStat->channels +
2493 (i * sizeof(tSirWifiChannelStats)));
2494
Sunil Duttc69bccb2014-05-26 21:30:20 +05302495 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302496 if(!chInfo)
2497 {
2498 hddLog(VOS_TRACE_LEVEL_ERROR,
2499 "%s: failed to put chInfo",
2500 __func__);
2501 kfree_skb(vendor_event);
2502 return;
2503 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302504
2505 if (nla_put_u32(vendor_event,
2506 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2507 pWifiChannelStats->channel.width) ||
2508 nla_put_u32(vendor_event,
2509 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2510 pWifiChannelStats->channel.centerFreq) ||
2511 nla_put_u32(vendor_event,
2512 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2513 pWifiChannelStats->channel.centerFreq0) ||
2514 nla_put_u32(vendor_event,
2515 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2516 pWifiChannelStats->channel.centerFreq1) ||
2517 nla_put_u32(vendor_event,
2518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2519 pWifiChannelStats->onTime) ||
2520 nla_put_u32(vendor_event,
2521 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2522 pWifiChannelStats->ccaBusyTime))
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR,
2525 FL("cfg80211_vendor_event_alloc failed") );
2526 kfree_skb(vendor_event);
2527 return ;
2528 }
2529 nla_nest_end(vendor_event, chInfo);
2530 }
2531 nla_nest_end(vendor_event, chList);
2532
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302534
2535 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 return;
2537}
2538
2539/*
2540 * hdd_link_layer_stats_ind_callback () - This function is called after
2541 * receiving Link Layer indications from FW.This callback converts the firmware
2542 * data to the NL data and send the same to the kernel/upper layers.
2543 */
2544static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2545 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302546 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302547{
Dino Mycled3d50022014-07-07 12:58:25 +05302548 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2549 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302550 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302551 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302552 int status;
2553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302554 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302556 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302557 if (0 != status)
2558 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 return;
2560 }
2561
Dino Mycled3d50022014-07-07 12:58:25 +05302562 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2563 if (NULL == pAdapter)
2564 {
2565 hddLog(VOS_TRACE_LEVEL_ERROR,
2566 FL(" MAC address %pM does not exist with host"),
2567 macAddr);
2568 return;
2569 }
2570
Sunil Duttc69bccb2014-05-26 21:30:20 +05302571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302572 "%s: Interface: %s LLStats indType: %d", __func__,
2573 pAdapter->dev->name, indType);
2574
Sunil Duttc69bccb2014-05-26 21:30:20 +05302575 switch (indType)
2576 {
2577 case SIR_HAL_LL_STATS_RESULTS_RSP:
2578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302579 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302580 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2581 "respId = %u, moreResultToFollow = %u",
2582 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2583 macAddr, linkLayerStatsResults->respId,
2584 linkLayerStatsResults->moreResultToFollow);
2585
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302586 spin_lock(&hdd_context_lock);
2587 context = &pHddCtx->ll_stats_context;
2588 /* validate response received from target */
2589 if ((context->request_id != linkLayerStatsResults->respId) ||
2590 !(context->request_bitmap & linkLayerStatsResults->paramId))
2591 {
2592 spin_unlock(&hdd_context_lock);
2593 hddLog(LOGE,
2594 FL("Error : Request id %d response id %d request bitmap 0x%x"
2595 "response bitmap 0x%x"),
2596 context->request_id, linkLayerStatsResults->respId,
2597 context->request_bitmap, linkLayerStatsResults->paramId);
2598 return;
2599 }
2600 spin_unlock(&hdd_context_lock);
2601
Sunil Duttc69bccb2014-05-26 21:30:20 +05302602 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2603 {
2604 hdd_link_layer_process_radio_stats(pAdapter,
2605 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302606 spin_lock(&hdd_context_lock);
2607 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2608 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302609 }
2610 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2611 {
2612 hdd_link_layer_process_iface_stats(pAdapter,
2613 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302614 spin_lock(&hdd_context_lock);
2615 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2616 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302617 }
2618 else if ( linkLayerStatsResults->paramId &
2619 WMI_LINK_STATS_ALL_PEER )
2620 {
2621 hdd_link_layer_process_peer_stats(pAdapter,
2622 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302623 spin_lock(&hdd_context_lock);
2624 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2625 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302626 } /* WMI_LINK_STATS_ALL_PEER */
2627 else
2628 {
2629 hddLog(VOS_TRACE_LEVEL_ERROR,
2630 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2631 }
2632
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302633 spin_lock(&hdd_context_lock);
2634 /* complete response event if all requests are completed */
2635 if (0 == context->request_bitmap)
2636 complete(&context->response_event);
2637 spin_unlock(&hdd_context_lock);
2638
Sunil Duttc69bccb2014-05-26 21:30:20 +05302639 break;
2640 }
2641 default:
2642 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2643 break;
2644 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302645
2646 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302647 return;
2648}
2649
2650const struct
2651nla_policy
2652qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2653{
2654 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2655 { .type = NLA_U32 },
2656 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2657 { .type = NLA_U32 },
2658};
2659
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302660static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2661 struct wireless_dev *wdev,
2662 const void *data,
2663 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302664{
2665 int status;
2666 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302667 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668 struct net_device *dev = wdev->netdev;
2669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2670 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2671
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302672 ENTER();
2673
Sunil Duttc69bccb2014-05-26 21:30:20 +05302674 status = wlan_hdd_validate_context(pHddCtx);
2675 if (0 != status)
2676 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302677 return -EINVAL;
2678 }
2679
2680 if (NULL == pAdapter)
2681 {
2682 hddLog(VOS_TRACE_LEVEL_ERROR,
2683 FL("HDD adapter is Null"));
2684 return -ENODEV;
2685 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302686 /* check the LLStats Capability */
2687 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2688 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2689 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302690 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302691 FL("Link Layer Statistics not supported by Firmware"));
2692 return -EINVAL;
2693 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302694
2695 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2696 (struct nlattr *)data,
2697 data_len, qca_wlan_vendor_ll_set_policy))
2698 {
2699 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2700 return -EINVAL;
2701 }
2702 if (!tb_vendor
2703 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2704 {
2705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2706 return -EINVAL;
2707 }
2708 if (!tb_vendor[
2709 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2710 {
2711 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2712 return -EINVAL;
2713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302714 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302715 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302716
Dino Mycledf0a5d92014-07-04 09:41:55 +05302717 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 nla_get_u32(
2719 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2720
Dino Mycledf0a5d92014-07-04 09:41:55 +05302721 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302722 nla_get_u32(
2723 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2724
Dino Mycled3d50022014-07-07 12:58:25 +05302725 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2726 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727
2728
2729 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302730 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2731 "Statistics Gathering = %d ",
2732 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2733 linkLayerStatsSetReq.mpduSizeThreshold,
2734 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302735
2736 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2737 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302738 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302739 {
2740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2741 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302742 return -EINVAL;
2743
2744 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302745
Sunil Duttc69bccb2014-05-26 21:30:20 +05302746 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302747 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 {
2749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2750 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302751 return -EINVAL;
2752 }
2753
2754 pAdapter->isLinkLayerStatsSet = 1;
2755
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302756 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302757 return 0;
2758}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302759static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2760 struct wireless_dev *wdev,
2761 const void *data,
2762 int data_len)
2763{
2764 int ret = 0;
2765
2766 vos_ssr_protect(__func__);
2767 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2768 vos_ssr_unprotect(__func__);
2769
2770 return ret;
2771}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302772
2773const struct
2774nla_policy
2775qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2776{
2777 /* Unsigned 32bit value provided by the caller issuing the GET stats
2778 * command. When reporting
2779 * the stats results, the driver uses the same value to indicate
2780 * which GET request the results
2781 * correspond to.
2782 */
2783 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2784
2785 /* Unsigned 32bit value . bit mask to identify what statistics are
2786 requested for retrieval */
2787 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2788};
2789
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302790static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2791 struct wireless_dev *wdev,
2792 const void *data,
2793 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302794{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302795 unsigned long rc;
2796 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302797 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2798 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302799 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302800 struct net_device *dev = wdev->netdev;
2801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302803 int status;
2804
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302805 ENTER();
2806
Sunil Duttc69bccb2014-05-26 21:30:20 +05302807 status = wlan_hdd_validate_context(pHddCtx);
2808 if (0 != status)
2809 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302810 return -EINVAL ;
2811 }
2812
2813 if (NULL == pAdapter)
2814 {
2815 hddLog(VOS_TRACE_LEVEL_FATAL,
2816 "%s: HDD adapter is Null", __func__);
2817 return -ENODEV;
2818 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302819
2820 if (pHddStaCtx == NULL)
2821 {
2822 hddLog(VOS_TRACE_LEVEL_FATAL,
2823 "%s: HddStaCtx is Null", __func__);
2824 return -ENODEV;
2825 }
2826
Dino Mycledf0a5d92014-07-04 09:41:55 +05302827 /* check the LLStats Capability */
2828 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2829 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2830 {
2831 hddLog(VOS_TRACE_LEVEL_ERROR,
2832 FL("Link Layer Statistics not supported by Firmware"));
2833 return -EINVAL;
2834 }
2835
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (!pAdapter->isLinkLayerStatsSet)
2838 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302839 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 "%s: isLinkLayerStatsSet : %d",
2841 __func__, pAdapter->isLinkLayerStatsSet);
2842 return -EINVAL;
2843 }
2844
Mukul Sharma10313ba2015-07-29 19:14:39 +05302845 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2846 {
2847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2848 "%s: Roaming in progress, so unable to proceed this request", __func__);
2849 return -EBUSY;
2850 }
2851
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2853 (struct nlattr *)data,
2854 data_len, qca_wlan_vendor_ll_get_policy))
2855 {
2856 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2857 return -EINVAL;
2858 }
2859
2860 if (!tb_vendor
2861 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2862 {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2864 return -EINVAL;
2865 }
2866
2867 if (!tb_vendor
2868 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2869 {
2870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2871 return -EINVAL;
2872 }
2873
Sunil Duttc69bccb2014-05-26 21:30:20 +05302874
Dino Mycledf0a5d92014-07-04 09:41:55 +05302875 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302876 nla_get_u32( tb_vendor[
2877 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302878 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302879 nla_get_u32( tb_vendor[
2880 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2881
Dino Mycled3d50022014-07-07 12:58:25 +05302882 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2883 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302884
2885 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302886 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2887 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302888 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302889
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302890 spin_lock(&hdd_context_lock);
2891 context = &pHddCtx->ll_stats_context;
2892 context->request_id = linkLayerStatsGetReq.reqId;
2893 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2894 INIT_COMPLETION(context->response_event);
2895 spin_unlock(&hdd_context_lock);
2896
Sunil Duttc69bccb2014-05-26 21:30:20 +05302897 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302898 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302899 {
2900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2901 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302902 return -EINVAL;
2903 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302904
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302905 rc = wait_for_completion_timeout(&context->response_event,
2906 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2907 if (!rc)
2908 {
2909 hddLog(LOGE,
2910 FL("Target response timed out request id %d request bitmap 0x%x"),
2911 context->request_id, context->request_bitmap);
2912 return -ETIMEDOUT;
2913 }
2914
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302915 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302916 return 0;
2917}
2918
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302919static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2920 struct wireless_dev *wdev,
2921 const void *data,
2922 int data_len)
2923{
2924 int ret = 0;
2925
2926 vos_ssr_protect(__func__);
2927 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2928 vos_ssr_unprotect(__func__);
2929
2930 return ret;
2931}
2932
Sunil Duttc69bccb2014-05-26 21:30:20 +05302933const struct
2934nla_policy
2935qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2936{
2937 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2938 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2939 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2941};
2942
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302943static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2944 struct wireless_dev *wdev,
2945 const void *data,
2946 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302947{
2948 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2949 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302950 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302951 struct net_device *dev = wdev->netdev;
2952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2953 u32 statsClearReqMask;
2954 u8 stopReq;
2955 int status;
2956
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302957 ENTER();
2958
Sunil Duttc69bccb2014-05-26 21:30:20 +05302959 status = wlan_hdd_validate_context(pHddCtx);
2960 if (0 != status)
2961 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302962 return -EINVAL;
2963 }
2964
2965 if (NULL == pAdapter)
2966 {
2967 hddLog(VOS_TRACE_LEVEL_FATAL,
2968 "%s: HDD adapter is Null", __func__);
2969 return -ENODEV;
2970 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302971 /* check the LLStats Capability */
2972 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2973 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2974 {
2975 hddLog(VOS_TRACE_LEVEL_ERROR,
2976 FL("Enable LLStats Capability"));
2977 return -EINVAL;
2978 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302979
2980 if (!pAdapter->isLinkLayerStatsSet)
2981 {
2982 hddLog(VOS_TRACE_LEVEL_FATAL,
2983 "%s: isLinkLayerStatsSet : %d",
2984 __func__, pAdapter->isLinkLayerStatsSet);
2985 return -EINVAL;
2986 }
2987
2988 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2989 (struct nlattr *)data,
2990 data_len, qca_wlan_vendor_ll_clr_policy))
2991 {
2992 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2993 return -EINVAL;
2994 }
2995
2996 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2997
2998 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2999 {
3000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3001 return -EINVAL;
3002
3003 }
3004
Sunil Duttc69bccb2014-05-26 21:30:20 +05303005
Dino Mycledf0a5d92014-07-04 09:41:55 +05303006 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303007 nla_get_u32(
3008 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3009
Dino Mycledf0a5d92014-07-04 09:41:55 +05303010 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303011 nla_get_u8(
3012 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3013
3014 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303015 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303016
Dino Mycled3d50022014-07-07 12:58:25 +05303017 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3018 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303019
3020 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303021 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3022 "statsClearReqMask = 0x%X, stopReq = %d",
3023 linkLayerStatsClearReq.reqId,
3024 linkLayerStatsClearReq.macAddr,
3025 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303026 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303027
3028 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303029 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303030 {
3031 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303032 hdd_station_ctx_t *pHddStaCtx;
3033
3034 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3035 if (VOS_STATUS_SUCCESS !=
3036 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3037 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3038 {
3039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3040 "WLANTL_ClearInterfaceStats Failed", __func__);
3041 return -EINVAL;
3042 }
3043 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3044 (statsClearReqMask & WIFI_STATS_IFACE)) {
3045 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3046 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3047 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3049 }
3050
Sunil Duttc69bccb2014-05-26 21:30:20 +05303051 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3052 2 * sizeof(u32) +
3053 NLMSG_HDRLEN);
3054
3055 if (temp_skbuff != NULL)
3056 {
3057
3058 if (nla_put_u32(temp_skbuff,
3059 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3060 statsClearReqMask) ||
3061 nla_put_u32(temp_skbuff,
3062 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3063 stopReq))
3064 {
3065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3066 kfree_skb(temp_skbuff);
3067 return -EINVAL;
3068 }
3069 /* If the ask is to stop the stats collection as part of clear
3070 * (stopReq = 1) , ensure that no further requests of get
3071 * go to the firmware by having isLinkLayerStatsSet set to 0.
3072 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303073 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303074 * case the firmware is just asked to clear the statistics.
3075 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303076 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303077 pAdapter->isLinkLayerStatsSet = 0;
3078 return cfg80211_vendor_cmd_reply(temp_skbuff);
3079 }
3080 return -ENOMEM;
3081 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303082
3083 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303084 return -EINVAL;
3085}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303086static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3087 struct wireless_dev *wdev,
3088 const void *data,
3089 int data_len)
3090{
3091 int ret = 0;
3092
3093 vos_ssr_protect(__func__);
3094 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3095 vos_ssr_unprotect(__func__);
3096
3097 return ret;
3098
3099
3100}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303101#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3102
Dino Mycle6fb96c12014-06-10 11:52:40 +05303103#ifdef WLAN_FEATURE_EXTSCAN
3104static const struct nla_policy
3105wlan_hdd_extscan_config_policy
3106 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3107{
3108 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3109 { .type = NLA_U32 },
3110 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3111 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3113 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3116 { .type = NLA_U32 },
3117 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3119
3120 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3124 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3126 { .type = NLA_U32 },
3127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3128 { .type = NLA_U32 },
3129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3130 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3132 { .type = NLA_U32 },
3133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3134 { .type = NLA_U32 },
3135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3136 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3138 { .type = NLA_U8 },
3139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303140 { .type = NLA_U8 },
3141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3142 { .type = NLA_U8 },
3143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3144 { .type = NLA_U8 },
3145
3146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3147 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3149 .type = NLA_UNSPEC,
3150 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3152 { .type = NLA_S32 },
3153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3154 { .type = NLA_S32 },
3155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3156 { .type = NLA_U32 },
3157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3158 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3160 { .type = NLA_U32 },
3161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3162 { .type = NLA_BINARY,
3163 .len = IEEE80211_MAX_SSID_LEN + 1 },
3164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3167 { .type = NLA_U32 },
3168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3169 { .type = NLA_U8 },
3170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3171 { .type = NLA_S32 },
3172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3173 { .type = NLA_S32 },
3174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3175 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303176};
3177
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303178/**
3179 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3180 * @ctx: hdd global context
3181 * @data: capabilities data
3182 *
3183 * Return: none
3184 */
3185static void
3186wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303187{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303188 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303189 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303190 tSirEXTScanCapabilitiesEvent *data =
3191 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303193 ENTER();
3194
3195 if (wlan_hdd_validate_context(pHddCtx))
3196 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303197 return;
3198 }
3199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303200 if (!pMsg)
3201 {
3202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3203 return;
3204 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303206 vos_spin_lock_acquire(&hdd_context_lock);
3207
3208 context = &pHddCtx->ext_scan_context;
3209 /* validate response received from target*/
3210 if (context->request_id != data->requestId)
3211 {
3212 vos_spin_lock_release(&hdd_context_lock);
3213 hddLog(LOGE,
3214 FL("Target response id did not match: request_id %d resposne_id %d"),
3215 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 return;
3217 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303218 else
3219 {
3220 context->capability_response = *data;
3221 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 }
3223
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303224 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 return;
3227}
3228
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303229/*
3230 * define short names for the global vendor params
3231 * used by wlan_hdd_send_ext_scan_capability()
3232 */
3233#define PARAM_REQUEST_ID \
3234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3235#define PARAM_STATUS \
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3237#define MAX_SCAN_CACHE_SIZE \
3238 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3239#define MAX_SCAN_BUCKETS \
3240 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3241#define MAX_AP_CACHE_PER_SCAN \
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3243#define MAX_RSSI_SAMPLE_SIZE \
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3245#define MAX_SCAN_RPT_THRHOLD \
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3247#define MAX_HOTLIST_BSSIDS \
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3249#define MAX_BSSID_HISTORY_ENTRIES \
3250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3251#define MAX_HOTLIST_SSIDS \
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303253#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303255
3256static int wlan_hdd_send_ext_scan_capability(void *ctx)
3257{
3258 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3259 struct sk_buff *skb = NULL;
3260 int ret;
3261 tSirEXTScanCapabilitiesEvent *data;
3262 tANI_U32 nl_buf_len;
3263
3264 ret = wlan_hdd_validate_context(pHddCtx);
3265 if (0 != ret)
3266 {
3267 return ret;
3268 }
3269
3270 data = &(pHddCtx->ext_scan_context.capability_response);
3271
3272 nl_buf_len = NLMSG_HDRLEN;
3273 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3274 (sizeof(data->status) + NLA_HDRLEN) +
3275 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3276 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3277 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3278 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3279 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3280 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3281 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3282 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3283
3284 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3285
3286 if (!skb)
3287 {
3288 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3289 return -ENOMEM;
3290 }
3291
3292 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3293 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3294 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3295 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3296 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3297 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3298 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3299 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3300
3301 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3302 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3303 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3304 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3305 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3306 data->maxApPerScan) ||
3307 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3308 data->maxRssiSampleSize) ||
3309 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3310 data->maxScanReportingThreshold) ||
3311 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3312 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3313 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303314 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3315 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303316 {
3317 hddLog(LOGE, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320
3321 cfg80211_vendor_cmd_reply(skb);
3322 return 0;
3323
3324nla_put_failure:
3325 kfree_skb(skb);
3326 return -EINVAL;;
3327}
3328
3329/*
3330 * done with short names for the global vendor params
3331 * used by wlan_hdd_send_ext_scan_capability()
3332 */
3333#undef PARAM_REQUEST_ID
3334#undef PARAM_STATUS
3335#undef MAX_SCAN_CACHE_SIZE
3336#undef MAX_SCAN_BUCKETS
3337#undef MAX_AP_CACHE_PER_SCAN
3338#undef MAX_RSSI_SAMPLE_SIZE
3339#undef MAX_SCAN_RPT_THRHOLD
3340#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303341#undef MAX_BSSID_HISTORY_ENTRIES
3342#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343
3344static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3345{
3346 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3347 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303349 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303351 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303352
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303353 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303354 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303356 if (!pMsg)
3357 {
3358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359 return;
3360 }
3361
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3363 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3364
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303365 context = &pHddCtx->ext_scan_context;
3366 spin_lock(&hdd_context_lock);
3367 if (context->request_id == pData->requestId) {
3368 context->response_status = pData->status ? -EINVAL : 0;
3369 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303371 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303372
3373 /*
3374 * Store the Request ID for comparing with the requestID obtained
3375 * in other requests.HDD shall return a failure is the extscan_stop
3376 * request is issued with a different requestId as that of the
3377 * extscan_start request. Also, This requestId shall be used while
3378 * indicating the full scan results to the upper layers.
3379 * The requestId is stored with the assumption that the firmware
3380 * shall return the ext scan start request's requestId in ext scan
3381 * start response.
3382 */
3383 if (pData->status == 0)
3384 pMac->sme.extScanStartReqId = pData->requestId;
3385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303386 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303387 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388}
3389
3390
3391static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3392{
3393 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303395 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303397 ENTER();
3398
3399 if (wlan_hdd_validate_context(pHddCtx)){
3400 return;
3401 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303403 if (!pMsg)
3404 {
3405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303406 return;
3407 }
3408
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303409 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3410 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303412 context = &pHddCtx->ext_scan_context;
3413 spin_lock(&hdd_context_lock);
3414 if (context->request_id == pData->requestId) {
3415 context->response_status = pData->status ? -EINVAL : 0;
3416 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303418 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303420 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303422}
3423
Dino Mycle6fb96c12014-06-10 11:52:40 +05303424static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3425 void *pMsg)
3426{
3427 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303428 tpSirEXTScanSetBssidHotListRspParams pData =
3429 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303430 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303432 ENTER();
3433
3434 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435 return;
3436 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303437
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 if (!pMsg)
3439 {
3440 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3441 return;
3442 }
3443
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3445 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303447 context = &pHddCtx->ext_scan_context;
3448 spin_lock(&hdd_context_lock);
3449 if (context->request_id == pData->requestId) {
3450 context->response_status = pData->status ? -EINVAL : 0;
3451 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303453 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457}
3458
3459static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3460 void *pMsg)
3461{
3462 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 tpSirEXTScanResetBssidHotlistRspParams pData =
3464 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303465 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 ENTER();
3468
3469 if (wlan_hdd_validate_context(pHddCtx)) {
3470 return;
3471 }
3472 if (!pMsg)
3473 {
3474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 return;
3476 }
3477
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303478 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3479 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303481 context = &pHddCtx->ext_scan_context;
3482 spin_lock(&hdd_context_lock);
3483 if (context->request_id == pData->requestId) {
3484 context->response_status = pData->status ? -EINVAL : 0;
3485 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303487 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303489 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491}
3492
Dino Mycle6fb96c12014-06-10 11:52:40 +05303493static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3494 void *pMsg)
3495{
3496 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3497 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303498 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 tANI_S32 totalResults;
3500 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303501 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3502 struct hdd_ext_scan_context *context;
3503 bool ignore_cached_results = false;
3504 tExtscanCachedScanResult *result;
3505 struct nlattr *nla_results;
3506 tANI_U16 ieLength= 0;
3507 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303509 ENTER();
3510
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303511 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303514 if (!pMsg)
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3517 return;
3518 }
3519
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303520 spin_lock(&hdd_context_lock);
3521 context = &pHddCtx->ext_scan_context;
3522 ignore_cached_results = context->ignore_cached_results;
3523 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303525 if (ignore_cached_results) {
3526 hddLog(LOGE,
3527 FL("Ignore the cached results received after timeout"));
3528 return;
3529 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303531 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3532 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303534 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303536 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3537 scan_id_index++) {
3538 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303540 totalResults = result->num_results;
3541 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3542 result->scan_id, result->flags, totalResults);
3543 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303545 do{
3546 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3547 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3548 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303550 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3551 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3552
3553 if (!skb) {
3554 hddLog(VOS_TRACE_LEVEL_ERROR,
3555 FL("cfg80211_vendor_event_alloc failed"));
3556 return;
3557 }
3558
3559 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3560
3561 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3562 pData->requestId) ||
3563 nla_put_u32(skb,
3564 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3565 resultsPerEvent)) {
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3567 goto fail;
3568 }
3569 if (nla_put_u8(skb,
3570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3571 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572 {
3573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3574 goto fail;
3575 }
3576
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303577 if (nla_put_u32(skb,
3578 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3579 result->scan_id)) {
3580 hddLog(LOGE, FL("put fail"));
3581 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303584 nla_results = nla_nest_start(skb,
3585 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3586 if (!nla_results)
3587 goto fail;
3588
3589 if (resultsPerEvent) {
3590 struct nlattr *aps;
3591 struct nlattr *nla_result;
3592
3593 nla_result = nla_nest_start(skb, scan_id_index);
3594 if(!nla_result)
3595 goto fail;
3596
3597 if (nla_put_u32(skb,
3598 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3599 result->scan_id) ||
3600 nla_put_u32(skb,
3601 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3602 result->flags) ||
3603 nla_put_u32(skb,
3604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3605 totalResults)) {
3606 hddLog(LOGE, FL("put fail"));
3607 goto fail;
3608 }
3609
3610 aps = nla_nest_start(skb,
3611 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3612 if (!aps)
3613 {
3614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3615 goto fail;
3616 }
3617
3618 head_ptr = (tpSirWifiScanResult) &(result->ap);
3619
3620 for (j = 0; j < resultsPerEvent; j++, i++) {
3621 struct nlattr *ap;
3622 pSirWifiScanResult = head_ptr + i;
3623
3624 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303625 * Firmware returns timestamp from extscan_start till
3626 * BSSID was cached (in micro seconds). Add this with
3627 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303628 * to derive the time since boot when the
3629 * BSSID was cached.
3630 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303631 pSirWifiScanResult->ts +=
3632 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303633 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3634 "Ssid (%s)"
3635 "Bssid: %pM "
3636 "Channel (%u)"
3637 "Rssi (%d)"
3638 "RTT (%u)"
3639 "RTT_SD (%u)"
3640 "Beacon Period %u"
3641 "Capability 0x%x "
3642 "Ie length %d",
3643 i,
3644 pSirWifiScanResult->ts,
3645 pSirWifiScanResult->ssid,
3646 pSirWifiScanResult->bssid,
3647 pSirWifiScanResult->channel,
3648 pSirWifiScanResult->rssi,
3649 pSirWifiScanResult->rtt,
3650 pSirWifiScanResult->rtt_sd,
3651 pSirWifiScanResult->beaconPeriod,
3652 pSirWifiScanResult->capability,
3653 ieLength);
3654
3655 ap = nla_nest_start(skb, j + 1);
3656 if (!ap)
3657 {
3658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3659 goto fail;
3660 }
3661
3662 if (nla_put_u64(skb,
3663 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3664 pSirWifiScanResult->ts) )
3665 {
3666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3667 goto fail;
3668 }
3669 if (nla_put(skb,
3670 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3671 sizeof(pSirWifiScanResult->ssid),
3672 pSirWifiScanResult->ssid) )
3673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677 if (nla_put(skb,
3678 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3679 sizeof(pSirWifiScanResult->bssid),
3680 pSirWifiScanResult->bssid) )
3681 {
3682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3683 goto fail;
3684 }
3685 if (nla_put_u32(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3687 pSirWifiScanResult->channel) )
3688 {
3689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3690 goto fail;
3691 }
3692 if (nla_put_s32(skb,
3693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3694 pSirWifiScanResult->rssi) )
3695 {
3696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3697 goto fail;
3698 }
3699 if (nla_put_u32(skb,
3700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3701 pSirWifiScanResult->rtt) )
3702 {
3703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3704 goto fail;
3705 }
3706 if (nla_put_u32(skb,
3707 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3708 pSirWifiScanResult->rtt_sd))
3709 {
3710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3711 goto fail;
3712 }
3713 if (nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3715 pSirWifiScanResult->beaconPeriod))
3716 {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3718 goto fail;
3719 }
3720 if (nla_put_u32(skb,
3721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3722 pSirWifiScanResult->capability))
3723 {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3725 goto fail;
3726 }
3727 if (nla_put_u32(skb,
3728 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3729 ieLength))
3730 {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3732 goto fail;
3733 }
3734
3735 if (ieLength)
3736 if (nla_put(skb,
3737 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3738 ieLength, ie)) {
3739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3740 goto fail;
3741 }
3742
3743 nla_nest_end(skb, ap);
3744 }
3745 nla_nest_end(skb, aps);
3746 nla_nest_end(skb, nla_result);
3747 }
3748
3749 nla_nest_end(skb, nla_results);
3750
3751 cfg80211_vendor_cmd_reply(skb);
3752
3753 } while (totalResults > 0);
3754 }
3755
3756 if (!pData->moreData) {
3757 spin_lock(&hdd_context_lock);
3758 context->response_status = 0;
3759 complete(&context->response_event);
3760 spin_unlock(&hdd_context_lock);
3761 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303763 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303764 return;
3765fail:
3766 kfree_skb(skb);
3767 return;
3768}
3769
3770static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3771 void *pMsg)
3772{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303773 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3775 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303776 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303777
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303778 ENTER();
3779
3780 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303781 hddLog(LOGE,
3782 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303783 return;
3784 }
3785 if (!pMsg)
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303788 return;
3789 }
3790
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303791 if (pData->bss_found)
3792 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3793 else
3794 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3795
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3798 NULL,
3799#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303801 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802
3803 if (!skb) {
3804 hddLog(VOS_TRACE_LEVEL_ERROR,
3805 FL("cfg80211_vendor_event_alloc failed"));
3806 return;
3807 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303809 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3810 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3811 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3812 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3813
3814 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3816 "Ssid (%s) "
3817 "Bssid (" MAC_ADDRESS_STR ") "
3818 "Channel (%u) "
3819 "Rssi (%d) "
3820 "RTT (%u) "
3821 "RTT_SD (%u) ",
3822 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303823 pData->bssHotlist[i].ts,
3824 pData->bssHotlist[i].ssid,
3825 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3826 pData->bssHotlist[i].channel,
3827 pData->bssHotlist[i].rssi,
3828 pData->bssHotlist[i].rtt,
3829 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830 }
3831
3832 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3833 pData->requestId) ||
3834 nla_put_u32(skb,
3835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303836 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3838 goto fail;
3839 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303840 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303841 struct nlattr *aps;
3842
3843 aps = nla_nest_start(skb,
3844 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3845 if (!aps)
3846 goto fail;
3847
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303848 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303849 struct nlattr *ap;
3850
3851 ap = nla_nest_start(skb, i + 1);
3852 if (!ap)
3853 goto fail;
3854
3855 if (nla_put_u64(skb,
3856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303857 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303858 nla_put(skb,
3859 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303860 sizeof(pData->bssHotlist[i].ssid),
3861 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862 nla_put(skb,
3863 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303864 sizeof(pData->bssHotlist[i].bssid),
3865 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303866 nla_put_u32(skb,
3867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303868 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869 nla_put_s32(skb,
3870 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303871 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872 nla_put_u32(skb,
3873 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 nla_put_u32(skb,
3876 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878 goto fail;
3879
3880 nla_nest_end(skb, ap);
3881 }
3882 nla_nest_end(skb, aps);
3883
3884 if (nla_put_u8(skb,
3885 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3886 pData->moreData))
3887 goto fail;
3888 }
3889
3890 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303892 return;
3893
3894fail:
3895 kfree_skb(skb);
3896 return;
3897
3898}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899
3900static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3901 void *pMsg)
3902{
3903 struct sk_buff *skb;
3904 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3905 tpSirWifiFullScanResultEvent pData =
3906 (tpSirWifiFullScanResultEvent) (pMsg);
3907
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303908 ENTER();
3909
3910 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303911 hddLog(LOGE,
3912 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303913 return;
3914 }
3915 if (!pMsg)
3916 {
3917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 return;
3919 }
3920
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303921 /*
3922 * If the full scan result including IE data exceeds NL 4K size
3923 * limitation, drop that beacon/probe rsp frame.
3924 */
3925 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3926 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3927 return;
3928 }
3929
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3932 NULL,
3933#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303934 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3935 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3936 GFP_KERNEL);
3937
3938 if (!skb) {
3939 hddLog(VOS_TRACE_LEVEL_ERROR,
3940 FL("cfg80211_vendor_event_alloc failed"));
3941 return;
3942 }
3943
Dino Mycle6fb96c12014-06-10 11:52:40 +05303944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3945 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3946 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3947 "Ssid (%s)"
3948 "Bssid (" MAC_ADDRESS_STR ")"
3949 "Channel (%u)"
3950 "Rssi (%d)"
3951 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303952 "RTT_SD (%u)"
3953 "Bcn Period %d"
3954 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955 pData->ap.ts,
3956 pData->ap.ssid,
3957 MAC_ADDR_ARRAY(pData->ap.bssid),
3958 pData->ap.channel,
3959 pData->ap.rssi,
3960 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303961 pData->ap.rtt_sd,
3962 pData->ap.beaconPeriod,
3963 pData->ap.capability);
3964
Dino Mycle6fb96c12014-06-10 11:52:40 +05303965 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3966 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3967 pData->requestId) ||
3968 nla_put_u64(skb,
3969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3970 pData->ap.ts) ||
3971 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3972 sizeof(pData->ap.ssid),
3973 pData->ap.ssid) ||
3974 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3975 WNI_CFG_BSSID_LEN,
3976 pData->ap.bssid) ||
3977 nla_put_u32(skb,
3978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3979 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303980 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303981 pData->ap.rssi) ||
3982 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3983 pData->ap.rtt) ||
3984 nla_put_u32(skb,
3985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3986 pData->ap.rtt_sd) ||
3987 nla_put_u16(skb,
3988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3989 pData->ap.beaconPeriod) ||
3990 nla_put_u16(skb,
3991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3992 pData->ap.capability) ||
3993 nla_put_u32(skb,
3994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303995 pData->ieLength) ||
3996 nla_put_u8(skb,
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3998 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303999 {
4000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4001 goto nla_put_failure;
4002 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304003
4004 if (pData->ieLength) {
4005 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4006 pData->ieLength,
4007 pData->ie))
4008 {
4009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4010 goto nla_put_failure;
4011 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304012 }
4013
4014 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304015 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304016 return;
4017
4018nla_put_failure:
4019 kfree_skb(skb);
4020 return;
4021}
4022
4023static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4024 void *pMsg)
4025{
4026 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4027 struct sk_buff *skb = NULL;
4028 tpSirEXTScanResultsAvailableIndParams pData =
4029 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4030
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304031 ENTER();
4032
4033 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304034 hddLog(LOGE,
4035 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304036 return;
4037 }
4038 if (!pMsg)
4039 {
4040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 return;
4042 }
4043
4044 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4046 NULL,
4047#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4049 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4050 GFP_KERNEL);
4051
4052 if (!skb) {
4053 hddLog(VOS_TRACE_LEVEL_ERROR,
4054 FL("cfg80211_vendor_event_alloc failed"));
4055 return;
4056 }
4057
Dino Mycle6fb96c12014-06-10 11:52:40 +05304058 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4059 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4060 pData->numResultsAvailable);
4061 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4062 pData->requestId) ||
4063 nla_put_u32(skb,
4064 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4065 pData->numResultsAvailable)) {
4066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4067 goto nla_put_failure;
4068 }
4069
4070 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304071 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304072 return;
4073
4074nla_put_failure:
4075 kfree_skb(skb);
4076 return;
4077}
4078
4079static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4080{
4081 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4082 struct sk_buff *skb = NULL;
4083 tpSirEXTScanProgressIndParams pData =
4084 (tpSirEXTScanProgressIndParams) pMsg;
4085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304086 ENTER();
4087
4088 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304089 hddLog(LOGE,
4090 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304091 return;
4092 }
4093 if (!pMsg)
4094 {
4095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304096 return;
4097 }
4098
4099 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4101 NULL,
4102#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304103 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4104 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4105 GFP_KERNEL);
4106
4107 if (!skb) {
4108 hddLog(VOS_TRACE_LEVEL_ERROR,
4109 FL("cfg80211_vendor_event_alloc failed"));
4110 return;
4111 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4114 pData->extScanEventType);
4115 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4116 pData->status);
4117
4118 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4119 pData->extScanEventType) ||
4120 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4122 pData->requestId) ||
4123 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4125 pData->status)) {
4126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4127 goto nla_put_failure;
4128 }
4129
4130 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304131 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132 return;
4133
4134nla_put_failure:
4135 kfree_skb(skb);
4136 return;
4137}
4138
4139void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4140 void *pMsg)
4141{
4142 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304144 ENTER();
4145
Dino Mycle6fb96c12014-06-10 11:52:40 +05304146 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 return;
4148 }
4149
4150 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4151
4152
4153 switch(evType) {
4154 case SIR_HAL_EXTSCAN_START_RSP:
4155 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4156 break;
4157
4158 case SIR_HAL_EXTSCAN_STOP_RSP:
4159 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4160 break;
4161 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4162 /* There is no need to send this response to upper layer
4163 Just log the message */
4164 hddLog(VOS_TRACE_LEVEL_INFO,
4165 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4166 break;
4167 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4168 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4169 break;
4170
4171 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4172 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4173 break;
4174
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304176 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304177 break;
4178 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4179 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4180 break;
4181 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4182 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4183 break;
4184 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4185 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4186 break;
4187 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4188 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4189 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4191 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4192 break;
4193 default:
4194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4195 break;
4196 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304197 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198}
4199
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304200static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4201 struct wireless_dev *wdev,
4202 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203{
Dino Myclee8843b32014-07-04 14:21:45 +05304204 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304205 struct net_device *dev = wdev->netdev;
4206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4207 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4208 struct nlattr
4209 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4210 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304211 struct hdd_ext_scan_context *context;
4212 unsigned long rc;
4213 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304215 ENTER();
4216
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 status = wlan_hdd_validate_context(pHddCtx);
4218 if (0 != status)
4219 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220 return -EINVAL;
4221 }
Dino Myclee8843b32014-07-04 14:21:45 +05304222 /* check the EXTScan Capability */
4223 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304224 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4225 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304226 {
4227 hddLog(VOS_TRACE_LEVEL_ERROR,
4228 FL("EXTScan not enabled/supported by Firmware"));
4229 return -EINVAL;
4230 }
4231
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4233 data, dataLen,
4234 wlan_hdd_extscan_config_policy)) {
4235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4236 return -EINVAL;
4237 }
4238
4239 /* Parse and fetch request Id */
4240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4242 return -EINVAL;
4243 }
4244
Dino Myclee8843b32014-07-04 14:21:45 +05304245 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248
Dino Myclee8843b32014-07-04 14:21:45 +05304249 reqMsg.sessionId = pAdapter->sessionId;
4250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304251
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304252 vos_spin_lock_acquire(&hdd_context_lock);
4253 context = &pHddCtx->ext_scan_context;
4254 context->request_id = reqMsg.requestId;
4255 INIT_COMPLETION(context->response_event);
4256 vos_spin_lock_release(&hdd_context_lock);
4257
Dino Myclee8843b32014-07-04 14:21:45 +05304258 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 if (!HAL_STATUS_SUCCESS(status)) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304262 return -EINVAL;
4263 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304264
4265 rc = wait_for_completion_timeout(&context->response_event,
4266 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4267 if (!rc) {
4268 hddLog(LOGE, FL("Target response timed out"));
4269 return -ETIMEDOUT;
4270 }
4271
4272 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4273 if (ret)
4274 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4275
4276 return ret;
4277
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304278 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279 return 0;
4280}
4281
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304282static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4283 struct wireless_dev *wdev,
4284 const void *data, int dataLen)
4285{
4286 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304288 vos_ssr_protect(__func__);
4289 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4290 vos_ssr_unprotect(__func__);
4291
4292 return ret;
4293}
4294
4295static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4296 struct wireless_dev *wdev,
4297 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304298{
Dino Myclee8843b32014-07-04 14:21:45 +05304299 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300 struct net_device *dev = wdev->netdev;
4301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4302 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4303 struct nlattr
4304 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4305 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304306 struct hdd_ext_scan_context *context;
4307 unsigned long rc;
4308 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304310 ENTER();
4311
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304312 if (VOS_FTM_MODE == hdd_get_conparam()) {
4313 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4314 return -EINVAL;
4315 }
4316
Dino Mycle6fb96c12014-06-10 11:52:40 +05304317 status = wlan_hdd_validate_context(pHddCtx);
4318 if (0 != status)
4319 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304320 return -EINVAL;
4321 }
Dino Myclee8843b32014-07-04 14:21:45 +05304322 /* check the EXTScan Capability */
4323 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304324 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4325 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304326 {
4327 hddLog(VOS_TRACE_LEVEL_ERROR,
4328 FL("EXTScan not enabled/supported by Firmware"));
4329 return -EINVAL;
4330 }
4331
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4333 data, dataLen,
4334 wlan_hdd_extscan_config_policy)) {
4335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4336 return -EINVAL;
4337 }
4338 /* Parse and fetch request Id */
4339 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4341 return -EINVAL;
4342 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304343
Dino Myclee8843b32014-07-04 14:21:45 +05304344 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304345 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4346
Dino Myclee8843b32014-07-04 14:21:45 +05304347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304348
Dino Myclee8843b32014-07-04 14:21:45 +05304349 reqMsg.sessionId = pAdapter->sessionId;
4350 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304351
4352 /* Parse and fetch flush parameter */
4353 if (!tb
4354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4355 {
4356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4357 goto failed;
4358 }
Dino Myclee8843b32014-07-04 14:21:45 +05304359 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4361
Dino Myclee8843b32014-07-04 14:21:45 +05304362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304364 spin_lock(&hdd_context_lock);
4365 context = &pHddCtx->ext_scan_context;
4366 context->request_id = reqMsg.requestId;
4367 context->ignore_cached_results = false;
4368 INIT_COMPLETION(context->response_event);
4369 spin_unlock(&hdd_context_lock);
4370
Dino Myclee8843b32014-07-04 14:21:45 +05304371 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 if (!HAL_STATUS_SUCCESS(status)) {
4373 hddLog(VOS_TRACE_LEVEL_ERROR,
4374 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304375 return -EINVAL;
4376 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304377
4378 rc = wait_for_completion_timeout(&context->response_event,
4379 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4380 if (!rc) {
4381 hddLog(LOGE, FL("Target response timed out"));
4382 retval = -ETIMEDOUT;
4383 spin_lock(&hdd_context_lock);
4384 context->ignore_cached_results = true;
4385 spin_unlock(&hdd_context_lock);
4386 } else {
4387 spin_lock(&hdd_context_lock);
4388 retval = context->response_status;
4389 spin_unlock(&hdd_context_lock);
4390 }
4391
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304392 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304393 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304394
4395failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 return -EINVAL;
4397}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4399 struct wireless_dev *wdev,
4400 const void *data, int dataLen)
4401{
4402 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304403
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304404 vos_ssr_protect(__func__);
4405 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4406 vos_ssr_unprotect(__func__);
4407
4408 return ret;
4409}
4410
4411static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304413 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304414{
4415 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4416 struct net_device *dev = wdev->netdev;
4417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4418 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4419 struct nlattr
4420 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4421 struct nlattr
4422 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4423 struct nlattr *apTh;
4424 eHalStatus status;
4425 tANI_U8 i = 0;
4426 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304427 struct hdd_ext_scan_context *context;
4428 tANI_U32 request_id;
4429 unsigned long rc;
4430 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304431
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304432 ENTER();
4433
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304434 if (VOS_FTM_MODE == hdd_get_conparam()) {
4435 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4436 return -EINVAL;
4437 }
4438
Dino Mycle6fb96c12014-06-10 11:52:40 +05304439 status = wlan_hdd_validate_context(pHddCtx);
4440 if (0 != status)
4441 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304442 return -EINVAL;
4443 }
Dino Myclee8843b32014-07-04 14:21:45 +05304444 /* check the EXTScan Capability */
4445 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304446 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4447 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304448 {
4449 hddLog(VOS_TRACE_LEVEL_ERROR,
4450 FL("EXTScan not enabled/supported by Firmware"));
4451 return -EINVAL;
4452 }
4453
Dino Mycle6fb96c12014-06-10 11:52:40 +05304454 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4455 data, dataLen,
4456 wlan_hdd_extscan_config_policy)) {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4458 return -EINVAL;
4459 }
4460
4461 /* Parse and fetch request Id */
4462 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4464 return -EINVAL;
4465 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304466 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4467 vos_mem_malloc(sizeof(*pReqMsg));
4468 if (!pReqMsg) {
4469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4470 return -ENOMEM;
4471 }
4472
Dino Myclee8843b32014-07-04 14:21:45 +05304473
Dino Mycle6fb96c12014-06-10 11:52:40 +05304474 pReqMsg->requestId = nla_get_u32(
4475 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4477
4478 /* Parse and fetch number of APs */
4479 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4481 goto fail;
4482 }
4483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304484 /* Parse and fetch lost ap sample size */
4485 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4486 hddLog(LOGE, FL("attr lost ap sample size failed"));
4487 goto fail;
4488 }
4489
4490 pReqMsg->lostBssidSampleSize = nla_get_u32(
4491 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4492 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4493
Dino Mycle6fb96c12014-06-10 11:52:40 +05304494 pReqMsg->sessionId = pAdapter->sessionId;
4495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4496
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304497 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304498 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304499 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4500 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4501 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4502 goto fail;
4503 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304504 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304505
4506 nla_for_each_nested(apTh,
4507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304508 if (i == pReqMsg->numBssid) {
4509 hddLog(LOGW, FL("Ignoring excess AP"));
4510 break;
4511 }
4512
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4514 nla_data(apTh), nla_len(apTh),
4515 NULL)) {
4516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4517 goto fail;
4518 }
4519
4520 /* Parse and fetch MAC address */
4521 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4523 goto fail;
4524 }
4525 memcpy(pReqMsg->ap[i].bssid, nla_data(
4526 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4527 sizeof(tSirMacAddr));
4528 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4529
4530 /* Parse and fetch low RSSI */
4531 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4533 goto fail;
4534 }
4535 pReqMsg->ap[i].low = nla_get_s32(
4536 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4537 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4538
4539 /* Parse and fetch high RSSI */
4540 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4542 goto fail;
4543 }
4544 pReqMsg->ap[i].high = nla_get_s32(
4545 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4546 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4547 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548 i++;
4549 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304550
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304551 if (i < pReqMsg->numBssid) {
4552 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4553 i, pReqMsg->numBssid);
4554 pReqMsg->numBssid = i;
4555 }
4556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304557 context = &pHddCtx->ext_scan_context;
4558 spin_lock(&hdd_context_lock);
4559 INIT_COMPLETION(context->response_event);
4560 context->request_id = request_id = pReqMsg->requestId;
4561 spin_unlock(&hdd_context_lock);
4562
Dino Mycle6fb96c12014-06-10 11:52:40 +05304563 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4564 if (!HAL_STATUS_SUCCESS(status)) {
4565 hddLog(VOS_TRACE_LEVEL_ERROR,
4566 FL("sme_SetBssHotlist failed(err=%d)"), status);
4567 vos_mem_free(pReqMsg);
4568 return -EINVAL;
4569 }
4570
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304571 /* request was sent -- wait for the response */
4572 rc = wait_for_completion_timeout(&context->response_event,
4573 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4574
4575 if (!rc) {
4576 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4577 retval = -ETIMEDOUT;
4578 } else {
4579 spin_lock(&hdd_context_lock);
4580 if (context->request_id == request_id)
4581 retval = context->response_status;
4582 else
4583 retval = -EINVAL;
4584 spin_unlock(&hdd_context_lock);
4585 }
4586
Dino Myclee8843b32014-07-04 14:21:45 +05304587 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304588 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304589 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304590
4591fail:
4592 vos_mem_free(pReqMsg);
4593 return -EINVAL;
4594}
4595
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304596static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4597 struct wireless_dev *wdev,
4598 const void *data, int dataLen)
4599{
4600 int ret = 0;
4601
4602 vos_ssr_protect(__func__);
4603 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4604 dataLen);
4605 vos_ssr_unprotect(__func__);
4606
4607 return ret;
4608}
4609
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304610static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304612 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304614 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4615 struct net_device *dev = wdev->netdev;
4616 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4617 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4618 uint8_t num_channels = 0;
4619 uint8_t num_chan_new = 0;
4620 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304621 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304622 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 tWifiBand wifiBand;
4624 eHalStatus status;
4625 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304626 tANI_U8 i,j,k;
4627 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304629 ENTER();
4630
Dino Mycle6fb96c12014-06-10 11:52:40 +05304631 status = wlan_hdd_validate_context(pHddCtx);
4632 if (0 != status)
4633 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304634 return -EINVAL;
4635 }
Dino Myclee8843b32014-07-04 14:21:45 +05304636
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4638 data, dataLen,
4639 wlan_hdd_extscan_config_policy)) {
4640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4641 return -EINVAL;
4642 }
4643
4644 /* Parse and fetch request Id */
4645 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4647 return -EINVAL;
4648 }
4649 requestId = nla_get_u32(
4650 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4652
4653 /* Parse and fetch wifi band */
4654 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4655 {
4656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4657 return -EINVAL;
4658 }
4659 wifiBand = nla_get_u32(
4660 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4662
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304663 /* Parse and fetch max channels */
4664 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4665 {
4666 hddLog(LOGE, FL("attr max channels failed"));
4667 return -EINVAL;
4668 }
4669 maxChannels = nla_get_u32(
4670 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4671 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4672
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304674 wifiBand, chan_list,
4675 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304676 if (eHAL_STATUS_SUCCESS != status) {
4677 hddLog(VOS_TRACE_LEVEL_ERROR,
4678 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4679 return -EINVAL;
4680 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304681
Agrawal Ashish16abf782016-08-18 22:42:59 +05304682 num_channels = VOS_MIN(num_channels, maxChannels);
4683 num_chan_new = num_channels;
4684 /* remove the indoor only channels if iface is SAP */
4685 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4686 {
4687 num_chan_new = 0;
4688 for (i = 0; i < num_channels; i++)
4689 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4690 if (wiphy->bands[j] == NULL)
4691 continue;
4692 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4693 if ((chan_list[i] ==
4694 wiphy->bands[j]->channels[k].center_freq) &&
4695 (!(wiphy->bands[j]->channels[k].flags &
4696 IEEE80211_CHAN_INDOOR_ONLY))) {
4697 chan_list[num_chan_new] = chan_list[i];
4698 num_chan_new++;
4699 }
4700 }
4701 }
4702 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304703
Agrawal Ashish16abf782016-08-18 22:42:59 +05304704 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4705 for (i = 0; i < num_chan_new; i++)
4706 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4707 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
4709 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304710 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304711 NLMSG_HDRLEN);
4712
4713 if (!replySkb) {
4714 hddLog(VOS_TRACE_LEVEL_ERROR,
4715 FL("valid channels: buffer alloc fail"));
4716 return -EINVAL;
4717 }
4718 if (nla_put_u32(replySkb,
4719 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304720 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304721 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304722 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723
4724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4725 kfree_skb(replySkb);
4726 return -EINVAL;
4727 }
4728
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304729 ret = cfg80211_vendor_cmd_reply(replySkb);
4730
4731 EXIT();
4732 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304733}
4734
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304735static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4736 struct wireless_dev *wdev,
4737 const void *data, int dataLen)
4738{
4739 int ret = 0;
4740
4741 vos_ssr_protect(__func__);
4742 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4743 dataLen);
4744 vos_ssr_unprotect(__func__);
4745
4746 return ret;
4747}
4748
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304749static int hdd_extscan_start_fill_bucket_channel_spec(
4750 hdd_context_t *pHddCtx,
4751 tpSirEXTScanStartReqParams pReqMsg,
4752 struct nlattr **tb)
4753{
4754 struct nlattr *bucket[
4755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4756 struct nlattr *channel[
4757 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4758 struct nlattr *buckets;
4759 struct nlattr *channels;
4760 int rem1, rem2;
4761 eHalStatus status;
4762 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304763 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304764 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4765 tANI_U32 passive_max_chn_time, active_max_chn_time;
4766
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304767 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304768 bktIndex = 0;
4769
4770 nla_for_each_nested(buckets,
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304772 if (bktIndex >= expected_buckets) {
4773 hddLog(LOGW, FL("ignoring excess buckets"));
4774 break;
4775 }
4776
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304777 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304778 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4779 nla_data(buckets), nla_len(buckets),
4780 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304781 hddLog(LOGE, FL("nla_parse failed"));
4782 return -EINVAL;
4783 }
4784
4785 /* Parse and fetch bucket spec */
4786 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4787 hddLog(LOGE, FL("attr bucket index failed"));
4788 return -EINVAL;
4789 }
4790 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4791 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4792 hddLog(LOG1, FL("Bucket spec Index %d"),
4793 pReqMsg->buckets[bktIndex].bucket);
4794
4795 /* Parse and fetch wifi band */
4796 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4797 hddLog(LOGE, FL("attr wifi band failed"));
4798 return -EINVAL;
4799 }
4800 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4801 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4802 hddLog(LOG1, FL("Wifi band %d"),
4803 pReqMsg->buckets[bktIndex].band);
4804
4805 /* Parse and fetch period */
4806 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4807 hddLog(LOGE, FL("attr period failed"));
4808 return -EINVAL;
4809 }
4810 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4811 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4812 hddLog(LOG1, FL("period %d"),
4813 pReqMsg->buckets[bktIndex].period);
4814
4815 /* Parse and fetch report events */
4816 if (!bucket[
4817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4818 hddLog(LOGE, FL("attr report events failed"));
4819 return -EINVAL;
4820 }
4821 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4822 bucket[
4823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4824 hddLog(LOG1, FL("report events %d"),
4825 pReqMsg->buckets[bktIndex].reportEvents);
4826
4827 /* Parse and fetch max period */
4828 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4829 hddLog(LOGE, FL("attr max period failed"));
4830 return -EINVAL;
4831 }
4832 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4833 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4834 hddLog(LOG1, FL("max period %u"),
4835 pReqMsg->buckets[bktIndex].max_period);
4836
4837 /* Parse and fetch exponent */
4838 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4839 hddLog(LOGE, FL("attr exponent failed"));
4840 return -EINVAL;
4841 }
4842 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4843 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4844 hddLog(LOG1, FL("exponent %u"),
4845 pReqMsg->buckets[bktIndex].exponent);
4846
4847 /* Parse and fetch step count */
4848 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4849 hddLog(LOGE, FL("attr step count failed"));
4850 return -EINVAL;
4851 }
4852 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4853 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4854 hddLog(LOG1, FL("Step count %u"),
4855 pReqMsg->buckets[bktIndex].step_count);
4856
4857 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4858 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4859
4860 /* Framework shall pass the channel list if the input WiFi band is
4861 * WIFI_BAND_UNSPECIFIED.
4862 * If the input WiFi band is specified (any value other than
4863 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4864 */
4865 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4866 numChannels = 0;
4867 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4868 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4869 pReqMsg->buckets[bktIndex].band,
4870 chanList, &numChannels);
4871 if (!HAL_STATUS_SUCCESS(status)) {
4872 hddLog(LOGE,
4873 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4874 status);
4875 return -EINVAL;
4876 }
4877
4878 pReqMsg->buckets[bktIndex].numChannels =
4879 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4880 hddLog(LOG1, FL("Num channels %d"),
4881 pReqMsg->buckets[bktIndex].numChannels);
4882
4883 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4884 j++) {
4885 pReqMsg->buckets[bktIndex].channels[j].channel =
4886 chanList[j];
4887 pReqMsg->buckets[bktIndex].channels[j].
4888 chnlClass = 0;
4889 if (CSR_IS_CHANNEL_DFS(
4890 vos_freq_to_chan(chanList[j]))) {
4891 pReqMsg->buckets[bktIndex].channels[j].
4892 passive = 1;
4893 pReqMsg->buckets[bktIndex].channels[j].
4894 dwellTimeMs = passive_max_chn_time;
4895 } else {
4896 pReqMsg->buckets[bktIndex].channels[j].
4897 passive = 0;
4898 pReqMsg->buckets[bktIndex].channels[j].
4899 dwellTimeMs = active_max_chn_time;
4900 }
4901
4902 hddLog(LOG1,
4903 "Channel %u Passive %u Dwell time %u ms",
4904 pReqMsg->buckets[bktIndex].channels[j].channel,
4905 pReqMsg->buckets[bktIndex].channels[j].passive,
4906 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4907 }
4908
4909 bktIndex++;
4910 continue;
4911 }
4912
4913 /* Parse and fetch number of channels */
4914 if (!bucket[
4915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4916 hddLog(LOGE, FL("attr num channels failed"));
4917 return -EINVAL;
4918 }
4919
4920 pReqMsg->buckets[bktIndex].numChannels =
4921 nla_get_u32(bucket[
4922 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4923 hddLog(LOG1, FL("num channels %d"),
4924 pReqMsg->buckets[bktIndex].numChannels);
4925
4926 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4927 hddLog(LOGE, FL("attr channel spec failed"));
4928 return -EINVAL;
4929 }
4930
4931 j = 0;
4932 nla_for_each_nested(channels,
4933 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4934 if (nla_parse(channel,
4935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4936 nla_data(channels), nla_len(channels),
4937 wlan_hdd_extscan_config_policy)) {
4938 hddLog(LOGE, FL("nla_parse failed"));
4939 return -EINVAL;
4940 }
4941
4942 /* Parse and fetch channel */
4943 if (!channel[
4944 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4945 hddLog(LOGE, FL("attr channel failed"));
4946 return -EINVAL;
4947 }
4948 pReqMsg->buckets[bktIndex].channels[j].channel =
4949 nla_get_u32(channel[
4950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4951 hddLog(LOG1, FL("channel %u"),
4952 pReqMsg->buckets[bktIndex].channels[j].channel);
4953
4954 /* Parse and fetch dwell time */
4955 if (!channel[
4956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4957 hddLog(LOGE, FL("attr dwelltime failed"));
4958 return -EINVAL;
4959 }
4960 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4961 nla_get_u32(channel[
4962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4963
4964 hddLog(LOG1, FL("Dwell time (%u ms)"),
4965 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4966
4967
4968 /* Parse and fetch channel spec passive */
4969 if (!channel[
4970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4971 hddLog(LOGE,
4972 FL("attr channel spec passive failed"));
4973 return -EINVAL;
4974 }
4975 pReqMsg->buckets[bktIndex].channels[j].passive =
4976 nla_get_u8(channel[
4977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4978 hddLog(LOG1, FL("Chnl spec passive %u"),
4979 pReqMsg->buckets[bktIndex].channels[j].passive);
4980
4981 j++;
4982 }
4983
4984 bktIndex++;
4985 }
4986
4987 return 0;
4988}
4989
4990
4991/*
4992 * define short names for the global vendor params
4993 * used by wlan_hdd_cfg80211_extscan_start()
4994 */
4995#define PARAM_MAX \
4996QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4997#define PARAM_REQUEST_ID \
4998QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4999#define PARAM_BASE_PERIOD \
5000QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5001#define PARAM_MAX_AP_PER_SCAN \
5002QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5003#define PARAM_RPT_THRHLD_PERCENT \
5004QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5005#define PARAM_RPT_THRHLD_NUM_SCANS \
5006QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5007#define PARAM_NUM_BUCKETS \
5008QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5009
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305010static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305011 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305012 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305013{
Dino Myclee8843b32014-07-04 14:21:45 +05305014 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305015 struct net_device *dev = wdev->netdev;
5016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5017 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5018 struct nlattr *tb[PARAM_MAX + 1];
5019 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305020 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305021 tANI_U32 request_id;
5022 struct hdd_ext_scan_context *context;
5023 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305025 ENTER();
5026
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305027 if (VOS_FTM_MODE == hdd_get_conparam()) {
5028 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5029 return -EINVAL;
5030 }
5031
Dino Mycle6fb96c12014-06-10 11:52:40 +05305032 status = wlan_hdd_validate_context(pHddCtx);
5033 if (0 != status)
5034 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305035 return -EINVAL;
5036 }
Dino Myclee8843b32014-07-04 14:21:45 +05305037 /* check the EXTScan Capability */
5038 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305039 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5040 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305041 {
5042 hddLog(VOS_TRACE_LEVEL_ERROR,
5043 FL("EXTScan not enabled/supported by Firmware"));
5044 return -EINVAL;
5045 }
5046
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305047 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305048 data, dataLen,
5049 wlan_hdd_extscan_config_policy)) {
5050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5051 return -EINVAL;
5052 }
5053
5054 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305055 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5057 return -EINVAL;
5058 }
5059
Dino Myclee8843b32014-07-04 14:21:45 +05305060 pReqMsg = (tpSirEXTScanStartReqParams)
5061 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305062 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5064 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305065 }
5066
5067 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305068 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5070
5071 pReqMsg->sessionId = pAdapter->sessionId;
5072 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5073
5074 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305075 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5077 goto fail;
5078 }
5079 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305080 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5082 pReqMsg->basePeriod);
5083
5084 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305085 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5087 goto fail;
5088 }
5089 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305090 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305091 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5092 pReqMsg->maxAPperScan);
5093
5094 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305095 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5097 goto fail;
5098 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305099 pReqMsg->reportThresholdPercent = nla_get_u8(
5100 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305101 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305102 pReqMsg->reportThresholdPercent);
5103
5104 /* Parse and fetch report threshold num scans */
5105 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5106 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5107 goto fail;
5108 }
5109 pReqMsg->reportThresholdNumScans = nla_get_u8(
5110 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5111 hddLog(LOG1, FL("Report Threshold num scans %d"),
5112 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305113
5114 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305115 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5117 goto fail;
5118 }
5119 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305120 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5122 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5123 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5124 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5125 }
5126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5127 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128
Dino Mycle6fb96c12014-06-10 11:52:40 +05305129 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5131 goto fail;
5132 }
5133
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305134 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305135
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305136 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5137 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305138
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305139 context = &pHddCtx->ext_scan_context;
5140 spin_lock(&hdd_context_lock);
5141 INIT_COMPLETION(context->response_event);
5142 context->request_id = request_id = pReqMsg->requestId;
5143 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305144
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5146 if (!HAL_STATUS_SUCCESS(status)) {
5147 hddLog(VOS_TRACE_LEVEL_ERROR,
5148 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305149 goto fail;
5150 }
5151
Srinivas Dasari91727c12016-03-23 17:59:06 +05305152 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5153
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305154 /* request was sent -- wait for the response */
5155 rc = wait_for_completion_timeout(&context->response_event,
5156 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5157
5158 if (!rc) {
5159 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5160 retval = -ETIMEDOUT;
5161 } else {
5162 spin_lock(&hdd_context_lock);
5163 if (context->request_id == request_id)
5164 retval = context->response_status;
5165 else
5166 retval = -EINVAL;
5167 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305168 }
5169
Dino Myclee8843b32014-07-04 14:21:45 +05305170 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305171 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305172 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305173
5174fail:
5175 vos_mem_free(pReqMsg);
5176 return -EINVAL;
5177}
5178
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305179/*
5180 * done with short names for the global vendor params
5181 * used by wlan_hdd_cfg80211_extscan_start()
5182 */
5183#undef PARAM_MAX
5184#undef PARAM_REQUEST_ID
5185#undef PARAM_BASE_PERIOD
5186#undef PARAMS_MAX_AP_PER_SCAN
5187#undef PARAMS_RPT_THRHLD_PERCENT
5188#undef PARAMS_RPT_THRHLD_NUM_SCANS
5189#undef PARAMS_NUM_BUCKETS
5190
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305191static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5192 struct wireless_dev *wdev,
5193 const void *data, int dataLen)
5194{
5195 int ret = 0;
5196
5197 vos_ssr_protect(__func__);
5198 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5199 vos_ssr_unprotect(__func__);
5200
5201 return ret;
5202}
5203
5204static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305205 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305206 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305207{
Dino Myclee8843b32014-07-04 14:21:45 +05305208 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305209 struct net_device *dev = wdev->netdev;
5210 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5212 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5213 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305214 int retval;
5215 unsigned long rc;
5216 struct hdd_ext_scan_context *context;
5217 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305219 ENTER();
5220
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305221 if (VOS_FTM_MODE == hdd_get_conparam()) {
5222 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5223 return -EINVAL;
5224 }
5225
Dino Mycle6fb96c12014-06-10 11:52:40 +05305226 status = wlan_hdd_validate_context(pHddCtx);
5227 if (0 != status)
5228 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305229 return -EINVAL;
5230 }
Dino Myclee8843b32014-07-04 14:21:45 +05305231 /* check the EXTScan Capability */
5232 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305233 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5234 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305235 {
5236 hddLog(VOS_TRACE_LEVEL_ERROR,
5237 FL("EXTScan not enabled/supported by Firmware"));
5238 return -EINVAL;
5239 }
5240
Dino Mycle6fb96c12014-06-10 11:52:40 +05305241 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5242 data, dataLen,
5243 wlan_hdd_extscan_config_policy)) {
5244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5245 return -EINVAL;
5246 }
5247
5248 /* Parse and fetch request Id */
5249 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5251 return -EINVAL;
5252 }
5253
Dino Myclee8843b32014-07-04 14:21:45 +05305254 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305255 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305257
Dino Myclee8843b32014-07-04 14:21:45 +05305258 reqMsg.sessionId = pAdapter->sessionId;
5259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305260
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305261 context = &pHddCtx->ext_scan_context;
5262 spin_lock(&hdd_context_lock);
5263 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305264 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305265 spin_unlock(&hdd_context_lock);
5266
Dino Myclee8843b32014-07-04 14:21:45 +05305267 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305268 if (!HAL_STATUS_SUCCESS(status)) {
5269 hddLog(VOS_TRACE_LEVEL_ERROR,
5270 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305271 return -EINVAL;
5272 }
5273
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305274 /* request was sent -- wait for the response */
5275 rc = wait_for_completion_timeout(&context->response_event,
5276 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5277
5278 if (!rc) {
5279 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5280 retval = -ETIMEDOUT;
5281 } else {
5282 spin_lock(&hdd_context_lock);
5283 if (context->request_id == request_id)
5284 retval = context->response_status;
5285 else
5286 retval = -EINVAL;
5287 spin_unlock(&hdd_context_lock);
5288 }
5289
5290 return retval;
5291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305292 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305293 return 0;
5294}
5295
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305296static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5297 struct wireless_dev *wdev,
5298 const void *data, int dataLen)
5299{
5300 int ret = 0;
5301
5302 vos_ssr_protect(__func__);
5303 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5304 vos_ssr_unprotect(__func__);
5305
5306 return ret;
5307}
5308
5309static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305311 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305312{
Dino Myclee8843b32014-07-04 14:21:45 +05305313 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305314 struct net_device *dev = wdev->netdev;
5315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5316 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5317 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5318 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305319 struct hdd_ext_scan_context *context;
5320 tANI_U32 request_id;
5321 unsigned long rc;
5322 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305324 ENTER();
5325
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305326 if (VOS_FTM_MODE == hdd_get_conparam()) {
5327 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5328 return -EINVAL;
5329 }
5330
Dino Mycle6fb96c12014-06-10 11:52:40 +05305331 status = wlan_hdd_validate_context(pHddCtx);
5332 if (0 != status)
5333 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305334 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305335 return -EINVAL;
5336 }
Dino Myclee8843b32014-07-04 14:21:45 +05305337 /* check the EXTScan Capability */
5338 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305339 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5340 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305341 {
5342 hddLog(VOS_TRACE_LEVEL_ERROR,
5343 FL("EXTScan not enabled/supported by Firmware"));
5344 return -EINVAL;
5345 }
5346
Dino Mycle6fb96c12014-06-10 11:52:40 +05305347 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5348 data, dataLen,
5349 wlan_hdd_extscan_config_policy)) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5351 return -EINVAL;
5352 }
5353
5354 /* Parse and fetch request Id */
5355 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5357 return -EINVAL;
5358 }
5359
Dino Myclee8843b32014-07-04 14:21:45 +05305360 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305363
Dino Myclee8843b32014-07-04 14:21:45 +05305364 reqMsg.sessionId = pAdapter->sessionId;
5365 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305366
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305367 context = &pHddCtx->ext_scan_context;
5368 spin_lock(&hdd_context_lock);
5369 INIT_COMPLETION(context->response_event);
5370 context->request_id = request_id = reqMsg.requestId;
5371 spin_unlock(&hdd_context_lock);
5372
Dino Myclee8843b32014-07-04 14:21:45 +05305373 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305374 if (!HAL_STATUS_SUCCESS(status)) {
5375 hddLog(VOS_TRACE_LEVEL_ERROR,
5376 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305377 return -EINVAL;
5378 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305379
5380 /* request was sent -- wait for the response */
5381 rc = wait_for_completion_timeout(&context->response_event,
5382 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5383 if (!rc) {
5384 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5385 retval = -ETIMEDOUT;
5386 } else {
5387 spin_lock(&hdd_context_lock);
5388 if (context->request_id == request_id)
5389 retval = context->response_status;
5390 else
5391 retval = -EINVAL;
5392 spin_unlock(&hdd_context_lock);
5393 }
5394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305396 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305397}
5398
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305399static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5400 struct wireless_dev *wdev,
5401 const void *data, int dataLen)
5402{
5403 int ret = 0;
5404
5405 vos_ssr_protect(__func__);
5406 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5407 vos_ssr_unprotect(__func__);
5408
5409 return ret;
5410}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411#endif /* WLAN_FEATURE_EXTSCAN */
5412
Atul Mittal115287b2014-07-08 13:26:33 +05305413/*EXT TDLS*/
5414static const struct nla_policy
5415wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5416{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305417 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5418 .type = NLA_UNSPEC,
5419 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305420 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5421 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5422 {.type = NLA_S32 },
5423 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5424 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5425
5426};
5427
5428static const struct nla_policy
5429wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5430{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305431 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5432 .type = NLA_UNSPEC,
5433 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305434
5435};
5436
5437static const struct nla_policy
5438wlan_hdd_tdls_config_state_change_policy[
5439 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5440{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305441 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5442 .type = NLA_UNSPEC,
5443 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305444 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5445 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305446 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5447 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5448 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305449
5450};
5451
5452static const struct nla_policy
5453wlan_hdd_tdls_config_get_status_policy[
5454 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5455{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305456 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5457 .type = NLA_UNSPEC,
5458 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305459 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5460 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305461 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5462 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5463 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305464
5465};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305466
5467static const struct nla_policy
5468wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5469{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305470 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5471 .type = NLA_UNSPEC,
5472 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305473};
5474
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305475static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305476 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305477 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305478 int data_len)
5479{
5480
5481 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5482 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305484 ENTER();
5485
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305486 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305487 return -EINVAL;
5488 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305489 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305490 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305491 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305492 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305493 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305494 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305495 return -ENOTSUPP;
5496 }
5497
5498 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5499 data, data_len, wlan_hdd_mac_config)) {
5500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5501 return -EINVAL;
5502 }
5503
5504 /* Parse and fetch mac address */
5505 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5507 return -EINVAL;
5508 }
5509
5510 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5511 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5512 VOS_MAC_ADDR_LAST_3_BYTES);
5513
Siddharth Bhal76972212014-10-15 16:22:51 +05305514 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5515
5516 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305517 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5518 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305519 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5520 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5521 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5522 {
5523 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5524 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5525 VOS_MAC_ADDRESS_LEN);
5526 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305527 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305528
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305529 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5530 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305532 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305533 return 0;
5534}
5535
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305536static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5537 struct wireless_dev *wdev,
5538 const void *data,
5539 int data_len)
5540{
5541 int ret = 0;
5542
5543 vos_ssr_protect(__func__);
5544 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5545 vos_ssr_unprotect(__func__);
5546
5547 return ret;
5548}
5549
5550static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305551 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305552 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305553 int data_len)
5554{
5555 u8 peer[6] = {0};
5556 struct net_device *dev = wdev->netdev;
5557 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5558 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5559 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5560 eHalStatus ret;
5561 tANI_S32 state;
5562 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305563 tANI_S32 global_operating_class = 0;
5564 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305565 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305566 int retVal;
5567
5568 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305569
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305570 if (!pAdapter) {
5571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5572 return -EINVAL;
5573 }
5574
Atul Mittal115287b2014-07-08 13:26:33 +05305575 ret = wlan_hdd_validate_context(pHddCtx);
5576 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305578 return -EINVAL;
5579 }
5580 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305582 return -ENOTSUPP;
5583 }
5584 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5585 data, data_len,
5586 wlan_hdd_tdls_config_get_status_policy)) {
5587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5588 return -EINVAL;
5589 }
5590
5591 /* Parse and fetch mac address */
5592 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5594 return -EINVAL;
5595 }
5596
5597 memcpy(peer, nla_data(
5598 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5599 sizeof(peer));
5600 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5601
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305602 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305603
Atul Mittal115287b2014-07-08 13:26:33 +05305604 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305605 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305606 NLMSG_HDRLEN);
5607
5608 if (!skb) {
5609 hddLog(VOS_TRACE_LEVEL_ERROR,
5610 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5611 return -EINVAL;
5612 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305613 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 +05305614 reason,
5615 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305616 global_operating_class,
5617 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305618 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305619 if (nla_put_s32(skb,
5620 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5621 state) ||
5622 nla_put_s32(skb,
5623 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5624 reason) ||
5625 nla_put_s32(skb,
5626 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5627 global_operating_class) ||
5628 nla_put_s32(skb,
5629 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5630 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305631
5632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5633 goto nla_put_failure;
5634 }
5635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305636 retVal = cfg80211_vendor_cmd_reply(skb);
5637 EXIT();
5638 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305639
5640nla_put_failure:
5641 kfree_skb(skb);
5642 return -EINVAL;
5643}
5644
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305645static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5646 struct wireless_dev *wdev,
5647 const void *data,
5648 int data_len)
5649{
5650 int ret = 0;
5651
5652 vos_ssr_protect(__func__);
5653 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5654 vos_ssr_unprotect(__func__);
5655
5656 return ret;
5657}
5658
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305659static int wlan_hdd_cfg80211_exttdls_callback(
5660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5661 const tANI_U8* mac,
5662#else
5663 tANI_U8* mac,
5664#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305665 tANI_S32 state,
5666 tANI_S32 reason,
5667 void *ctx)
5668{
5669 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305670 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305671 tANI_S32 global_operating_class = 0;
5672 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305673 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305675 ENTER();
5676
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305677 if (!pAdapter) {
5678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5679 return -EINVAL;
5680 }
5681
5682 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305683 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305685 return -EINVAL;
5686 }
5687
5688 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305690 return -ENOTSUPP;
5691 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305692 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5694 NULL,
5695#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305696 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5697 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5698 GFP_KERNEL);
5699
5700 if (!skb) {
5701 hddLog(VOS_TRACE_LEVEL_ERROR,
5702 FL("cfg80211_vendor_event_alloc failed"));
5703 return -EINVAL;
5704 }
5705 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5707 reason,
5708 state,
5709 global_operating_class,
5710 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305711 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5712 MAC_ADDR_ARRAY(mac));
5713
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 if (nla_put(skb,
5715 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5716 VOS_MAC_ADDR_SIZE, mac) ||
5717 nla_put_s32(skb,
5718 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5719 state) ||
5720 nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5722 reason) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5725 channel) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5728 global_operating_class)
5729 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5731 goto nla_put_failure;
5732 }
5733
5734 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305735 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305736 return (0);
5737
5738nla_put_failure:
5739 kfree_skb(skb);
5740 return -EINVAL;
5741}
5742
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305743static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305744 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305745 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305746 int data_len)
5747{
5748 u8 peer[6] = {0};
5749 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305750 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5751 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5752 eHalStatus status;
5753 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305754 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305755 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305756
5757 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305758
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305759 if (!dev) {
5760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5761 return -EINVAL;
5762 }
5763
5764 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5765 if (!pAdapter) {
5766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5767 return -EINVAL;
5768 }
5769
Atul Mittal115287b2014-07-08 13:26:33 +05305770 status = wlan_hdd_validate_context(pHddCtx);
5771 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305773 return -EINVAL;
5774 }
5775 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305777 return -ENOTSUPP;
5778 }
5779 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5780 data, data_len,
5781 wlan_hdd_tdls_config_enable_policy)) {
5782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5783 return -EINVAL;
5784 }
5785
5786 /* Parse and fetch mac address */
5787 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5789 return -EINVAL;
5790 }
5791
5792 memcpy(peer, nla_data(
5793 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5794 sizeof(peer));
5795 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5796
5797 /* Parse and fetch channel */
5798 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5800 return -EINVAL;
5801 }
5802 pReqMsg.channel = nla_get_s32(
5803 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5805
5806 /* Parse and fetch global operating class */
5807 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5809 return -EINVAL;
5810 }
5811 pReqMsg.global_operating_class = nla_get_s32(
5812 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5813 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5814 pReqMsg.global_operating_class);
5815
5816 /* Parse and fetch latency ms */
5817 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5819 return -EINVAL;
5820 }
5821 pReqMsg.max_latency_ms = nla_get_s32(
5822 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5824 pReqMsg.max_latency_ms);
5825
5826 /* Parse and fetch required bandwidth kbps */
5827 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5829 return -EINVAL;
5830 }
5831
5832 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5833 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5834 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5835 pReqMsg.min_bandwidth_kbps);
5836
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305837 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305838 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305839 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305840 wlan_hdd_cfg80211_exttdls_callback);
5841
5842 EXIT();
5843 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305844}
5845
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305846static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5847 struct wireless_dev *wdev,
5848 const void *data,
5849 int data_len)
5850{
5851 int ret = 0;
5852
5853 vos_ssr_protect(__func__);
5854 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5855 vos_ssr_unprotect(__func__);
5856
5857 return ret;
5858}
5859
5860static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305861 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305862 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305863 int data_len)
5864{
5865 u8 peer[6] = {0};
5866 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305867 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5868 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5869 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305870 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305871 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305872
5873 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305874
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305875 if (!dev) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5877 return -EINVAL;
5878 }
5879
5880 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5881 if (!pAdapter) {
5882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5883 return -EINVAL;
5884 }
5885
Atul Mittal115287b2014-07-08 13:26:33 +05305886 status = wlan_hdd_validate_context(pHddCtx);
5887 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305889 return -EINVAL;
5890 }
5891 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305893 return -ENOTSUPP;
5894 }
5895 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5896 data, data_len,
5897 wlan_hdd_tdls_config_disable_policy)) {
5898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5899 return -EINVAL;
5900 }
5901 /* Parse and fetch mac address */
5902 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5904 return -EINVAL;
5905 }
5906
5907 memcpy(peer, nla_data(
5908 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5909 sizeof(peer));
5910 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305912 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5913
5914 EXIT();
5915 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305916}
5917
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305918static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5919 struct wireless_dev *wdev,
5920 const void *data,
5921 int data_len)
5922{
5923 int ret = 0;
5924
5925 vos_ssr_protect(__func__);
5926 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5927 vos_ssr_unprotect(__func__);
5928
5929 return ret;
5930}
5931
Dasari Srinivas7875a302014-09-26 17:50:57 +05305932static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305933__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305934 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305935 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305936{
5937 struct net_device *dev = wdev->netdev;
5938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5939 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5940 struct sk_buff *skb = NULL;
5941 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305942 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305943
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305944 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305945
5946 ret = wlan_hdd_validate_context(pHddCtx);
5947 if (0 != ret)
5948 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305949 return ret;
5950 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305951 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5952 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5953 fset |= WIFI_FEATURE_INFRA;
5954 }
5955
5956 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5957 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5958 fset |= WIFI_FEATURE_INFRA_5G;
5959 }
5960
5961#ifdef WLAN_FEATURE_P2P
5962 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5963 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5964 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5965 fset |= WIFI_FEATURE_P2P;
5966 }
5967#endif
5968
5969 /* Soft-AP is supported currently by default */
5970 fset |= WIFI_FEATURE_SOFT_AP;
5971
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305972 /* HOTSPOT is a supplicant feature, enable it by default */
5973 fset |= WIFI_FEATURE_HOTSPOT;
5974
Dasari Srinivas7875a302014-09-26 17:50:57 +05305975#ifdef WLAN_FEATURE_EXTSCAN
5976 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305977 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5978 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5979 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305980 fset |= WIFI_FEATURE_EXTSCAN;
5981 }
5982#endif
5983
Dasari Srinivas7875a302014-09-26 17:50:57 +05305984 if (sme_IsFeatureSupportedByFW(NAN)) {
5985 hddLog(LOG1, FL("NAN is supported by firmware"));
5986 fset |= WIFI_FEATURE_NAN;
5987 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305988
5989 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305990 if (sme_IsFeatureSupportedByFW(RTT) &&
5991 pHddCtx->cfg_ini->enable_rtt_support) {
5992 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305993 fset |= WIFI_FEATURE_D2AP_RTT;
5994 }
5995
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305996 if (sme_IsFeatureSupportedByFW(RTT3)) {
5997 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5998 fset |= WIFI_FEATURE_RTT3;
5999 }
6000
Dasari Srinivas7875a302014-09-26 17:50:57 +05306001#ifdef FEATURE_WLAN_BATCH_SCAN
6002 if (fset & WIFI_FEATURE_EXTSCAN) {
6003 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6004 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6005 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6006 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6007 fset |= WIFI_FEATURE_BATCH_SCAN;
6008 }
6009#endif
6010
6011#ifdef FEATURE_WLAN_SCAN_PNO
6012 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6013 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6014 hddLog(LOG1, FL("PNO is supported by firmware"));
6015 fset |= WIFI_FEATURE_PNO;
6016 }
6017#endif
6018
6019 /* STA+STA is supported currently by default */
6020 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6021
6022#ifdef FEATURE_WLAN_TDLS
6023 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6024 sme_IsFeatureSupportedByFW(TDLS)) {
6025 hddLog(LOG1, FL("TDLS is supported by firmware"));
6026 fset |= WIFI_FEATURE_TDLS;
6027 }
6028
6029 /* TDLS_OFFCHANNEL is not supported currently by default */
6030#endif
6031
6032#ifdef WLAN_AP_STA_CONCURRENCY
6033 /* AP+STA concurrency is supported currently by default */
6034 fset |= WIFI_FEATURE_AP_STA;
6035#endif
6036
Mukul Sharma5add0532015-08-17 15:57:47 +05306037#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306038 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6039 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306040 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6041 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306042 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306043#endif
6044
Dasari Srinivas7875a302014-09-26 17:50:57 +05306045 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6046 NLMSG_HDRLEN);
6047
6048 if (!skb) {
6049 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6050 return -EINVAL;
6051 }
6052 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6053
6054 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6055 hddLog(LOGE, FL("nla put fail"));
6056 goto nla_put_failure;
6057 }
6058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306059 ret = cfg80211_vendor_cmd_reply(skb);
6060 EXIT();
6061 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306062
6063nla_put_failure:
6064 kfree_skb(skb);
6065 return -EINVAL;
6066}
6067
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306068static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306069wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6070 struct wireless_dev *wdev,
6071 const void *data, int data_len)
6072{
6073 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306074 vos_ssr_protect(__func__);
6075 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6076 vos_ssr_unprotect(__func__);
6077
6078 return ret;
6079}
6080
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306081
6082static const struct
6083nla_policy
6084qca_wlan_vendor_wifi_logger_get_ring_data_policy
6085[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6086 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6087 = {.type = NLA_U32 },
6088};
6089
6090static int
6091 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6092 struct wireless_dev *wdev,
6093 const void *data,
6094 int data_len)
6095{
6096 int ret;
6097 VOS_STATUS status;
6098 uint32_t ring_id;
6099 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6100 struct nlattr *tb
6101 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6102
6103 ENTER();
6104
6105 ret = wlan_hdd_validate_context(hdd_ctx);
6106 if (0 != ret) {
6107 return ret;
6108 }
6109
6110 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6111 data, data_len,
6112 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6113 hddLog(LOGE, FL("Invalid attribute"));
6114 return -EINVAL;
6115 }
6116
6117 /* Parse and fetch ring id */
6118 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6119 hddLog(LOGE, FL("attr ATTR failed"));
6120 return -EINVAL;
6121 }
6122
6123 ring_id = nla_get_u32(
6124 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6125
6126 hddLog(LOG1, FL("Bug report triggered by framework"));
6127
6128 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6129 WLAN_LOG_INDICATOR_FRAMEWORK,
6130 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306131 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306132 );
6133 if (VOS_STATUS_SUCCESS != status) {
6134 hddLog(LOGE, FL("Failed to trigger bug report"));
6135
6136 return -EINVAL;
6137 }
6138
6139 return 0;
6140
6141
6142}
6143
6144
6145static int
6146 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6147 struct wireless_dev *wdev,
6148 const void *data,
6149 int data_len)
6150{
6151 int ret = 0;
6152
6153 vos_ssr_protect(__func__);
6154 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6155 wdev, data, data_len);
6156 vos_ssr_unprotect(__func__);
6157
6158 return ret;
6159
6160}
6161
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306162#define MAX_CONCURRENT_MATRIX \
6163 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6164#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6165 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6166static const struct nla_policy
6167wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6168 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6169};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306170
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306171static int
6172__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306173 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306174 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306175{
6176 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6177 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306178 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306179 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306180 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6181 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306182
6183 ENTER();
6184
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306185 ret = wlan_hdd_validate_context(pHddCtx);
6186 if (0 != ret)
6187 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306188 return ret;
6189 }
6190
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306191 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6192 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306193 hddLog(LOGE, FL("Invalid ATTR"));
6194 return -EINVAL;
6195 }
6196
6197 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306198 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306199 hddLog(LOGE, FL("Attr max feature set size failed"));
6200 return -EINVAL;
6201 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306202 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306203 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6204
6205 /* Fill feature combination matrix */
6206 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306207 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6208 WIFI_FEATURE_P2P;
6209
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306210 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6211 WIFI_FEATURE_SOFT_AP;
6212
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306213 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6214 WIFI_FEATURE_SOFT_AP;
6215
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306216 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6217 WIFI_FEATURE_SOFT_AP |
6218 WIFI_FEATURE_P2P;
6219
6220 /* Add more feature combinations here */
6221
6222 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6223 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6224 hddLog(LOG1, "Feature set matrix");
6225 for (i = 0; i < feature_sets; i++)
6226 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6227
6228 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6229 sizeof(u32) * feature_sets +
6230 NLMSG_HDRLEN);
6231
6232 if (reply_skb) {
6233 if (nla_put_u32(reply_skb,
6234 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6235 feature_sets) ||
6236 nla_put(reply_skb,
6237 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6238 sizeof(u32) * feature_sets, feature_set_matrix)) {
6239 hddLog(LOGE, FL("nla put fail"));
6240 kfree_skb(reply_skb);
6241 return -EINVAL;
6242 }
6243
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306244 ret = cfg80211_vendor_cmd_reply(reply_skb);
6245 EXIT();
6246 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306247 }
6248 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6249 return -ENOMEM;
6250
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306251}
6252
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306253#undef MAX_CONCURRENT_MATRIX
6254#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6255
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306256static int
6257wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6258 struct wireless_dev *wdev,
6259 const void *data, int data_len)
6260{
6261 int ret = 0;
6262
6263 vos_ssr_protect(__func__);
6264 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6265 data_len);
6266 vos_ssr_unprotect(__func__);
6267
6268 return ret;
6269}
6270
c_manjeecfd1efb2015-09-25 19:32:34 +05306271
6272static int
6273__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6274 struct wireless_dev *wdev,
6275 const void *data, int data_len)
6276{
6277 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6278 int ret;
6279 ENTER();
6280
6281 ret = wlan_hdd_validate_context(pHddCtx);
6282 if (0 != ret)
6283 {
6284 return ret;
6285 }
6286
6287 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6288 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6289 {
6290 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306291 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306292 }
6293 /*call common API for FW mem dump req*/
6294 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6295
Abhishek Singhc783fa72015-12-09 18:07:34 +05306296 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306297 {
6298 /*indicate to userspace the status of fw mem dump */
6299 wlan_indicate_mem_dump_complete(true);
6300 }
6301 else
6302 {
6303 /*else send failure to userspace */
6304 wlan_indicate_mem_dump_complete(false);
6305 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306306 EXIT();
6307 return ret;
6308}
6309
6310/**
6311 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6312 * @wiphy: pointer to wireless wiphy structure.
6313 * @wdev: pointer to wireless_dev structure.
6314 * @data: Pointer to the NL data.
6315 * @data_len:Length of @data
6316 *
6317 * This is called when wlan driver needs to get the firmware memory dump
6318 * via vendor specific command.
6319 *
6320 * Return: 0 on success, error number otherwise.
6321 */
6322
6323static int
6324wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6325 struct wireless_dev *wdev,
6326 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306327{
6328 int ret = 0;
6329 vos_ssr_protect(__func__);
6330 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6331 data_len);
6332 vos_ssr_unprotect(__func__);
6333 return ret;
6334}
c_manjeecfd1efb2015-09-25 19:32:34 +05306335
Sushant Kaushik8e644982015-09-23 12:18:54 +05306336static const struct
6337nla_policy
6338qca_wlan_vendor_wifi_logger_start_policy
6339[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6340 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6341 = {.type = NLA_U32 },
6342 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6343 = {.type = NLA_U32 },
6344 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6345 = {.type = NLA_U32 },
6346};
6347
6348/**
6349 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6350 * or disable the collection of packet statistics from the firmware
6351 * @wiphy: WIPHY structure pointer
6352 * @wdev: Wireless device structure pointer
6353 * @data: Pointer to the data received
6354 * @data_len: Length of the data received
6355 *
6356 * This function is used to enable or disable the collection of packet
6357 * statistics from the firmware
6358 *
6359 * Return: 0 on success and errno on failure
6360 */
6361static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6362 struct wireless_dev *wdev,
6363 const void *data,
6364 int data_len)
6365{
6366 eHalStatus status;
6367 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6368 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6369 tAniWifiStartLog start_log;
6370
6371 status = wlan_hdd_validate_context(hdd_ctx);
6372 if (0 != status) {
6373 return -EINVAL;
6374 }
6375
6376 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6377 data, data_len,
6378 qca_wlan_vendor_wifi_logger_start_policy)) {
6379 hddLog(LOGE, FL("Invalid attribute"));
6380 return -EINVAL;
6381 }
6382
6383 /* Parse and fetch ring id */
6384 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6385 hddLog(LOGE, FL("attr ATTR failed"));
6386 return -EINVAL;
6387 }
6388 start_log.ringId = nla_get_u32(
6389 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6390 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6391
6392 /* Parse and fetch verbose level */
6393 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6394 hddLog(LOGE, FL("attr verbose_level failed"));
6395 return -EINVAL;
6396 }
6397 start_log.verboseLevel = nla_get_u32(
6398 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6399 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6400
6401 /* Parse and fetch flag */
6402 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6403 hddLog(LOGE, FL("attr flag failed"));
6404 return -EINVAL;
6405 }
6406 start_log.flag = nla_get_u32(
6407 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6408 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6409
6410 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306411 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6412 !vos_isPktStatsEnabled()))
6413
Sushant Kaushik8e644982015-09-23 12:18:54 +05306414 {
6415 hddLog(LOGE, FL("per pkt stats not enabled"));
6416 return -EINVAL;
6417 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306418
Sushant Kaushik33200572015-08-05 16:46:20 +05306419 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306420 return 0;
6421}
6422
6423/**
6424 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6425 * or disable the collection of packet statistics from the firmware
6426 * @wiphy: WIPHY structure pointer
6427 * @wdev: Wireless device structure pointer
6428 * @data: Pointer to the data received
6429 * @data_len: Length of the data received
6430 *
6431 * This function is used to enable or disable the collection of packet
6432 * statistics from the firmware
6433 *
6434 * Return: 0 on success and errno on failure
6435 */
6436static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6437 struct wireless_dev *wdev,
6438 const void *data,
6439 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306440{
6441 int ret = 0;
6442
6443 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306444
6445 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6446 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306447 vos_ssr_unprotect(__func__);
6448
6449 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306450}
6451
6452
Agarwal Ashish738843c2014-09-25 12:27:56 +05306453static const struct nla_policy
6454wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6455 +1] =
6456{
6457 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6458};
6459
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306460static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306461 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306462 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306463 int data_len)
6464{
6465 struct net_device *dev = wdev->netdev;
6466 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6467 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6470 eHalStatus status;
6471 u32 dfsFlag = 0;
6472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306473 ENTER();
6474
Agarwal Ashish738843c2014-09-25 12:27:56 +05306475 status = wlan_hdd_validate_context(pHddCtx);
6476 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306477 return -EINVAL;
6478 }
6479 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6480 data, data_len,
6481 wlan_hdd_set_no_dfs_flag_config_policy)) {
6482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6483 return -EINVAL;
6484 }
6485
6486 /* Parse and fetch required bandwidth kbps */
6487 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6489 return -EINVAL;
6490 }
6491
6492 dfsFlag = nla_get_u32(
6493 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6494 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6495 dfsFlag);
6496
6497 pHddCtx->disable_dfs_flag = dfsFlag;
6498
6499 sme_disable_dfs_channel(hHal, dfsFlag);
6500 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306501
6502 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306503 return 0;
6504}
Atul Mittal115287b2014-07-08 13:26:33 +05306505
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306506static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6507 struct wireless_dev *wdev,
6508 const void *data,
6509 int data_len)
6510{
6511 int ret = 0;
6512
6513 vos_ssr_protect(__func__);
6514 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6515 vos_ssr_unprotect(__func__);
6516
6517 return ret;
6518
6519}
6520
Mukul Sharma2a271632014-10-13 14:59:01 +05306521const struct
6522nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6523{
6524 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306525 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6526 .type = NLA_UNSPEC,
6527 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306528};
6529
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306530static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306531 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306532{
6533
6534 u8 bssid[6] = {0};
6535 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6536 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6537 eHalStatus status = eHAL_STATUS_SUCCESS;
6538 v_U32_t isFwrRoamEnabled = FALSE;
6539 int ret;
6540
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306541 ENTER();
6542
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306543 ret = wlan_hdd_validate_context(pHddCtx);
6544 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306545 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306546 }
6547
6548 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6549 data, data_len,
6550 qca_wlan_vendor_attr);
6551 if (ret){
6552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6553 return -EINVAL;
6554 }
6555
6556 /* Parse and fetch Enable flag */
6557 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6559 return -EINVAL;
6560 }
6561
6562 isFwrRoamEnabled = nla_get_u32(
6563 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6564
6565 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6566
6567 /* Parse and fetch bssid */
6568 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6570 return -EINVAL;
6571 }
6572
6573 memcpy(bssid, nla_data(
6574 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6575 sizeof(bssid));
6576 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6577
6578 //Update roaming
6579 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306580 if (!HAL_STATUS_SUCCESS(status)) {
6581 hddLog(LOGE,
6582 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6583 return -EINVAL;
6584 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306585 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306586 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306587}
6588
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306589static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6590 struct wireless_dev *wdev, const void *data, int data_len)
6591{
6592 int ret = 0;
6593
6594 vos_ssr_protect(__func__);
6595 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6596 vos_ssr_unprotect(__func__);
6597
6598 return ret;
6599}
6600
Sushant Kaushik847890c2015-09-28 16:05:17 +05306601static const struct
6602nla_policy
6603qca_wlan_vendor_get_wifi_info_policy[
6604 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6605 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6606 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6607};
6608
6609
6610/**
6611 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6612 * @wiphy: pointer to wireless wiphy structure.
6613 * @wdev: pointer to wireless_dev structure.
6614 * @data: Pointer to the data to be passed via vendor interface
6615 * @data_len:Length of the data to be passed
6616 *
6617 * This is called when wlan driver needs to send wifi driver related info
6618 * (driver/fw version) to the user space application upon request.
6619 *
6620 * Return: Return the Success or Failure code.
6621 */
6622static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6623 struct wireless_dev *wdev,
6624 const void *data, int data_len)
6625{
6626 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6627 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6628 tSirVersionString version;
6629 uint32 version_len;
6630 uint8 attr;
6631 int status;
6632 struct sk_buff *reply_skb = NULL;
6633
6634 if (VOS_FTM_MODE == hdd_get_conparam()) {
6635 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6636 return -EINVAL;
6637 }
6638
6639 status = wlan_hdd_validate_context(hdd_ctx);
6640 if (0 != status) {
6641 hddLog(LOGE, FL("HDD context is not valid"));
6642 return -EINVAL;
6643 }
6644
6645 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6646 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6647 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6648 return -EINVAL;
6649 }
6650
6651 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6652 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6653 QWLAN_VERSIONSTR);
6654 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6655 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6656 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6657 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6658 hdd_ctx->fw_Version);
6659 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6660 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6661 } else {
6662 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6663 return -EINVAL;
6664 }
6665
6666 version_len = strlen(version);
6667 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6668 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6669 if (!reply_skb) {
6670 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6671 return -ENOMEM;
6672 }
6673
6674 if (nla_put(reply_skb, attr, version_len, version)) {
6675 hddLog(LOGE, FL("nla put fail"));
6676 kfree_skb(reply_skb);
6677 return -EINVAL;
6678 }
6679
6680 return cfg80211_vendor_cmd_reply(reply_skb);
6681}
6682
6683/**
6684 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6685 * @wiphy: pointer to wireless wiphy structure.
6686 * @wdev: pointer to wireless_dev structure.
6687 * @data: Pointer to the data to be passed via vendor interface
6688 * @data_len:Length of the data to be passed
6689 * @data_len: Length of the data received
6690 *
6691 * This function is used to enable or disable the collection of packet
6692 * statistics from the firmware
6693 *
6694 * Return: 0 on success and errno on failure
6695 */
6696
6697static int
6698wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6699 struct wireless_dev *wdev,
6700 const void *data, int data_len)
6701
6702
6703{
6704 int ret = 0;
6705
6706 vos_ssr_protect(__func__);
6707 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6708 wdev, data, data_len);
6709 vos_ssr_unprotect(__func__);
6710
6711 return ret;
6712}
6713
6714
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306715/*
6716 * define short names for the global vendor params
6717 * used by __wlan_hdd_cfg80211_monitor_rssi()
6718 */
6719#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6720#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6721#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6722#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6723#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6724
6725/**---------------------------------------------------------------------------
6726
6727 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6728 monitor start is completed successfully.
6729
6730 \return - None
6731
6732 --------------------------------------------------------------------------*/
6733void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6734{
6735 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6736
6737 if (NULL == pHddCtx)
6738 {
6739 hddLog(VOS_TRACE_LEVEL_ERROR,
6740 "%s: HDD context is NULL",__func__);
6741 return;
6742 }
6743
6744 if (VOS_STATUS_SUCCESS == status)
6745 {
6746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6747 }
6748 else
6749 {
6750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6751 }
6752
6753 return;
6754}
6755
6756/**---------------------------------------------------------------------------
6757
6758 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6759 stop is completed successfully.
6760
6761 \return - None
6762
6763 --------------------------------------------------------------------------*/
6764void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6765{
6766 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6767
6768 if (NULL == pHddCtx)
6769 {
6770 hddLog(VOS_TRACE_LEVEL_ERROR,
6771 "%s: HDD context is NULL",__func__);
6772 return;
6773 }
6774
6775 if (VOS_STATUS_SUCCESS == status)
6776 {
6777 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6778 }
6779 else
6780 {
6781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6782 }
6783
6784 return;
6785}
6786
6787/**
6788 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6789 * @wiphy: Pointer to wireless phy
6790 * @wdev: Pointer to wireless device
6791 * @data: Pointer to data
6792 * @data_len: Data length
6793 *
6794 * Return: 0 on success, negative errno on failure
6795 */
6796
6797static int
6798__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6799 struct wireless_dev *wdev,
6800 const void *data,
6801 int data_len)
6802{
6803 struct net_device *dev = wdev->netdev;
6804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6805 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6806 hdd_station_ctx_t *pHddStaCtx;
6807 struct nlattr *tb[PARAM_MAX + 1];
6808 tpSirRssiMonitorReq pReq;
6809 eHalStatus status;
6810 int ret;
6811 uint32_t control;
6812 static const struct nla_policy policy[PARAM_MAX + 1] = {
6813 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6814 [PARAM_CONTROL] = { .type = NLA_U32 },
6815 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6816 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6817 };
6818
6819 ENTER();
6820
6821 ret = wlan_hdd_validate_context(hdd_ctx);
6822 if (0 != ret) {
6823 return -EINVAL;
6824 }
6825
6826 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6827 hddLog(LOGE, FL("Not in Connected state!"));
6828 return -ENOTSUPP;
6829 }
6830
6831 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6832 hddLog(LOGE, FL("Invalid ATTR"));
6833 return -EINVAL;
6834 }
6835
6836 if (!tb[PARAM_REQUEST_ID]) {
6837 hddLog(LOGE, FL("attr request id failed"));
6838 return -EINVAL;
6839 }
6840
6841 if (!tb[PARAM_CONTROL]) {
6842 hddLog(LOGE, FL("attr control failed"));
6843 return -EINVAL;
6844 }
6845
6846 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6847
6848 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6849 if(NULL == pReq)
6850 {
6851 hddLog(LOGE,
6852 FL("vos_mem_alloc failed "));
6853 return eHAL_STATUS_FAILED_ALLOC;
6854 }
6855 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6856
6857 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6858 pReq->sessionId = pAdapter->sessionId;
6859 pReq->rssiMonitorCbContext = hdd_ctx;
6860 control = nla_get_u32(tb[PARAM_CONTROL]);
6861 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6862
6863 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6864 pReq->requestId, pReq->sessionId, control);
6865
6866 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6867 if (!tb[PARAM_MIN_RSSI]) {
6868 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306869 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306870 }
6871
6872 if (!tb[PARAM_MAX_RSSI]) {
6873 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306874 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306875 }
6876
6877 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6878 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6879 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6880
6881 if (!(pReq->minRssi < pReq->maxRssi)) {
6882 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6883 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306884 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306885 }
6886 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6887 pReq->minRssi, pReq->maxRssi);
6888 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6889
6890 }
6891 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6892 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6893 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6894 }
6895 else {
6896 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306897 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306898 }
6899
6900 if (!HAL_STATUS_SUCCESS(status)) {
6901 hddLog(LOGE,
6902 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306903 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306904 }
6905
6906 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306907fail:
6908 vos_mem_free(pReq);
6909 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306910}
6911
6912/*
6913 * done with short names for the global vendor params
6914 * used by __wlan_hdd_cfg80211_monitor_rssi()
6915 */
6916#undef PARAM_MAX
6917#undef PARAM_CONTROL
6918#undef PARAM_REQUEST_ID
6919#undef PARAM_MAX_RSSI
6920#undef PARAM_MIN_RSSI
6921
6922/**
6923 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6924 * @wiphy: wiphy structure pointer
6925 * @wdev: Wireless device structure pointer
6926 * @data: Pointer to the data received
6927 * @data_len: Length of @data
6928 *
6929 * Return: 0 on success; errno on failure
6930 */
6931static int
6932wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6933 const void *data, int data_len)
6934{
6935 int ret;
6936
6937 vos_ssr_protect(__func__);
6938 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6939 vos_ssr_unprotect(__func__);
6940
6941 return ret;
6942}
6943
6944/**
6945 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6946 * @hddctx: HDD context
6947 * @data: rssi breached event data
6948 *
6949 * This function reads the rssi breached event %data and fill in the skb with
6950 * NL attributes and send up the NL event.
6951 * This callback execute in atomic context and must not invoke any
6952 * blocking calls.
6953 *
6954 * Return: none
6955 */
6956void hdd_rssi_threshold_breached_cb(void *hddctx,
6957 struct rssi_breach_event *data)
6958{
6959 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6960 int status;
6961 struct sk_buff *skb;
6962
6963 ENTER();
6964 status = wlan_hdd_validate_context(pHddCtx);
6965
6966 if (0 != status) {
6967 return;
6968 }
6969
6970 if (!data) {
6971 hddLog(LOGE, FL("data is null"));
6972 return;
6973 }
6974
6975 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6977 NULL,
6978#endif
6979 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6980 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6981 GFP_KERNEL);
6982
6983 if (!skb) {
6984 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6985 return;
6986 }
6987
6988 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6989 data->request_id, data->curr_rssi);
6990 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6991 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6992
6993 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6994 data->request_id) ||
6995 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6996 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6997 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6998 data->curr_rssi)) {
6999 hddLog(LOGE, FL("nla put fail"));
7000 goto fail;
7001 }
7002
7003 cfg80211_vendor_event(skb, GFP_KERNEL);
7004 return;
7005
7006fail:
7007 kfree_skb(skb);
7008 return;
7009}
7010
7011
7012
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307013/**
7014 * __wlan_hdd_cfg80211_setband() - set band
7015 * @wiphy: Pointer to wireless phy
7016 * @wdev: Pointer to wireless device
7017 * @data: Pointer to data
7018 * @data_len: Data length
7019 *
7020 * Return: 0 on success, negative errno on failure
7021 */
7022static int
7023__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7024 struct wireless_dev *wdev,
7025 const void *data,
7026 int data_len)
7027{
7028 struct net_device *dev = wdev->netdev;
7029 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7030 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7031 int ret;
7032 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7033 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7034
7035 ENTER();
7036
7037 ret = wlan_hdd_validate_context(hdd_ctx);
7038 if (0 != ret) {
7039 hddLog(LOGE, FL("HDD context is not valid"));
7040 return ret;
7041 }
7042
7043 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7044 policy)) {
7045 hddLog(LOGE, FL("Invalid ATTR"));
7046 return -EINVAL;
7047 }
7048
7049 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7050 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7051 return -EINVAL;
7052 }
7053
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307054 hdd_ctx->isSetBandByNL = TRUE;
7055 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307056 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307057 hdd_ctx->isSetBandByNL = FALSE;
7058
7059 EXIT();
7060 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307061}
7062
7063/**
7064 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7065 * @wiphy: wiphy structure pointer
7066 * @wdev: Wireless device structure pointer
7067 * @data: Pointer to the data received
7068 * @data_len: Length of @data
7069 *
7070 * Return: 0 on success; errno on failure
7071 */
7072static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7073 struct wireless_dev *wdev,
7074 const void *data,
7075 int data_len)
7076{
7077 int ret = 0;
7078
7079 vos_ssr_protect(__func__);
7080 ret = __wlan_hdd_cfg80211_setband(wiphy,
7081 wdev, data, data_len);
7082 vos_ssr_unprotect(__func__);
7083
7084 return ret;
7085}
7086
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307087#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7088/**
7089 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7090 * @hdd_ctx: HDD context
7091 * @request_id: [input] request id
7092 * @pattern_id: [output] pattern id
7093 *
7094 * This function loops through request id to pattern id array
7095 * if the slot is available, store the request id and return pattern id
7096 * if entry exists, return the pattern id
7097 *
7098 * Return: 0 on success and errno on failure
7099 */
7100static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7101 uint32_t request_id,
7102 uint8_t *pattern_id)
7103{
7104 uint32_t i;
7105
7106 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7107 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7108 {
7109 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7110 {
7111 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7112 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7113 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7114 return 0;
7115 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7116 request_id) {
7117 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7118 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7119 return 0;
7120 }
7121 }
7122 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7123 return -EINVAL;
7124}
7125
7126/**
7127 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7128 * @hdd_ctx: HDD context
7129 * @request_id: [input] request id
7130 * @pattern_id: [output] pattern id
7131 *
7132 * This function loops through request id to pattern id array
7133 * reset request id to 0 (slot available again) and
7134 * return pattern id
7135 *
7136 * Return: 0 on success and errno on failure
7137 */
7138static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7139 uint32_t request_id,
7140 uint8_t *pattern_id)
7141{
7142 uint32_t i;
7143
7144 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7145 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7146 {
7147 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7148 {
7149 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7150 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7151 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7152 return 0;
7153 }
7154 }
7155 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7156 return -EINVAL;
7157}
7158
7159
7160/*
7161 * define short names for the global vendor params
7162 * used by __wlan_hdd_cfg80211_offloaded_packets()
7163 */
7164#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7165#define PARAM_REQUEST_ID \
7166 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7167#define PARAM_CONTROL \
7168 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7169#define PARAM_IP_PACKET \
7170 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7171#define PARAM_SRC_MAC_ADDR \
7172 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7173#define PARAM_DST_MAC_ADDR \
7174 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7175#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7176
7177/**
7178 * wlan_hdd_add_tx_ptrn() - add tx pattern
7179 * @adapter: adapter pointer
7180 * @hdd_ctx: hdd context
7181 * @tb: nl attributes
7182 *
7183 * This function reads the NL attributes and forms a AddTxPtrn message
7184 * posts it to SME.
7185 *
7186 */
7187static int
7188wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7189 struct nlattr **tb)
7190{
7191 struct sSirAddPeriodicTxPtrn *add_req;
7192 eHalStatus status;
7193 uint32_t request_id, ret, len;
7194 uint8_t pattern_id = 0;
7195 v_MACADDR_t dst_addr;
7196 uint16_t eth_type = htons(ETH_P_IP);
7197
7198 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7199 {
7200 hddLog(LOGE, FL("Not in Connected state!"));
7201 return -ENOTSUPP;
7202 }
7203
7204 add_req = vos_mem_malloc(sizeof(*add_req));
7205 if (!add_req)
7206 {
7207 hddLog(LOGE, FL("memory allocation failed"));
7208 return -ENOMEM;
7209 }
7210
7211 /* Parse and fetch request Id */
7212 if (!tb[PARAM_REQUEST_ID])
7213 {
7214 hddLog(LOGE, FL("attr request id failed"));
7215 goto fail;
7216 }
7217
7218 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7219 hddLog(LOG1, FL("Request Id: %u"), request_id);
7220 if (request_id == 0)
7221 {
7222 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307223 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307224 }
7225
7226 if (!tb[PARAM_PERIOD])
7227 {
7228 hddLog(LOGE, FL("attr period failed"));
7229 goto fail;
7230 }
7231 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7232 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7233 if (add_req->usPtrnIntervalMs == 0)
7234 {
7235 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7236 goto fail;
7237 }
7238
7239 if (!tb[PARAM_SRC_MAC_ADDR])
7240 {
7241 hddLog(LOGE, FL("attr source mac address failed"));
7242 goto fail;
7243 }
7244 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7245 VOS_MAC_ADDR_SIZE);
7246 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7247 MAC_ADDR_ARRAY(add_req->macAddress));
7248
7249 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7250 VOS_MAC_ADDR_SIZE))
7251 {
7252 hddLog(LOGE,
7253 FL("input src mac address and connected ap bssid are different"));
7254 goto fail;
7255 }
7256
7257 if (!tb[PARAM_DST_MAC_ADDR])
7258 {
7259 hddLog(LOGE, FL("attr dst mac address failed"));
7260 goto fail;
7261 }
7262 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7263 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7264 MAC_ADDR_ARRAY(dst_addr.bytes));
7265
7266 if (!tb[PARAM_IP_PACKET])
7267 {
7268 hddLog(LOGE, FL("attr ip packet failed"));
7269 goto fail;
7270 }
7271 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7272 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7273
7274 if (add_req->ucPtrnSize < 0 ||
7275 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7276 HDD_ETH_HEADER_LEN))
7277 {
7278 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7279 add_req->ucPtrnSize);
7280 goto fail;
7281 }
7282
7283 len = 0;
7284 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7285 len += VOS_MAC_ADDR_SIZE;
7286 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7287 VOS_MAC_ADDR_SIZE);
7288 len += VOS_MAC_ADDR_SIZE;
7289 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7290 len += 2;
7291
7292 /*
7293 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7294 * ------------------------------------------------------------
7295 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7296 * ------------------------------------------------------------
7297 */
7298 vos_mem_copy(&add_req->ucPattern[len],
7299 nla_data(tb[PARAM_IP_PACKET]),
7300 add_req->ucPtrnSize);
7301 add_req->ucPtrnSize += len;
7302
7303 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7304 add_req->ucPattern, add_req->ucPtrnSize);
7305
7306 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7307 if (ret)
7308 {
7309 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7310 goto fail;
7311 }
7312 add_req->ucPtrnId = pattern_id;
7313 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7314
7315 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7316 if (!HAL_STATUS_SUCCESS(status))
7317 {
7318 hddLog(LOGE,
7319 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7320 goto fail;
7321 }
7322
7323 EXIT();
7324 vos_mem_free(add_req);
7325 return 0;
7326
7327fail:
7328 vos_mem_free(add_req);
7329 return -EINVAL;
7330}
7331
7332/**
7333 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7334 * @adapter: adapter pointer
7335 * @hdd_ctx: hdd context
7336 * @tb: nl attributes
7337 *
7338 * This function reads the NL attributes and forms a DelTxPtrn message
7339 * posts it to SME.
7340 *
7341 */
7342static int
7343wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7344 struct nlattr **tb)
7345{
7346 struct sSirDelPeriodicTxPtrn *del_req;
7347 eHalStatus status;
7348 uint32_t request_id, ret;
7349 uint8_t pattern_id = 0;
7350
7351 /* Parse and fetch request Id */
7352 if (!tb[PARAM_REQUEST_ID])
7353 {
7354 hddLog(LOGE, FL("attr request id failed"));
7355 return -EINVAL;
7356 }
7357 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7358 if (request_id == 0)
7359 {
7360 hddLog(LOGE, FL("request_id cannot be zero"));
7361 return -EINVAL;
7362 }
7363
7364 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7365 if (ret)
7366 {
7367 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7368 return -EINVAL;
7369 }
7370
7371 del_req = vos_mem_malloc(sizeof(*del_req));
7372 if (!del_req)
7373 {
7374 hddLog(LOGE, FL("memory allocation failed"));
7375 return -ENOMEM;
7376 }
7377
7378 vos_mem_set(del_req, sizeof(*del_req), 0);
7379 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7380 VOS_MAC_ADDR_SIZE);
7381 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7382 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7383 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7384 request_id, pattern_id, del_req->ucPatternIdBitmap);
7385
7386 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7387 if (!HAL_STATUS_SUCCESS(status))
7388 {
7389 hddLog(LOGE,
7390 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7391 goto fail;
7392 }
7393
7394 EXIT();
7395 vos_mem_free(del_req);
7396 return 0;
7397
7398fail:
7399 vos_mem_free(del_req);
7400 return -EINVAL;
7401}
7402
7403
7404/**
7405 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7406 * @wiphy: Pointer to wireless phy
7407 * @wdev: Pointer to wireless device
7408 * @data: Pointer to data
7409 * @data_len: Data length
7410 *
7411 * Return: 0 on success, negative errno on failure
7412 */
7413static int
7414__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7415 struct wireless_dev *wdev,
7416 const void *data,
7417 int data_len)
7418{
7419 struct net_device *dev = wdev->netdev;
7420 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7421 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7422 struct nlattr *tb[PARAM_MAX + 1];
7423 uint8_t control;
7424 int ret;
7425 static const struct nla_policy policy[PARAM_MAX + 1] =
7426 {
7427 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7428 [PARAM_CONTROL] = { .type = NLA_U32 },
7429 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7430 .len = VOS_MAC_ADDR_SIZE },
7431 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7432 .len = VOS_MAC_ADDR_SIZE },
7433 [PARAM_PERIOD] = { .type = NLA_U32 },
7434 };
7435
7436 ENTER();
7437
7438 ret = wlan_hdd_validate_context(hdd_ctx);
7439 if (0 != ret)
7440 {
7441 hddLog(LOGE, FL("HDD context is not valid"));
7442 return ret;
7443 }
7444
7445 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7446 {
7447 hddLog(LOGE,
7448 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7449 return -ENOTSUPP;
7450 }
7451
7452 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7453 {
7454 hddLog(LOGE, FL("Invalid ATTR"));
7455 return -EINVAL;
7456 }
7457
7458 if (!tb[PARAM_CONTROL])
7459 {
7460 hddLog(LOGE, FL("attr control failed"));
7461 return -EINVAL;
7462 }
7463 control = nla_get_u32(tb[PARAM_CONTROL]);
7464 hddLog(LOG1, FL("Control: %d"), control);
7465
7466 if (control == WLAN_START_OFFLOADED_PACKETS)
7467 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7468 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7469 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7470 else
7471 {
7472 hddLog(LOGE, FL("Invalid control: %d"), control);
7473 return -EINVAL;
7474 }
7475}
7476
7477/*
7478 * done with short names for the global vendor params
7479 * used by __wlan_hdd_cfg80211_offloaded_packets()
7480 */
7481#undef PARAM_MAX
7482#undef PARAM_REQUEST_ID
7483#undef PARAM_CONTROL
7484#undef PARAM_IP_PACKET
7485#undef PARAM_SRC_MAC_ADDR
7486#undef PARAM_DST_MAC_ADDR
7487#undef PARAM_PERIOD
7488
7489/**
7490 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7491 * @wiphy: wiphy structure pointer
7492 * @wdev: Wireless device structure pointer
7493 * @data: Pointer to the data received
7494 * @data_len: Length of @data
7495 *
7496 * Return: 0 on success; errno on failure
7497 */
7498static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7499 struct wireless_dev *wdev,
7500 const void *data,
7501 int data_len)
7502{
7503 int ret = 0;
7504
7505 vos_ssr_protect(__func__);
7506 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7507 wdev, data, data_len);
7508 vos_ssr_unprotect(__func__);
7509
7510 return ret;
7511}
7512#endif
7513
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307514static const struct
7515nla_policy
7516qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307517 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7518 .type = NLA_BINARY,
7519 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307520};
7521
7522/**
7523 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7524 * get link properties like nss, rate flags and operating frequency for
7525 * the connection with the given peer.
7526 * @wiphy: WIPHY structure pointer
7527 * @wdev: Wireless device structure pointer
7528 * @data: Pointer to the data received
7529 * @data_len: Length of the data received
7530 *
7531 * This function return the above link properties on success.
7532 *
7533 * Return: 0 on success and errno on failure
7534 */
7535static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7536 struct wireless_dev *wdev,
7537 const void *data,
7538 int data_len)
7539{
7540 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7541 struct net_device *dev = wdev->netdev;
7542 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7543 hdd_station_ctx_t *hdd_sta_ctx;
7544 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7545 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7546 uint32_t sta_id;
7547 struct sk_buff *reply_skb;
7548 uint32_t rate_flags = 0;
7549 uint8_t nss;
7550 uint8_t final_rate_flags = 0;
7551 uint32_t freq;
7552 v_CONTEXT_t pVosContext = NULL;
7553 ptSapContext pSapCtx = NULL;
7554
7555 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7557 return -EINVAL;
7558 }
7559
7560 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7561 qca_wlan_vendor_attr_policy)) {
7562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7563 return -EINVAL;
7564 }
7565
7566 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7567 hddLog(VOS_TRACE_LEVEL_ERROR,
7568 FL("Attribute peerMac not provided for mode=%d"),
7569 adapter->device_mode);
7570 return -EINVAL;
7571 }
7572
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307573 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7574 hddLog(VOS_TRACE_LEVEL_ERROR,
7575 FL("Attribute peerMac is invalid=%d"),
7576 adapter->device_mode);
7577 return -EINVAL;
7578 }
7579
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307580 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7581 sizeof(peer_mac));
7582 hddLog(VOS_TRACE_LEVEL_INFO,
7583 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7584 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7585
7586 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7587 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7588 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7589 if ((hdd_sta_ctx->conn_info.connState !=
7590 eConnectionState_Associated) ||
7591 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7592 VOS_MAC_ADDRESS_LEN)) {
7593 hddLog(VOS_TRACE_LEVEL_ERROR,
7594 FL("Not Associated to mac "MAC_ADDRESS_STR),
7595 MAC_ADDR_ARRAY(peer_mac));
7596 return -EINVAL;
7597 }
7598
7599 nss = 1; //pronto supports only one spatial stream
7600 freq = vos_chan_to_freq(
7601 hdd_sta_ctx->conn_info.operationChannel);
7602 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7603
7604 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7605 adapter->device_mode == WLAN_HDD_SOFTAP) {
7606
7607 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7608 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7609 if(pSapCtx == NULL){
7610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7611 FL("psapCtx is NULL"));
7612 return -ENOENT;
7613 }
7614
7615
7616 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7617 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7618 !vos_is_macaddr_broadcast(
7619 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7620 vos_mem_compare(
7621 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7622 peer_mac, VOS_MAC_ADDRESS_LEN))
7623 break;
7624 }
7625
7626 if (WLAN_MAX_STA_COUNT == sta_id) {
7627 hddLog(VOS_TRACE_LEVEL_ERROR,
7628 FL("No active peer with mac="MAC_ADDRESS_STR),
7629 MAC_ADDR_ARRAY(peer_mac));
7630 return -EINVAL;
7631 }
7632
7633 nss = 1; //pronto supports only one spatial stream
7634 freq = vos_chan_to_freq(
7635 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7636 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7637 } else {
7638 hddLog(VOS_TRACE_LEVEL_ERROR,
7639 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7640 MAC_ADDR_ARRAY(peer_mac));
7641 return -EINVAL;
7642 }
7643
7644 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7645 if (rate_flags & eHAL_TX_RATE_VHT80) {
7646 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7647 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7648 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7649 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7650 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7651 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7652 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7653 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7654 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7655 if (rate_flags & eHAL_TX_RATE_HT40)
7656 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7657 }
7658
7659 if (rate_flags & eHAL_TX_RATE_SGI) {
7660 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7661 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7662 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7663 }
7664 }
7665
7666 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7667 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7668
7669 if (NULL == reply_skb) {
7670 hddLog(VOS_TRACE_LEVEL_ERROR,
7671 FL("getLinkProperties: skb alloc failed"));
7672 return -EINVAL;
7673 }
7674
7675 if (nla_put_u8(reply_skb,
7676 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7677 nss) ||
7678 nla_put_u8(reply_skb,
7679 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7680 final_rate_flags) ||
7681 nla_put_u32(reply_skb,
7682 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7683 freq)) {
7684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7685 kfree_skb(reply_skb);
7686 return -EINVAL;
7687 }
7688
7689 return cfg80211_vendor_cmd_reply(reply_skb);
7690}
7691
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307692#define BEACON_MISS_THRESH_2_4 \
7693 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7694#define BEACON_MISS_THRESH_5_0 \
7695 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307696#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7697#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7698#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7699#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307700#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7701 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307702
7703/**
7704 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7705 * vendor command
7706 *
7707 * @wiphy: wiphy device pointer
7708 * @wdev: wireless device pointer
7709 * @data: Vendor command data buffer
7710 * @data_len: Buffer length
7711 *
7712 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7713 *
7714 * Return: EOK or other error codes.
7715 */
7716
7717static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7718 struct wireless_dev *wdev,
7719 const void *data,
7720 int data_len)
7721{
7722 struct net_device *dev = wdev->netdev;
7723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7725 hdd_station_ctx_t *pHddStaCtx;
7726 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7727 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307728 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307729 eHalStatus status;
7730 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307731 uint8_t hb_thresh_val;
7732
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307733 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7734 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7735 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307736 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7737 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7738 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307739 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7740 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307741 };
7742
7743 ENTER();
7744
7745 if (VOS_FTM_MODE == hdd_get_conparam()) {
7746 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7747 return -EINVAL;
7748 }
7749
7750 ret_val = wlan_hdd_validate_context(pHddCtx);
7751 if (ret_val) {
7752 return ret_val;
7753 }
7754
7755 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7756
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307757 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7758 hddLog(LOGE, FL("Invalid ATTR"));
7759 return -EINVAL;
7760 }
7761
7762 /* check the Wifi Capability */
7763 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7764 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7765 {
7766 hddLog(VOS_TRACE_LEVEL_ERROR,
7767 FL("WIFICONFIG not supported by Firmware"));
7768 return -EINVAL;
7769 }
7770
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307771 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7772 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7773 modifyRoamParamsReq.value =
7774 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7775
7776 if (eHAL_STATUS_SUCCESS !=
7777 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7778 {
7779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7780 ret_val = -EINVAL;
7781 }
7782 return ret_val;
7783 }
7784
7785 /* Moved this down in order to provide provision to set beacon
7786 * miss penalty count irrespective of connection state.
7787 */
7788 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7789 hddLog(LOGE, FL("Not in Connected state!"));
7790 return -ENOTSUPP;
7791 }
7792
7793 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307794
7795 if (!pReq) {
7796 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7797 "%s: Not able to allocate memory for tSetWifiConfigParams",
7798 __func__);
7799 return eHAL_STATUS_E_MALLOC_FAILED;
7800 }
7801
7802 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7803
7804 pReq->sessionId = pAdapter->sessionId;
7805 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7806
7807 if (tb[PARAM_MODULATED_DTIM]) {
7808 pReq->paramValue = nla_get_u32(
7809 tb[PARAM_MODULATED_DTIM]);
7810 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7811 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307812 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307813 hdd_set_pwrparams(pHddCtx);
7814 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7815 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7816
7817 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7818 iw_full_power_cbfn, pAdapter,
7819 eSME_FULL_PWR_NEEDED_BY_HDD);
7820 }
7821 else
7822 {
7823 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7824 }
7825 }
7826
7827 if (tb[PARAM_STATS_AVG_FACTOR]) {
7828 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7829 pReq->paramValue = nla_get_u16(
7830 tb[PARAM_STATS_AVG_FACTOR]);
7831 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7832 pReq->paramType, pReq->paramValue);
7833 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7834
7835 if (eHAL_STATUS_SUCCESS != status)
7836 {
7837 vos_mem_free(pReq);
7838 pReq = NULL;
7839 ret_val = -EPERM;
7840 return ret_val;
7841 }
7842 }
7843
7844
7845 if (tb[PARAM_GUARD_TIME]) {
7846 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7847 pReq->paramValue = nla_get_u32(
7848 tb[PARAM_GUARD_TIME]);
7849 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7850 pReq->paramType, pReq->paramValue);
7851 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7852
7853 if (eHAL_STATUS_SUCCESS != status)
7854 {
7855 vos_mem_free(pReq);
7856 pReq = NULL;
7857 ret_val = -EPERM;
7858 return ret_val;
7859 }
7860
7861 }
7862
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307863 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7864 hb_thresh_val = nla_get_u8(
7865 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7866
7867 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %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_24);
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
7885 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7886 hb_thresh_val = nla_get_u8(
7887 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7888
7889 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7890 hb_thresh_val);
7891 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7892 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7893 NULL, eANI_BOOLEAN_FALSE);
7894
7895 status = sme_update_hb_threshold(
7896 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7897 WNI_CFG_HEART_BEAT_THRESHOLD,
7898 hb_thresh_val, eCSR_BAND_5G);
7899 if (eHAL_STATUS_SUCCESS != status) {
7900 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7901 vos_mem_free(pReq);
7902 pReq = NULL;
7903 return -EPERM;
7904 }
7905 }
7906
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307907 EXIT();
7908 return ret_val;
7909}
7910
7911/**
7912 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7913 * vendor command
7914 *
7915 * @wiphy: wiphy device pointer
7916 * @wdev: wireless device pointer
7917 * @data: Vendor command data buffer
7918 * @data_len: Buffer length
7919 *
7920 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7921 *
7922 * Return: EOK or other error codes.
7923 */
7924static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7925 struct wireless_dev *wdev,
7926 const void *data,
7927 int data_len)
7928{
7929 int ret;
7930
7931 vos_ssr_protect(__func__);
7932 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7933 data, data_len);
7934 vos_ssr_unprotect(__func__);
7935
7936 return ret;
7937}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307938
7939/*
7940 * define short names for the global vendor params
7941 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7942 */
7943#define STATS_SET_INVALID \
7944 QCA_ATTR_NUD_STATS_SET_INVALID
7945#define STATS_SET_START \
7946 QCA_ATTR_NUD_STATS_SET_START
7947#define STATS_GW_IPV4 \
7948 QCA_ATTR_NUD_STATS_GW_IPV4
7949#define STATS_SET_MAX \
7950 QCA_ATTR_NUD_STATS_SET_MAX
7951
7952const struct nla_policy
7953qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7954{
7955 [STATS_SET_START] = {.type = NLA_FLAG },
7956 [STATS_GW_IPV4] = {.type = NLA_U32 },
7957};
7958
7959/**
7960 * hdd_set_nud_stats_cb() - hdd callback api to get status
7961 * @data: pointer to adapter
7962 * @rsp: status
7963 *
7964 * Return: None
7965 */
7966static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7967{
7968
7969 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7970
7971 if (NULL == adapter)
7972 return;
7973
7974 if (VOS_STATUS_SUCCESS == rsp) {
7975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7976 "%s success received STATS_SET_START", __func__);
7977 } else {
7978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7979 "%s STATS_SET_START Failed!!", __func__);
7980 }
7981 return;
7982}
7983
7984/**
7985 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7986 * @wiphy: pointer to wireless wiphy structure.
7987 * @wdev: pointer to wireless_dev structure.
7988 * @data: pointer to apfind configuration data.
7989 * @data_len: the length in byte of apfind data.
7990 *
7991 * This is called when wlan driver needs to send arp stats to
7992 * firmware.
7993 *
7994 * Return: An error code or 0 on success.
7995 */
7996static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7997 struct wireless_dev *wdev,
7998 const void *data, int data_len)
7999{
8000 struct nlattr *tb[STATS_SET_MAX + 1];
8001 struct net_device *dev = wdev->netdev;
8002 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8003 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308004 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308005 setArpStatsParams arp_stats_params;
8006 int err = 0;
8007
8008 ENTER();
8009
8010 err = wlan_hdd_validate_context(hdd_ctx);
8011 if (0 != err)
8012 return err;
8013
8014 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8016 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8017 return -EINVAL;
8018 }
8019
8020 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8021 qca_wlan_vendor_set_nud_stats);
8022 if (err)
8023 {
8024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8025 "%s STATS_SET_START ATTR", __func__);
8026 return err;
8027 }
8028
8029 if (tb[STATS_SET_START])
8030 {
8031 if (!tb[STATS_GW_IPV4]) {
8032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8033 "%s STATS_SET_START CMD", __func__);
8034 return -EINVAL;
8035 }
8036 arp_stats_params.flag = true;
8037 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8038 } else {
8039 arp_stats_params.flag = false;
8040 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308041 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8043 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308044 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8045 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308046
8047 arp_stats_params.pkt_type = 1; // ARP packet type
8048
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308049 if (arp_stats_params.flag) {
8050 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8051 WLANTL_SetARPFWDatapath(pVosContext, true);
8052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8053 "%s Set FW in data path for ARP with tgt IP :%d",
8054 __func__, hdd_ctx->track_arp_ip);
8055 }
8056 else {
8057 WLANTL_SetARPFWDatapath(pVosContext, false);
8058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8059 "%s Remove FW from data path", __func__);
8060 }
8061
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308062 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8063 arp_stats_params.data_ctx = adapter;
8064
8065 if (eHAL_STATUS_SUCCESS !=
8066 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8068 "%s STATS_SET_START CMD Failed!!", __func__);
8069 return -EINVAL;
8070 }
8071
8072 EXIT();
8073
8074 return err;
8075}
8076
8077/**
8078 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8079 * @wiphy: pointer to wireless wiphy structure.
8080 * @wdev: pointer to wireless_dev structure.
8081 * @data: pointer to apfind configuration data.
8082 * @data_len: the length in byte of apfind data.
8083 *
8084 * This is called when wlan driver needs to send arp stats to
8085 * firmware.
8086 *
8087 * Return: An error code or 0 on success.
8088 */
8089static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8090 struct wireless_dev *wdev,
8091 const void *data, int data_len)
8092{
8093 int ret;
8094
8095 vos_ssr_protect(__func__);
8096 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8097 vos_ssr_unprotect(__func__);
8098
8099 return ret;
8100}
8101#undef STATS_SET_INVALID
8102#undef STATS_SET_START
8103#undef STATS_GW_IPV4
8104#undef STATS_SET_MAX
8105
8106/*
8107 * define short names for the global vendor params
8108 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8109 */
8110#define STATS_GET_INVALID \
8111 QCA_ATTR_NUD_STATS_SET_INVALID
8112#define COUNT_FROM_NETDEV \
8113 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8114#define COUNT_TO_LOWER_MAC \
8115 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8116#define RX_COUNT_BY_LOWER_MAC \
8117 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8118#define COUNT_TX_SUCCESS \
8119 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8120#define RSP_RX_COUNT_BY_LOWER_MAC \
8121 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8122#define RSP_RX_COUNT_BY_UPPER_MAC \
8123 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8124#define RSP_COUNT_TO_NETDEV \
8125 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8126#define RSP_COUNT_OUT_OF_ORDER_DROP \
8127 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8128#define AP_LINK_ACTIVE \
8129 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8130#define AP_LINK_DAD \
8131 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8132#define STATS_GET_MAX \
8133 QCA_ATTR_NUD_STATS_GET_MAX
8134
8135const struct nla_policy
8136qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8137{
8138 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8139 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8140 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8141 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8142 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8143 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8144 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8145 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8146 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8147 [AP_LINK_DAD] = {.type = NLA_FLAG },
8148};
8149
8150static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8151{
8152
8153 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8154 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8155 struct hdd_nud_stats_context *context;
8156 int status;
8157
8158 ENTER();
8159
8160 if (NULL == adapter)
8161 return;
8162
8163 status = wlan_hdd_validate_context(hdd_ctx);
8164 if (0 != status) {
8165 return;
8166 }
8167
8168 if (!rsp) {
8169 hddLog(LOGE, FL("data is null"));
8170 return;
8171 }
8172
8173 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8174 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8175 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8176 adapter->dad |= rsp->dad;
8177
8178 spin_lock(&hdd_context_lock);
8179 context = &hdd_ctx->nud_stats_context;
8180 complete(&context->response_event);
8181 spin_unlock(&hdd_context_lock);
8182
8183 return;
8184}
8185static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8186 struct wireless_dev *wdev,
8187 const void *data, int data_len)
8188{
8189 int err = 0;
8190 unsigned long rc;
8191 struct hdd_nud_stats_context *context;
8192 struct net_device *dev = wdev->netdev;
8193 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8194 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8195 getArpStatsParams arp_stats_params;
8196 struct sk_buff *skb;
8197
8198 ENTER();
8199
8200 err = wlan_hdd_validate_context(hdd_ctx);
8201 if (0 != err)
8202 return err;
8203
8204 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8205 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8206 arp_stats_params.data_ctx = adapter;
8207
8208 spin_lock(&hdd_context_lock);
8209 context = &hdd_ctx->nud_stats_context;
8210 INIT_COMPLETION(context->response_event);
8211 spin_unlock(&hdd_context_lock);
8212
8213 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8215 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8216 return -EINVAL;
8217 }
8218
8219 if (eHAL_STATUS_SUCCESS !=
8220 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8222 "%s STATS_SET_START CMD Failed!!", __func__);
8223 return -EINVAL;
8224 }
8225
8226 rc = wait_for_completion_timeout(&context->response_event,
8227 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8228 if (!rc)
8229 {
8230 hddLog(LOGE,
8231 FL("Target response timed out request "));
8232 return -ETIMEDOUT;
8233 }
8234
8235 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8236 WLAN_NUD_STATS_LEN);
8237 if (!skb)
8238 {
8239 hddLog(VOS_TRACE_LEVEL_ERROR,
8240 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8241 __func__);
8242 return -ENOMEM;
8243 }
8244
8245 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8246 adapter->hdd_stats.hddArpStats.txCount) ||
8247 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8248 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8249 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8250 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8251 nla_put_u16(skb, COUNT_TX_SUCCESS,
8252 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8253 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8254 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8255 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8256 adapter->hdd_stats.hddArpStats.rxCount) ||
8257 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8258 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8259 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8260 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8261 hddLog(LOGE, FL("nla put fail"));
8262 kfree_skb(skb);
8263 return -EINVAL;
8264 }
8265 if (adapter->con_status)
8266 nla_put_flag(skb, AP_LINK_ACTIVE);
8267 if (adapter->dad)
8268 nla_put_flag(skb, AP_LINK_DAD);
8269
8270 cfg80211_vendor_cmd_reply(skb);
8271 return err;
8272}
8273
8274static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8275 struct wireless_dev *wdev,
8276 const void *data, int data_len)
8277{
8278 int ret;
8279
8280 vos_ssr_protect(__func__);
8281 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8282 vos_ssr_unprotect(__func__);
8283
8284 return ret;
8285}
8286
8287#undef QCA_ATTR_NUD_STATS_SET_INVALID
8288#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8289#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8290#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8291#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8292#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8293#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8294#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8295#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8296#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8297#undef QCA_ATTR_NUD_STATS_GET_MAX
8298
8299
8300
Kapil Guptaee33bf12016-12-20 18:27:37 +05308301#ifdef WLAN_FEATURE_APFIND
8302/**
8303 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8304 * @wiphy: pointer to wireless wiphy structure.
8305 * @wdev: pointer to wireless_dev structure.
8306 * @data: pointer to apfind configuration data.
8307 * @data_len: the length in byte of apfind data.
8308 *
8309 * This is called when wlan driver needs to send APFIND configurations to
8310 * firmware.
8311 *
8312 * Return: An error code or 0 on success.
8313 */
8314static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8315 struct wireless_dev *wdev,
8316 const void *data, int data_len)
8317{
8318 struct sme_ap_find_request_req apfind_req;
8319 VOS_STATUS status;
8320 int ret_val;
8321 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8322
8323 ENTER();
8324
8325 ret_val = wlan_hdd_validate_context(hdd_ctx);
8326 if (ret_val)
8327 return ret_val;
8328
8329 if (VOS_FTM_MODE == hdd_get_conparam()) {
8330 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8331 return -EPERM;
8332 }
8333
8334 apfind_req.request_data_len = data_len;
8335 apfind_req.request_data = data;
8336
8337 status = sme_apfind_set_cmd(&apfind_req);
8338 if (VOS_STATUS_SUCCESS != status) {
8339 ret_val = -EIO;
8340 }
8341 return ret_val;
8342}
8343
8344/**
8345 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8346 * @wiphy: pointer to wireless wiphy structure.
8347 * @wdev: pointer to wireless_dev structure.
8348 * @data: pointer to apfind configuration data.
8349 * @data_len: the length in byte of apfind data.
8350 *
8351 * This is called when wlan driver needs to send APFIND configurations to
8352 * firmware.
8353 *
8354 * Return: An error code or 0 on success.
8355 */
8356static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8357 struct wireless_dev *wdev,
8358 const void *data, int data_len)
8359{
8360 int ret;
8361
8362 vos_ssr_protect(__func__);
8363 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8364 vos_ssr_unprotect(__func__);
8365
8366 return ret;
8367}
8368#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308369const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8370{
Mukul Sharma2a271632014-10-13 14:59:01 +05308371 {
8372 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8373 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8374 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8375 WIPHY_VENDOR_CMD_NEED_NETDEV |
8376 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308377 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308378 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308379
8380 {
8381 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8382 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8383 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8384 WIPHY_VENDOR_CMD_NEED_NETDEV |
8385 WIPHY_VENDOR_CMD_NEED_RUNNING,
8386 .doit = wlan_hdd_cfg80211_nan_request
8387 },
8388
Sunil Duttc69bccb2014-05-26 21:30:20 +05308389#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8390 {
8391 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8392 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8393 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8394 WIPHY_VENDOR_CMD_NEED_NETDEV |
8395 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308396 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308397 },
8398
8399 {
8400 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8401 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8402 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8403 WIPHY_VENDOR_CMD_NEED_NETDEV |
8404 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308405 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308406 },
8407
8408 {
8409 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8410 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8411 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8412 WIPHY_VENDOR_CMD_NEED_NETDEV |
8413 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308414 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308415 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308416#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308417#ifdef WLAN_FEATURE_EXTSCAN
8418 {
8419 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8420 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8421 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8422 WIPHY_VENDOR_CMD_NEED_NETDEV |
8423 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308424 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308425 },
8426 {
8427 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8428 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8429 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8430 WIPHY_VENDOR_CMD_NEED_NETDEV |
8431 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308432 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308433 },
8434 {
8435 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8436 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8437 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8438 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308439 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308440 },
8441 {
8442 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8443 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8444 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8445 WIPHY_VENDOR_CMD_NEED_NETDEV |
8446 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308447 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308448 },
8449 {
8450 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8451 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8452 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8453 WIPHY_VENDOR_CMD_NEED_NETDEV |
8454 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308455 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308456 },
8457 {
8458 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8459 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8460 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8461 WIPHY_VENDOR_CMD_NEED_NETDEV |
8462 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308463 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308464 },
8465 {
8466 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8467 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8468 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8469 WIPHY_VENDOR_CMD_NEED_NETDEV |
8470 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308471 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308472 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308473#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308474/*EXT TDLS*/
8475 {
8476 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8477 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8478 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8479 WIPHY_VENDOR_CMD_NEED_NETDEV |
8480 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308481 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308482 },
8483 {
8484 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8485 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8486 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8487 WIPHY_VENDOR_CMD_NEED_NETDEV |
8488 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308489 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308490 },
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308496 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308497 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308498 {
8499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8502 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308503 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308504 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308505 {
8506 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8507 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8508 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8509 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308510 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308511 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308512 {
8513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8516 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308517 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308518 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308524 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308525 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308526 {
8527 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308528 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8529 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8530 WIPHY_VENDOR_CMD_NEED_NETDEV |
8531 WIPHY_VENDOR_CMD_NEED_RUNNING,
8532 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8533 },
8534 {
8535 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308536 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8537 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8538 WIPHY_VENDOR_CMD_NEED_NETDEV |
8539 WIPHY_VENDOR_CMD_NEED_RUNNING,
8540 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308541 },
8542 {
8543 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8544 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8545 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8546 WIPHY_VENDOR_CMD_NEED_NETDEV,
8547 .doit = wlan_hdd_cfg80211_wifi_logger_start
8548 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308549 {
8550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8553 WIPHY_VENDOR_CMD_NEED_NETDEV|
8554 WIPHY_VENDOR_CMD_NEED_RUNNING,
8555 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308556 },
8557 {
8558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8561 WIPHY_VENDOR_CMD_NEED_NETDEV |
8562 WIPHY_VENDOR_CMD_NEED_RUNNING,
8563 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308564 },
8565 {
8566 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8567 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8568 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8569 WIPHY_VENDOR_CMD_NEED_NETDEV |
8570 WIPHY_VENDOR_CMD_NEED_RUNNING,
8571 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308572 },
8573#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8574 {
8575 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8576 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8577 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8578 WIPHY_VENDOR_CMD_NEED_NETDEV |
8579 WIPHY_VENDOR_CMD_NEED_RUNNING,
8580 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308581 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308582#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308583 {
8584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8587 WIPHY_VENDOR_CMD_NEED_NETDEV |
8588 WIPHY_VENDOR_CMD_NEED_RUNNING,
8589 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308590 },
8591 {
8592 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8593 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8594 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8595 WIPHY_VENDOR_CMD_NEED_NETDEV |
8596 WIPHY_VENDOR_CMD_NEED_RUNNING,
8597 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308598 },
8599#ifdef WLAN_FEATURE_APFIND
8600 {
8601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8604 WIPHY_VENDOR_CMD_NEED_NETDEV,
8605 .doit = wlan_hdd_cfg80211_apfind_cmd
8606 },
8607#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308608 {
8609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8612 WIPHY_VENDOR_CMD_NEED_NETDEV |
8613 WIPHY_VENDOR_CMD_NEED_RUNNING,
8614 .doit = wlan_hdd_cfg80211_set_nud_stats
8615 },
8616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV |
8621 WIPHY_VENDOR_CMD_NEED_RUNNING,
8622 .doit = wlan_hdd_cfg80211_get_nud_stats
8623 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308624 {
8625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8628 WIPHY_VENDOR_CMD_NEED_NETDEV |
8629 WIPHY_VENDOR_CMD_NEED_RUNNING,
8630 .doit = hdd_cfg80211_get_station_cmd
8631 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308632};
8633
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008634/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308635static const
8636struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008637{
8638#ifdef FEATURE_WLAN_CH_AVOID
8639 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308640 .vendor_id = QCA_NL80211_VENDOR_ID,
8641 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008642 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308643#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8644#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8645 {
8646 /* Index = 1*/
8647 .vendor_id = QCA_NL80211_VENDOR_ID,
8648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8649 },
8650 {
8651 /* Index = 2*/
8652 .vendor_id = QCA_NL80211_VENDOR_ID,
8653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8654 },
8655 {
8656 /* Index = 3*/
8657 .vendor_id = QCA_NL80211_VENDOR_ID,
8658 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8659 },
8660 {
8661 /* Index = 4*/
8662 .vendor_id = QCA_NL80211_VENDOR_ID,
8663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8664 },
8665 {
8666 /* Index = 5*/
8667 .vendor_id = QCA_NL80211_VENDOR_ID,
8668 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8669 },
8670 {
8671 /* Index = 6*/
8672 .vendor_id = QCA_NL80211_VENDOR_ID,
8673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8674 },
8675#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308676#ifdef WLAN_FEATURE_EXTSCAN
8677 {
8678 .vendor_id = QCA_NL80211_VENDOR_ID,
8679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8680 },
8681 {
8682 .vendor_id = QCA_NL80211_VENDOR_ID,
8683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8684 },
8685 {
8686 .vendor_id = QCA_NL80211_VENDOR_ID,
8687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8688 },
8689 {
8690 .vendor_id = QCA_NL80211_VENDOR_ID,
8691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8692 },
8693 {
8694 .vendor_id = QCA_NL80211_VENDOR_ID,
8695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8696 },
8697 {
8698 .vendor_id = QCA_NL80211_VENDOR_ID,
8699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8700 },
8701 {
8702 .vendor_id = QCA_NL80211_VENDOR_ID,
8703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8704 },
8705 {
8706 .vendor_id = QCA_NL80211_VENDOR_ID,
8707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8708 },
8709 {
8710 .vendor_id = QCA_NL80211_VENDOR_ID,
8711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8712 },
8713 {
8714 .vendor_id = QCA_NL80211_VENDOR_ID,
8715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8716 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308717#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308718/*EXT TDLS*/
8719 {
8720 .vendor_id = QCA_NL80211_VENDOR_ID,
8721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8722 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308723 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8724 .vendor_id = QCA_NL80211_VENDOR_ID,
8725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8726 },
8727
Srinivas Dasari030bad32015-02-18 23:23:54 +05308728
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308729 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308730 .vendor_id = QCA_NL80211_VENDOR_ID,
8731 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8732 },
8733
Sushant Kaushik084f6592015-09-10 13:11:56 +05308734 {
8735 .vendor_id = QCA_NL80211_VENDOR_ID,
8736 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308737 },
8738 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8739 .vendor_id = QCA_NL80211_VENDOR_ID,
8740 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8741 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308742 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8743 .vendor_id = QCA_NL80211_VENDOR_ID,
8744 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8745 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308746 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8747 .vendor_id = QCA_NL80211_VENDOR_ID,
8748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8749 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008750};
8751
Jeff Johnson295189b2012-06-20 16:38:30 -07008752/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308753 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308754 * This function is called by hdd_wlan_startup()
8755 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308756 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308758struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008759{
8760 struct wiphy *wiphy;
8761 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308762 /*
8763 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 */
8765 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8766
8767 if (!wiphy)
8768 {
8769 /* Print error and jump into err label and free the memory */
8770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8771 return NULL;
8772 }
8773
Sunil Duttc69bccb2014-05-26 21:30:20 +05308774
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 return wiphy;
8776}
8777
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308778#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8779 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8780/**
8781 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8782 * @wiphy: pointer to wiphy
8783 * @config: pointer to config
8784 *
8785 * Return: None
8786 */
8787static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8788 hdd_config_t *config)
8789{
8790 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8791 if (config->max_sched_scan_plan_interval)
8792 wiphy->max_sched_scan_plan_interval =
8793 config->max_sched_scan_plan_interval;
8794 if (config->max_sched_scan_plan_iterations)
8795 wiphy->max_sched_scan_plan_iterations =
8796 config->max_sched_scan_plan_iterations;
8797}
8798#else
8799static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8800 hdd_config_t *config)
8801{
8802}
8803#endif
8804
Jeff Johnson295189b2012-06-20 16:38:30 -07008805/*
8806 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308807 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 * private ioctl to change the band value
8809 */
8810int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8811{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308812 int i, j;
8813 eNVChannelEnabledType channelEnabledState;
8814
Jeff Johnsone7245742012-09-05 17:12:55 -07008815 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308816
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308817 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308819
8820 if (NULL == wiphy->bands[i])
8821 {
8822 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8823 __func__, i);
8824 continue;
8825 }
8826
8827 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8828 {
8829 struct ieee80211_supported_band *band = wiphy->bands[i];
8830
8831 channelEnabledState = vos_nv_getChannelEnabledState(
8832 band->channels[j].hw_value);
8833
8834 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8835 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308836 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308837 continue;
8838 }
8839 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8840 {
8841 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8842 continue;
8843 }
8844
8845 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8846 NV_CHANNEL_INVALID == channelEnabledState)
8847 {
8848 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8849 }
8850 else if (NV_CHANNEL_DFS == channelEnabledState)
8851 {
8852 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8853 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8854 }
8855 else
8856 {
8857 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8858 |IEEE80211_CHAN_RADAR);
8859 }
8860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 }
8862 return 0;
8863}
8864/*
8865 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308866 * This function is called by hdd_wlan_startup()
8867 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 * This function is used to initialize and register wiphy structure.
8869 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308870int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008871 struct wiphy *wiphy,
8872 hdd_config_t *pCfg
8873 )
8874{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308875 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308876 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8877
Jeff Johnsone7245742012-09-05 17:12:55 -07008878 ENTER();
8879
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 /* Now bind the underlying wlan device with wiphy */
8881 set_wiphy_dev(wiphy, dev);
8882
8883 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008884
Kiet Lam6c583332013-10-14 05:37:09 +05308885#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008886 /* the flag for the other case would be initialzed in
8887 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308888#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8889 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8890#else
Amar Singhal0a402232013-10-11 20:57:16 -07008891 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308892#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308893#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008894
Amar Singhalfddc28c2013-09-05 13:03:40 -07008895 /* This will disable updating of NL channels from passive to
8896 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8898 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8899#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008900 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308901#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008902
Amar Singhala49cbc52013-10-08 18:37:44 -07008903
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008905 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8906 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8907 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008908 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308910 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308911#else
8912 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8913#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008914#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008915
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008916#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008917 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008918#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008919 || pCfg->isFastRoamIniFeatureEnabled
8920#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008921#ifdef FEATURE_WLAN_ESE
8922 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008923#endif
8924 )
8925 {
8926 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8927 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008928#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008929#ifdef FEATURE_WLAN_TDLS
8930 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8931 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8932#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308933#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308934 if (pCfg->configPNOScanSupport)
8935 {
8936 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8937 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8938 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8939 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8940 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308941#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008942
Abhishek Singh10d85972015-04-17 10:27:23 +05308943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8944 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8945#endif
8946
Amar Singhalfddc28c2013-09-05 13:03:40 -07008947#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008948 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8949 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008950 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008951 driver need to determine what to do with both
8952 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008953
8954 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008955#else
8956 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008957#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008958
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308959 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8960
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308961 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008962
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308963 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8964
Jeff Johnson295189b2012-06-20 16:38:30 -07008965 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308966 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8967 | BIT(NL80211_IFTYPE_ADHOC)
8968 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8969 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308970 | BIT(NL80211_IFTYPE_AP)
8971 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07008972
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308973 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008974 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8976 if( pCfg->enableMCC )
8977 {
8978 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308979 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008980
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308981 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308982 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008983
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308984 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308985 wiphy->iface_combinations = wlan_hdd_iface_combination;
8986 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008987#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308988 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008989
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 /* Before registering we need to update the ht capabilitied based
8991 * on ini values*/
8992 if( !pCfg->ShortGI20MhzEnable )
8993 {
8994 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8995 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 }
8997
8998 if( !pCfg->ShortGI40MhzEnable )
8999 {
9000 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9001 }
9002
9003 if( !pCfg->nChannelBondingMode5GHz )
9004 {
9005 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9006 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309007 /*
9008 * In case of static linked driver at the time of driver unload,
9009 * module exit doesn't happens. Module cleanup helps in cleaning
9010 * of static memory.
9011 * If driver load happens statically, at the time of driver unload,
9012 * wiphy flags don't get reset because of static memory.
9013 * It's better not to store channel in static memory.
9014 */
9015 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9016 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
9017 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
9018 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
9019 {
9020 hddLog(VOS_TRACE_LEVEL_ERROR,
9021 FL("Not enough memory to allocate channels"));
9022 return -ENOMEM;
9023 }
9024 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
9025 &hdd_channels_2_4_GHZ[0],
9026 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009027
Agrawal Ashish97dec502015-11-26 20:20:58 +05309028 if (true == hdd_is_5g_supported(pHddCtx))
9029 {
9030 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9031 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
9032 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
9033 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
9034 {
9035 hddLog(VOS_TRACE_LEVEL_ERROR,
9036 FL("Not enough memory to allocate channels"));
9037 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
9038 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
9039 return -ENOMEM;
9040 }
9041 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
9042 &hdd_channels_5_GHZ[0],
9043 sizeof(hdd_channels_5_GHZ));
9044 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309045
9046 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9047 {
9048
9049 if (NULL == wiphy->bands[i])
9050 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309051 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309052 __func__, i);
9053 continue;
9054 }
9055
9056 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9057 {
9058 struct ieee80211_supported_band *band = wiphy->bands[i];
9059
9060 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
9061 {
9062 // Enable social channels for P2P
9063 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9064 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9065 else
9066 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9067 continue;
9068 }
9069 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
9070 {
9071 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9072 continue;
9073 }
9074 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 }
9076 /*Initialise the supported cipher suite details*/
9077 wiphy->cipher_suites = hdd_cipher_suites;
9078 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9079
9080 /*signal strength in mBm (100*dBm) */
9081 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9082
9083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309084 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009086
Sunil Duttc69bccb2014-05-26 21:30:20 +05309087 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9088 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009089 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9090 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9091
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309092 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9093
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309094 EXIT();
9095 return 0;
9096}
9097
9098/* In this function we are registering wiphy. */
9099int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9100{
9101 ENTER();
9102 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 if (0 > wiphy_register(wiphy))
9104 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309105 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9107 return -EIO;
9108 }
9109
9110 EXIT();
9111 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309112}
Jeff Johnson295189b2012-06-20 16:38:30 -07009113
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309114/* In this function we are updating channel list when,
9115 regulatory domain is FCC and country code is US.
9116 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9117 As per FCC smart phone is not a indoor device.
9118 GO should not opeate on indoor channels */
9119void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9120{
9121 int j;
9122 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9123 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9124 //Default counrtycode from NV at the time of wiphy initialization.
9125 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9126 &defaultCountryCode[0]))
9127 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009128 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309129 }
9130 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9131 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309132 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
9133 {
9134 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
9135 return;
9136 }
9137 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
9138 {
9139 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
9140 // Mark UNII -1 band channel as passive
9141 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9142 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9143 }
9144 }
9145}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309146/* This function registers for all frame which supplicant is interested in */
9147void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009148{
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9150 /* Register for all P2P action, public action etc frames */
9151 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009152 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309153 /* Register frame indication call back */
9154 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 /* Right now we are registering these frame when driver is getting
9156 initialized. Once we will move to 2.6.37 kernel, in which we have
9157 frame register ops, we will move this code as a part of that */
9158 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9161
9162 /* GAS Initial Response */
9163 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9164 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 /* GAS Comeback Request */
9167 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9168 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9169
9170 /* GAS Comeback Response */
9171 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9172 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9173
9174 /* P2P Public Action */
9175 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309176 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 P2P_PUBLIC_ACTION_FRAME_SIZE );
9178
9179 /* P2P Action */
9180 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9181 (v_U8_t*)P2P_ACTION_FRAME,
9182 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009183
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309184 /* WNM BSS Transition Request frame */
9185 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9186 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9187 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009188
9189 /* WNM-Notification */
9190 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9191 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9192 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009193}
9194
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309195void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009196{
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9198 /* Register for all P2P action, public action etc frames */
9199 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9200
Jeff Johnsone7245742012-09-05 17:12:55 -07009201 ENTER();
9202
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 /* Right now we are registering these frame when driver is getting
9204 initialized. Once we will move to 2.6.37 kernel, in which we have
9205 frame register ops, we will move this code as a part of that */
9206 /* GAS Initial Request */
9207
9208 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9209 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9210
9211 /* GAS Initial Response */
9212 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9213 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309214
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 /* GAS Comeback Request */
9216 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9217 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9218
9219 /* GAS Comeback Response */
9220 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9221 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9222
9223 /* P2P Public Action */
9224 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309225 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 P2P_PUBLIC_ACTION_FRAME_SIZE );
9227
9228 /* P2P Action */
9229 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9230 (v_U8_t*)P2P_ACTION_FRAME,
9231 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009232 /* WNM-Notification */
9233 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9234 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9235 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009236}
9237
9238#ifdef FEATURE_WLAN_WAPI
9239void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309240 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009241{
9242 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9243 tCsrRoamSetKey setKey;
9244 v_BOOL_t isConnected = TRUE;
9245 int status = 0;
9246 v_U32_t roamId= 0xFF;
9247 tANI_U8 *pKeyPtr = NULL;
9248 int n = 0;
9249
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309250 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9251 __func__, hdd_device_modetoString(pAdapter->device_mode),
9252 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309254 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 setKey.keyId = key_index; // Store Key ID
9256 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9257 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9258 setKey.paeRole = 0 ; // the PAE role
9259 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9260 {
9261 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9262 }
9263 else
9264 {
9265 isConnected = hdd_connIsConnected(pHddStaCtx);
9266 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9267 }
9268 setKey.keyLength = key_Len;
9269 pKeyPtr = setKey.Key;
9270 memcpy( pKeyPtr, key, key_Len);
9271
Arif Hussain6d2a3322013-11-17 19:50:10 -08009272 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 __func__, key_Len);
9274 for (n = 0 ; n < key_Len; n++)
9275 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9276 __func__,n,setKey.Key[n]);
9277
9278 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9279 if ( isConnected )
9280 {
9281 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9282 pAdapter->sessionId, &setKey, &roamId );
9283 }
9284 if ( status != 0 )
9285 {
9286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9287 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9288 __LINE__, status );
9289 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9290 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309291 /* Need to clear any trace of key value in the memory.
9292 * Thus zero out the memory even though it is local
9293 * variable.
9294 */
9295 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009296}
9297#endif /* FEATURE_WLAN_WAPI*/
9298
9299#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 beacon_data_t **ppBeacon,
9302 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009303#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309304int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009305 beacon_data_t **ppBeacon,
9306 struct cfg80211_beacon_data *params,
9307 int dtim_period)
9308#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309{
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 int size;
9311 beacon_data_t *beacon = NULL;
9312 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309313 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9314 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009315
Jeff Johnsone7245742012-09-05 17:12:55 -07009316 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309318 {
9319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9320 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009323
9324 old = pAdapter->sessionCtx.ap.beacon;
9325
9326 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309327 {
9328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9329 FL("session(%d) old and new heads points to NULL"),
9330 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309332 }
9333
9334 if (params->tail && !params->tail_len)
9335 {
9336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9337 FL("tail_len is zero but tail is not NULL"));
9338 return -EINVAL;
9339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009340
Jeff Johnson295189b2012-06-20 16:38:30 -07009341#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9342 /* Kernel 3.0 is not updating dtim_period for set beacon */
9343 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309344 {
9345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9346 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009349#endif
9350
Kapil Gupta137ef892016-12-13 19:38:00 +05309351 if (params->head)
9352 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309354 head = params->head;
9355 } else
9356 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309358 head = old->head;
9359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009360
Kapil Gupta137ef892016-12-13 19:38:00 +05309361 if (params->tail || !old)
9362 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309364 tail = params->tail;
9365 } else
9366 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309368 tail = old->tail;
9369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009370
Kapil Gupta137ef892016-12-13 19:38:00 +05309371 if (params->proberesp_ies || !old)
9372 {
9373 proberesp_ies_len = params->proberesp_ies_len;
9374 proberesp_ies = params->proberesp_ies;
9375 } else
9376 {
9377 proberesp_ies_len = old->proberesp_ies_len;
9378 proberesp_ies = old->proberesp_ies;
9379 }
9380
9381 if (params->assocresp_ies || !old)
9382 {
9383 assocresp_ies_len = params->assocresp_ies_len;
9384 assocresp_ies = params->assocresp_ies;
9385 } else
9386 {
9387 assocresp_ies_len = old->assocresp_ies_len;
9388 assocresp_ies = old->assocresp_ies;
9389 }
9390
9391 size = sizeof(beacon_data_t) + head_len + tail_len +
9392 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009393
9394 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309396 {
9397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9398 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009402#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309403 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 beacon->dtim_period = params->dtim_period;
9405 else
9406 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009407#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309408 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009409 beacon->dtim_period = dtim_period;
9410 else
9411 beacon->dtim_period = old->dtim_period;
9412#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309413
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9415 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309416 beacon->proberesp_ies = beacon->tail + tail_len;
9417 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 beacon->head_len = head_len;
9420 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309421 beacon->proberesp_ies_len = proberesp_ies_len;
9422 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009423
c_manjee527ecac2017-01-25 12:25:27 +05309424 if (head && head_len)
9425 memcpy(beacon->head, head, head_len);
9426 if (tail && tail_len)
9427 memcpy(beacon->tail, tail, tail_len);
9428 if (proberesp_ies && proberesp_ies_len)
9429 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9430 if (assocresp_ies && assocresp_ies_len)
9431 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009432
9433 *ppBeacon = beacon;
9434
9435 kfree(old);
9436
9437 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009438}
Jeff Johnson295189b2012-06-20 16:38:30 -07009439
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309440v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9442 const v_U8_t *pIes,
9443#else
9444 v_U8_t *pIes,
9445#endif
9446 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009447{
9448 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309449 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309451
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 elem_id = ptr[0];
9455 elem_len = ptr[1];
9456 left -= 2;
9457 if(elem_len > left)
9458 {
9459 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009460 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 eid,elem_len,left);
9462 return NULL;
9463 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 {
9466 return ptr;
9467 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309468
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 left -= elem_len;
9470 ptr += (elem_len + 2);
9471 }
9472 return NULL;
9473}
9474
Jeff Johnson295189b2012-06-20 16:38:30 -07009475/* Check if rate is 11g rate or not */
9476static int wlan_hdd_rate_is_11g(u8 rate)
9477{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009478 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 u8 i;
9480 for (i = 0; i < 8; i++)
9481 {
9482 if(rate == gRateArray[i])
9483 return TRUE;
9484 }
9485 return FALSE;
9486}
9487
9488/* Check for 11g rate and set proper 11g only mode */
9489static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9490 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9491{
9492 u8 i, num_rates = pIe[0];
9493
9494 pIe += 1;
9495 for ( i = 0; i < num_rates; i++)
9496 {
9497 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9498 {
9499 /* If rate set have 11g rate than change the mode to 11G */
9500 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9501 if (pIe[i] & BASIC_RATE_MASK)
9502 {
9503 /* If we have 11g rate as basic rate, it means mode
9504 is 11g only mode.
9505 */
9506 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9507 *pCheckRatesfor11g = FALSE;
9508 }
9509 }
9510 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9511 {
9512 *require_ht = TRUE;
9513 }
9514 }
9515 return;
9516}
9517
9518static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9519{
9520 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9521 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9522 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9523 u8 checkRatesfor11g = TRUE;
9524 u8 require_ht = FALSE;
9525 u8 *pIe=NULL;
9526
9527 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9528
9529 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9530 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9531 if (pIe != NULL)
9532 {
9533 pIe += 1;
9534 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9535 &pConfig->SapHw_mode);
9536 }
9537
9538 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9539 WLAN_EID_EXT_SUPP_RATES);
9540 if (pIe != NULL)
9541 {
9542
9543 pIe += 1;
9544 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9545 &pConfig->SapHw_mode);
9546 }
9547
9548 if( pConfig->channel > 14 )
9549 {
9550 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9551 }
9552
9553 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9554 WLAN_EID_HT_CAPABILITY);
9555
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 {
9558 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9559 if(require_ht)
9560 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9561 }
9562}
9563
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309564static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9565 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9566{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009567 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309568 v_U8_t *pIe = NULL;
9569 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9570
9571 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9572 pBeacon->tail, pBeacon->tail_len);
9573
9574 if (pIe)
9575 {
9576 ielen = pIe[1] + 2;
9577 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9578 {
9579 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9580 }
9581 else
9582 {
9583 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9584 return -EINVAL;
9585 }
9586 *total_ielen += ielen;
9587 }
9588 return 0;
9589}
9590
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009591static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9592 v_U8_t *genie, v_U8_t *total_ielen)
9593{
9594 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9595 int left = pBeacon->tail_len;
9596 v_U8_t *ptr = pBeacon->tail;
9597 v_U8_t elem_id, elem_len;
9598 v_U16_t ielen = 0;
9599
9600 if ( NULL == ptr || 0 == left )
9601 return;
9602
9603 while (left >= 2)
9604 {
9605 elem_id = ptr[0];
9606 elem_len = ptr[1];
9607 left -= 2;
9608 if (elem_len > left)
9609 {
9610 hddLog( VOS_TRACE_LEVEL_ERROR,
9611 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9612 elem_id, elem_len, left);
9613 return;
9614 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309615 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009616 {
9617 /* skipping the VSIE's which we don't want to include or
9618 * it will be included by existing code
9619 */
9620 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9621#ifdef WLAN_FEATURE_WFD
9622 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9623#endif
9624 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9625 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9626 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9627 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9628 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9629 {
9630 ielen = ptr[1] + 2;
9631 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9632 {
9633 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9634 *total_ielen += ielen;
9635 }
9636 else
9637 {
9638 hddLog( VOS_TRACE_LEVEL_ERROR,
9639 "IE Length is too big "
9640 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9641 elem_id, elem_len, *total_ielen);
9642 }
9643 }
9644 }
9645
9646 left -= elem_len;
9647 ptr += (elem_len + 2);
9648 }
9649 return;
9650}
9651
Kapil Gupta137ef892016-12-13 19:38:00 +05309652int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009653{
9654 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309655 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009657 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309658 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009659
9660 genie = vos_mem_malloc(MAX_GENIE_LEN);
9661
9662 if(genie == NULL) {
9663
9664 return -ENOMEM;
9665 }
9666
Kapil Gupta137ef892016-12-13 19:38:00 +05309667 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309668 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9669 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309671 hddLog(LOGE,
9672 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309673 ret = -EINVAL;
9674 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 }
9676
9677#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309678 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9679 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9680 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309681 hddLog(LOGE,
9682 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683 ret = -EINVAL;
9684 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 }
9686#endif
9687
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309688 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9689 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309691 hddLog(LOGE,
9692 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309693 ret = -EINVAL;
9694 goto done;
9695 }
9696
9697 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9698 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009699 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009701
9702 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9703 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9704 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9705 {
9706 hddLog(LOGE,
9707 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009708 ret = -EINVAL;
9709 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 }
9711
9712 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9713 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9714 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9715 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9716 ==eHAL_STATUS_FAILURE)
9717 {
9718 hddLog(LOGE,
9719 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009720 ret = -EINVAL;
9721 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 }
9723
9724 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309725 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309727 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 u8 probe_rsp_ie_len[3] = {0};
9729 u8 counter = 0;
9730 /* Check Probe Resp Length if it is greater then 255 then Store
9731 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9732 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9733 Store More then 255 bytes into One Variable.
9734 */
9735 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9736 {
9737 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9738 {
9739 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9740 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9741 }
9742 else
9743 {
9744 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9745 rem_probe_resp_ie_len = 0;
9746 }
9747 }
9748
9749 rem_probe_resp_ie_len = 0;
9750
9751 if (probe_rsp_ie_len[0] > 0)
9752 {
9753 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9754 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309755 (tANI_U8*)&pBeacon->
9756 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 probe_rsp_ie_len[0], NULL,
9758 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9759 {
9760 hddLog(LOGE,
9761 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009762 ret = -EINVAL;
9763 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 }
9765 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9766 }
9767
9768 if (probe_rsp_ie_len[1] > 0)
9769 {
9770 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9771 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309772 (tANI_U8*)&pBeacon->
9773 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 probe_rsp_ie_len[1], NULL,
9775 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9776 {
9777 hddLog(LOGE,
9778 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009779 ret = -EINVAL;
9780 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 }
9782 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9783 }
9784
9785 if (probe_rsp_ie_len[2] > 0)
9786 {
9787 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9788 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309789 (tANI_U8*)&pBeacon->
9790 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 probe_rsp_ie_len[2], NULL,
9792 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9793 {
9794 hddLog(LOGE,
9795 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009796 ret = -EINVAL;
9797 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 }
9799 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9800 }
9801
9802 if (probe_rsp_ie_len[1] == 0 )
9803 {
9804 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9805 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9806 eANI_BOOLEAN_FALSE) )
9807 {
9808 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009809 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009810 }
9811 }
9812
9813 if (probe_rsp_ie_len[2] == 0 )
9814 {
9815 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9816 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9817 eANI_BOOLEAN_FALSE) )
9818 {
9819 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009820 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 }
9822 }
9823
9824 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9825 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9826 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9827 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9828 == eHAL_STATUS_FAILURE)
9829 {
9830 hddLog(LOGE,
9831 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009832 ret = -EINVAL;
9833 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 }
9835 }
9836 else
9837 {
9838 // Reset WNI_CFG_PROBE_RSP Flags
9839 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9840
9841 hddLog(VOS_TRACE_LEVEL_INFO,
9842 "%s: No Probe Response IE received in set beacon",
9843 __func__);
9844 }
9845
9846 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309847 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 {
9849 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309850 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9851 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9853 {
9854 hddLog(LOGE,
9855 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009856 ret = -EINVAL;
9857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 }
9859
9860 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9861 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9862 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9863 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9864 == eHAL_STATUS_FAILURE)
9865 {
9866 hddLog(LOGE,
9867 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009868 ret = -EINVAL;
9869 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 }
9871 }
9872 else
9873 {
9874 hddLog(VOS_TRACE_LEVEL_INFO,
9875 "%s: No Assoc Response IE received in set beacon",
9876 __func__);
9877
9878 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9879 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9880 eANI_BOOLEAN_FALSE) )
9881 {
9882 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009883 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 }
9885 }
9886
Jeff Johnsone7245742012-09-05 17:12:55 -07009887done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309889 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009890}
Jeff Johnson295189b2012-06-20 16:38:30 -07009891
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309892/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 * FUNCTION: wlan_hdd_validate_operation_channel
9894 * called by wlan_hdd_cfg80211_start_bss() and
9895 * wlan_hdd_cfg80211_set_channel()
9896 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309897 * channel list.
9898 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009899VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009900{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309901
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 v_U32_t num_ch = 0;
9903 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9904 u32 indx = 0;
9905 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309906 v_U8_t fValidChannel = FALSE, count = 0;
9907 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309908
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9910
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309911 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309913 /* Validate the channel */
9914 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309916 if ( channel == rfChannels[count].channelNum )
9917 {
9918 fValidChannel = TRUE;
9919 break;
9920 }
9921 }
9922 if (fValidChannel != TRUE)
9923 {
9924 hddLog(VOS_TRACE_LEVEL_ERROR,
9925 "%s: Invalid Channel [%d]", __func__, channel);
9926 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 }
9928 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309929 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309931 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9932 valid_ch, &num_ch))
9933 {
9934 hddLog(VOS_TRACE_LEVEL_ERROR,
9935 "%s: failed to get valid channel list", __func__);
9936 return VOS_STATUS_E_FAILURE;
9937 }
9938 for (indx = 0; indx < num_ch; indx++)
9939 {
9940 if (channel == valid_ch[indx])
9941 {
9942 break;
9943 }
9944 }
9945
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309946 if (indx >= num_ch)
9947 {
9948 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9949 {
9950 eCsrBand band;
9951 unsigned int freq;
9952
9953 sme_GetFreqBand(hHal, &band);
9954
9955 if (eCSR_BAND_5G == band)
9956 {
9957#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9958 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9959 {
9960 freq = ieee80211_channel_to_frequency(channel,
9961 IEEE80211_BAND_2GHZ);
9962 }
9963 else
9964 {
9965 freq = ieee80211_channel_to_frequency(channel,
9966 IEEE80211_BAND_5GHZ);
9967 }
9968#else
9969 freq = ieee80211_channel_to_frequency(channel);
9970#endif
9971 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9972 return VOS_STATUS_SUCCESS;
9973 }
9974 }
9975
9976 hddLog(VOS_TRACE_LEVEL_ERROR,
9977 "%s: Invalid Channel [%d]", __func__, channel);
9978 return VOS_STATUS_E_FAILURE;
9979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309981
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309983
Jeff Johnson295189b2012-06-20 16:38:30 -07009984}
9985
Viral Modi3a32cc52013-02-08 11:14:52 -08009986/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309987 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009988 * This function is used to set the channel number
9989 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309990static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009991 struct ieee80211_channel *chan,
9992 enum nl80211_channel_type channel_type
9993 )
9994{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309995 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009996 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009997 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009998 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309999 hdd_context_t *pHddCtx;
10000 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010001
10002 ENTER();
10003
10004 if( NULL == dev )
10005 {
10006 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010007 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010008 return -ENODEV;
10009 }
10010 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010011
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10013 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10014 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010015 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010016 "%s: device_mode = %s (%d) freq = %d", __func__,
10017 hdd_device_modetoString(pAdapter->device_mode),
10018 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010019
10020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10021 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010022 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010023 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010024 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010025 }
10026
10027 /*
10028 * Do freq to chan conversion
10029 * TODO: for 11a
10030 */
10031
10032 channel = ieee80211_frequency_to_channel(freq);
10033
10034 /* Check freq range */
10035 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10036 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10037 {
10038 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010039 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010040 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10041 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10042 return -EINVAL;
10043 }
10044
10045 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10046
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010047 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10048 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010049 {
10050 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10051 {
10052 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010053 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010054 return -EINVAL;
10055 }
10056 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10057 "%s: set channel to [%d] for device mode =%d",
10058 __func__, channel,pAdapter->device_mode);
10059 }
10060 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010061 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010062 )
10063 {
10064 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10065 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10066 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10067
10068 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10069 {
10070 /* Link is up then return cant set channel*/
10071 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010072 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010073 return -EINVAL;
10074 }
10075
10076 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10077 pHddStaCtx->conn_info.operationChannel = channel;
10078 pRoamProfile->ChannelInfo.ChannelList =
10079 &pHddStaCtx->conn_info.operationChannel;
10080 }
10081 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010082 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010083 )
10084 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010085 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10086 {
10087 if(VOS_STATUS_SUCCESS !=
10088 wlan_hdd_validate_operation_channel(pAdapter,channel))
10089 {
10090 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010091 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010092 return -EINVAL;
10093 }
10094 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10095 }
10096 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010097 {
10098 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10099
10100 /* If auto channel selection is configured as enable/ 1 then ignore
10101 channel set by supplicant
10102 */
10103 if ( cfg_param->apAutoChannelSelection )
10104 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010105 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10106 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010107 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010108 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10109 __func__, hdd_device_modetoString(pAdapter->device_mode),
10110 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010111 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010112 else
10113 {
10114 if(VOS_STATUS_SUCCESS !=
10115 wlan_hdd_validate_operation_channel(pAdapter,channel))
10116 {
10117 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010118 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010119 return -EINVAL;
10120 }
10121 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10122 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010123 }
10124 }
10125 else
10126 {
10127 hddLog(VOS_TRACE_LEVEL_FATAL,
10128 "%s: Invalid device mode failed to set valid channel", __func__);
10129 return -EINVAL;
10130 }
10131 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010132 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010133}
10134
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010135static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10136 struct net_device *dev,
10137 struct ieee80211_channel *chan,
10138 enum nl80211_channel_type channel_type
10139 )
10140{
10141 int ret;
10142
10143 vos_ssr_protect(__func__);
10144 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10145 vos_ssr_unprotect(__func__);
10146
10147 return ret;
10148}
10149
Anurag Chouhan83026002016-12-13 22:46:21 +053010150#ifdef DHCP_SERVER_OFFLOAD
10151void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10152 VOS_STATUS status)
10153{
10154 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10155
10156 ENTER();
10157
10158 if (NULL == adapter)
10159 {
10160 hddLog(VOS_TRACE_LEVEL_ERROR,
10161 "%s: adapter is NULL",__func__);
10162 return;
10163 }
10164
10165 adapter->dhcp_status.dhcp_offload_status = status;
10166 vos_event_set(&adapter->dhcp_status.vos_event);
10167 return;
10168}
10169
10170/**
10171 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10172 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010173 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010174 *
10175 * Return: None
10176 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010177VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10178 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010179{
10180 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10181 sir_dhcp_srv_offload_info dhcp_srv_info;
10182 tANI_U8 num_entries = 0;
10183 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10184 tANI_U8 num;
10185 tANI_U32 temp;
10186 VOS_STATUS ret;
10187
10188 ENTER();
10189
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010190 if (!re_init) {
10191 ret = wlan_hdd_validate_context(hdd_ctx);
10192 if (0 != ret)
10193 return VOS_STATUS_E_INVAL;
10194 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010195
10196 /* Prepare the request to send to SME */
10197 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10198 if (NULL == dhcp_srv_info) {
10199 hddLog(VOS_TRACE_LEVEL_ERROR,
10200 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10201 return VOS_STATUS_E_NOMEM;
10202 }
10203
10204 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10205
10206 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10207 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10208 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10209 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10210 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10211 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10212
10213 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10214 srv_ip,
10215 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010216 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010217 if (num_entries != IPADDR_NUM_ENTRIES) {
10218 hddLog(VOS_TRACE_LEVEL_ERROR,
10219 "%s: incorrect IP address (%s) assigned for DHCP server!",
10220 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10221 vos_mem_free(dhcp_srv_info);
10222 return VOS_STATUS_E_FAILURE;
10223 }
10224
10225 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10226 hddLog(VOS_TRACE_LEVEL_ERROR,
10227 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10228 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10229 vos_mem_free(dhcp_srv_info);
10230 return VOS_STATUS_E_FAILURE;
10231 }
10232
10233 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10234 hddLog(VOS_TRACE_LEVEL_ERROR,
10235 "%s: invalid IP address (%s)! The last field must be less than 100!",
10236 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10237 vos_mem_free(dhcp_srv_info);
10238 return VOS_STATUS_E_FAILURE;
10239 }
10240
10241 for (num = 0; num < num_entries; num++) {
10242 temp = srv_ip[num];
10243 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10244 }
10245
10246 if (eHAL_STATUS_SUCCESS !=
10247 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10248 hddLog(VOS_TRACE_LEVEL_ERROR,
10249 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10250 vos_mem_free(dhcp_srv_info);
10251 return VOS_STATUS_E_FAILURE;
10252 }
10253
10254 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10255 "%s: enable DHCP Server offload successfully!", __func__);
10256
10257 vos_mem_free(dhcp_srv_info);
10258 return 0;
10259}
10260#endif /* DHCP_SERVER_OFFLOAD */
10261
Jeff Johnson295189b2012-06-20 16:38:30 -070010262#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10263static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10264 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010265#else
10266static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10267 struct cfg80211_beacon_data *params,
10268 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010269 enum nl80211_hidden_ssid hidden_ssid,
10270 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010271#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010272{
10273 tsap_Config_t *pConfig;
10274 beacon_data_t *pBeacon = NULL;
10275 struct ieee80211_mgmt *pMgmt_frame;
10276 v_U8_t *pIe=NULL;
10277 v_U16_t capab_info;
10278 eCsrAuthType RSNAuthType;
10279 eCsrEncryptionType RSNEncryptType;
10280 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010281 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 tpWLAN_SAPEventCB pSapEventCallback;
10283 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010285 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010287 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010289 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010290 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010291 v_BOOL_t MFPCapable = VOS_FALSE;
10292 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010293 v_BOOL_t sapEnable11AC =
10294 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010295 u_int16_t prev_rsn_length = 0;
10296
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 ENTER();
10298
Nitesh Shah9b066282017-06-06 18:05:52 +053010299 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010300 iniConfig = pHddCtx->cfg_ini;
10301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10303
10304 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10305
10306 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10307
10308 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10309
10310 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10311
10312 //channel is already set in the set_channel Call back
10313 //pConfig->channel = pCommitConfig->channel;
10314
10315 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010316 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10318
10319 pConfig->dtim_period = pBeacon->dtim_period;
10320
Arif Hussain6d2a3322013-11-17 19:50:10 -080010321 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 pConfig->dtim_period);
10323
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010324 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010325 {
10326 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010328 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10329 {
10330 tANI_BOOLEAN restartNeeded;
10331 pConfig->ieee80211d = 1;
10332 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10333 sme_setRegInfo(hHal, pConfig->countryCode);
10334 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10335 }
10336 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010338 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010339 pConfig->ieee80211d = 1;
10340 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10341 sme_setRegInfo(hHal, pConfig->countryCode);
10342 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010344 else
10345 {
10346 pConfig->ieee80211d = 0;
10347 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010348 /*
10349 * If auto channel is configured i.e. channel is 0,
10350 * so skip channel validation.
10351 */
10352 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10353 {
10354 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10355 {
10356 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010357 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010358 return -EINVAL;
10359 }
10360 }
10361 else
10362 {
10363 if(1 != pHddCtx->is_dynamic_channel_range_set)
10364 {
10365 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10366 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10367 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10368 }
10369 pHddCtx->is_dynamic_channel_range_set = 0;
10370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010372 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 {
10374 pConfig->ieee80211d = 0;
10375 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010376
10377#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10378 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10379 pConfig->authType = eSAP_OPEN_SYSTEM;
10380 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10381 pConfig->authType = eSAP_SHARED_KEY;
10382 else
10383 pConfig->authType = eSAP_AUTO_SWITCH;
10384#else
10385 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10386 pConfig->authType = eSAP_OPEN_SYSTEM;
10387 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10388 pConfig->authType = eSAP_SHARED_KEY;
10389 else
10390 pConfig->authType = eSAP_AUTO_SWITCH;
10391#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010392
10393 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010394
10395 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010397#ifdef SAP_AUTH_OFFLOAD
10398 /* In case of sap offload, hostapd.conf is configuted with open mode and
10399 * security is configured from ini file. Due to open mode in hostapd.conf
10400 * privacy bit is set to false which will result in not sending,
10401 * data packets as encrypted.
10402 * If enable_sap_auth_offload is enabled in ini and
10403 * sap_auth_offload_sec_type is type of WPA2-PSK,
10404 * driver will set privacy bit to 1.
10405 */
10406 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10407 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10408 pConfig->privacy = VOS_TRUE;
10409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010410
10411 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10412
10413 /*Set wps station to configured*/
10414 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10415
10416 if(pIe)
10417 {
10418 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10419 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010420 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 return -EINVAL;
10422 }
10423 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10424 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010425 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 /* Check 15 bit of WPS IE as it contain information for wps state
10427 * WPS state
10428 */
10429 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10430 {
10431 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10432 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10433 {
10434 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10435 }
10436 }
10437 }
10438 else
10439 {
10440 pConfig->wps_state = SAP_WPS_DISABLED;
10441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010443
c_hpothufe599e92014-06-16 11:38:55 +053010444 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10445 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10446 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10447 eCSR_ENCRYPT_TYPE_NONE;
10448
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010450 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010451 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 WLAN_EID_RSN);
10453 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010456 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10457 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10458 pConfig->RSNWPAReqIELength);
10459 else
10460 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10461 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010462 /* The actual processing may eventually be more extensive than
10463 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 * by the app.
10465 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010466 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10468 &RSNEncryptType,
10469 &mcRSNEncryptType,
10470 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010471 &MFPCapable,
10472 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010473 pConfig->RSNWPAReqIE[1]+2,
10474 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010475
10476 if( VOS_STATUS_SUCCESS == status )
10477 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 /* Now copy over all the security attributes you have
10479 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 * */
10481 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10482 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10483 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10484 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010485 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010486 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10488 }
10489 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010490
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10492 pBeacon->tail, pBeacon->tail_len);
10493
10494 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10495 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010496 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 {
10498 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010499 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010501 if (pConfig->RSNWPAReqIELength <=
10502 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10503 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10504 pIe[1] + 2);
10505 else
10506 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10507 pConfig->RSNWPAReqIELength);
10508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 }
10510 else
10511 {
10512 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010513 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10514 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10515 pConfig->RSNWPAReqIELength);
10516 else
10517 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10518 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010519 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10521 &RSNEncryptType,
10522 &mcRSNEncryptType,
10523 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010524 &MFPCapable,
10525 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010526 pConfig->RSNWPAReqIE[1]+2,
10527 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010528
10529 if( VOS_STATUS_SUCCESS == status )
10530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010531 /* Now copy over all the security attributes you have
10532 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 * */
10534 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10535 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10536 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10537 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010538 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010539 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010540 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10541 }
10542 }
10543 }
10544
Kapil Gupta137ef892016-12-13 19:38:00 +053010545 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010546 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10547 return -EINVAL;
10548 }
10549
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10551
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010552#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 if (params->ssid != NULL)
10554 {
10555 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10556 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10557 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10558 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10559 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010560#else
10561 if (ssid != NULL)
10562 {
10563 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10564 pConfig->SSIDinfo.ssid.length = ssid_len;
10565 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10566 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10567 }
10568#endif
10569
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010570 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010572
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 /* default value */
10574 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10575 pConfig->num_accept_mac = 0;
10576 pConfig->num_deny_mac = 0;
10577
10578 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10579 pBeacon->tail, pBeacon->tail_len);
10580
10581 /* pIe for black list is following form:
10582 type : 1 byte
10583 length : 1 byte
10584 OUI : 4 bytes
10585 acl type : 1 byte
10586 no of mac addr in black list: 1 byte
10587 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010588 */
10589 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 {
10591 pConfig->SapMacaddr_acl = pIe[6];
10592 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010593 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010595 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10596 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10598 for (i = 0; i < pConfig->num_deny_mac; i++)
10599 {
10600 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10601 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010602 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 }
10604 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10605 pBeacon->tail, pBeacon->tail_len);
10606
10607 /* pIe for white list is following form:
10608 type : 1 byte
10609 length : 1 byte
10610 OUI : 4 bytes
10611 acl type : 1 byte
10612 no of mac addr in white list: 1 byte
10613 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010614 */
10615 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 {
10617 pConfig->SapMacaddr_acl = pIe[6];
10618 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010619 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010621 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10622 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10624 for (i = 0; i < pConfig->num_accept_mac; i++)
10625 {
10626 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10627 acl_entry++;
10628 }
10629 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010630
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10632
Jeff Johnsone7245742012-09-05 17:12:55 -070010633#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010634 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010635 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10636 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010637 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10638 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010639 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10640 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010641 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10642 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010643 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010644 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010645 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010646 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010647
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010648 /* If ACS disable and selected channel <= 14
10649 * OR
10650 * ACS enabled and ACS operating band is choosen as 2.4
10651 * AND
10652 * VHT in 2.4G Disabled
10653 * THEN
10654 * Fallback to 11N mode
10655 */
10656 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10657 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010658 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010659 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010660 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010661 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10662 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010663 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10664 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010665 }
10666#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010667
Jeff Johnson295189b2012-06-20 16:38:30 -070010668 // ht_capab is not what the name conveys,this is used for protection bitmap
10669 pConfig->ht_capab =
10670 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10671
Kapil Gupta137ef892016-12-13 19:38:00 +053010672 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 {
10674 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10675 return -EINVAL;
10676 }
10677
10678 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010679 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10681 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010682 pConfig->obssProtEnabled =
10683 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010684
Chet Lanctot8cecea22014-02-11 19:09:36 -080010685#ifdef WLAN_FEATURE_11W
10686 pConfig->mfpCapable = MFPCapable;
10687 pConfig->mfpRequired = MFPRequired;
10688 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10689 pConfig->mfpCapable, pConfig->mfpRequired);
10690#endif
10691
Arif Hussain6d2a3322013-11-17 19:50:10 -080010692 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010694 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10695 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10696 (int)pConfig->channel);
10697 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10698 pConfig->SapHw_mode, pConfig->privacy,
10699 pConfig->authType);
10700 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10701 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10702 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10703 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010704
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010705 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 {
10707 //Bss already started. just return.
10708 //TODO Probably it should update some beacon params.
10709 hddLog( LOGE, "Bss Already started...Ignore the request");
10710 EXIT();
10711 return 0;
10712 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010713
Agarwal Ashish51325b52014-06-16 16:50:49 +053010714 if (vos_max_concurrent_connections_reached()) {
10715 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10716 return -EINVAL;
10717 }
10718
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 pConfig->persona = pHostapdAdapter->device_mode;
10720
Peng Xu2446a892014-09-05 17:21:18 +053010721 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10722 if ( NULL != psmeConfig)
10723 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010724 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010725 sme_GetConfigParam(hHal, psmeConfig);
10726 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010727#ifdef WLAN_FEATURE_AP_HT40_24G
10728 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10729 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10730 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10731 {
10732 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10733 sme_UpdateConfig (hHal, psmeConfig);
10734 }
10735#endif
Peng Xu2446a892014-09-05 17:21:18 +053010736 vos_mem_free(psmeConfig);
10737 }
Peng Xuafc34e32014-09-25 13:23:55 +053010738 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010739
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010740 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10741
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 pSapEventCallback = hdd_hostapd_SAPEventCB;
10743 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10744 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10745 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010746 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010747 ret = -EINVAL;
10748 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 }
10750
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10753
10754 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010755
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757 {
10758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010759 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010760 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 VOS_ASSERT(0);
10762 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010763
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010765 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10766 VOS_STATUS_SUCCESS)
10767 {
10768 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10769 VOS_ASSERT(0);
10770 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010771 /* Initialize WMM configuation */
10772 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010773 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010774
Anurag Chouhan83026002016-12-13 22:46:21 +053010775#ifdef DHCP_SERVER_OFFLOAD
10776 /* set dhcp server offload */
10777 if (iniConfig->enable_dhcp_srv_offload &&
10778 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010779 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010780 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010781 if (!VOS_IS_STATUS_SUCCESS(status))
10782 {
10783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10784 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010785 vos_event_reset(&pHostapdState->vosEvent);
10786 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10787 status = vos_wait_single_event(&pHostapdState->vosEvent,
10788 10000);
10789 if (!VOS_IS_STATUS_SUCCESS(status)) {
10790 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010791 ret = -EINVAL;
10792 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010793 }
10794 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010795 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010796 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10797 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10798 {
10799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10800 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10801 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010802 vos_event_reset(&pHostapdState->vosEvent);
10803 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10804 status = vos_wait_single_event(&pHostapdState->vosEvent,
10805 10000);
10806 if (!VOS_IS_STATUS_SUCCESS(status)) {
10807 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010808 ret = -EINVAL;
10809 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010810 }
10811 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010812 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010813#ifdef MDNS_OFFLOAD
10814 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010815 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010816 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10817 if (VOS_IS_STATUS_SUCCESS(status))
10818 {
10819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10820 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010821 vos_event_reset(&pHostapdState->vosEvent);
10822 if (VOS_STATUS_SUCCESS ==
10823 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10824 status = vos_wait_single_event(&pHostapdState->vosEvent,
10825 10000);
10826 if (!VOS_IS_STATUS_SUCCESS(status)) {
10827 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010828 ret = -EINVAL;
10829 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010830 }
10831 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010832 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010833 status = vos_wait_single_event(&pHostapdAdapter->
10834 mdns_status.vos_event, 2000);
10835 if (!VOS_IS_STATUS_SUCCESS(status) ||
10836 pHostapdAdapter->mdns_status.mdns_enable_status ||
10837 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10838 pHostapdAdapter->mdns_status.mdns_resp_status)
10839 {
10840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10841 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10842 pHostapdAdapter->mdns_status.mdns_enable_status,
10843 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10844 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010845 vos_event_reset(&pHostapdState->vosEvent);
10846 if (VOS_STATUS_SUCCESS ==
10847 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10848 status = vos_wait_single_event(&pHostapdState->vosEvent,
10849 10000);
10850 if (!VOS_IS_STATUS_SUCCESS(status)) {
10851 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010852 ret = -EINVAL;
10853 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010854 }
10855 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010856 }
10857 }
10858#endif /* MDNS_OFFLOAD */
10859 } else {
10860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10861 ("DHCP Disabled ini %d, FW %d"),
10862 iniConfig->enable_dhcp_srv_offload,
10863 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010864 }
10865#endif /* DHCP_SERVER_OFFLOAD */
10866
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010867#ifdef WLAN_FEATURE_P2P_DEBUG
10868 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10869 {
10870 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10871 {
10872 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10873 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010874 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010875 }
10876 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10877 {
10878 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10879 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010880 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010881 }
10882 }
10883#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010884 /* Check and restart SAP if it is on Unsafe channel */
10885 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010886
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 pHostapdState->bCommit = TRUE;
10888 EXIT();
10889
10890 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010891error:
10892 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10893 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010894}
10895
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010896#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010897static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010898 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 struct beacon_parameters *params)
10900{
10901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010902 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010903 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010904
10905 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010906
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10908 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
10909 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010910 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
10911 hdd_device_modetoString(pAdapter->device_mode),
10912 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10915 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010916 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010917 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010918 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010919 }
10920
Agarwal Ashish51325b52014-06-16 16:50:49 +053010921 if (vos_max_concurrent_connections_reached()) {
10922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10923 return -EINVAL;
10924 }
10925
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010926 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 )
10929 {
10930 beacon_data_t *old,*new;
10931
10932 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010935 {
10936 hddLog(VOS_TRACE_LEVEL_WARN,
10937 FL("already beacon info added to session(%d)"),
10938 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010940 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010941
10942 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10943
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 {
10946 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010947 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 return -EINVAL;
10949 }
10950
10951 pAdapter->sessionCtx.ap.beacon = new;
10952
10953 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10954 }
10955
10956 EXIT();
10957 return status;
10958}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010960static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10961 struct net_device *dev,
10962 struct beacon_parameters *params)
10963{
10964 int ret;
10965
10966 vos_ssr_protect(__func__);
10967 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10968 vos_ssr_unprotect(__func__);
10969
10970 return ret;
10971}
10972
10973static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 struct net_device *dev,
10975 struct beacon_parameters *params)
10976{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010977 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10979 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010980 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010981
10982 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010983
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010984 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10985 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10986 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10988 __func__, hdd_device_modetoString(pAdapter->device_mode),
10989 pAdapter->device_mode);
10990
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010991 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10992 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010993 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010994 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010995 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010996 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010997
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010998 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011000 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 {
11002 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011003
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011005
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011007 {
11008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11009 FL("session(%d) old and new heads points to NULL"),
11010 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011012 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011013
11014 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11015
11016 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011018 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 return -EINVAL;
11020 }
11021
11022 pAdapter->sessionCtx.ap.beacon = new;
11023
11024 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11025 }
11026
11027 EXIT();
11028 return status;
11029}
11030
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011031static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11032 struct net_device *dev,
11033 struct beacon_parameters *params)
11034{
11035 int ret;
11036
11037 vos_ssr_protect(__func__);
11038 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11039 vos_ssr_unprotect(__func__);
11040
11041 return ret;
11042}
11043
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011044#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11045
11046#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011047static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011049#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011050static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011051 struct net_device *dev)
11052#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011053{
11054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011055 hdd_context_t *pHddCtx = NULL;
11056 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011057 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011058 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011059
11060 ENTER();
11061
11062 if (NULL == pAdapter)
11063 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011065 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 return -ENODEV;
11067 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011068
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011069 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11070 TRACE_CODE_HDD_CFG80211_STOP_AP,
11071 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011072 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11073 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011074 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011075 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011076 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011077 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011078
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011079 pScanInfo = &pHddCtx->scan_info;
11080
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011081 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11082 __func__, hdd_device_modetoString(pAdapter->device_mode),
11083 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011084
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011085 ret = wlan_hdd_scan_abort(pAdapter);
11086
Girish Gowli4bf7a632014-06-12 13:42:11 +053011087 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011088 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11090 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011091
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011092 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011093 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11095 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011096
Jeff Johnsone7245742012-09-05 17:12:55 -070011097 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011098 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011099 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011100 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011101 }
11102
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011103 /* Delete all associated STAs before stopping AP/P2P GO */
11104 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011105 hdd_hostapd_stop(dev);
11106
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 )
11110 {
11111 beacon_data_t *old;
11112
11113 old = pAdapter->sessionCtx.ap.beacon;
11114
11115 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011116 {
11117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11118 FL("session(%d) beacon data points to NULL"),
11119 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011121 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011122
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011124
11125 mutex_lock(&pHddCtx->sap_lock);
11126 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11127 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011128 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 {
11130 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11131
11132 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11133
11134 if (!VOS_IS_STATUS_SUCCESS(status))
11135 {
11136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011137 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011139 }
11140 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011142 /* BSS stopped, clear the active sessions for this device mode */
11143 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 }
11145 mutex_unlock(&pHddCtx->sap_lock);
11146
11147 if(status != VOS_STATUS_SUCCESS)
11148 {
11149 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011150 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 return -EINVAL;
11152 }
11153
Jeff Johnson4416a782013-03-25 14:17:50 -070011154 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11156 ==eHAL_STATUS_FAILURE)
11157 {
11158 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011159 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 }
11161
Jeff Johnson4416a782013-03-25 14:17:50 -070011162 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11164 eANI_BOOLEAN_FALSE) )
11165 {
11166 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011167 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 }
11169
11170 // Reset WNI_CFG_PROBE_RSP Flags
11171 wlan_hdd_reset_prob_rspies(pAdapter);
11172
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011173 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11174
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 pAdapter->sessionCtx.ap.beacon = NULL;
11176 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011177#ifdef WLAN_FEATURE_P2P_DEBUG
11178 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11179 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11180 {
11181 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11182 "GO got removed");
11183 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11184 }
11185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 }
11187 EXIT();
11188 return status;
11189}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011190
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011191#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11192static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11193 struct net_device *dev)
11194{
11195 int ret;
11196
11197 vos_ssr_protect(__func__);
11198 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11199 vos_ssr_unprotect(__func__);
11200
11201 return ret;
11202}
11203#else
11204static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11205 struct net_device *dev)
11206{
11207 int ret;
11208
11209 vos_ssr_protect(__func__);
11210 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11211 vos_ssr_unprotect(__func__);
11212
11213 return ret;
11214}
11215#endif
11216
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011217#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11218
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011219static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011220 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011221 struct cfg80211_ap_settings *params)
11222{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011223 hdd_adapter_t *pAdapter;
11224 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011225 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011226
11227 ENTER();
11228
Girish Gowlib143d7a2015-02-18 19:39:55 +053011229 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011230 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011232 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011233 return -ENODEV;
11234 }
11235
11236 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11237 if (NULL == pAdapter)
11238 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011240 "%s: HDD adapter is Null", __func__);
11241 return -ENODEV;
11242 }
11243
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11245 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11246 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011247 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11248 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011250 "%s: HDD adapter magic is invalid", __func__);
11251 return -ENODEV;
11252 }
11253
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011254 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11255
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011257 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011258 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011259 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011260 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011261 }
11262
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011263 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11264 __func__, hdd_device_modetoString(pAdapter->device_mode),
11265 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011266
11267 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011268 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011269 )
11270 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011271 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011272
11273 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011274
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011275 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011276 {
11277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11278 FL("already beacon info added to session(%d)"),
11279 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011280 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011281 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011282
Girish Gowlib143d7a2015-02-18 19:39:55 +053011283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11284 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11285 &new,
11286 &params->beacon);
11287#else
11288 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11289 &new,
11290 &params->beacon,
11291 params->dtim_period);
11292#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011293
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011294 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011295 {
11296 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011297 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011298 return -EINVAL;
11299 }
11300 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011302 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11303#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11304 params->channel, params->channel_type);
11305#else
11306 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11307#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011308#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011309 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011310 params->ssid_len, params->hidden_ssid,
11311 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011312 }
11313
11314 EXIT();
11315 return status;
11316}
11317
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011318static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11319 struct net_device *dev,
11320 struct cfg80211_ap_settings *params)
11321{
11322 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011323
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011324 vos_ssr_protect(__func__);
11325 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11326 vos_ssr_unprotect(__func__);
11327
11328 return ret;
11329}
11330
11331static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011332 struct net_device *dev,
11333 struct cfg80211_beacon_data *params)
11334{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011336 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011337 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011338
11339 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011340
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011341 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11342 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11343 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011345 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011346
11347 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11348 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011349 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011350 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011351 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011352 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011353
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011354 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011355 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011356 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011357 {
11358 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011359
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011360 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011361
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011362 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011363 {
11364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11365 FL("session(%d) beacon data points to NULL"),
11366 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011367 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011368 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011369
11370 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11371
11372 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011373 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011374 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011375 return -EINVAL;
11376 }
11377
11378 pAdapter->sessionCtx.ap.beacon = new;
11379
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011380 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11381 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011382 }
11383
11384 EXIT();
11385 return status;
11386}
11387
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011388static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11389 struct net_device *dev,
11390 struct cfg80211_beacon_data *params)
11391{
11392 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011393
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011394 vos_ssr_protect(__func__);
11395 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11396 vos_ssr_unprotect(__func__);
11397
11398 return ret;
11399}
11400
11401#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011402
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011403static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 struct net_device *dev,
11405 struct bss_parameters *params)
11406{
11407 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011408 hdd_context_t *pHddCtx;
11409 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011410
11411 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011412
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011413 if (NULL == pAdapter)
11414 {
11415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11416 "%s: HDD adapter is Null", __func__);
11417 return -ENODEV;
11418 }
11419 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011420 ret = wlan_hdd_validate_context(pHddCtx);
11421 if (0 != ret)
11422 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011423 return ret;
11424 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011425 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11426 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11427 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11429 __func__, hdd_device_modetoString(pAdapter->device_mode),
11430 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011431
11432 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011434 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 {
11436 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11437 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 {
11440 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 }
11443
11444 EXIT();
11445 return 0;
11446}
11447
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011448static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11449 struct net_device *dev,
11450 struct bss_parameters *params)
11451{
11452 int ret;
11453
11454 vos_ssr_protect(__func__);
11455 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11456 vos_ssr_unprotect(__func__);
11457
11458 return ret;
11459}
Kiet Lam10841362013-11-01 11:36:50 +053011460/* FUNCTION: wlan_hdd_change_country_code_cd
11461* to wait for contry code completion
11462*/
11463void* wlan_hdd_change_country_code_cb(void *pAdapter)
11464{
11465 hdd_adapter_t *call_back_pAdapter = pAdapter;
11466 complete(&call_back_pAdapter->change_country_code);
11467 return NULL;
11468}
11469
Jeff Johnson295189b2012-06-20 16:38:30 -070011470/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011471 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11473 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011474int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011475 struct net_device *ndev,
11476 enum nl80211_iftype type,
11477 u32 *flags,
11478 struct vif_params *params
11479 )
11480{
11481 struct wireless_dev *wdev;
11482 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011483 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011484 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 tCsrRoamProfile *pRoamProfile = NULL;
11486 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011487 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011488 eMib_dot11DesiredBssType connectedBssType;
11489 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011490 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011491
11492 ENTER();
11493
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011494 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011495 {
11496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11497 "%s: Adapter context is null", __func__);
11498 return VOS_STATUS_E_FAILURE;
11499 }
11500
11501 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11502 if (!pHddCtx)
11503 {
11504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11505 "%s: HDD context is null", __func__);
11506 return VOS_STATUS_E_FAILURE;
11507 }
11508
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011509 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11510 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11511 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011512 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011513 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011515 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 }
11517
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11519 __func__, hdd_device_modetoString(pAdapter->device_mode),
11520 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011521
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011522 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11523 hddLog(VOS_TRACE_LEVEL_FATAL,
11524 "%s: STA + MON is in progress, cannot change interface",
11525 __func__);
11526 }
11527
Agarwal Ashish51325b52014-06-16 16:50:49 +053011528 if (vos_max_concurrent_connections_reached()) {
11529 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11530 return -EINVAL;
11531 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011532 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 wdev = ndev->ieee80211_ptr;
11534
11535#ifdef WLAN_BTAMP_FEATURE
11536 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11537 (NL80211_IFTYPE_ADHOC == type)||
11538 (NL80211_IFTYPE_AP == type)||
11539 (NL80211_IFTYPE_P2P_GO == type))
11540 {
11541 pHddCtx->isAmpAllowed = VOS_FALSE;
11542 // stop AMP traffic
11543 status = WLANBAP_StopAmp();
11544 if(VOS_STATUS_SUCCESS != status )
11545 {
11546 pHddCtx->isAmpAllowed = VOS_TRUE;
11547 hddLog(VOS_TRACE_LEVEL_FATAL,
11548 "%s: Failed to stop AMP", __func__);
11549 return -EINVAL;
11550 }
11551 }
11552#endif //WLAN_BTAMP_FEATURE
11553 /* Reset the current device mode bit mask*/
11554 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11555
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011556 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11557 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11558 (type == NL80211_IFTYPE_P2P_GO)))
11559 {
11560 /* Notify Mode change in case of concurrency.
11561 * Below function invokes TDLS teardown Functionality Since TDLS is
11562 * not Supported in case of concurrency i.e Once P2P session
11563 * is detected disable offchannel and teardown TDLS links
11564 */
11565 hddLog(LOG1,
11566 FL("Device mode = %d Interface type = %d"),
11567 pAdapter->device_mode, type);
11568 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11569 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011570
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011573 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 )
11575 {
11576 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011577 if (!pWextState)
11578 {
11579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11580 "%s: pWextState is null", __func__);
11581 return VOS_STATUS_E_FAILURE;
11582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 pRoamProfile = &pWextState->roamProfile;
11584 LastBSSType = pRoamProfile->BSSType;
11585
11586 switch (type)
11587 {
11588 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 hddLog(VOS_TRACE_LEVEL_INFO,
11591 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11592 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011593#ifdef WLAN_FEATURE_11AC
11594 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11595 {
11596 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11597 }
11598#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011599 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011600 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011602 //Check for sub-string p2p to confirm its a p2p interface
11603 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011605#ifdef FEATURE_WLAN_TDLS
11606 mutex_lock(&pHddCtx->tdls_lock);
11607 wlan_hdd_tdls_exit(pAdapter, TRUE);
11608 mutex_unlock(&pHddCtx->tdls_lock);
11609#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011610 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11611 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11612 }
11613 else
11614 {
11615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011617 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011619
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 case NL80211_IFTYPE_ADHOC:
11621 hddLog(VOS_TRACE_LEVEL_INFO,
11622 "%s: setting interface Type to ADHOC", __func__);
11623 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11624 pRoamProfile->phyMode =
11625 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011626 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011628 hdd_set_ibss_ops( pAdapter );
11629 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011630
11631 status = hdd_sta_id_hash_attach(pAdapter);
11632 if (VOS_STATUS_SUCCESS != status) {
11633 hddLog(VOS_TRACE_LEVEL_ERROR,
11634 FL("Failed to initialize hash for IBSS"));
11635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 break;
11637
11638 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011640 {
11641 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11642 "%s: setting interface Type to %s", __func__,
11643 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11644
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011645 //Cancel any remain on channel for GO mode
11646 if (NL80211_IFTYPE_P2P_GO == type)
11647 {
11648 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11649 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011650 if (NL80211_IFTYPE_AP == type)
11651 {
11652 /* As Loading WLAN Driver one interface being created for p2p device
11653 * address. This will take one HW STA and the max number of clients
11654 * that can connect to softAP will be reduced by one. so while changing
11655 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11656 * interface as it is not required in SoftAP mode.
11657 */
11658
11659 // Get P2P Adapter
11660 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11661
11662 if (pP2pAdapter)
11663 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011664 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011665 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011666 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11667 }
11668 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011669 //Disable IMPS & BMPS for SAP/GO
11670 if(VOS_STATUS_E_FAILURE ==
11671 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11672 {
11673 //Fail to Exit BMPS
11674 VOS_ASSERT(0);
11675 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011676
11677 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11678
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011679#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011680
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011681 /* A Mutex Lock is introduced while changing the mode to
11682 * protect the concurrent access for the Adapters by TDLS
11683 * module.
11684 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011685 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011686#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011688 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11691 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011692#ifdef FEATURE_WLAN_TDLS
11693 mutex_unlock(&pHddCtx->tdls_lock);
11694#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011695 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11696 (pConfig->apRandomBssidEnabled))
11697 {
11698 /* To meet Android requirements create a randomized
11699 MAC address of the form 02:1A:11:Fx:xx:xx */
11700 get_random_bytes(&ndev->dev_addr[3], 3);
11701 ndev->dev_addr[0] = 0x02;
11702 ndev->dev_addr[1] = 0x1A;
11703 ndev->dev_addr[2] = 0x11;
11704 ndev->dev_addr[3] |= 0xF0;
11705 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11706 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011707 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11708 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011709 }
11710
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 hdd_set_ap_ops( pAdapter->dev );
11712
Kiet Lam10841362013-11-01 11:36:50 +053011713 /* This is for only SAP mode where users can
11714 * control country through ini.
11715 * P2P GO follows station country code
11716 * acquired during the STA scanning. */
11717 if((NL80211_IFTYPE_AP == type) &&
11718 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11719 {
11720 int status = 0;
11721 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11722 "%s: setting country code from INI ", __func__);
11723 init_completion(&pAdapter->change_country_code);
11724 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11725 (void *)(tSmeChangeCountryCallback)
11726 wlan_hdd_change_country_code_cb,
11727 pConfig->apCntryCode, pAdapter,
11728 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011729 eSIR_FALSE,
11730 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011731 if (eHAL_STATUS_SUCCESS == status)
11732 {
11733 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011734 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011735 &pAdapter->change_country_code,
11736 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011737 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011738 {
11739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011740 FL("SME Timed out while setting country code %ld"),
11741 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011742
11743 if (pHddCtx->isLogpInProgress)
11744 {
11745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11746 "%s: LOGP in Progress. Ignore!!!", __func__);
11747 return -EAGAIN;
11748 }
Kiet Lam10841362013-11-01 11:36:50 +053011749 }
11750 }
11751 else
11752 {
11753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011754 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011755 return -EINVAL;
11756 }
11757 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011758 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 if(status != VOS_STATUS_SUCCESS)
11760 {
11761 hddLog(VOS_TRACE_LEVEL_FATAL,
11762 "%s: Error initializing the ap mode", __func__);
11763 return -EINVAL;
11764 }
11765 hdd_set_conparam(1);
11766
Nirav Shah7e3c8132015-06-22 23:51:42 +053011767 status = hdd_sta_id_hash_attach(pAdapter);
11768 if (VOS_STATUS_SUCCESS != status)
11769 {
11770 hddLog(VOS_TRACE_LEVEL_ERROR,
11771 FL("Failed to initialize hash for AP"));
11772 return -EINVAL;
11773 }
11774
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 /*interface type changed update in wiphy structure*/
11776 if(wdev)
11777 {
11778 wdev->iftype = type;
11779 pHddCtx->change_iface = type;
11780 }
11781 else
11782 {
11783 hddLog(VOS_TRACE_LEVEL_ERROR,
11784 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11785 return -EINVAL;
11786 }
11787 goto done;
11788 }
11789
11790 default:
11791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11792 __func__);
11793 return -EOPNOTSUPP;
11794 }
11795 }
11796 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 )
11799 {
11800 switch(type)
11801 {
11802 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011805
11806 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011807#ifdef FEATURE_WLAN_TDLS
11808
11809 /* A Mutex Lock is introduced while changing the mode to
11810 * protect the concurrent access for the Adapters by TDLS
11811 * module.
11812 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011813 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011814#endif
c_hpothu002231a2015-02-05 14:58:51 +053011815 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011817 //Check for sub-string p2p to confirm its a p2p interface
11818 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011819 {
11820 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11821 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11822 }
11823 else
11824 {
11825 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011827 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011828
11829 /* set con_mode to STA only when no SAP concurrency mode */
11830 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11831 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11834 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011835#ifdef FEATURE_WLAN_TDLS
11836 mutex_unlock(&pHddCtx->tdls_lock);
11837#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011838 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 if( VOS_STATUS_SUCCESS != status )
11840 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011841 /* In case of JB, for P2P-GO, only change interface will be called,
11842 * This is the right place to enable back bmps_imps()
11843 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011844 if (pHddCtx->hdd_wlan_suspended)
11845 {
11846 hdd_set_pwrparams(pHddCtx);
11847 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011848 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011849 goto done;
11850 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011851 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11854 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 goto done;
11856 default:
11857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11858 __func__);
11859 return -EOPNOTSUPP;
11860
11861 }
11862
11863 }
11864 else
11865 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011866 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11867 __func__, hdd_device_modetoString(pAdapter->device_mode),
11868 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 return -EOPNOTSUPP;
11870 }
11871
11872
11873 if(pRoamProfile)
11874 {
11875 if ( LastBSSType != pRoamProfile->BSSType )
11876 {
11877 /*interface type changed update in wiphy structure*/
11878 wdev->iftype = type;
11879
11880 /*the BSS mode changed, We need to issue disconnect
11881 if connected or in IBSS disconnect state*/
11882 if ( hdd_connGetConnectedBssType(
11883 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11884 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11885 {
11886 /*need to issue a disconnect to CSR.*/
11887 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11888 if( eHAL_STATUS_SUCCESS ==
11889 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11890 pAdapter->sessionId,
11891 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11892 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011893 ret = wait_for_completion_interruptible_timeout(
11894 &pAdapter->disconnect_comp_var,
11895 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11896 if (ret <= 0)
11897 {
11898 hddLog(VOS_TRACE_LEVEL_ERROR,
11899 FL("wait on disconnect_comp_var failed %ld"), ret);
11900 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902 }
11903 }
11904 }
11905
11906done:
11907 /*set bitmask based on updated value*/
11908 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070011909
11910 /* Only STA mode support TM now
11911 * all other mode, TM feature should be disabled */
11912 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
11913 (~VOS_STA & pHddCtx->concurrency_mode) )
11914 {
11915 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
11916 }
11917
Jeff Johnson295189b2012-06-20 16:38:30 -070011918#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011919 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011920 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 {
11922 //we are ok to do AMP
11923 pHddCtx->isAmpAllowed = VOS_TRUE;
11924 }
11925#endif //WLAN_BTAMP_FEATURE
11926 EXIT();
11927 return 0;
11928}
11929
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011930/*
11931 * FUNCTION: wlan_hdd_cfg80211_change_iface
11932 * wrapper function to protect the actual implementation from SSR.
11933 */
11934int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
11935 struct net_device *ndev,
11936 enum nl80211_iftype type,
11937 u32 *flags,
11938 struct vif_params *params
11939 )
11940{
11941 int ret;
11942
11943 vos_ssr_protect(__func__);
11944 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
11945 vos_ssr_unprotect(__func__);
11946
11947 return ret;
11948}
11949
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011950#ifdef FEATURE_WLAN_TDLS
11951static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011952 struct net_device *dev,
11953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11954 const u8 *mac,
11955#else
11956 u8 *mac,
11957#endif
11958 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011959{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011960 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011961 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011962 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011963 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011964 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011965 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011966
11967 ENTER();
11968
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011969 if (!dev) {
11970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11971 return -EINVAL;
11972 }
11973
11974 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11975 if (!pAdapter) {
11976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11977 return -EINVAL;
11978 }
11979
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011980 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011981 {
11982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11983 "Invalid arguments");
11984 return -EINVAL;
11985 }
Hoonki Lee27511902013-03-14 18:19:06 -070011986
11987 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11988 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11989 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011991 "%s: TDLS mode is disabled OR not enabled in FW."
11992 MAC_ADDRESS_STR " Request declined.",
11993 __func__, MAC_ADDR_ARRAY(mac));
11994 return -ENOTSUPP;
11995 }
11996
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011997 if (pHddCtx->isLogpInProgress)
11998 {
11999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12000 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012001 wlan_hdd_tdls_set_link_status(pAdapter,
12002 mac,
12003 eTDLS_LINK_IDLE,
12004 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012005 return -EBUSY;
12006 }
12007
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012008 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012009 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012010
12011 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012013 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12014 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012015 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012016 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012017 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012018
12019 /* in add station, we accept existing valid staId if there is */
12020 if ((0 == update) &&
12021 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12022 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012023 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012025 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012026 " link_status %d. staId %d. add station ignored.",
12027 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012028 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012029 return 0;
12030 }
12031 /* in change station, we accept only when staId is valid */
12032 if ((1 == update) &&
12033 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12034 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12035 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012036 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012038 "%s: " MAC_ADDRESS_STR
12039 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012040 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12041 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12042 mutex_unlock(&pHddCtx->tdls_lock);
12043 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012044 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012045 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012046
12047 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012048 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012049 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12051 "%s: " MAC_ADDRESS_STR
12052 " TDLS setup is ongoing. Request declined.",
12053 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012054 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012055 }
12056
12057 /* first to check if we reached to maximum supported TDLS peer.
12058 TODO: for now, return -EPERM looks working fine,
12059 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012060 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12061 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012062 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12064 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012065 " TDLS Max peer already connected. Request declined."
12066 " Num of peers (%d), Max allowed (%d).",
12067 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12068 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012069 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012070 }
12071 else
12072 {
12073 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012074 mutex_lock(&pHddCtx->tdls_lock);
12075 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012076 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012077 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012078 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12080 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12081 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012082 return -EPERM;
12083 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012084 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012085 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012086 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012087 wlan_hdd_tdls_set_link_status(pAdapter,
12088 mac,
12089 eTDLS_LINK_CONNECTING,
12090 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012091
Jeff Johnsond75fe012013-04-06 10:53:06 -070012092 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012093 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012094 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012096 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012097 if(StaParams->htcap_present)
12098 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012100 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012102 "ht_capa->extended_capabilities: %0x",
12103 StaParams->HTCap.extendedHtCapInfo);
12104 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012106 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012108 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012109 if(StaParams->vhtcap_present)
12110 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012112 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12113 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12114 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12115 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012116 {
12117 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012119 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012121 "[%d]: %x ", i, StaParams->supported_rates[i]);
12122 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012123 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012124 else if ((1 == update) && (NULL == StaParams))
12125 {
12126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12127 "%s : update is true, but staParams is NULL. Error!", __func__);
12128 return -EPERM;
12129 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012130
12131 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12132
12133 if (!update)
12134 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012135 /*Before adding sta make sure that device exited from BMPS*/
12136 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12137 {
12138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12139 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12140 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12141 if (status != VOS_STATUS_SUCCESS) {
12142 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12143 }
12144 }
12145
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012146 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012147 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012148 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012149 hddLog(VOS_TRACE_LEVEL_ERROR,
12150 FL("Failed to add TDLS peer STA. Enable Bmps"));
12151 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012152 return -EPERM;
12153 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012154 }
12155 else
12156 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012157 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012158 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012159 if (ret != eHAL_STATUS_SUCCESS) {
12160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12161 return -EPERM;
12162 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012163 }
12164
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012165 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012166 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12167
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012168 mutex_lock(&pHddCtx->tdls_lock);
12169 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12170
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012171 if ((pTdlsPeer != NULL) &&
12172 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012173 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012174 hddLog(VOS_TRACE_LEVEL_ERROR,
12175 FL("peer link status %u"), pTdlsPeer->link_status);
12176 mutex_unlock(&pHddCtx->tdls_lock);
12177 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012178 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012179 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012180
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012181 if (ret <= 0)
12182 {
12183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12184 "%s: timeout waiting for tdls add station indication %ld",
12185 __func__, ret);
12186 goto error;
12187 }
12188
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012189 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12190 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012192 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012193 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012194 }
12195
12196 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012197
12198error:
Atul Mittal115287b2014-07-08 13:26:33 +053012199 wlan_hdd_tdls_set_link_status(pAdapter,
12200 mac,
12201 eTDLS_LINK_IDLE,
12202 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012203 return -EPERM;
12204
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012205}
12206#endif
12207
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012208static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12211 const u8 *mac,
12212#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012214#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 struct station_parameters *params)
12216{
12217 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012218 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012219 hdd_context_t *pHddCtx;
12220 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012222 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012223#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012224 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012225 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012226 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012227 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012228#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012229
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012230 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012231
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012232 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012233 if ((NULL == pAdapter))
12234 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012236 "invalid adapter ");
12237 return -EINVAL;
12238 }
12239
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012240 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12241 TRACE_CODE_HDD_CHANGE_STATION,
12242 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012244
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012245 ret = wlan_hdd_validate_context(pHddCtx);
12246 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012247 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012248 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012249 }
12250
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012251 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12252
12253 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012254 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12256 "invalid HDD station context");
12257 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012258 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12260
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012261 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12262 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012264 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012266 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 WLANTL_STA_AUTHENTICATED);
12268
Gopichand Nakkala29149562013-05-10 21:43:41 +053012269 if (status != VOS_STATUS_SUCCESS)
12270 {
12271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12272 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12273 return -EINVAL;
12274 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 }
12276 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012277 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12278 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012279#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012280 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12281 StaParams.capability = params->capability;
12282 StaParams.uapsd_queues = params->uapsd_queues;
12283 StaParams.max_sp = params->max_sp;
12284
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012285 /* Convert (first channel , number of channels) tuple to
12286 * the total list of channels. This goes with the assumption
12287 * that if the first channel is < 14, then the next channels
12288 * are an incremental of 1 else an incremental of 4 till the number
12289 * of channels.
12290 */
12291 if (0 != params->supported_channels_len) {
12292 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12293 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12294 {
12295 int wifi_chan_index;
12296 StaParams.supported_channels[j] = params->supported_channels[i];
12297 wifi_chan_index =
12298 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12299 no_of_channels = params->supported_channels[i+1];
12300 for(k=1; k <= no_of_channels; k++)
12301 {
12302 StaParams.supported_channels[j+1] =
12303 StaParams.supported_channels[j] + wifi_chan_index;
12304 j+=1;
12305 }
12306 }
12307 StaParams.supported_channels_len = j;
12308 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012309 if (params->supported_oper_classes_len >
12310 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12312 "received oper classes:%d, resetting it to max supported %d",
12313 params->supported_oper_classes_len,
12314 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12315 params->supported_oper_classes_len =
12316 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12317 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012318 vos_mem_copy(StaParams.supported_oper_classes,
12319 params->supported_oper_classes,
12320 params->supported_oper_classes_len);
12321 StaParams.supported_oper_classes_len =
12322 params->supported_oper_classes_len;
12323
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012324 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12326 "received extn capabilities:%d, resetting it to max supported",
12327 params->ext_capab_len);
12328 params->ext_capab_len = sizeof(StaParams.extn_capability);
12329 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012330 if (0 != params->ext_capab_len)
12331 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012332 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012333
12334 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012335 {
12336 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012337 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012338 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012339
12340 StaParams.supported_rates_len = params->supported_rates_len;
12341
12342 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12343 * The supported_rates array , for all the structures propogating till Add Sta
12344 * to the firmware has to be modified , if the supplicant (ieee80211) is
12345 * modified to send more rates.
12346 */
12347
12348 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12349 */
12350 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12351 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12352
12353 if (0 != StaParams.supported_rates_len) {
12354 int i = 0;
12355 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12356 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012358 "Supported Rates with Length %d", StaParams.supported_rates_len);
12359 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012361 "[%d]: %0x", i, StaParams.supported_rates[i]);
12362 }
12363
12364 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012365 {
12366 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012367 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012368 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012369
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012370 if (0 != params->ext_capab_len ) {
12371 /*Define A Macro : TODO Sunil*/
12372 if ((1<<4) & StaParams.extn_capability[3]) {
12373 isBufSta = 1;
12374 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012375 /* TDLS Channel Switching Support */
12376 if ((1<<6) & StaParams.extn_capability[3]) {
12377 isOffChannelSupported = 1;
12378 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012379 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012380
12381 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012382 (params->ht_capa || params->vht_capa ||
12383 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012384 /* TDLS Peer is WME/QoS capable */
12385 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012386
12387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12388 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12389 __func__, isQosWmmSta, StaParams.htcap_present);
12390
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012391 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12392 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012393 isOffChannelSupported,
12394 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012395
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012396 if (VOS_STATUS_SUCCESS != status) {
12397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12398 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12399 return -EINVAL;
12400 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012401 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12402
12403 if (VOS_STATUS_SUCCESS != status) {
12404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12405 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12406 return -EINVAL;
12407 }
12408 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012409#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012410 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012411 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 return status;
12413}
12414
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12416static int wlan_hdd_change_station(struct wiphy *wiphy,
12417 struct net_device *dev,
12418 const u8 *mac,
12419 struct station_parameters *params)
12420#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012421static int wlan_hdd_change_station(struct wiphy *wiphy,
12422 struct net_device *dev,
12423 u8 *mac,
12424 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012425#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012426{
12427 int ret;
12428
12429 vos_ssr_protect(__func__);
12430 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12431 vos_ssr_unprotect(__func__);
12432
12433 return ret;
12434}
12435
Jeff Johnson295189b2012-06-20 16:38:30 -070012436/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012437 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 * This function is used to initialize the key information
12439 */
12440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012441static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 struct net_device *ndev,
12443 u8 key_index, bool pairwise,
12444 const u8 *mac_addr,
12445 struct key_params *params
12446 )
12447#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012448static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 struct net_device *ndev,
12450 u8 key_index, const u8 *mac_addr,
12451 struct key_params *params
12452 )
12453#endif
12454{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 tCsrRoamSetKey setKey;
12457 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012458 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012459 v_U32_t roamId= 0xFF;
12460 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012461 hdd_hostapd_state_t *pHostapdState;
12462 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012463 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012464 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012465 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012466 v_MACADDR_t *peerMacAddr;
12467 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012468 uint8_t staid = HDD_MAX_STA_COUNT;
12469 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012470
12471 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012472
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012473 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12474 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12475 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12477 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012478 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012479 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012480 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012481 }
12482
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012483 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12484 __func__, hdd_device_modetoString(pAdapter->device_mode),
12485 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012486
12487 if (CSR_MAX_NUM_KEY <= key_index)
12488 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012489 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 key_index);
12491
12492 return -EINVAL;
12493 }
12494
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012495 if (CSR_MAX_KEY_LEN < params->key_len)
12496 {
12497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12498 params->key_len);
12499
12500 return -EINVAL;
12501 }
12502
Jingxiang Gec438aea2017-10-26 16:44:00 +080012503 if (CSR_MAX_RSC_LEN < params->seq_len)
12504 {
12505 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12506 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012507
12508 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012509 }
12510
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012511 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012512 "%s: called with key index = %d & key length %d & seq length %d",
12513 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012514
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012515 peerMacAddr = (v_MACADDR_t *)mac_addr;
12516
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 /*extract key idx, key len and key*/
12518 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12519 setKey.keyId = key_index;
12520 setKey.keyLength = params->key_len;
12521 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012522 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012523
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012524 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 {
12526 case WLAN_CIPHER_SUITE_WEP40:
12527 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12528 break;
12529
12530 case WLAN_CIPHER_SUITE_WEP104:
12531 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12532 break;
12533
12534 case WLAN_CIPHER_SUITE_TKIP:
12535 {
12536 u8 *pKey = &setKey.Key[0];
12537 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12538
12539 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12540
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012541 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012542
12543 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012544 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 |--------------|----------|----------|
12546 <---16bytes---><--8bytes--><--8bytes-->
12547
12548 */
12549 /*Sme expects the 32 bytes key to be in the below order
12550
12551 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012552 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 |--------------|----------|----------|
12554 <---16bytes---><--8bytes--><--8bytes-->
12555 */
12556 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012557 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012558
12559 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012560 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012561
12562 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012563 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012564
12565
12566 break;
12567 }
12568
12569 case WLAN_CIPHER_SUITE_CCMP:
12570 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12571 break;
12572
12573#ifdef FEATURE_WLAN_WAPI
12574 case WLAN_CIPHER_SUITE_SMS4:
12575 {
12576 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12577 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12578 params->key, params->key_len);
12579 return 0;
12580 }
12581#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012583#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012584 case WLAN_CIPHER_SUITE_KRK:
12585 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12586 break;
12587#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012588
12589#ifdef WLAN_FEATURE_11W
12590 case WLAN_CIPHER_SUITE_AES_CMAC:
12591 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012592 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012593#endif
12594
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012598 status = -EOPNOTSUPP;
12599 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 }
12601
12602 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12603 __func__, setKey.encType);
12604
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012605 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12607 (!pairwise)
12608#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012609 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012610#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012611 )
12612 {
12613 /* set group key*/
12614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12615 "%s- %d: setting Broadcast key",
12616 __func__, __LINE__);
12617 setKey.keyDirection = eSIR_RX_ONLY;
12618 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12619 }
12620 else
12621 {
12622 /* set pairwise key*/
12623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12624 "%s- %d: setting pairwise key",
12625 __func__, __LINE__);
12626 setKey.keyDirection = eSIR_TX_RX;
12627 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012628 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012629 }
12630 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12631 {
12632 setKey.keyDirection = eSIR_TX_RX;
12633 /*Set the group key*/
12634 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12635 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012636
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012637 if ( 0 != status )
12638 {
12639 hddLog(VOS_TRACE_LEVEL_ERROR,
12640 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012641 status = -EINVAL;
12642 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012643 }
12644 /*Save the keys here and call sme_RoamSetKey for setting
12645 the PTK after peer joins the IBSS network*/
12646 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12647 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012648 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012649 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012650 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12651 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12652 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012654 if( pHostapdState->bssState == BSS_START )
12655 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012656 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12657 vos_status = wlan_hdd_check_ula_done(pAdapter);
12658
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012659 if (peerMacAddr && (pairwise_set_key == true))
12660 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012661
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012662 if ( vos_status != VOS_STATUS_SUCCESS )
12663 {
12664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12665 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12666 __LINE__, vos_status );
12667
12668 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12669
12670 status = -EINVAL;
12671 goto end;
12672 }
12673
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12675
12676 if ( status != eHAL_STATUS_SUCCESS )
12677 {
12678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12679 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12680 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012681 status = -EINVAL;
12682 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 }
12684 }
12685
12686 /* Saving WEP keys */
12687 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12688 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12689 {
12690 //Save the wep key in ap context. Issue setkey after the BSS is started.
12691 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12692 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12693 }
12694 else
12695 {
12696 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012697 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012698 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12699 }
12700 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012701 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12702 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 {
12704 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12705 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12706
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12708 if (!pairwise)
12709#else
12710 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12711#endif
12712 {
12713 /* set group key*/
12714 if (pHddStaCtx->roam_info.deferKeyComplete)
12715 {
12716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12717 "%s- %d: Perform Set key Complete",
12718 __func__, __LINE__);
12719 hdd_PerformRoamSetKeyComplete(pAdapter);
12720 }
12721 }
12722
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012723 if (pairwise_set_key == true)
12724 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012725
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12727
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012728 pWextState->roamProfile.Keys.defaultIndex = key_index;
12729
12730
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012731 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 params->key, params->key_len);
12733
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012734
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12736
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012737 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012739 __func__, setKey.peerMac[0], setKey.peerMac[1],
12740 setKey.peerMac[2], setKey.peerMac[3],
12741 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 setKey.keyDirection);
12743
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012744 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012745
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012746 if ( vos_status != VOS_STATUS_SUCCESS )
12747 {
12748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12750 __LINE__, vos_status );
12751
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012752 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012753
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012754 status = -EINVAL;
12755 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012756
12757 }
12758
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012759#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012760 /* The supplicant may attempt to set the PTK once pre-authentication
12761 is done. Save the key in the UMAC and include it in the ADD BSS
12762 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012763 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012764 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012765 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012766 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12767 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012768 status = 0;
12769 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012770 }
12771 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12772 {
12773 hddLog(VOS_TRACE_LEVEL_ERROR,
12774 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012775 status = -EINVAL;
12776 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012777 }
12778#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012779
12780 /* issue set key request to SME*/
12781 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12782 pAdapter->sessionId, &setKey, &roamId );
12783
12784 if ( 0 != status )
12785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012786 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12788 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012789 status = -EINVAL;
12790 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 }
12792
12793
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012794 /* in case of IBSS as there was no information available about WEP keys during
12795 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012796 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012797 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12798 !( ( IW_AUTH_KEY_MGMT_802_1X
12799 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12801 )
12802 &&
12803 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12804 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12805 )
12806 )
12807 {
12808 setKey.keyDirection = eSIR_RX_ONLY;
12809 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12810
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012811 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012813 __func__, setKey.peerMac[0], setKey.peerMac[1],
12814 setKey.peerMac[2], setKey.peerMac[3],
12815 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012816 setKey.keyDirection);
12817
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 pAdapter->sessionId, &setKey, &roamId );
12820
12821 if ( 0 != status )
12822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012823 hddLog(VOS_TRACE_LEVEL_ERROR,
12824 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012825 __func__, status);
12826 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012827 status = -EINVAL;
12828 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 }
12830 }
12831 }
12832
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012833 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012834 for (i = 0; i < params->seq_len; i++) {
12835 rsc_counter |= (params->seq[i] << i*8);
12836 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012837 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12838 }
12839
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012840end:
12841 /* Need to clear any trace of key value in the memory.
12842 * Thus zero out the memory even though it is local
12843 * variable.
12844 */
12845 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012846 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012847 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012848}
12849
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12851static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12852 struct net_device *ndev,
12853 u8 key_index, bool pairwise,
12854 const u8 *mac_addr,
12855 struct key_params *params
12856 )
12857#else
12858static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12859 struct net_device *ndev,
12860 u8 key_index, const u8 *mac_addr,
12861 struct key_params *params
12862 )
12863#endif
12864{
12865 int ret;
12866 vos_ssr_protect(__func__);
12867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12868 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12869 mac_addr, params);
12870#else
12871 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12872 params);
12873#endif
12874 vos_ssr_unprotect(__func__);
12875
12876 return ret;
12877}
12878
Jeff Johnson295189b2012-06-20 16:38:30 -070012879/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012880 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 * This function is used to get the key information
12882 */
12883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012884static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012885 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012887 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 const u8 *mac_addr, void *cookie,
12889 void (*callback)(void *cookie, struct key_params*)
12890 )
12891#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012892static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012893 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 struct net_device *ndev,
12895 u8 key_index, const u8 *mac_addr, void *cookie,
12896 void (*callback)(void *cookie, struct key_params*)
12897 )
12898#endif
12899{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012901 hdd_wext_state_t *pWextState = NULL;
12902 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012904 hdd_context_t *pHddCtx;
12905 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012906
12907 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012908
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012909 if (NULL == pAdapter)
12910 {
12911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12912 "%s: HDD adapter is Null", __func__);
12913 return -ENODEV;
12914 }
12915
12916 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12917 ret = wlan_hdd_validate_context(pHddCtx);
12918 if (0 != ret)
12919 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012920 return ret;
12921 }
12922
12923 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12924 pRoamProfile = &(pWextState->roamProfile);
12925
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012926 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12927 __func__, hdd_device_modetoString(pAdapter->device_mode),
12928 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012929
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 memset(&params, 0, sizeof(params));
12931
12932 if (CSR_MAX_NUM_KEY <= key_index)
12933 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012935 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012936 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012937
12938 switch(pRoamProfile->EncryptionType.encryptionType[0])
12939 {
12940 case eCSR_ENCRYPT_TYPE_NONE:
12941 params.cipher = IW_AUTH_CIPHER_NONE;
12942 break;
12943
12944 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
12945 case eCSR_ENCRYPT_TYPE_WEP40:
12946 params.cipher = WLAN_CIPHER_SUITE_WEP40;
12947 break;
12948
12949 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
12950 case eCSR_ENCRYPT_TYPE_WEP104:
12951 params.cipher = WLAN_CIPHER_SUITE_WEP104;
12952 break;
12953
12954 case eCSR_ENCRYPT_TYPE_TKIP:
12955 params.cipher = WLAN_CIPHER_SUITE_TKIP;
12956 break;
12957
12958 case eCSR_ENCRYPT_TYPE_AES:
12959 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
12960 break;
12961
12962 default:
12963 params.cipher = IW_AUTH_CIPHER_NONE;
12964 break;
12965 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012966
c_hpothuaaf19692014-05-17 17:01:48 +053012967 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12968 TRACE_CODE_HDD_CFG80211_GET_KEY,
12969 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012970
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
12972 params.seq_len = 0;
12973 params.seq = NULL;
12974 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
12975 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012976 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012977 return 0;
12978}
12979
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12981static int wlan_hdd_cfg80211_get_key(
12982 struct wiphy *wiphy,
12983 struct net_device *ndev,
12984 u8 key_index, bool pairwise,
12985 const u8 *mac_addr, void *cookie,
12986 void (*callback)(void *cookie, struct key_params*)
12987 )
12988#else
12989static int wlan_hdd_cfg80211_get_key(
12990 struct wiphy *wiphy,
12991 struct net_device *ndev,
12992 u8 key_index, const u8 *mac_addr, void *cookie,
12993 void (*callback)(void *cookie, struct key_params*)
12994 )
12995#endif
12996{
12997 int ret;
12998
12999 vos_ssr_protect(__func__);
13000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13001 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13002 mac_addr, cookie, callback);
13003#else
13004 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13005 callback);
13006#endif
13007 vos_ssr_unprotect(__func__);
13008
13009 return ret;
13010}
13011
Jeff Johnson295189b2012-06-20 16:38:30 -070013012/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013013 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 * This function is used to delete the key information
13015 */
13016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013017static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013019 u8 key_index,
13020 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 const u8 *mac_addr
13022 )
13023#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013024static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 struct net_device *ndev,
13026 u8 key_index,
13027 const u8 *mac_addr
13028 )
13029#endif
13030{
13031 int status = 0;
13032
13033 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013034 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 //it is observed that this is invalidating peer
13036 //key index whenever re-key is done. This is affecting data link.
13037 //It should be ok to ignore del_key.
13038#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13040 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13042 tCsrRoamSetKey setKey;
13043 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013044
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 ENTER();
13046
13047 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13048 __func__,pAdapter->device_mode);
13049
13050 if (CSR_MAX_NUM_KEY <= key_index)
13051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 key_index);
13054
13055 return -EINVAL;
13056 }
13057
13058 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13059 setKey.keyId = key_index;
13060
13061 if (mac_addr)
13062 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13063 else
13064 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13065
13066 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13067
13068 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013070 )
13071 {
13072
13073 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013074 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13075 if( pHostapdState->bssState == BSS_START)
13076 {
13077 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013078
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 if ( status != eHAL_STATUS_SUCCESS )
13080 {
13081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13082 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13083 __LINE__, status );
13084 }
13085 }
13086 }
13087 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013088 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 )
13090 {
13091 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13092
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013093 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13094
13095 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013097 __func__, setKey.peerMac[0], setKey.peerMac[1],
13098 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013100 if(pAdapter->sessionCtx.station.conn_info.connState ==
13101 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013103 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013104 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013105
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 if ( 0 != status )
13107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013108 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013109 "%s: sme_RoamSetKey failure, returned %d",
13110 __func__, status);
13111 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13112 return -EINVAL;
13113 }
13114 }
13115 }
13116#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013117 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 return status;
13119}
13120
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13122static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13123 struct net_device *ndev,
13124 u8 key_index,
13125 bool pairwise,
13126 const u8 *mac_addr
13127 )
13128#else
13129static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13130 struct net_device *ndev,
13131 u8 key_index,
13132 const u8 *mac_addr
13133 )
13134#endif
13135{
13136 int ret;
13137
13138 vos_ssr_protect(__func__);
13139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13140 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13141 mac_addr);
13142#else
13143 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13144#endif
13145 vos_ssr_unprotect(__func__);
13146
13147 return ret;
13148}
13149
Jeff Johnson295189b2012-06-20 16:38:30 -070013150/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013151 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013152 * This function is used to set the default tx key index
13153 */
13154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013155static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013156 struct net_device *ndev,
13157 u8 key_index,
13158 bool unicast, bool multicast)
13159#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013160static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013161 struct net_device *ndev,
13162 u8 key_index)
13163#endif
13164{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013165 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013166 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013167 hdd_wext_state_t *pWextState;
13168 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013169 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013170
13171 ENTER();
13172
Gopichand Nakkala29149562013-05-10 21:43:41 +053013173 if ((NULL == pAdapter))
13174 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013176 "invalid adapter");
13177 return -EINVAL;
13178 }
13179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13181 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13182 pAdapter->sessionId, key_index));
13183
Gopichand Nakkala29149562013-05-10 21:43:41 +053013184 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13185 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13186
13187 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13188 {
13189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13190 "invalid Wext state or HDD context");
13191 return -EINVAL;
13192 }
13193
Arif Hussain6d2a3322013-11-17 19:50:10 -080013194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013195 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013196
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 if (CSR_MAX_NUM_KEY <= key_index)
13198 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 key_index);
13201
13202 return -EINVAL;
13203 }
13204
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13206 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013207 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013208 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013209 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013210 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013211
Jeff Johnson295189b2012-06-20 16:38:30 -070013212 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013215 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013216 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013217 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013218#ifdef FEATURE_WLAN_WAPI
13219 (eCSR_ENCRYPT_TYPE_WPI !=
13220 pHddStaCtx->conn_info.ucEncryptionType) &&
13221#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013222 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013223 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225 {
13226 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013228
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 tCsrRoamSetKey setKey;
13230 v_U32_t roamId= 0xFF;
13231 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013232
13233 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013235
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 Keys->defaultIndex = (u8)key_index;
13237 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13238 setKey.keyId = key_index;
13239 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013240
13241 vos_mem_copy(&setKey.Key[0],
13242 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013244
Gopichand Nakkala29149562013-05-10 21:43:41 +053013245 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013246
13247 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 &pHddStaCtx->conn_info.bssId[0],
13249 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013250
Gopichand Nakkala29149562013-05-10 21:43:41 +053013251 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13252 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13253 eCSR_ENCRYPT_TYPE_WEP104)
13254 {
13255 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13256 even though ap is configured for WEP-40 encryption. In this canse the key length
13257 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13258 type(104) and switching encryption type to 40*/
13259 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13260 eCSR_ENCRYPT_TYPE_WEP40;
13261 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13262 eCSR_ENCRYPT_TYPE_WEP40;
13263 }
13264
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013265 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013266 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013267
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013269 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013271
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 if ( 0 != status )
13273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013274 hddLog(VOS_TRACE_LEVEL_ERROR,
13275 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013276 status);
13277 return -EINVAL;
13278 }
13279 }
13280 }
13281
13282 /* In SoftAp mode setting key direction for default mode */
13283 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13284 {
13285 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13286 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13287 (eCSR_ENCRYPT_TYPE_AES !=
13288 pWextState->roamProfile.EncryptionType.encryptionType[0])
13289 )
13290 {
13291 /* Saving key direction for default key index to TX default */
13292 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13293 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13294 }
13295 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013296 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 return status;
13298}
13299
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013300#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13301static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13302 struct net_device *ndev,
13303 u8 key_index,
13304 bool unicast, bool multicast)
13305#else
13306static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13307 struct net_device *ndev,
13308 u8 key_index)
13309#endif
13310{
13311 int ret;
13312 vos_ssr_protect(__func__);
13313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13314 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13315 multicast);
13316#else
13317 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13318#endif
13319 vos_ssr_unprotect(__func__);
13320
13321 return ret;
13322}
13323
Jeff Johnson295189b2012-06-20 16:38:30 -070013324/*
13325 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13326 * This function is used to inform the BSS details to nl80211 interface.
13327 */
13328static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13329 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13330{
13331 struct net_device *dev = pAdapter->dev;
13332 struct wireless_dev *wdev = dev->ieee80211_ptr;
13333 struct wiphy *wiphy = wdev->wiphy;
13334 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13335 int chan_no;
13336 int ie_length;
13337 const char *ie;
13338 unsigned int freq;
13339 struct ieee80211_channel *chan;
13340 int rssi = 0;
13341 struct cfg80211_bss *bss = NULL;
13342
Jeff Johnson295189b2012-06-20 16:38:30 -070013343 if( NULL == pBssDesc )
13344 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013345 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 return bss;
13347 }
13348
13349 chan_no = pBssDesc->channelId;
13350 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13351 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13352
13353 if( NULL == ie )
13354 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013355 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 return bss;
13357 }
13358
13359#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13360 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13361 {
13362 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13363 }
13364 else
13365 {
13366 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13367 }
13368#else
13369 freq = ieee80211_channel_to_frequency(chan_no);
13370#endif
13371
13372 chan = __ieee80211_get_channel(wiphy, freq);
13373
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013374 if (!chan) {
13375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13376 return NULL;
13377 }
13378
Abhishek Singhaee43942014-06-16 18:55:47 +053013379 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013380
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013381 return cfg80211_inform_bss(wiphy, chan,
13382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13383 CFG80211_BSS_FTYPE_UNKNOWN,
13384#endif
13385 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013386 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 pBssDesc->capabilityInfo,
13388 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013389 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013390}
13391
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013392/*
13393 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13394 * interface that BSS might have been lost.
13395 * @pAdapter: adaptor
13396 * @bssid: bssid which might have been lost
13397 *
13398 * Return: bss which is unlinked from kernel cache
13399 */
13400struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13401 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13402{
13403 struct net_device *dev = pAdapter->dev;
13404 struct wireless_dev *wdev = dev->ieee80211_ptr;
13405 struct wiphy *wiphy = wdev->wiphy;
13406 struct cfg80211_bss *bss = NULL;
13407
Abhishek Singh5a597e62016-12-05 15:16:30 +053013408 bss = hdd_get_bss_entry(wiphy,
13409 NULL, bssid,
13410 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013411 if (bss == NULL) {
13412 hddLog(LOGE, FL("BSS not present"));
13413 } else {
13414 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13415 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13416 cfg80211_unlink_bss(wiphy, bss);
13417 }
13418 return bss;
13419}
Jeff Johnson295189b2012-06-20 16:38:30 -070013420
13421
13422/*
13423 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13424 * This function is used to inform the BSS details to nl80211 interface.
13425 */
13426struct cfg80211_bss*
13427wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13428 tSirBssDescription *bss_desc
13429 )
13430{
13431 /*
13432 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13433 already exists in bss data base of cfg80211 for that particular BSS ID.
13434 Using cfg80211_inform_bss_frame to update the bss entry instead of
13435 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13436 now there is no possibility to get the mgmt(probe response) frame from PE,
13437 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13438 cfg80211_inform_bss_frame.
13439 */
13440 struct net_device *dev = pAdapter->dev;
13441 struct wireless_dev *wdev = dev->ieee80211_ptr;
13442 struct wiphy *wiphy = wdev->wiphy;
13443 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013444#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13445 qcom_ie_age *qie_age = NULL;
13446 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13447#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013449#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013450 const char *ie =
13451 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13452 unsigned int freq;
13453 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013454 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 struct cfg80211_bss *bss_status = NULL;
13456 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13457 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013458 hdd_context_t *pHddCtx;
13459 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013460#ifdef WLAN_OPEN_SOURCE
13461 struct timespec ts;
13462#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013464
Wilson Yangf80a0542013-10-07 13:02:37 -070013465 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13466 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013467 if (0 != status)
13468 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013469 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013470 }
13471
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013472 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013473 if (!mgmt)
13474 {
13475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13476 "%s: memory allocation failed ", __func__);
13477 return NULL;
13478 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013479
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013481
13482#ifdef WLAN_OPEN_SOURCE
13483 /* Android does not want the timestamp from the frame.
13484 Instead it wants a monotonic increasing value */
13485 get_monotonic_boottime(&ts);
13486 mgmt->u.probe_resp.timestamp =
13487 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13488#else
13489 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13491 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013492
13493#endif
13494
Jeff Johnson295189b2012-06-20 16:38:30 -070013495 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13496 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013497
13498#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13499 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13500 /* Assuming this is the last IE, copy at the end */
13501 ie_length -=sizeof(qcom_ie_age);
13502 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13503 qie_age->element_id = QCOM_VENDOR_IE_ID;
13504 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13505 qie_age->oui_1 = QCOM_OUI1;
13506 qie_age->oui_2 = QCOM_OUI2;
13507 qie_age->oui_3 = QCOM_OUI3;
13508 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013509 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13510 * bss related timestamp is in units of ms. Due to this when scan results
13511 * are sent to lowi the scan age is high.To address this, send age in units
13512 * of 1/10 ms.
13513 */
13514 qie_age->age = (vos_timer_get_system_time() -
13515 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013516#endif
13517
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013519 if (bss_desc->fProbeRsp)
13520 {
13521 mgmt->frame_control |=
13522 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13523 }
13524 else
13525 {
13526 mgmt->frame_control |=
13527 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13528 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013529
13530#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013531 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13533 {
13534 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13535 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013536 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13538
13539 {
13540 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13541 }
13542 else
13543 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13545 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 kfree(mgmt);
13547 return NULL;
13548 }
13549#else
13550 freq = ieee80211_channel_to_frequency(chan_no);
13551#endif
13552 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013553 /*when the band is changed on the fly using the GUI, three things are done
13554 * 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)
13555 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13556 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13557 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13558 * and discards the channels correponding to previous band and calls back with zero bss results.
13559 * 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
13560 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13561 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13562 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13563 * So drop the bss and continue to next bss.
13564 */
13565 if(chan == NULL)
13566 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013567 hddLog(VOS_TRACE_LEVEL_ERROR,
13568 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13569 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013570 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013571 return NULL;
13572 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013573 /*To keep the rssi icon of the connected AP in the scan window
13574 *and the rssi icon of the wireless networks in sync
13575 * */
13576 if (( eConnectionState_Associated ==
13577 pAdapter->sessionCtx.station.conn_info.connState ) &&
13578 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13579 pAdapter->sessionCtx.station.conn_info.bssId,
13580 WNI_CFG_BSSID_LEN)) &&
13581 (pHddCtx->hdd_wlan_suspended == FALSE))
13582 {
13583 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13584 rssi = (pAdapter->rssi * 100);
13585 }
13586 else
13587 {
13588 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013590
Nirav Shah20ac06f2013-12-12 18:14:06 +053013591 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013592 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13593 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013594
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13596 frame_len, rssi, GFP_KERNEL);
13597 kfree(mgmt);
13598 return bss_status;
13599}
13600
13601/*
13602 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13603 * This function is used to update the BSS data base of CFG8011
13604 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013605struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 tCsrRoamInfo *pRoamInfo
13607 )
13608{
13609 tCsrRoamConnectedProfile roamProfile;
13610 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13611 struct cfg80211_bss *bss = NULL;
13612
13613 ENTER();
13614
13615 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13616 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13617
13618 if (NULL != roamProfile.pBssDesc)
13619 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013620 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13621 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013622
13623 if (NULL == bss)
13624 {
13625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13626 __func__);
13627 }
13628
13629 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13630 }
13631 else
13632 {
13633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13634 __func__);
13635 }
13636 return bss;
13637}
13638
13639/*
13640 * FUNCTION: wlan_hdd_cfg80211_update_bss
13641 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013642static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13643 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 tCsrScanResultInfo *pScanResult;
13648 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013649 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 tScanResultHandle pResult;
13651 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013652 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013653 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013655
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013656 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13657 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13658 NO_SESSION, pAdapter->sessionId));
13659
Wilson Yangf80a0542013-10-07 13:02:37 -070013660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013661 ret = wlan_hdd_validate_context(pHddCtx);
13662 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013664 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013665 }
13666
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013667 if (pAdapter->request != NULL)
13668 {
13669 if ((pAdapter->request->n_ssids == 1)
13670 && (pAdapter->request->ssids != NULL)
13671 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13672 is_p2p_scan = true;
13673 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 /*
13675 * start getting scan results and populate cgf80211 BSS database
13676 */
13677 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13678
13679 /* no scan results */
13680 if (NULL == pResult)
13681 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13683 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013684 wlan_hdd_get_frame_logs(pAdapter,
13685 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 return status;
13687 }
13688
13689 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13690
13691 while (pScanResult)
13692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013693 /*
13694 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13695 * entry already exists in bss data base of cfg80211 for that
13696 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13697 * bss entry instead of cfg80211_inform_bss, But this call expects
13698 * mgmt packet as input. As of now there is no possibility to get
13699 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 * ieee80211_mgmt(probe response) and passing to c
13701 * fg80211_inform_bss_frame.
13702 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013703 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13704 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13705 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013706 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13707 continue; //Skip the non p2p bss entries
13708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13710 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711
Jeff Johnson295189b2012-06-20 16:38:30 -070013712
13713 if (NULL == bss_status)
13714 {
13715 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013716 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 }
13718 else
13719 {
Yue Maf49ba872013-08-19 12:04:25 -070013720 cfg80211_put_bss(
13721#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13722 wiphy,
13723#endif
13724 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 }
13726
13727 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13728 }
13729
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013730 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013731 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013733}
13734
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013735void
13736hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13737{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013738 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013739 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013740} /****** end hddPrintMacAddr() ******/
13741
13742void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013743hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013744{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013745 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013746 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013747 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13748 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13749 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013750} /****** end hddPrintPmkId() ******/
13751
13752//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13753//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13754
13755//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13756//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13757
13758#define dump_bssid(bssid) \
13759 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013760 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13761 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013762 }
13763
13764#define dump_pmkid(pMac, pmkid) \
13765 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013766 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13767 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013768 }
13769
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013770#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013771/*
13772 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13773 * This function is used to notify the supplicant of a new PMKSA candidate.
13774 */
13775int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013777 int index, bool preauth )
13778{
Jeff Johnsone7245742012-09-05 17:12:55 -070013779#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013780 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013781 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013782
13783 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013784 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013785
13786 if( NULL == pRoamInfo )
13787 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013788 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013789 return -EINVAL;
13790 }
13791
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013792 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13793 {
13794 dump_bssid(pRoamInfo->bssid);
13795 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013796 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013797 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013798#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013799 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013800}
13801#endif //FEATURE_WLAN_LFR
13802
Yue Maef608272013-04-08 23:09:17 -070013803#ifdef FEATURE_WLAN_LFR_METRICS
13804/*
13805 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13806 * 802.11r/LFR metrics reporting function to report preauth initiation
13807 *
13808 */
13809#define MAX_LFR_METRICS_EVENT_LENGTH 100
13810VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13811 tCsrRoamInfo *pRoamInfo)
13812{
13813 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13814 union iwreq_data wrqu;
13815
13816 ENTER();
13817
13818 if (NULL == pAdapter)
13819 {
13820 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13821 return VOS_STATUS_E_FAILURE;
13822 }
13823
13824 /* create the event */
13825 memset(&wrqu, 0, sizeof(wrqu));
13826 memset(metrics_notification, 0, sizeof(metrics_notification));
13827
13828 wrqu.data.pointer = metrics_notification;
13829 wrqu.data.length = scnprintf(metrics_notification,
13830 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13831 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13832
13833 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13834
13835 EXIT();
13836
13837 return VOS_STATUS_SUCCESS;
13838}
13839
13840/*
13841 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13842 * 802.11r/LFR metrics reporting function to report preauth completion
13843 * or failure
13844 */
13845VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13846 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13847{
13848 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13849 union iwreq_data wrqu;
13850
13851 ENTER();
13852
13853 if (NULL == pAdapter)
13854 {
13855 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13856 return VOS_STATUS_E_FAILURE;
13857 }
13858
13859 /* create the event */
13860 memset(&wrqu, 0, sizeof(wrqu));
13861 memset(metrics_notification, 0, sizeof(metrics_notification));
13862
13863 scnprintf(metrics_notification, sizeof(metrics_notification),
13864 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13865 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13866
13867 if (1 == preauth_status)
13868 strncat(metrics_notification, " TRUE", 5);
13869 else
13870 strncat(metrics_notification, " FALSE", 6);
13871
13872 wrqu.data.pointer = metrics_notification;
13873 wrqu.data.length = strlen(metrics_notification);
13874
13875 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13876
13877 EXIT();
13878
13879 return VOS_STATUS_SUCCESS;
13880}
13881
13882/*
13883 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13884 * 802.11r/LFR metrics reporting function to report handover initiation
13885 *
13886 */
13887VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13888 tCsrRoamInfo *pRoamInfo)
13889{
13890 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13891 union iwreq_data wrqu;
13892
13893 ENTER();
13894
13895 if (NULL == pAdapter)
13896 {
13897 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13898 return VOS_STATUS_E_FAILURE;
13899 }
13900
13901 /* create the event */
13902 memset(&wrqu, 0, sizeof(wrqu));
13903 memset(metrics_notification, 0, sizeof(metrics_notification));
13904
13905 wrqu.data.pointer = metrics_notification;
13906 wrqu.data.length = scnprintf(metrics_notification,
13907 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
13908 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13909
13910 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13911
13912 EXIT();
13913
13914 return VOS_STATUS_SUCCESS;
13915}
13916#endif
13917
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013918
13919/**
13920 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
13921 * @scan_req: scan request to be checked
13922 *
13923 * Return: true or false
13924 */
13925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
13926static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13927 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013928 *scan_req, hdd_context_t
13929 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013930{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013931 if (!scan_req || !scan_req->wiphy ||
13932 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013933 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13934 return false;
13935 }
13936 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
13937 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
13938 return false;
13939 }
13940 return true;
13941}
13942#else
13943static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
13944 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013945 *scan_req, hdd_context_t
13946 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013947{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053013948 if (!scan_req || !scan_req->wiphy ||
13949 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013950 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
13951 return false;
13952 }
13953 return true;
13954}
13955#endif
13956
Mukul Sharmab392b642017-08-17 17:45:29 +053013957#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013958/*
13959 * FUNCTION: hdd_cfg80211_scan_done_callback
13960 * scanning callback function, called after finishing scan
13961 *
13962 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
13965{
13966 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013967 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013969 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 struct cfg80211_scan_request *req = NULL;
13971 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013972 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013973 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013974 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013975 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013976
13977 ENTER();
13978
c_manjee1b4ab9a2016-10-26 11:36:55 +053013979 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
13980 !pAdapter->dev) {
13981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
13982 return 0;
13983 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013984 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053013985 if (NULL == pHddCtx) {
13986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013987 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013988 }
13989
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053013991 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013992 {
13993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053013994 }
13995#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013996 pScanInfo = &pHddCtx->scan_info;
13997
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013999 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014000 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 __func__, halHandle, pContext, (int) scanId, (int) status);
14002
Kiet Lamac06e2c2013-10-23 16:25:07 +053014003 pScanInfo->mScanPendingCounter = 0;
14004
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014006 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014007 &pScanInfo->scan_req_completion_event,
14008 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014009 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014011 hddLog(VOS_TRACE_LEVEL_ERROR,
14012 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014014 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 }
14016
Yue Maef608272013-04-08 23:09:17 -070014017 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014018 {
14019 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014020 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 }
14022
14023 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014024 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 {
14026 hddLog(VOS_TRACE_LEVEL_INFO,
14027 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014028 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 (int) scanId);
14030 }
14031
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014033 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014034#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014035 {
14036 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14037 pAdapter);
14038 if (0 > ret)
14039 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014040 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014041
Jeff Johnson295189b2012-06-20 16:38:30 -070014042 /* If any client wait scan result through WEXT
14043 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014044 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 {
14046 /* The other scan request waiting for current scan finish
14047 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014048 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014050 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 }
14052 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014053 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 {
14055 struct net_device *dev = pAdapter->dev;
14056 union iwreq_data wrqu;
14057 int we_event;
14058 char *msg;
14059
14060 memset(&wrqu, '\0', sizeof(wrqu));
14061 we_event = SIOCGIWSCAN;
14062 msg = NULL;
14063 wireless_send_event(dev, we_event, &wrqu, msg);
14064 }
14065 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014066 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014067
14068 /* Get the Scan Req */
14069 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014070 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014071
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014072 /* Scan is no longer pending */
14073 pScanInfo->mScanPending = VOS_FALSE;
14074
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014075 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014079 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014080#endif
14081
14082 if (pAdapter->dev) {
14083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14084 pAdapter->dev->name);
14085 }
mukul sharmae7041822015-12-03 15:09:21 +053014086 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014087 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 }
14089
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014090 /* last_scan_timestamp is used to decide if new scan
14091 * is needed or not on station interface. If last station
14092 * scan time and new station scan time is less then
14093 * last_scan_timestamp ; driver will return cached scan.
14094 */
14095 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14096 {
14097 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14098
14099 if ( req->n_channels )
14100 {
14101 for (i = 0; i < req->n_channels ; i++ )
14102 {
14103 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14104 }
14105 /* store no of channel scanned */
14106 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14107 }
14108
14109 }
14110
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014111 /*
14112 * cfg80211_scan_done informing NL80211 about completion
14113 * of scanning
14114 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014115 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14116 {
14117 aborted = true;
14118 }
mukul sharmae7041822015-12-03 15:09:21 +053014119
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014121 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14122 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014123#endif
14124 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014125
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014126 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014127
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014128allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014129 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14130 ) && (pHddCtx->spoofMacAddr.isEnabled
14131 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014132 /* Generate new random mac addr for next scan */
14133 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014134
14135 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14136 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014137 }
14138
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014139 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014140 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014141
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014142 /* Acquire wakelock to handle the case where APP's tries to suspend
14143 * immediatly after the driver gets connect request(i.e after scan)
14144 * from supplicant, this result in app's is suspending and not able
14145 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014146 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014147
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014149 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014150#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014151#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014152 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014153#endif
14154
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 EXIT();
14156 return 0;
14157}
14158
14159/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014160 * FUNCTION: hdd_isConnectionInProgress
14161 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014162 *
14163 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014164v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14165 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014166{
14167 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14168 hdd_station_ctx_t *pHddStaCtx = NULL;
14169 hdd_adapter_t *pAdapter = NULL;
14170 VOS_STATUS status = 0;
14171 v_U8_t staId = 0;
14172 v_U8_t *staMac = NULL;
14173
14174 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14175
14176 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14177 {
14178 pAdapter = pAdapterNode->pAdapter;
14179
14180 if( pAdapter )
14181 {
14182 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014183 "%s: Adapter with device mode %s (%d) exists",
14184 __func__, hdd_device_modetoString(pAdapter->device_mode),
14185 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014186 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014187 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14188 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14189 (eConnectionState_Connecting ==
14190 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14191 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014192 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014193 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014194 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014195 if (session_id && reason)
14196 {
14197 *session_id = pAdapter->sessionId;
14198 *reason = eHDD_CONNECTION_IN_PROGRESS;
14199 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014200 return VOS_TRUE;
14201 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014202 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014203 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014204 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014205 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014206 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014207 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014208 if (session_id && reason)
14209 {
14210 *session_id = pAdapter->sessionId;
14211 *reason = eHDD_REASSOC_IN_PROGRESS;
14212 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014213 return VOS_TRUE;
14214 }
14215 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014216 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14217 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014218 {
14219 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14220 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014221 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014222 {
14223 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014224 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014225 "%s: client " MAC_ADDRESS_STR
14226 " is in the middle of WPS/EAPOL exchange.", __func__,
14227 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014228 if (session_id && reason)
14229 {
14230 *session_id = pAdapter->sessionId;
14231 *reason = eHDD_EAPOL_IN_PROGRESS;
14232 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014233 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014234 }
14235 }
14236 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14237 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14238 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014239 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14240 ptSapContext pSapCtx = NULL;
14241 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14242 if(pSapCtx == NULL){
14243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14244 FL("psapCtx is NULL"));
14245 return VOS_FALSE;
14246 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014247 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14248 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014249 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14250 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014251 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014252 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014253
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014254 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014255 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14256 "middle of WPS/EAPOL exchange.", __func__,
14257 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014258 if (session_id && reason)
14259 {
14260 *session_id = pAdapter->sessionId;
14261 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14262 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014263 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014264 }
14265 }
14266 }
14267 }
14268 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14269 pAdapterNode = pNext;
14270 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014271 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014272}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014273
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014274/**
14275 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14276 * to the Scan request
14277 * @scanRequest: Pointer to the csr scan request
14278 * @request: Pointer to the scan request from supplicant
14279 *
14280 * Return: None
14281 */
14282#ifdef CFG80211_SCAN_BSSID
14283static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14284 struct cfg80211_scan_request *request)
14285{
14286 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14287}
14288#else
14289static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14290 struct cfg80211_scan_request *request)
14291{
14292}
14293#endif
14294
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014295/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014296 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014297 * this scan respond to scan trigger and update cfg80211 scan database
14298 * later, scan dump command can be used to recieve scan results
14299 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014300int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014301#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14302 struct net_device *dev,
14303#endif
14304 struct cfg80211_scan_request *request)
14305{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014306 hdd_adapter_t *pAdapter = NULL;
14307 hdd_context_t *pHddCtx = NULL;
14308 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014309 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 tCsrScanRequest scanRequest;
14311 tANI_U8 *channelList = NULL, i;
14312 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014313 int status;
14314 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014316 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014317 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014318 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014319 v_U8_t curr_session_id;
14320 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014321
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014322#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14323 struct net_device *dev = NULL;
14324 if (NULL == request)
14325 {
14326 hddLog(VOS_TRACE_LEVEL_ERROR,
14327 "%s: scan req param null", __func__);
14328 return -EINVAL;
14329 }
14330 dev = request->wdev->netdev;
14331#endif
14332
14333 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14334 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14335 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14336
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 ENTER();
14338
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14340 __func__, hdd_device_modetoString(pAdapter->device_mode),
14341 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014343 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014344 if (0 != status)
14345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014346 return status;
14347 }
14348
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014349 if (NULL == pwextBuf)
14350 {
14351 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14352 __func__);
14353 return -EIO;
14354 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014355 cfg_param = pHddCtx->cfg_ini;
14356 pScanInfo = &pHddCtx->scan_info;
14357
Jeff Johnson295189b2012-06-20 16:38:30 -070014358#ifdef WLAN_BTAMP_FEATURE
14359 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014360 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014362 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 "%s: No scanning when AMP is on", __func__);
14364 return -EOPNOTSUPP;
14365 }
14366#endif
14367 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014368 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014369 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014370 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014371 "%s: Not scanning on device_mode = %s (%d)",
14372 __func__, hdd_device_modetoString(pAdapter->device_mode),
14373 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 return -EOPNOTSUPP;
14375 }
14376
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014377 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14378 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14379 return -EOPNOTSUPP;
14380 }
14381
Jeff Johnson295189b2012-06-20 16:38:30 -070014382 if (TRUE == pScanInfo->mScanPending)
14383 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014384 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14385 {
14386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14387 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014388 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014389 }
14390
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014391 // Don't allow scan if PNO scan is going on.
14392 if (pHddCtx->isPnoEnable)
14393 {
14394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14395 FL("pno scan in progress"));
14396 return -EBUSY;
14397 }
14398
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014399 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014400 //Channel and action frame is pending
14401 //Otherwise Cancel Remain On Channel and allow Scan
14402 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014403 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014404 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014406 return -EBUSY;
14407 }
14408
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14410 {
14411 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014412 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014413 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014414 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14416 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 "%s: MAX TM Level Scan not allowed", __func__);
14419 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014420 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 }
14422 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14423
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014424 /* Check if scan is allowed at this point of time.
14425 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014426 if (TRUE == pHddCtx->btCoexModeSet)
14427 {
14428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14429 FL("BTCoex Mode operation in progress"));
14430 return -EBUSY;
14431 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014432 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014433 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014434
14435 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14436 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14437 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014438 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14439 pHddCtx->last_scan_reject_reason != curr_reason ||
14440 !pHddCtx->last_scan_reject_timestamp)
14441 {
14442 pHddCtx->last_scan_reject_session_id = curr_session_id;
14443 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014444 pHddCtx->last_scan_reject_timestamp =
14445 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014446 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014447 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014448 else
14449 {
14450 pHddCtx->scan_reject_cnt++;
14451
Abhishek Singhe4b12562017-06-20 16:53:39 +053014452 if ((pHddCtx->scan_reject_cnt >=
14453 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014454 vos_system_time_after(jiffies_to_msecs(jiffies),
14455 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014456 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014457 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14458 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14459 vos_system_time_after(jiffies_to_msecs(jiffies),
14460 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014461 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014462 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014463 if (pHddCtx->cfg_ini->enableFatalEvent)
14464 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14465 WLAN_LOG_INDICATOR_HOST_DRIVER,
14466 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14467 FALSE, FALSE);
14468 else
14469 {
14470 hddLog(LOGE, FL("Triggering SSR"));
14471 vos_wlanRestart();
14472 }
14473 }
14474 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014475 return -EBUSY;
14476 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014477 pHddCtx->last_scan_reject_timestamp = 0;
14478 pHddCtx->last_scan_reject_session_id = 0xFF;
14479 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014480 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014481
Jeff Johnson295189b2012-06-20 16:38:30 -070014482 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14483
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014484 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14485 * Becasue of this, driver is assuming that this is not wildcard scan and so
14486 * is not aging out the scan results.
14487 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014488 if ((request->ssids) && (request->n_ssids == 1) &&
14489 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014490 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014492
14493 if ((request->ssids) && (0 < request->n_ssids))
14494 {
14495 tCsrSSIDInfo *SsidInfo;
14496 int j;
14497 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14498 /* Allocate num_ssid tCsrSSIDInfo structure */
14499 SsidInfo = scanRequest.SSIDs.SSIDList =
14500 ( tCsrSSIDInfo *)vos_mem_malloc(
14501 request->n_ssids*sizeof(tCsrSSIDInfo));
14502
14503 if(NULL == scanRequest.SSIDs.SSIDList)
14504 {
14505 hddLog(VOS_TRACE_LEVEL_ERROR,
14506 "%s: memory alloc failed SSIDInfo buffer", __func__);
14507 return -ENOMEM;
14508 }
14509
14510 /* copy all the ssid's and their length */
14511 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14512 {
14513 /* get the ssid length */
14514 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14515 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14516 SsidInfo->SSID.length);
14517 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14518 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14519 j, SsidInfo->SSID.ssId);
14520 }
14521 /* set the scan type to active */
14522 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14523 }
14524 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014526 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14527 TRACE_CODE_HDD_CFG80211_SCAN,
14528 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014529 /* set the scan type to active */
14530 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014532 else
14533 {
14534 /*Set the scan type to default type, in this case it is ACTIVE*/
14535 scanRequest.scanType = pScanInfo->scan_mode;
14536 }
14537 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14538 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014539
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014540 csr_scan_request_assign_bssid(&scanRequest, request);
14541
Jeff Johnson295189b2012-06-20 16:38:30 -070014542 /* set BSSType to default type */
14543 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14544
14545 /*TODO: scan the requested channels only*/
14546
14547 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014548 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014549 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014550 hddLog(VOS_TRACE_LEVEL_WARN,
14551 "No of Scan Channels exceeded limit: %d", request->n_channels);
14552 request->n_channels = MAX_CHANNEL;
14553 }
14554
14555 hddLog(VOS_TRACE_LEVEL_INFO,
14556 "No of Scan Channels: %d", request->n_channels);
14557
14558
14559 if( request->n_channels )
14560 {
14561 char chList [(request->n_channels*5)+1];
14562 int len;
14563 channelList = vos_mem_malloc( request->n_channels );
14564 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014565 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014566 hddLog(VOS_TRACE_LEVEL_ERROR,
14567 "%s: memory alloc failed channelList", __func__);
14568 status = -ENOMEM;
14569 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014570 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014571
14572 for( i = 0, len = 0; i < request->n_channels ; i++ )
14573 {
14574 channelList[i] = request->channels[i]->hw_value;
14575 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14576 }
14577
Nirav Shah20ac06f2013-12-12 18:14:06 +053014578 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014579 "Channel-List: %s ", chList);
14580 }
c_hpothu53512302014-04-15 18:49:53 +053014581
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014582 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14583 scanRequest.ChannelInfo.ChannelList = channelList;
14584
14585 /* set requestType to full scan */
14586 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14587
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014588 /* if there is back to back scan happening in driver with in
14589 * nDeferScanTimeInterval interval driver should defer new scan request
14590 * and should provide last cached scan results instead of new channel list.
14591 * This rule is not applicable if scan is p2p scan.
14592 * This condition will work only in case when last request no of channels
14593 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014594 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014595 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014596 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014597
Sushant Kaushik86592172015-04-27 16:35:03 +053014598 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14599 /* if wps ie is NULL , then only defer scan */
14600 if ( pWpsIe == NULL &&
14601 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014602 {
14603 if ( pScanInfo->last_scan_timestamp !=0 &&
14604 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14605 {
14606 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14607 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14608 vos_mem_compare(pScanInfo->last_scan_channelList,
14609 channelList, pScanInfo->last_scan_numChannels))
14610 {
14611 hddLog(VOS_TRACE_LEVEL_WARN,
14612 " New and old station scan time differ is less then %u",
14613 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14614
14615 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014616 pAdapter);
14617
Agarwal Ashish57e84372014-12-05 18:26:53 +053014618 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014619 "Return old cached scan as all channels and no of channels are same");
14620
Agarwal Ashish57e84372014-12-05 18:26:53 +053014621 if (0 > ret)
14622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014623
Agarwal Ashish57e84372014-12-05 18:26:53 +053014624 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014625
14626 status = eHAL_STATUS_SUCCESS;
14627 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014628 }
14629 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014630 }
14631
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014632 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14633 * search (Flush on both full scan and social scan but not on single
14634 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14635 */
14636
14637 /* Supplicant does single channel scan after 8-way handshake
14638 * and in that case driver shoudnt flush scan results. If
14639 * driver flushes the scan results here and unfortunately if
14640 * the AP doesnt respond to our probe req then association
14641 * fails which is not desired
14642 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014643 if ((request->n_ssids == 1)
14644 && (request->ssids != NULL)
14645 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14646 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014647
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014648 if( is_p2p_scan ||
14649 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014650 {
14651 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14652 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14653 pAdapter->sessionId );
14654 }
14655
14656 if( request->ie_len )
14657 {
14658 /* save this for future association (join requires this) */
14659 /*TODO: Array needs to be converted to dynamic allocation,
14660 * as multiple ie.s can be sent in cfg80211_scan_request structure
14661 * CR 597966
14662 */
14663 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14664 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14665 pScanInfo->scanAddIE.length = request->ie_len;
14666
14667 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14668 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14669 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014670 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014671 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014672 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014673 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14674 memcpy( pwextBuf->roamProfile.addIEScan,
14675 request->ie, request->ie_len);
14676 }
14677 else
14678 {
14679 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14680 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014681 }
14682
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014683 }
14684 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14685 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14686
14687 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14688 request->ie_len);
14689 if (pP2pIe != NULL)
14690 {
14691#ifdef WLAN_FEATURE_P2P_DEBUG
14692 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14693 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14694 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014695 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014696 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14697 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14698 "Go nego completed to Connection is started");
14699 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14700 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014701 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014702 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14703 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014704 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014705 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14706 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14707 "Disconnected state to Connection is started");
14708 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14709 "for 4way Handshake");
14710 }
14711#endif
14712
14713 /* no_cck will be set during p2p find to disable 11b rates */
14714 if(TRUE == request->no_cck)
14715 {
14716 hddLog(VOS_TRACE_LEVEL_INFO,
14717 "%s: This is a P2P Search", __func__);
14718 scanRequest.p2pSearch = 1;
14719
14720 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014721 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014722 /* set requestType to P2P Discovery */
14723 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14724 }
14725
14726 /*
14727 Skip Dfs Channel in case of P2P Search
14728 if it is set in ini file
14729 */
14730 if(cfg_param->skipDfsChnlInP2pSearch)
14731 {
14732 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014733 }
14734 else
14735 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014736 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014737 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014738
Agarwal Ashish4f616132013-12-30 23:32:50 +053014739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 }
14741 }
14742
14743 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14744
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014745#ifdef FEATURE_WLAN_TDLS
14746 /* if tdls disagree scan right now, return immediately.
14747 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14748 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14749 */
14750 status = wlan_hdd_tdls_scan_callback (pAdapter,
14751 wiphy,
14752#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14753 dev,
14754#endif
14755 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014756 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014757 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014758 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14760 "scan rejected %d", __func__, status);
14761 else
14762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14763 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014764 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014765 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014766 }
14767#endif
14768
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014769 /* acquire the wakelock to avoid the apps suspend during the scan. To
14770 * address the following issues.
14771 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14772 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14773 * for long time, this result in apps running at full power for long time.
14774 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14775 * be stuck in full power because of resume BMPS
14776 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014777 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014778
Nirav Shah20ac06f2013-12-12 18:14:06 +053014779 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14780 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014781 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14782 scanRequest.requestType, scanRequest.scanType,
14783 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014784 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14785
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014786 if (pHddCtx->spoofMacAddr.isEnabled &&
14787 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014788 {
14789 hddLog(VOS_TRACE_LEVEL_INFO,
14790 "%s: MAC Spoofing enabled for current scan", __func__);
14791 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14792 * to fill TxBds for probe request during current scan
14793 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014794 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014795 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014796
14797 if(status != VOS_STATUS_SUCCESS)
14798 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014799 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014800 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014801#ifdef FEATURE_WLAN_TDLS
14802 wlan_hdd_tdls_scan_done_callback(pAdapter);
14803#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014804 goto free_mem;
14805 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014806 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014807 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014808 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014809 pAdapter->sessionId, &scanRequest, &scanId,
14810 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014811
Jeff Johnson295189b2012-06-20 16:38:30 -070014812 if (eHAL_STATUS_SUCCESS != status)
14813 {
14814 hddLog(VOS_TRACE_LEVEL_ERROR,
14815 "%s: sme_ScanRequest returned error %d", __func__, status);
14816 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014817 if(eHAL_STATUS_RESOURCES == status)
14818 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14820 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014821 status = -EBUSY;
14822 } else {
14823 status = -EIO;
14824 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014825 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014826
14827#ifdef FEATURE_WLAN_TDLS
14828 wlan_hdd_tdls_scan_done_callback(pAdapter);
14829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 goto free_mem;
14831 }
14832
14833 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014834 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 pAdapter->request = request;
14836 pScanInfo->scanId = scanId;
14837
14838 complete(&pScanInfo->scan_req_completion_event);
14839
14840free_mem:
14841 if( scanRequest.SSIDs.SSIDList )
14842 {
14843 vos_mem_free(scanRequest.SSIDs.SSIDList);
14844 }
14845
14846 if( channelList )
14847 vos_mem_free( channelList );
14848
14849 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 return status;
14851}
14852
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014853int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14854#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14855 struct net_device *dev,
14856#endif
14857 struct cfg80211_scan_request *request)
14858{
14859 int ret;
14860
14861 vos_ssr_protect(__func__);
14862 ret = __wlan_hdd_cfg80211_scan(wiphy,
14863#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14864 dev,
14865#endif
14866 request);
14867 vos_ssr_unprotect(__func__);
14868
14869 return ret;
14870}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014871
14872void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14873{
14874 v_U8_t iniDot11Mode =
14875 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14876 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14877
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014878 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14879 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014880 switch ( iniDot11Mode )
14881 {
14882 case eHDD_DOT11_MODE_AUTO:
14883 case eHDD_DOT11_MODE_11ac:
14884 case eHDD_DOT11_MODE_11ac_ONLY:
14885#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014886 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14887 sme_IsFeatureSupportedByFW(DOT11AC) )
14888 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14889 else
14890 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014891#else
14892 hddDot11Mode = eHDD_DOT11_MODE_11n;
14893#endif
14894 break;
14895 case eHDD_DOT11_MODE_11n:
14896 case eHDD_DOT11_MODE_11n_ONLY:
14897 hddDot11Mode = eHDD_DOT11_MODE_11n;
14898 break;
14899 default:
14900 hddDot11Mode = iniDot11Mode;
14901 break;
14902 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014903#ifdef WLAN_FEATURE_AP_HT40_24G
14904 if (operationChannel > SIR_11B_CHANNEL_END)
14905#endif
14906 {
14907 /* This call decides required channel bonding mode */
14908 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014909 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053014910 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053014911 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014912}
14913
Jeff Johnson295189b2012-06-20 16:38:30 -070014914/*
14915 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014916 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014918int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014919 const u8 *ssid, size_t ssid_len, const u8 *bssid,
14920 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070014921{
14922 int status = 0;
14923 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080014924 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014925 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 v_U32_t roamId;
14927 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 eCsrAuthType RSNAuthType;
14929
14930 ENTER();
14931
14932 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053014934 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080014935
14936 status = wlan_hdd_validate_context(pHddCtx);
14937 if (status)
14938 {
Yue Mae36e3552014-03-05 17:06:20 -080014939 return status;
14940 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014941
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
14943 {
14944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
14945 return -EINVAL;
14946 }
14947
Nitesh Shah9b066282017-06-06 18:05:52 +053014948 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
14949
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 pRoamProfile = &pWextState->roamProfile;
14951
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014952 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014954 hdd_station_ctx_t *pHddStaCtx;
14955 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053014956 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014957
Siddharth Bhalda0d1622015-04-24 15:47:49 +053014958 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
14959
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014960 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
14962 {
14963 /*QoS not enabled in cfg file*/
14964 pRoamProfile->uapsd_mask = 0;
14965 }
14966 else
14967 {
14968 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014969 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
14971 }
14972
14973 pRoamProfile->SSIDs.numOfSSIDs = 1;
14974 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
14975 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014976 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
14978 ssid, ssid_len);
14979
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014980 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
14981 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
14982
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 if (bssid)
14984 {
14985 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014986 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014988 /* Save BSSID in seperate variable as well, as RoamProfile
14989 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 case of join failure we should send valid BSSID to supplicant
14991 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014992 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014994
Jeff Johnson295189b2012-06-20 16:38:30 -070014995 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014996 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070014997 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053014998 /* Store bssid_hint to use in the scan filter. */
14999 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15000 WNI_CFG_BSSID_LEN);
15001 /*
15002 * Save BSSID in seperate variable as well, as RoamProfile
15003 * BSSID is getting zeroed out in the association process. And in
15004 * case of join failure we should send valid BSSID to supplicant
15005 */
15006 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15007 WNI_CFG_BSSID_LEN);
15008 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15009 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015011
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015012
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015013 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15014 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15016 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015017 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 /*set gen ie*/
15019 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15020 /*set auth*/
15021 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15022 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015023#ifdef FEATURE_WLAN_WAPI
15024 if (pAdapter->wapi_info.nWapiMode)
15025 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015026 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 switch (pAdapter->wapi_info.wapiAuthMode)
15028 {
15029 case WAPI_AUTH_MODE_PSK:
15030 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015031 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015032 pAdapter->wapi_info.wapiAuthMode);
15033 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15034 break;
15035 }
15036 case WAPI_AUTH_MODE_CERT:
15037 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015038 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015039 pAdapter->wapi_info.wapiAuthMode);
15040 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15041 break;
15042 }
15043 } // End of switch
15044 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15045 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15046 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015047 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 pRoamProfile->AuthType.numEntries = 1;
15049 pRoamProfile->EncryptionType.numEntries = 1;
15050 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15051 pRoamProfile->mcEncryptionType.numEntries = 1;
15052 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15053 }
15054 }
15055#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015056#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015057 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015058 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15059 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15060 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015061 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15062 sizeof (tSirGtkOffloadParams));
15063 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015064 }
15065#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 pRoamProfile->csrPersona = pAdapter->device_mode;
15067
Jeff Johnson32d95a32012-09-10 13:15:23 -070015068 if( operatingChannel )
15069 {
15070 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15071 pRoamProfile->ChannelInfo.numOfChannels = 1;
15072 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015073 else
15074 {
15075 pRoamProfile->ChannelInfo.ChannelList = NULL;
15076 pRoamProfile->ChannelInfo.numOfChannels = 0;
15077 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015078 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15079 {
15080 hdd_select_cbmode(pAdapter,operatingChannel);
15081 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015082
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015083 /*
15084 * Change conn_state to connecting before sme_RoamConnect(),
15085 * because sme_RoamConnect() has a direct path to call
15086 * hdd_smeRoamCallback(), which will change the conn_state
15087 * If direct path, conn_state will be accordingly changed
15088 * to NotConnected or Associated by either
15089 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15090 * in sme_RoamCallback()
15091 * if sme_RomConnect is to be queued,
15092 * Connecting state will remain until it is completed.
15093 * If connection state is not changed,
15094 * connection state will remain in eConnectionState_NotConnected state.
15095 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15096 * if conn state is eConnectionState_NotConnected.
15097 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15098 * informed of connect result indication which is an issue.
15099 */
15100
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015101 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15102 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015103 {
15104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015105 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015106 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15107 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015108 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015109 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 pAdapter->sessionId, pRoamProfile, &roamId);
15111
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015112 if ((eHAL_STATUS_SUCCESS != status) &&
15113 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15114 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015115
15116 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015117 hddLog(VOS_TRACE_LEVEL_ERROR,
15118 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15119 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015120 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015121 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015122 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015123 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015124
15125 pRoamProfile->ChannelInfo.ChannelList = NULL;
15126 pRoamProfile->ChannelInfo.numOfChannels = 0;
15127
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 }
15129 else
15130 {
15131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15132 return -EINVAL;
15133 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015134 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015135 return status;
15136}
15137
15138/*
15139 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15140 * This function is used to set the authentication type (OPEN/SHARED).
15141 *
15142 */
15143static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15144 enum nl80211_auth_type auth_type)
15145{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015146 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015147 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15148
15149 ENTER();
15150
15151 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015152 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015153 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015155 hddLog(VOS_TRACE_LEVEL_INFO,
15156 "%s: set authentication type to AUTOSWITCH", __func__);
15157 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15158 break;
15159
15160 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015161#ifdef WLAN_FEATURE_VOWIFI_11R
15162 case NL80211_AUTHTYPE_FT:
15163#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015164 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015165 "%s: set authentication type to OPEN", __func__);
15166 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15167 break;
15168
15169 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015170 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015171 "%s: set authentication type to SHARED", __func__);
15172 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15173 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015174#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015175 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015176 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015177 "%s: set authentication type to CCKM WPA", __func__);
15178 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15179 break;
15180#endif
15181
15182
15183 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015184 hddLog(VOS_TRACE_LEVEL_ERROR,
15185 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 auth_type);
15187 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15188 return -EINVAL;
15189 }
15190
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015191 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015192 pHddStaCtx->conn_info.authType;
15193 return 0;
15194}
15195
15196/*
15197 * FUNCTION: wlan_hdd_set_akm_suite
15198 * This function is used to set the key mgmt type(PSK/8021x).
15199 *
15200 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015201static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 u32 key_mgmt
15203 )
15204{
15205 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15206 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015207 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015208#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015209#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015210#endif
15211#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015212#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015213#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015214 /*set key mgmt type*/
15215 switch(key_mgmt)
15216 {
15217 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015218 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015219#ifdef WLAN_FEATURE_VOWIFI_11R
15220 case WLAN_AKM_SUITE_FT_PSK:
15221#endif
15222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015223 __func__);
15224 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15225 break;
15226
15227 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015228 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015229#ifdef WLAN_FEATURE_VOWIFI_11R
15230 case WLAN_AKM_SUITE_FT_8021X:
15231#endif
15232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015233 __func__);
15234 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15235 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015236#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015237#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15238#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15239 case WLAN_AKM_SUITE_CCKM:
15240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15241 __func__);
15242 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15243 break;
15244#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015245#ifndef WLAN_AKM_SUITE_OSEN
15246#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15247 case WLAN_AKM_SUITE_OSEN:
15248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15249 __func__);
15250 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15251 break;
15252#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015253
15254 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015256 __func__, key_mgmt);
15257 return -EINVAL;
15258
15259 }
15260 return 0;
15261}
15262
15263/*
15264 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015265 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015266 * (NONE/WEP40/WEP104/TKIP/CCMP).
15267 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015268static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15269 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015270 bool ucast
15271 )
15272{
15273 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015274 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15276
15277 ENTER();
15278
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015279 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 __func__, cipher);
15283 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15284 }
15285 else
15286 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015287
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 {
15291 case IW_AUTH_CIPHER_NONE:
15292 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15293 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015294
Jeff Johnson295189b2012-06-20 16:38:30 -070015295 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015296 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015297 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015298
Jeff Johnson295189b2012-06-20 16:38:30 -070015299 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015300 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015301 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015302
Jeff Johnson295189b2012-06-20 16:38:30 -070015303 case WLAN_CIPHER_SUITE_TKIP:
15304 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15305 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015306
Jeff Johnson295189b2012-06-20 16:38:30 -070015307 case WLAN_CIPHER_SUITE_CCMP:
15308 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15309 break;
15310#ifdef FEATURE_WLAN_WAPI
15311 case WLAN_CIPHER_SUITE_SMS4:
15312 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15313 break;
15314#endif
15315
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015316#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 case WLAN_CIPHER_SUITE_KRK:
15318 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15319 break;
15320#endif
15321 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015323 __func__, cipher);
15324 return -EOPNOTSUPP;
15325 }
15326 }
15327
15328 if (ucast)
15329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015331 __func__, encryptionType);
15332 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15333 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015334 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015335 encryptionType;
15336 }
15337 else
15338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 __func__, encryptionType);
15341 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15342 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15343 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15344 }
15345
15346 return 0;
15347}
15348
15349
15350/*
15351 * FUNCTION: wlan_hdd_cfg80211_set_ie
15352 * This function is used to parse WPA/RSN IE's.
15353 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015354int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15356 const u8 *ie,
15357#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015358 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 size_t ie_len
15361 )
15362{
15363 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15365 const u8 *genie = ie;
15366#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015367 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015368#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015369 v_U16_t remLen = ie_len;
15370#ifdef FEATURE_WLAN_WAPI
15371 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15372 u16 *tmp;
15373 v_U16_t akmsuiteCount;
15374 int *akmlist;
15375#endif
15376 ENTER();
15377
15378 /* clear previous assocAddIE */
15379 pWextState->assocAddIE.length = 0;
15380 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015381 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015382
15383 while (remLen >= 2)
15384 {
15385 v_U16_t eLen = 0;
15386 v_U8_t elementId;
15387 elementId = *genie++;
15388 eLen = *genie++;
15389 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015390
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015391 /* Sanity check on eLen */
15392 if (eLen > remLen) {
15393 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15394 __func__, eLen, elementId);
15395 VOS_ASSERT(0);
15396 return -EINVAL;
15397 }
15398
Arif Hussain6d2a3322013-11-17 19:50:10 -080015399 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015400 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015401
15402 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015403 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015404 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015405 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 -070015406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015407 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015408 "%s: Invalid WPA IE", __func__);
15409 return -EINVAL;
15410 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015411 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 {
15413 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015414 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015416
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015417 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015419 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15420 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015421 VOS_ASSERT(0);
15422 return -ENOMEM;
15423 }
15424 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15425 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15426 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015427
Jeff Johnson295189b2012-06-20 16:38:30 -070015428 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15429 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15430 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15431 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015432 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15433 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015434 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15435 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15436 __func__, eLen);
15437 VOS_ASSERT(0);
15438 return -EINVAL;
15439 }
15440
Jeff Johnson295189b2012-06-20 16:38:30 -070015441 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15442 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15443 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15444 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15445 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15446 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015447 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015448 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 {
15450 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015451 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015454 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015456 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15457 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015458 VOS_ASSERT(0);
15459 return -ENOMEM;
15460 }
15461 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15462 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15463 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464
Jeff Johnson295189b2012-06-20 16:38:30 -070015465 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15466 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15467 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015468#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015469 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15470 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 /*Consider WFD IE, only for P2P Client */
15472 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15473 {
15474 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015475 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015477
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015478 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015480 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15481 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 VOS_ASSERT(0);
15483 return -ENOMEM;
15484 }
15485 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15486 // WPS IE + P2P IE + WFD IE
15487 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15488 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015489
Jeff Johnson295189b2012-06-20 16:38:30 -070015490 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15491 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15492 }
15493#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015494 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015495 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015496 HS20_OUI_TYPE_SIZE)) )
15497 {
15498 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015499 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015500 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015501
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015502 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015503 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015504 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15505 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015506 VOS_ASSERT(0);
15507 return -ENOMEM;
15508 }
15509 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15510 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015511
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015512 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15513 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15514 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015515 /* Appending OSEN Information Element in Assiciation Request */
15516 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15517 OSEN_OUI_TYPE_SIZE)) )
15518 {
15519 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15520 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15521 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015522
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015523 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015524 {
15525 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15526 "Need bigger buffer space");
15527 VOS_ASSERT(0);
15528 return -ENOMEM;
15529 }
15530 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15531 pWextState->assocAddIE.length += eLen + 2;
15532
15533 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15534 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15535 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15536 }
15537
Abhishek Singh4322e622015-06-10 15:42:54 +053015538 /* Update only for WPA IE */
15539 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15540 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015541
15542 /* populating as ADDIE in beacon frames */
15543 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015544 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015545 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15546 {
15547 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15548 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15549 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15550 {
15551 hddLog(LOGE,
15552 "Coldn't pass "
15553 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15554 }
15555 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15556 else
15557 hddLog(LOGE,
15558 "Could not pass on "
15559 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15560
15561 /* IBSS mode doesn't contain params->proberesp_ies still
15562 beaconIE's need to be populated in probe response frames */
15563 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15564 {
15565 u16 rem_probe_resp_ie_len = eLen + 2;
15566 u8 probe_rsp_ie_len[3] = {0};
15567 u8 counter = 0;
15568
15569 /* Check Probe Resp Length if it is greater then 255 then
15570 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15571 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15572 not able Store More then 255 bytes into One Variable */
15573
15574 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15575 {
15576 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15577 {
15578 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15579 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15580 }
15581 else
15582 {
15583 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15584 rem_probe_resp_ie_len = 0;
15585 }
15586 }
15587
15588 rem_probe_resp_ie_len = 0;
15589
15590 if (probe_rsp_ie_len[0] > 0)
15591 {
15592 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15593 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15594 (tANI_U8*)(genie - 2),
15595 probe_rsp_ie_len[0], NULL,
15596 eANI_BOOLEAN_FALSE)
15597 == eHAL_STATUS_FAILURE)
15598 {
15599 hddLog(LOGE,
15600 "Could not pass"
15601 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15602 }
15603 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15604 }
15605
15606 if (probe_rsp_ie_len[1] > 0)
15607 {
15608 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15609 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15610 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15611 probe_rsp_ie_len[1], NULL,
15612 eANI_BOOLEAN_FALSE)
15613 == eHAL_STATUS_FAILURE)
15614 {
15615 hddLog(LOGE,
15616 "Could not pass"
15617 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15618 }
15619 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15620 }
15621
15622 if (probe_rsp_ie_len[2] > 0)
15623 {
15624 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15625 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15626 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15627 probe_rsp_ie_len[2], NULL,
15628 eANI_BOOLEAN_FALSE)
15629 == eHAL_STATUS_FAILURE)
15630 {
15631 hddLog(LOGE,
15632 "Could not pass"
15633 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15634 }
15635 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15636 }
15637
15638 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15639 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15640 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15641 {
15642 hddLog(LOGE,
15643 "Could not pass"
15644 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15645 }
15646 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015647 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015648 break;
15649 case DOT11F_EID_RSN:
15650 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15651 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15652 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15653 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15654 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15655 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015656
Abhishek Singhb16f3562016-01-20 11:08:32 +053015657 /* Appending extended capabilities with Interworking or
15658 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015659 *
15660 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015661 * interworkingService or bsstransition bit is set to 1.
15662 * Driver is only interested in interworkingService and
15663 * bsstransition capability from supplicant.
15664 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015665 * required from supplicat, it needs to be handled while
15666 * sending Assoc Req in LIM.
15667 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015668 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015669 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015670 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015671 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015672 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015673
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015674 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015675 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015676 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15677 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015678 VOS_ASSERT(0);
15679 return -ENOMEM;
15680 }
15681 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15682 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015683
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015684 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15685 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15686 break;
15687 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015688#ifdef FEATURE_WLAN_WAPI
15689 case WLAN_EID_WAPI:
15690 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015691 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 pAdapter->wapi_info.nWapiMode);
15693 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015694 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015695 akmsuiteCount = WPA_GET_LE16(tmp);
15696 tmp = tmp + 1;
15697 akmlist = (int *)(tmp);
15698 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15699 {
15700 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15701 }
15702 else
15703 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015704 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015705 VOS_ASSERT(0);
15706 return -EINVAL;
15707 }
15708
15709 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15710 {
15711 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015712 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015714 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015716 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015718 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015719 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15720 }
15721 break;
15722#endif
15723 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015724 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015725 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015726 /* when Unknown IE is received we should break and continue
15727 * to the next IE in the buffer instead we were returning
15728 * so changing this to break */
15729 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015730 }
15731 genie += eLen;
15732 remLen -= eLen;
15733 }
15734 EXIT();
15735 return 0;
15736}
15737
15738/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015739 * FUNCTION: hdd_isWPAIEPresent
15740 * Parse the received IE to find the WPA IE
15741 *
15742 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015743static bool hdd_isWPAIEPresent(
15744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15745 const u8 *ie,
15746#else
15747 u8 *ie,
15748#endif
15749 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015750{
15751 v_U8_t eLen = 0;
15752 v_U16_t remLen = ie_len;
15753 v_U8_t elementId = 0;
15754
15755 while (remLen >= 2)
15756 {
15757 elementId = *ie++;
15758 eLen = *ie++;
15759 remLen -= 2;
15760 if (eLen > remLen)
15761 {
15762 hddLog(VOS_TRACE_LEVEL_ERROR,
15763 "%s: IE length is wrong %d", __func__, eLen);
15764 return FALSE;
15765 }
15766 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15767 {
15768 /* OUI - 0x00 0X50 0XF2
15769 WPA Information Element - 0x01
15770 WPA version - 0x01*/
15771 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15772 return TRUE;
15773 }
15774 ie += eLen;
15775 remLen -= eLen;
15776 }
15777 return FALSE;
15778}
15779
15780/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015781 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015782 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 * parameters during connect operation.
15784 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015785int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015786 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015787 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015788{
15789 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015790 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015791 ENTER();
15792
15793 /*set wpa version*/
15794 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15795
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015796 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015798 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 {
15800 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15801 }
15802 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15803 {
15804 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15805 }
15806 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015807
15808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015809 pWextState->wpaVersion);
15810
15811 /*set authentication type*/
15812 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15813
15814 if (0 > status)
15815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 "%s: failed to set authentication type ", __func__);
15818 return status;
15819 }
15820
15821 /*set key mgmt type*/
15822 if (req->crypto.n_akm_suites)
15823 {
15824 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15825 if (0 > status)
15826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 __func__);
15829 return status;
15830 }
15831 }
15832
15833 /*set pairwise cipher type*/
15834 if (req->crypto.n_ciphers_pairwise)
15835 {
15836 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15837 req->crypto.ciphers_pairwise[0], true);
15838 if (0 > status)
15839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015840 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015841 "%s: failed to set unicast cipher type", __func__);
15842 return status;
15843 }
15844 }
15845 else
15846 {
15847 /*Reset previous cipher suite to none*/
15848 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15849 if (0 > status)
15850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015851 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015852 "%s: failed to set unicast cipher type", __func__);
15853 return status;
15854 }
15855 }
15856
15857 /*set group cipher type*/
15858 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15859 false);
15860
15861 if (0 > status)
15862 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015864 __func__);
15865 return status;
15866 }
15867
Chet Lanctot186b5732013-03-18 10:26:30 -070015868#ifdef WLAN_FEATURE_11W
15869 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15870#endif
15871
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15873 if (req->ie_len)
15874 {
15875 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15876 if ( 0 > status)
15877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015879 __func__);
15880 return status;
15881 }
15882 }
15883
15884 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015885 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 {
15887 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
15888 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
15889 )
15890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
15893 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 __func__);
15896 return -EOPNOTSUPP;
15897 }
15898 else
15899 {
15900 u8 key_len = req->key_len;
15901 u8 key_idx = req->key_idx;
15902
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015903 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015904 && (CSR_MAX_NUM_KEY > key_idx)
15905 )
15906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015907 hddLog(VOS_TRACE_LEVEL_INFO,
15908 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015909 __func__, key_idx, key_len);
15910 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015911 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070015912 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015913 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015914 (u8)key_len;
15915 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
15916 }
15917 }
15918 }
15919 }
15920
15921 return status;
15922}
15923
15924/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015925 * FUNCTION: wlan_hdd_try_disconnect
15926 * This function is used to disconnect from previous
15927 * connection
15928 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053015929int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015930{
15931 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015932 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015933 hdd_station_ctx_t *pHddStaCtx;
15934 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015936
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015937 ret = wlan_hdd_validate_context(pHddCtx);
15938 if (0 != ret)
15939 {
15940 return ret;
15941 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15943
15944 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
15945
15946 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
15947 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053015948 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015949 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
15950 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053015951 /* Indicate disconnect to SME so that in-progress connection or preauth
15952 * can be aborted
15953 */
15954 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
15955 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053015956 spin_lock_bh(&pAdapter->lock_for_active_session);
15957 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15958 {
15959 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15960 }
15961 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053015962 hdd_connSetConnectionState(pHddStaCtx,
15963 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015964 /* Issue disconnect to CSR */
15965 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015966 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015967 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015968 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15969 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
15970 hddLog(LOG1,
15971 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
15972 } else if ( 0 != status ) {
15973 hddLog(LOGE,
15974 FL("csrRoamDisconnect failure, returned %d"),
15975 (int)status );
15976 result = -EINVAL;
15977 goto disconnected;
15978 }
15979 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015980 &pAdapter->disconnect_comp_var,
15981 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015982 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
15983 hddLog(LOGE,
15984 "%s: Failed to disconnect, timed out", __func__);
15985 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015986 }
15987 }
15988 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
15989 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015990 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015991 &pAdapter->disconnect_comp_var,
15992 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015993 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015994 {
15995 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015996 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015997 }
15998 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015999disconnected:
16000 hddLog(LOG1,
16001 FL("Set HDD connState to eConnectionState_NotConnected"));
16002 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16003 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016004}
16005
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016006/**
16007 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16008 * @adapter: Pointer to the HDD adapter
16009 * @req: Pointer to the structure cfg_connect_params receieved from user space
16010 *
16011 * This function will start reassociation if bssid hint, channel hint and
16012 * previous bssid parameters are present in the connect request
16013 *
16014 * Return: success if reassociation is happening
16015 * Error code if reassociation is not permitted or not happening
16016 */
16017#ifdef CFG80211_CONNECT_PREV_BSSID
16018static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16019 struct cfg80211_connect_params *req)
16020{
16021 int status = -EPERM;
16022 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16023 hddLog(VOS_TRACE_LEVEL_INFO,
16024 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16025 req->channel_hint->hw_value,
16026 MAC_ADDR_ARRAY(req->bssid_hint));
16027 status = hdd_reassoc(adapter, req->bssid_hint,
16028 req->channel_hint->hw_value,
16029 CONNECT_CMD_USERSPACE);
16030 }
16031 return status;
16032}
16033#else
16034static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16035 struct cfg80211_connect_params *req)
16036{
16037 return -EPERM;
16038}
16039#endif
16040
Abhishek Singhe3beee22017-07-31 15:35:40 +053016041/**
16042 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16043 * connect in HT20 mode
16044 * @hdd_ctx: hdd context
16045 * @adapter: Pointer to the HDD adapter
16046 * @req: Pointer to the structure cfg_connect_params receieved from user space
16047 *
16048 * This function will check if supplicant has indicated to to connect in HT20
16049 * mode. this is currently applicable only for 2.4Ghz mode only.
16050 * if feature is enabled and supplicant indicate HT20 set
16051 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16052 *
16053 * Return: void
16054 */
16055#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16056static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16057 hdd_adapter_t *adapter,
16058 struct cfg80211_connect_params *req)
16059{
16060 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16061 tCsrRoamProfile *roam_profile;
16062
16063 roam_profile = &wext_state->roamProfile;
16064 roam_profile->force_24ghz_in_ht20 = false;
16065 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16066 !(req->ht_capa.cap_info &
16067 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16068 roam_profile->force_24ghz_in_ht20 = true;
16069
16070 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16071 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16072}
16073#else
16074static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16075 hdd_adapter_t *adapter,
16076 struct cfg80211_connect_params *req)
16077{
16078 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16079 tCsrRoamProfile *roam_profile;
16080
16081 roam_profile = &wext_state->roamProfile;
16082 roam_profile->force_24ghz_in_ht20 = false;
16083}
16084#endif
16085
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016086/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016087 * FUNCTION: __wlan_hdd_cfg80211_connect
16088 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016090static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 struct net_device *ndev,
16092 struct cfg80211_connect_params *req
16093 )
16094{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016095 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016096 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16098 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016099 const u8 *bssid_hint = req->bssid_hint;
16100#else
16101 const u8 *bssid_hint = NULL;
16102#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016104 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016105 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016106
16107 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016108
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016109 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16110 TRACE_CODE_HDD_CFG80211_CONNECT,
16111 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016112 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016113 "%s: device_mode = %s (%d)", __func__,
16114 hdd_device_modetoString(pAdapter->device_mode),
16115 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016116
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016117 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016118 if (!pHddCtx)
16119 {
16120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16121 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016122 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016123 }
16124
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016125 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016126 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016128 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016129 }
16130
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016131 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16132 return -EINVAL;
16133
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016134 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16135 if (0 == status)
16136 return status;
16137
Agarwal Ashish51325b52014-06-16 16:50:49 +053016138
Jeff Johnson295189b2012-06-20 16:38:30 -070016139#ifdef WLAN_BTAMP_FEATURE
16140 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016141 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016142 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016143 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016144 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016145 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 }
16147#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016148
16149 //If Device Mode is Station Concurrent Sessions Exit BMps
16150 //P2P Mode will be taken care in Open/close adapter
16151 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016152 (vos_concurrent_open_sessions_running())) {
16153 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16154 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016155 }
16156
16157 /*Try disconnecting if already in connected state*/
16158 status = wlan_hdd_try_disconnect(pAdapter);
16159 if ( 0 > status)
16160 {
16161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16162 " connection"));
16163 return -EALREADY;
16164 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016165 /* Check for max concurrent connections after doing disconnect if any*/
16166 if (vos_max_concurrent_connections_reached()) {
16167 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16168 return -ECONNREFUSED;
16169 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016170
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016172 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016173
16174 if ( 0 > status)
16175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 __func__);
16178 return status;
16179 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016180
16181 if (pHddCtx->spoofMacAddr.isEnabled)
16182 {
16183 hddLog(VOS_TRACE_LEVEL_INFO,
16184 "%s: MAC Spoofing enabled ", __func__);
16185 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16186 * to fill TxBds for probe request during SSID scan which may happen
16187 * as part of connect command
16188 */
16189 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16190 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16191 if (status != VOS_STATUS_SUCCESS)
16192 return -ECONNREFUSED;
16193 }
16194
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016195 if (req->channel)
16196 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016197 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016198 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016199
16200 /* Abort if any scan is going on */
16201 status = wlan_hdd_scan_abort(pAdapter);
16202 if (0 != status)
16203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16204
Abhishek Singhe3beee22017-07-31 15:35:40 +053016205 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16206
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016207 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16208 req->ssid_len, req->bssid,
16209 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016210
Sushant Kaushikd7083982015-03-18 14:33:24 +053016211 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 {
16213 //ReEnable BMPS if disabled
16214 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16215 (NULL != pHddCtx))
16216 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016217 if (pHddCtx->hdd_wlan_suspended)
16218 {
16219 hdd_set_pwrparams(pHddCtx);
16220 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016221 //ReEnable Bmps and Imps back
16222 hdd_enable_bmps_imps(pHddCtx);
16223 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016225 return status;
16226 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016227 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016228 EXIT();
16229 return status;
16230}
16231
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016232static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16233 struct net_device *ndev,
16234 struct cfg80211_connect_params *req)
16235{
16236 int ret;
16237 vos_ssr_protect(__func__);
16238 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16239 vos_ssr_unprotect(__func__);
16240
16241 return ret;
16242}
Jeff Johnson295189b2012-06-20 16:38:30 -070016243
16244/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016245 * FUNCTION: wlan_hdd_disconnect
16246 * This function is used to issue a disconnect request to SME
16247 */
16248int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
16249{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016250 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016251 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016253 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016254 eConnectionState prev_conn_state;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016255 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016257 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016259 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016260 if (0 != status)
16261 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016262 return status;
16263 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053016264 /* Indicate sme of disconnect so that in progress connection or preauth
16265 * can be aborted
16266 */
16267 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053016268 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016269 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016270
Agarwal Ashish47d18112014-08-04 19:55:07 +053016271 /* Need to apply spin lock before decreasing active sessions
16272 * as there can be chance for double decrement if context switch
16273 * Calls hdd_DisConnectHandler.
16274 */
16275
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016276 prev_conn_state = pHddStaCtx->conn_info.connState;
16277
Agarwal Ashish47d18112014-08-04 19:55:07 +053016278 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016279 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16280 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016281 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16282 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053016283 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
16284 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053016285 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016286
Abhishek Singhf4669da2014-05-26 15:07:49 +053016287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053016288 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
16289
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016290 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016291
Mihir Shete182a0b22014-08-18 16:08:48 +053016292 /*
16293 * stop tx queues before deleting STA/BSS context from the firmware.
16294 * tx has to be disabled because the firmware can get busy dropping
16295 * the tx frames after BSS/STA has been deleted and will not send
16296 * back a response resulting in WDI timeout
16297 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053016298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053016299 netif_tx_disable(pAdapter->dev);
16300 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016301
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016302 wlan_hdd_check_and_stop_mon(pAdapter, true);
16303
Mihir Shete182a0b22014-08-18 16:08:48 +053016304 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016305 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
16306 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016307 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
16308 prev_conn_state != eConnectionState_Connecting)
16309 {
16310 hddLog(LOG1,
16311 FL("status = %d, already disconnected"), status);
16312 result = 0;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016313 /*
16314 * Wait here instead of returning directly. This will block the
16315 * next connect command and allow processing of the disconnect
16316 * in SME else we might hit some race conditions leading to SME
16317 * and HDD out of sync. As disconnect is already in progress,
16318 * wait here for 1 sec instead of 5 sec.
16319 */
16320 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
16321 goto wait_for_disconnect;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016322 }
16323 /*
16324 * Wait here instead of returning directly, this will block the next
16325 * connect command and allow processing of the scan for ssid and
16326 * the previous connect command in CSR. Else we might hit some
16327 * race conditions leading to SME and HDD out of sync.
16328 */
16329 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016330 {
16331 hddLog(LOG1,
16332 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016333 }
16334 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016335 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016336 hddLog(LOGE,
16337 FL("csrRoamDisconnect failure, returned %d"),
16338 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016339 result = -EINVAL;
16340 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016341 }
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016342wait_for_disconnect:
16343 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
16344 msecs_to_jiffies(wait_time));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016345 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016346 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016347 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016348 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016349 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016350 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016351disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016352 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016353 FL("Set HDD connState to eConnectionState_NotConnected"));
16354 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016355#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
16356 /* Sending disconnect event to userspace for kernel version < 3.11
16357 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
16358 */
16359 hddLog(LOG1, FL("Send disconnected event to userspace"));
16360
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053016361 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016362 WLAN_REASON_UNSPECIFIED);
16363#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016365 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016366 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016367}
16368
16369
16370/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016371 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016372 * This function is used to issue a disconnect request to SME
16373 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016374static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016375 struct net_device *dev,
16376 u16 reason
16377 )
16378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016380 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016381 tCsrRoamProfile *pRoamProfile;
16382 hdd_station_ctx_t *pHddStaCtx;
16383 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016384#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016385 tANI_U8 staIdx;
16386#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016387
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016389
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016390 if (!pAdapter) {
16391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16392 return -EINVAL;
16393 }
16394
16395 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16396 if (!pHddStaCtx) {
16397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16398 return -EINVAL;
16399 }
16400
16401 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16402 status = wlan_hdd_validate_context(pHddCtx);
16403 if (0 != status)
16404 {
16405 return status;
16406 }
16407
16408 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16409
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16411 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16412 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016413 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16414 __func__, hdd_device_modetoString(pAdapter->device_mode),
16415 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016416
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16418 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016419
Jeff Johnson295189b2012-06-20 16:38:30 -070016420 if (NULL != pRoamProfile)
16421 {
16422 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016423 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16424 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016426 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016427 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016428 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016429 switch(reason)
16430 {
16431 case WLAN_REASON_MIC_FAILURE:
16432 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16433 break;
16434
16435 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16436 case WLAN_REASON_DISASSOC_AP_BUSY:
16437 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16438 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16439 break;
16440
16441 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16442 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016443 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016444 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16445 break;
16446
Jeff Johnson295189b2012-06-20 16:38:30 -070016447 default:
16448 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16449 break;
16450 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016451 pScanInfo = &pHddCtx->scan_info;
16452 if (pScanInfo->mScanPending)
16453 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016454 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016455 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016456 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016457 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016458 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016459 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016460#ifdef FEATURE_WLAN_TDLS
16461 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016462 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016463 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016464 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16465 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016466 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016467 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016468 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016470 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016471 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016472 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016473 status = sme_DeleteTdlsPeerSta(
16474 WLAN_HDD_GET_HAL_CTX(pAdapter),
16475 pAdapter->sessionId,
16476 mac);
16477 if (status != eHAL_STATUS_SUCCESS) {
16478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16479 return -EPERM;
16480 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016481 }
16482 }
16483#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016484
16485 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16486 reasonCode,
16487 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016488 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16489 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016490 {
16491 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016492 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016493 __func__, (int)status );
16494 return -EINVAL;
16495 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016496 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016497 else
16498 {
16499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16500 "called while in %d state", __func__,
16501 pHddStaCtx->conn_info.connState);
16502 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016503 }
16504 else
16505 {
16506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16507 }
16508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016509 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 return status;
16511}
16512
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016513static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16514 struct net_device *dev,
16515 u16 reason
16516 )
16517{
16518 int ret;
16519 vos_ssr_protect(__func__);
16520 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16521 vos_ssr_unprotect(__func__);
16522
16523 return ret;
16524}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016525
Jeff Johnson295189b2012-06-20 16:38:30 -070016526/*
16527 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016528 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 * settings in IBSS mode.
16530 */
16531static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016532 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016533 struct cfg80211_ibss_params *params
16534 )
16535{
16536 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016537 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016538 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16539 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016540
Jeff Johnson295189b2012-06-20 16:38:30 -070016541 ENTER();
16542
16543 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016544 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016545
16546 if (params->ie_len && ( NULL != params->ie) )
16547 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016548 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16549 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016550 {
16551 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16552 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16553 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016554 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016555 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016556 tDot11fIEWPA dot11WPAIE;
16557 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016558 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016559
Wilson Yang00256342013-10-10 23:13:38 -070016560 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016561 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16562 params->ie_len, DOT11F_EID_WPA);
16563 if ( NULL != ie )
16564 {
16565 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16566 // Unpack the WPA IE
16567 //Skip past the EID byte and length byte - and four byte WiFi OUI
16568 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16569 &ie[2+4],
16570 ie[1] - 4,
16571 &dot11WPAIE);
16572 /*Extract the multicast cipher, the encType for unicast
16573 cipher for wpa-none is none*/
16574 encryptionType =
16575 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16576 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016578
Jeff Johnson295189b2012-06-20 16:38:30 -070016579 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16580
16581 if (0 > status)
16582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016584 __func__);
16585 return status;
16586 }
16587 }
16588
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016589 pWextState->roamProfile.AuthType.authType[0] =
16590 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016591 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16592
16593 if (params->privacy)
16594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016595 /* Security enabled IBSS, At this time there is no information available
16596 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016597 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016598 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016600 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 *enable privacy bit in beacons */
16602
16603 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16604 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016605 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16606 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16608 pWextState->roamProfile.EncryptionType.numEntries = 1;
16609 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 return status;
16611}
16612
16613/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016614 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016615 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016616 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016617static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 struct net_device *dev,
16619 struct cfg80211_ibss_params *params
16620 )
16621{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016622 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016623 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16624 tCsrRoamProfile *pRoamProfile;
16625 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016626 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16627 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016628 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016629
16630 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16633 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16634 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016635 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016636 "%s: device_mode = %s (%d)", __func__,
16637 hdd_device_modetoString(pAdapter->device_mode),
16638 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016639
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016641 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016643 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016644 }
16645
16646 if (NULL == pWextState)
16647 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016648 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016649 __func__);
16650 return -EIO;
16651 }
16652
Agarwal Ashish51325b52014-06-16 16:50:49 +053016653 if (vos_max_concurrent_connections_reached()) {
16654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16655 return -ECONNREFUSED;
16656 }
16657
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016658 /*Try disconnecting if already in connected state*/
16659 status = wlan_hdd_try_disconnect(pAdapter);
16660 if ( 0 > status)
16661 {
16662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16663 " IBSS connection"));
16664 return -EALREADY;
16665 }
16666
Jeff Johnson295189b2012-06-20 16:38:30 -070016667 pRoamProfile = &pWextState->roamProfile;
16668
16669 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016671 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016672 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016673 return -EINVAL;
16674 }
16675
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016676 /* BSSID is provided by upper layers hence no need to AUTO generate */
16677 if (NULL != params->bssid) {
16678 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16679 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16680 hddLog (VOS_TRACE_LEVEL_ERROR,
16681 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16682 return -EIO;
16683 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016684 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016685 }
krunal sonie9002db2013-11-25 14:24:17 -080016686 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16687 {
16688 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16689 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16690 {
16691 hddLog (VOS_TRACE_LEVEL_ERROR,
16692 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16693 return -EIO;
16694 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016695
16696 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016697 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016698 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016699 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016700
Jeff Johnson295189b2012-06-20 16:38:30 -070016701 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016702 if (NULL !=
16703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16704 params->chandef.chan)
16705#else
16706 params->channel)
16707#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016708 {
16709 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016710 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16711 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16712 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16713 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016714
16715 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016716 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016717 ieee80211_frequency_to_channel(
16718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16719 params->chandef.chan->center_freq);
16720#else
16721 params->channel->center_freq);
16722#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016723
16724 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16725 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016726 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16728 __func__);
16729 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016730 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016731
16732 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016733 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016734 if (channelNum == validChan[indx])
16735 {
16736 break;
16737 }
16738 }
16739 if (indx >= numChans)
16740 {
16741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016742 __func__, channelNum);
16743 return -EINVAL;
16744 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016745 /* Set the Operational Channel */
16746 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16747 channelNum);
16748 pRoamProfile->ChannelInfo.numOfChannels = 1;
16749 pHddStaCtx->conn_info.operationChannel = channelNum;
16750 pRoamProfile->ChannelInfo.ChannelList =
16751 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016752 }
16753
16754 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016755 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016756 if (status < 0)
16757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016759 __func__);
16760 return status;
16761 }
16762
16763 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016764 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016765 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016766 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016767
16768 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016770
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016771 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016772 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016773}
16774
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016775static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16776 struct net_device *dev,
16777 struct cfg80211_ibss_params *params
16778 )
16779{
16780 int ret = 0;
16781
16782 vos_ssr_protect(__func__);
16783 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16784 vos_ssr_unprotect(__func__);
16785
16786 return ret;
16787}
16788
Jeff Johnson295189b2012-06-20 16:38:30 -070016789/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016790 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016791 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016793static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016794 struct net_device *dev
16795 )
16796{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016797 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016798 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16799 tCsrRoamProfile *pRoamProfile;
16800 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016801 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016802 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016803#ifdef WLAN_FEATURE_RMC
16804 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16805#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016806
16807 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016808
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016809 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16810 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16811 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016812 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016813 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016815 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016816 }
16817
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16819 hdd_device_modetoString(pAdapter->device_mode),
16820 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016821 if (NULL == pWextState)
16822 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016823 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016824 __func__);
16825 return -EIO;
16826 }
16827
16828 pRoamProfile = &pWextState->roamProfile;
16829
16830 /* Issue disconnect only if interface type is set to IBSS */
16831 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016833 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 __func__);
16835 return -EINVAL;
16836 }
16837
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016838#ifdef WLAN_FEATURE_RMC
16839 /* Clearing add IE of beacon */
16840 if (ccmCfgSetStr(pHddCtx->hHal,
16841 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16842 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16843 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16844 {
16845 hddLog (VOS_TRACE_LEVEL_ERROR,
16846 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16847 return -EINVAL;
16848 }
16849 if (ccmCfgSetInt(pHddCtx->hHal,
16850 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16851 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16852 {
16853 hddLog (VOS_TRACE_LEVEL_ERROR,
16854 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16855 __func__);
16856 return -EINVAL;
16857 }
16858
16859 // Reset WNI_CFG_PROBE_RSP Flags
16860 wlan_hdd_reset_prob_rspies(pAdapter);
16861
16862 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16863 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16864 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16865 {
16866 hddLog (VOS_TRACE_LEVEL_ERROR,
16867 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16868 __func__);
16869 return -EINVAL;
16870 }
16871#endif
16872
Jeff Johnson295189b2012-06-20 16:38:30 -070016873 /* Issue Disconnect request */
16874 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016875 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16876 pAdapter->sessionId,
16877 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16878 if (!HAL_STATUS_SUCCESS(hal_status)) {
16879 hddLog(LOGE,
16880 FL("sme_RoamDisconnect failed hal_status(%d)"),
16881 hal_status);
16882 return -EAGAIN;
16883 }
16884 status = wait_for_completion_timeout(
16885 &pAdapter->disconnect_comp_var,
16886 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16887 if (!status) {
16888 hddLog(LOGE,
16889 FL("wait on disconnect_comp_var failed"));
16890 return -ETIMEDOUT;
16891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016892
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016893 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016894 return 0;
16895}
16896
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016897static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
16898 struct net_device *dev
16899 )
16900{
16901 int ret = 0;
16902
16903 vos_ssr_protect(__func__);
16904 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
16905 vos_ssr_unprotect(__func__);
16906
16907 return ret;
16908}
16909
Jeff Johnson295189b2012-06-20 16:38:30 -070016910/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016911 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070016912 * This function is used to set the phy parameters
16913 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
16914 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016915static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016916 u32 changed)
16917{
16918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16919 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016920 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016921
16922 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016923
16924 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016925 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
16926 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016928 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016929 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016930 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016931 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016932 }
16933
Jeff Johnson295189b2012-06-20 16:38:30 -070016934 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
16935 {
16936 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
16937 WNI_CFG_RTS_THRESHOLD_STAMAX :
16938 wiphy->rts_threshold;
16939
16940 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016941 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070016942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016943 hddLog(VOS_TRACE_LEVEL_ERROR,
16944 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016945 __func__, rts_threshold);
16946 return -EINVAL;
16947 }
16948
16949 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
16950 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016951 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016953 hddLog(VOS_TRACE_LEVEL_ERROR,
16954 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016955 __func__, rts_threshold);
16956 return -EIO;
16957 }
16958
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016959 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016960 rts_threshold);
16961 }
16962
16963 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
16964 {
16965 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
16966 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
16967 wiphy->frag_threshold;
16968
16969 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016970 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016971 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016972 hddLog(VOS_TRACE_LEVEL_ERROR,
16973 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 frag_threshold);
16975 return -EINVAL;
16976 }
16977
16978 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
16979 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016980 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016982 hddLog(VOS_TRACE_LEVEL_ERROR,
16983 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016984 __func__, frag_threshold);
16985 return -EIO;
16986 }
16987
16988 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
16989 frag_threshold);
16990 }
16991
16992 if ((changed & WIPHY_PARAM_RETRY_SHORT)
16993 || (changed & WIPHY_PARAM_RETRY_LONG))
16994 {
16995 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
16996 wiphy->retry_short :
16997 wiphy->retry_long;
16998
16999 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17000 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017003 __func__, retry_value);
17004 return -EINVAL;
17005 }
17006
17007 if (changed & WIPHY_PARAM_RETRY_SHORT)
17008 {
17009 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17010 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017011 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017013 hddLog(VOS_TRACE_LEVEL_ERROR,
17014 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017015 __func__, retry_value);
17016 return -EIO;
17017 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017018 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 __func__, retry_value);
17020 }
17021 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17022 {
17023 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17024 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017025 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017027 hddLog(VOS_TRACE_LEVEL_ERROR,
17028 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 __func__, retry_value);
17030 return -EIO;
17031 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017032 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017033 __func__, retry_value);
17034 }
17035 }
17036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017037 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017038 return 0;
17039}
17040
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017041static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17042 u32 changed)
17043{
17044 int ret;
17045
17046 vos_ssr_protect(__func__);
17047 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17048 vos_ssr_unprotect(__func__);
17049
17050 return ret;
17051}
17052
Jeff Johnson295189b2012-06-20 16:38:30 -070017053/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017054 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017055 * This function is used to set the txpower
17056 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017057static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017058#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17059 struct wireless_dev *wdev,
17060#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017061#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017062 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017063#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017064 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017065#endif
17066 int dbm)
17067{
17068 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017069 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17071 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017072 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017073
17074 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017075
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017076 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17077 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17078 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017079 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017080 if (0 != status)
17081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017082 return status;
17083 }
17084
17085 hHal = pHddCtx->hHal;
17086
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017087 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17088 dbm, ccmCfgSetCallback,
17089 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017091 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017092 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17093 return -EIO;
17094 }
17095
17096 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17097 dbm);
17098
17099 switch(type)
17100 {
17101 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17102 /* Fall through */
17103 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17104 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17107 __func__);
17108 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017109 }
17110 break;
17111 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017113 __func__);
17114 return -EOPNOTSUPP;
17115 break;
17116 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17118 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017119 return -EIO;
17120 }
17121
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017122 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017123 return 0;
17124}
17125
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017126static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17127#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17128 struct wireless_dev *wdev,
17129#endif
17130#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17131 enum tx_power_setting type,
17132#else
17133 enum nl80211_tx_power_setting type,
17134#endif
17135 int dbm)
17136{
17137 int ret;
17138 vos_ssr_protect(__func__);
17139 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17140#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17141 wdev,
17142#endif
17143#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17144 type,
17145#else
17146 type,
17147#endif
17148 dbm);
17149 vos_ssr_unprotect(__func__);
17150
17151 return ret;
17152}
17153
Jeff Johnson295189b2012-06-20 16:38:30 -070017154/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017155 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017156 * This function is used to read the txpower
17157 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017158static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017159#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17160 struct wireless_dev *wdev,
17161#endif
17162 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017163{
17164
17165 hdd_adapter_t *pAdapter;
17166 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017167 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017168
Jeff Johnsone7245742012-09-05 17:12:55 -070017169 ENTER();
17170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017171 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017172 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017174 *dbm = 0;
17175 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017176 }
17177
Jeff Johnson295189b2012-06-20 16:38:30 -070017178 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17179 if (NULL == pAdapter)
17180 {
17181 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17182 return -ENOENT;
17183 }
17184
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17186 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17187 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017188 wlan_hdd_get_classAstats(pAdapter);
17189 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17190
Jeff Johnsone7245742012-09-05 17:12:55 -070017191 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 return 0;
17193}
17194
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017195static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17196#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17197 struct wireless_dev *wdev,
17198#endif
17199 int *dbm)
17200{
17201 int ret;
17202
17203 vos_ssr_protect(__func__);
17204 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17205#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17206 wdev,
17207#endif
17208 dbm);
17209 vos_ssr_unprotect(__func__);
17210
17211 return ret;
17212}
17213
Dustin Brown8c1d4092017-07-28 18:08:01 +053017214/*
17215 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17216 * @stats: summary stats to use as a source
17217 * @info: kernel station_info struct to use as a destination
17218 *
17219 * Return: None
17220 */
17221static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17222 struct station_info *info)
17223{
17224 int i;
17225
17226 info->rx_packets = stats->rx_frm_cnt;
17227 info->tx_packets = 0;
17228 info->tx_retries = 0;
17229 info->tx_failed = 0;
17230
17231 for (i = 0; i < 4; ++i) {
17232 info->tx_packets += stats->tx_frm_cnt[i];
17233 info->tx_retries += stats->multiple_retry_cnt[i];
17234 info->tx_failed += stats->fail_cnt[i];
17235 }
17236
17237 info->filled |= STATION_INFO_TX_PACKETS |
17238 STATION_INFO_TX_RETRIES |
17239 STATION_INFO_TX_FAILED |
17240 STATION_INFO_RX_PACKETS;
17241}
17242
17243/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017244 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17245 * @adapter: sap adapter pointer
17246 * @staid: station id of the client
17247 * @rssi: rssi value to fill
17248 *
17249 * Return: None
17250 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017251void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017252wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17253{
17254 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17255
17256 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17257}
17258
17259/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017260 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17261 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017262 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017263 * @info: kernel station_info struct to populate
17264 *
17265 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17266 * support "station dump" and "station get" for SAP vdevs, even though they
17267 * aren't technically stations.
17268 *
17269 * Return: errno
17270 */
17271static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017272wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17274 const u8* mac,
17275#else
17276 u8* mac,
17277#endif
17278 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017279{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017280 v_MACADDR_t *peerMacAddr;
17281 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017282 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017283 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017284
17285 status = wlan_hdd_get_station_stats(adapter);
17286 if (!VOS_IS_STATUS_SUCCESS(status)) {
17287 hddLog(VOS_TRACE_LEVEL_ERROR,
17288 "Failed to get SAP stats; status:%d", status);
17289 return 0;
17290 }
17291
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017292 peerMacAddr = (v_MACADDR_t *)mac;
17293 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17294 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17295 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17296
17297 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17298 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
17299 info->filled |= STATION_INFO_SIGNAL;
17300 }
17301
Dustin Brown8c1d4092017-07-28 18:08:01 +053017302 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17303
17304 return 0;
17305}
17306
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017307static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17309 const u8* mac,
17310#else
17311 u8* mac,
17312#endif
17313 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017314{
17315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17316 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17317 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017318 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017319
17320 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17321 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017322
17323 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17324 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17325 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17326 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17327 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17328 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17329 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017330 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017331 tANI_U16 myRate;
17332 tANI_U16 currentRate = 0;
17333 tANI_U8 maxSpeedMCS = 0;
17334 tANI_U8 maxMCSIdx = 0;
17335 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017336 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017337 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017338 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017339
Leo Chang6f8870f2013-03-26 18:11:36 -070017340#ifdef WLAN_FEATURE_11AC
17341 tANI_U32 vht_mcs_map;
17342 eDataRate11ACMaxMcs vhtMaxMcs;
17343#endif /* WLAN_FEATURE_11AC */
17344
Jeff Johnsone7245742012-09-05 17:12:55 -070017345 ENTER();
17346
Dustin Brown8c1d4092017-07-28 18:08:01 +053017347 status = wlan_hdd_validate_context(pHddCtx);
17348 if (0 != status)
17349 {
17350 return status;
17351 }
17352
17353 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017354 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017355
Jeff Johnson295189b2012-06-20 16:38:30 -070017356 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17357 (0 == ssidlen))
17358 {
17359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17360 " Invalid ssidlen, %d", __func__, ssidlen);
17361 /*To keep GUI happy*/
17362 return 0;
17363 }
17364
Mukul Sharma811205f2014-07-09 21:07:30 +053017365 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17366 {
17367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17368 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017369 /* return a cached value */
17370 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017371 return 0;
17372 }
17373
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017374 wlan_hdd_get_station_stats(pAdapter);
17375 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017376
Kiet Lam3b17fc82013-09-27 05:24:08 +053017377 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017378 wlan_hdd_get_snr(pAdapter, &snr);
17379 pHddStaCtx->conn_info.signal = sinfo->signal;
17380 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053017381 sinfo->filled |= STATION_INFO_SIGNAL;
17382
c_hpothu09f19542014-05-30 21:53:31 +053017383 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017384 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17385 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017386 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017387 {
17388 rate_flags = pAdapter->maxRateFlags;
17389 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017390
Jeff Johnson295189b2012-06-20 16:38:30 -070017391 //convert to the UI units of 100kbps
17392 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17393
17394#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017395 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 -070017396 sinfo->signal,
17397 pCfg->reportMaxLinkSpeed,
17398 myRate,
17399 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017400 (int) pCfg->linkSpeedRssiMid,
17401 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017402 (int) rate_flags,
17403 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017404#endif //LINKSPEED_DEBUG_ENABLED
17405
17406 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17407 {
17408 // we do not want to necessarily report the current speed
17409 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17410 {
17411 // report the max possible speed
17412 rssidx = 0;
17413 }
17414 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17415 {
17416 // report the max possible speed with RSSI scaling
17417 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17418 {
17419 // report the max possible speed
17420 rssidx = 0;
17421 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017422 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 {
17424 // report middle speed
17425 rssidx = 1;
17426 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017427 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17428 {
17429 // report middle speed
17430 rssidx = 2;
17431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 else
17433 {
17434 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017435 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017436 }
17437 }
17438 else
17439 {
17440 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17441 hddLog(VOS_TRACE_LEVEL_ERROR,
17442 "%s: Invalid value for reportMaxLinkSpeed: %u",
17443 __func__, pCfg->reportMaxLinkSpeed);
17444 rssidx = 0;
17445 }
17446
17447 maxRate = 0;
17448
17449 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017450 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17451 OperationalRates, &ORLeng))
17452 {
17453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17454 /*To keep GUI happy*/
17455 return 0;
17456 }
17457
Jeff Johnson295189b2012-06-20 16:38:30 -070017458 for (i = 0; i < ORLeng; i++)
17459 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017460 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017461 {
17462 /* Validate Rate Set */
17463 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17464 {
17465 currentRate = supported_data_rate[j].supported_rate[rssidx];
17466 break;
17467 }
17468 }
17469 /* Update MAX rate */
17470 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17471 }
17472
17473 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017474 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17475 ExtendedRates, &ERLeng))
17476 {
17477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17478 /*To keep GUI happy*/
17479 return 0;
17480 }
17481
Jeff Johnson295189b2012-06-20 16:38:30 -070017482 for (i = 0; i < ERLeng; i++)
17483 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017484 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017485 {
17486 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17487 {
17488 currentRate = supported_data_rate[j].supported_rate[rssidx];
17489 break;
17490 }
17491 }
17492 /* Update MAX rate */
17493 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17494 }
c_hpothu79aab322014-07-14 21:11:01 +053017495
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017496 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017497 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017498 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017499 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017500 {
c_hpothu79aab322014-07-14 21:11:01 +053017501 if (rate_flags & eHAL_TX_RATE_VHT80)
17502 mode = 2;
17503 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17504 mode = 1;
17505 else
17506 mode = 0;
17507
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017508 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17509 MCSRates, &MCSLeng))
17510 {
17511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17512 /*To keep GUI happy*/
17513 return 0;
17514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017515 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017516#ifdef WLAN_FEATURE_11AC
17517 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017518 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017520 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017521 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017522 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017523 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017524 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017525 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017526 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017527 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017528 maxMCSIdx = 7;
17529 }
17530 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17531 {
17532 maxMCSIdx = 8;
17533 }
17534 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17535 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017536 //VHT20 is supporting 0~8
17537 if (rate_flags & eHAL_TX_RATE_VHT20)
17538 maxMCSIdx = 8;
17539 else
17540 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017541 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017542
c_hpothu79aab322014-07-14 21:11:01 +053017543 if (0 != rssidx)/*check for scaled */
17544 {
17545 //get middle rate MCS index if rssi=1/2
17546 for (i=0; i <= maxMCSIdx; i++)
17547 {
17548 if (sinfo->signal <= rssiMcsTbl[mode][i])
17549 {
17550 maxMCSIdx = i;
17551 break;
17552 }
17553 }
17554 }
17555
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017556 if (rate_flags & eHAL_TX_RATE_VHT80)
17557 {
17558 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17559 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17560 }
17561 else if (rate_flags & eHAL_TX_RATE_VHT40)
17562 {
17563 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17564 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17565 }
17566 else if (rate_flags & eHAL_TX_RATE_VHT20)
17567 {
17568 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17569 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17570 }
17571
Leo Chang6f8870f2013-03-26 18:11:36 -070017572 maxSpeedMCS = 1;
17573 if (currentRate > maxRate)
17574 {
17575 maxRate = currentRate;
17576 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017577
Leo Chang6f8870f2013-03-26 18:11:36 -070017578 }
17579 else
17580#endif /* WLAN_FEATURE_11AC */
17581 {
17582 if (rate_flags & eHAL_TX_RATE_HT40)
17583 {
17584 rateFlag |= 1;
17585 }
17586 if (rate_flags & eHAL_TX_RATE_SGI)
17587 {
17588 rateFlag |= 2;
17589 }
17590
Girish Gowli01abcee2014-07-31 20:18:55 +053017591 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017592 if (rssidx == 1 || rssidx == 2)
17593 {
17594 //get middle rate MCS index if rssi=1/2
17595 for (i=0; i <= 7; i++)
17596 {
17597 if (sinfo->signal <= rssiMcsTbl[mode][i])
17598 {
17599 temp = i+1;
17600 break;
17601 }
17602 }
17603 }
c_hpothu79aab322014-07-14 21:11:01 +053017604
17605 for (i = 0; i < MCSLeng; i++)
17606 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017607 for (j = 0; j < temp; j++)
17608 {
17609 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17610 {
17611 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017612 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017613 break;
17614 }
17615 }
17616 if ((j < temp) && (currentRate > maxRate))
17617 {
17618 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017619 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017621 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017622 }
17623 }
17624
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017625 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17626 {
17627 maxRate = myRate;
17628 maxSpeedMCS = 1;
17629 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17630 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017632 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017633 {
17634 maxRate = myRate;
17635 if (rate_flags & eHAL_TX_RATE_LEGACY)
17636 {
17637 maxSpeedMCS = 0;
17638 }
17639 else
17640 {
17641 maxSpeedMCS = 1;
17642 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17643 }
17644 }
17645
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017646 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017647 {
17648 sinfo->txrate.legacy = maxRate;
17649#ifdef LINKSPEED_DEBUG_ENABLED
17650 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17651#endif //LINKSPEED_DEBUG_ENABLED
17652 }
17653 else
17654 {
17655 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017656#ifdef WLAN_FEATURE_11AC
17657 sinfo->txrate.nss = 1;
17658 if (rate_flags & eHAL_TX_RATE_VHT80)
17659 {
17660 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017661 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017662 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017663 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017664 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017665 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17666 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17667 }
17668 else if (rate_flags & eHAL_TX_RATE_VHT20)
17669 {
17670 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17671 }
17672#endif /* WLAN_FEATURE_11AC */
17673 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17674 {
17675 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17676 if (rate_flags & eHAL_TX_RATE_HT40)
17677 {
17678 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17679 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017681 if (rate_flags & eHAL_TX_RATE_SGI)
17682 {
17683 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17684 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017685
Jeff Johnson295189b2012-06-20 16:38:30 -070017686#ifdef LINKSPEED_DEBUG_ENABLED
17687 pr_info("Reporting MCS rate %d flags %x\n",
17688 sinfo->txrate.mcs,
17689 sinfo->txrate.flags );
17690#endif //LINKSPEED_DEBUG_ENABLED
17691 }
17692 }
17693 else
17694 {
17695 // report current rate instead of max rate
17696
17697 if (rate_flags & eHAL_TX_RATE_LEGACY)
17698 {
17699 //provide to the UI in units of 100kbps
17700 sinfo->txrate.legacy = myRate;
17701#ifdef LINKSPEED_DEBUG_ENABLED
17702 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17703#endif //LINKSPEED_DEBUG_ENABLED
17704 }
17705 else
17706 {
17707 //must be MCS
17708 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017709#ifdef WLAN_FEATURE_11AC
17710 sinfo->txrate.nss = 1;
17711 if (rate_flags & eHAL_TX_RATE_VHT80)
17712 {
17713 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17714 }
17715 else
17716#endif /* WLAN_FEATURE_11AC */
17717 {
17718 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17719 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 if (rate_flags & eHAL_TX_RATE_SGI)
17721 {
17722 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17723 }
17724 if (rate_flags & eHAL_TX_RATE_HT40)
17725 {
17726 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17727 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017728#ifdef WLAN_FEATURE_11AC
17729 else if (rate_flags & eHAL_TX_RATE_VHT80)
17730 {
17731 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17732 }
17733#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017734#ifdef LINKSPEED_DEBUG_ENABLED
17735 pr_info("Reporting actual MCS rate %d flags %x\n",
17736 sinfo->txrate.mcs,
17737 sinfo->txrate.flags );
17738#endif //LINKSPEED_DEBUG_ENABLED
17739 }
17740 }
17741 sinfo->filled |= STATION_INFO_TX_BITRATE;
17742
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017743 sinfo->tx_packets =
17744 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17745 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17746 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17747 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17748
17749 sinfo->tx_retries =
17750 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17751 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17752 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17753 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17754
17755 sinfo->tx_failed =
17756 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17757 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17758 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17759 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17760
17761 sinfo->filled |=
17762 STATION_INFO_TX_PACKETS |
17763 STATION_INFO_TX_RETRIES |
17764 STATION_INFO_TX_FAILED;
17765
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017766 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17767 sinfo->filled |= STATION_INFO_RX_PACKETS;
17768
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017769 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17770 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017771 if (rate_flags & eHAL_TX_RATE_LEGACY)
17772 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17773 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17774 sinfo->rx_packets);
17775 else
17776 hddLog(LOG1,
17777 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17778 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17779 sinfo->tx_packets, sinfo->rx_packets);
17780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17782 TRACE_CODE_HDD_CFG80211_GET_STA,
17783 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017784 EXIT();
17785 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017786}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17788static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17789 const u8* mac, struct station_info *sinfo)
17790#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017791static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17792 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017793#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017794{
17795 int ret;
17796
17797 vos_ssr_protect(__func__);
17798 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17799 vos_ssr_unprotect(__func__);
17800
17801 return ret;
17802}
17803
17804static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017805 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017806{
17807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017808 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017809 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017810 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017811
Jeff Johnsone7245742012-09-05 17:12:55 -070017812 ENTER();
17813
Jeff Johnson295189b2012-06-20 16:38:30 -070017814 if (NULL == pAdapter)
17815 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017817 return -ENODEV;
17818 }
17819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17821 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17822 pAdapter->sessionId, timeout));
17823
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017825 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017826 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017828 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017829 }
17830
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017831 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17832 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17833 (pHddCtx->cfg_ini->fhostArpOffload) &&
17834 (eConnectionState_Associated ==
17835 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17836 {
Amar Singhald53568e2013-09-26 11:03:45 -070017837
17838 hddLog(VOS_TRACE_LEVEL_INFO,
17839 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017840 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017841 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17842 {
17843 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017844 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017845 __func__, vos_status);
17846 }
17847 }
17848
Jeff Johnson295189b2012-06-20 16:38:30 -070017849 /**The get power cmd from the supplicant gets updated by the nl only
17850 *on successful execution of the function call
17851 *we are oppositely mapped w.r.t mode in the driver
17852 **/
17853 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17854
17855 if (VOS_STATUS_E_FAILURE == vos_status)
17856 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17858 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017859 return -EINVAL;
17860 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017861 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017862 return 0;
17863}
17864
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017865static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17866 struct net_device *dev, bool mode, int timeout)
17867{
17868 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017869
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017870 vos_ssr_protect(__func__);
17871 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17872 vos_ssr_unprotect(__func__);
17873
17874 return ret;
17875}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017876
Jeff Johnson295189b2012-06-20 16:38:30 -070017877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017878static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17879 struct net_device *netdev,
17880 u8 key_index)
17881{
17882 ENTER();
17883 return 0;
17884}
17885
Jeff Johnson295189b2012-06-20 16:38:30 -070017886static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017887 struct net_device *netdev,
17888 u8 key_index)
17889{
17890 int ret;
17891 vos_ssr_protect(__func__);
17892 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
17893 vos_ssr_unprotect(__func__);
17894 return ret;
17895}
17896#endif //LINUX_VERSION_CODE
17897
17898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17899static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17900 struct net_device *dev,
17901 struct ieee80211_txq_params *params)
17902{
17903 ENTER();
17904 return 0;
17905}
17906#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17907static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
17908 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017909{
Jeff Johnsone7245742012-09-05 17:12:55 -070017910 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070017911 return 0;
17912}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017913#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070017914
17915#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
17916static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017917 struct net_device *dev,
17918 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070017919{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017920 int ret;
17921
17922 vos_ssr_protect(__func__);
17923 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
17924 vos_ssr_unprotect(__func__);
17925 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017926}
17927#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17928static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
17929 struct ieee80211_txq_params *params)
17930{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017931 int ret;
17932
17933 vos_ssr_protect(__func__);
17934 ret = __wlan_hdd_set_txq_params(wiphy, params);
17935 vos_ssr_unprotect(__func__);
17936 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017937}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017939
Naresh Jayaram69e3f282014-10-14 12:29:12 +053017940static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017941 struct net_device *dev,
17942 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070017943{
17944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017945 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017946 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017947 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080017948 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017949 v_CONTEXT_t pVosContext = NULL;
17950 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017951
Jeff Johnsone7245742012-09-05 17:12:55 -070017952 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017953
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017954 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070017955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017957 return -EINVAL;
17958 }
17959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17961 TRACE_CODE_HDD_CFG80211_DEL_STA,
17962 pAdapter->sessionId, pAdapter->device_mode));
17963
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017964 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17965 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017966 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017967 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017968 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017969 }
17970
Jeff Johnson295189b2012-06-20 16:38:30 -070017971 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017972 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070017973 )
17974 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017975 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
17976 pSapCtx = VOS_GET_SAP_CB(pVosContext);
17977 if(pSapCtx == NULL){
17978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17979 FL("psapCtx is NULL"));
17980 return -ENOENT;
17981 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053017982 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
17983 {
17984 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
17985 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
17986 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
17987 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017988 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070017989 {
17990 v_U16_t i;
17991 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
17992 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017993 if ((pSapCtx->aStaInfo[i].isUsed) &&
17994 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070017995 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017996 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053017997 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053017998 ETHER_ADDR_LEN);
17999
Jeff Johnson295189b2012-06-20 16:38:30 -070018000 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018001 "%s: Delete STA with MAC::"
18002 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018003 __func__,
18004 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18005 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018006 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018007 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018008 }
18009 }
18010 }
18011 else
18012 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018013
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018014 vos_status = hdd_softap_GetStaId(pAdapter,
18015 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018016 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18017 {
18018 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018019 "%s: Skip this DEL STA as this is not used::"
18020 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018021 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018022 return -ENOENT;
18023 }
18024
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018025 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018026 {
18027 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018028 "%s: Skip this DEL STA as deauth is in progress::"
18029 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018030 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018031 return -ENOENT;
18032 }
18033
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018034 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018035
Jeff Johnson295189b2012-06-20 16:38:30 -070018036 hddLog(VOS_TRACE_LEVEL_INFO,
18037 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018038 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018039 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018040 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018041
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018042 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018043 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18044 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018045 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018046 hddLog(VOS_TRACE_LEVEL_INFO,
18047 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018048 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018049 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018050 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018051 return -ENOENT;
18052 }
18053
Jeff Johnson295189b2012-06-20 16:38:30 -070018054 }
18055 }
18056
18057 EXIT();
18058
18059 return 0;
18060}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018061
18062#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018063int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018064 struct net_device *dev,
18065 struct station_del_parameters *param)
18066#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018068int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018069 struct net_device *dev, const u8 *mac)
18070#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018071int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018072 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018073#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018074#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018075{
18076 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018077 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018078
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018079 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018080
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018081#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018082 if (NULL == param) {
18083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018084 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018085 return -EINVAL;
18086 }
18087
18088 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18089 param->subtype, &delStaParams);
18090
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018091#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018092 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018093 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018094#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018095 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18096
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018097 vos_ssr_unprotect(__func__);
18098
18099 return ret;
18100}
18101
18102static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018103 struct net_device *dev,
18104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18105 const u8 *mac,
18106#else
18107 u8 *mac,
18108#endif
18109 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018110{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018111 hdd_adapter_t *pAdapter;
18112 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018113 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018114#ifdef FEATURE_WLAN_TDLS
18115 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018116
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018117 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018118
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018119 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18120 if (NULL == pAdapter)
18121 {
18122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18123 "%s: Adapter is NULL",__func__);
18124 return -EINVAL;
18125 }
18126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18127 status = wlan_hdd_validate_context(pHddCtx);
18128 if (0 != status)
18129 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018130 return status;
18131 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018132
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018133 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18134 TRACE_CODE_HDD_CFG80211_ADD_STA,
18135 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018136 mask = params->sta_flags_mask;
18137
18138 set = params->sta_flags_set;
18139
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018141 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18142 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018143
18144 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18145 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018146 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018147 }
18148 }
18149#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018150 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018151 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018152}
18153
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18155static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18156 struct net_device *dev, const u8 *mac,
18157 struct station_parameters *params)
18158#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018159static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18160 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018161#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018162{
18163 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018164
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018165 vos_ssr_protect(__func__);
18166 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18167 vos_ssr_unprotect(__func__);
18168
18169 return ret;
18170}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018171#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018172
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018173static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018174 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018175{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18177 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018178 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018179 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018180 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018181 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018182
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018183 ENTER();
18184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018185 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018186 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018187 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018189 return -EINVAL;
18190 }
18191
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018192 if (!pmksa) {
18193 hddLog(LOGE, FL("pmksa is NULL"));
18194 return -EINVAL;
18195 }
18196
18197 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018198 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018199 pmksa->bssid, pmksa->pmkid);
18200 return -EINVAL;
18201 }
18202
18203 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18204 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18205
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018206 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18207 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018208 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018209 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018210 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018211 }
18212
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018213 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018214 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18215
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018216 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18217 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018218
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018219 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018220 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018221 &pmk_id, 1, FALSE);
18222
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18224 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18225 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018226
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018227 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018228 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018229}
18230
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018231static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18232 struct cfg80211_pmksa *pmksa)
18233{
18234 int ret;
18235
18236 vos_ssr_protect(__func__);
18237 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18238 vos_ssr_unprotect(__func__);
18239
18240 return ret;
18241}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018242
Wilson Yang6507c4e2013-10-01 20:11:19 -070018243
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018244static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018245 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018246{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18248 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018249 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018250 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018252 ENTER();
18253
Wilson Yang6507c4e2013-10-01 20:11:19 -070018254 /* Validate pAdapter */
18255 if (NULL == pAdapter)
18256 {
18257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18258 return -EINVAL;
18259 }
18260
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018261 if (!pmksa) {
18262 hddLog(LOGE, FL("pmksa is NULL"));
18263 return -EINVAL;
18264 }
18265
18266 if (!pmksa->bssid) {
18267 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18268 return -EINVAL;
18269 }
18270
Kiet Lam98c46a12014-10-31 15:34:57 -070018271 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18272 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18273
Wilson Yang6507c4e2013-10-01 20:11:19 -070018274 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18275 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018276 if (0 != status)
18277 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018278 return status;
18279 }
18280
18281 /*Retrieve halHandle*/
18282 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18283
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018284 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18285 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18286 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018287 /* Delete the PMKID CSR cache */
18288 if (eHAL_STATUS_SUCCESS !=
18289 sme_RoamDelPMKIDfromCache(halHandle,
18290 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18291 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18292 MAC_ADDR_ARRAY(pmksa->bssid));
18293 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018294 }
18295
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018296 EXIT();
18297 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018298}
18299
Wilson Yang6507c4e2013-10-01 20:11:19 -070018300
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018301static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18302 struct cfg80211_pmksa *pmksa)
18303{
18304 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018305
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018306 vos_ssr_protect(__func__);
18307 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18308 vos_ssr_unprotect(__func__);
18309
18310 return ret;
18311
18312}
18313
18314static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018315{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18317 tHalHandle halHandle;
18318 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018319 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018320
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018321 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018322
18323 /* Validate pAdapter */
18324 if (NULL == pAdapter)
18325 {
18326 hddLog(VOS_TRACE_LEVEL_ERROR,
18327 "%s: Invalid Adapter" ,__func__);
18328 return -EINVAL;
18329 }
18330
18331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18332 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018333 if (0 != status)
18334 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018335 return status;
18336 }
18337
18338 /*Retrieve halHandle*/
18339 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18340
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018341 /* Flush the PMKID cache in CSR */
18342 if (eHAL_STATUS_SUCCESS !=
18343 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18345 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018346 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018347 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018348 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018349}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018350
18351static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18352{
18353 int ret;
18354
18355 vos_ssr_protect(__func__);
18356 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18357 vos_ssr_unprotect(__func__);
18358
18359 return ret;
18360}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018361#endif
18362
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018363#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018364static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18365 struct net_device *dev,
18366 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018367{
18368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18369 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018370 hdd_context_t *pHddCtx;
18371 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018373 ENTER();
18374
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018375 if (NULL == pAdapter)
18376 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018378 return -ENODEV;
18379 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018380 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18381 ret = wlan_hdd_validate_context(pHddCtx);
18382 if (0 != ret)
18383 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018384 return ret;
18385 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018386 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018387 if (NULL == pHddStaCtx)
18388 {
18389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18390 return -EINVAL;
18391 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018392
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018393 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18394 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18395 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018396 // Added for debug on reception of Re-assoc Req.
18397 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18398 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018399 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018400 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018401 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018402 }
18403
18404#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018405 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018406 ftie->ie_len);
18407#endif
18408
18409 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018410 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18411 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018412 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018413
18414 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018415 return 0;
18416}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018417
18418static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18419 struct net_device *dev,
18420 struct cfg80211_update_ft_ies_params *ftie)
18421{
18422 int ret;
18423
18424 vos_ssr_protect(__func__);
18425 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18426 vos_ssr_unprotect(__func__);
18427
18428 return ret;
18429}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018430#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018431
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018432#ifdef FEATURE_WLAN_SCAN_PNO
18433
18434void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18435 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18436{
18437 int ret;
18438 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18439 hdd_context_t *pHddCtx;
18440
Nirav Shah80830bf2013-12-31 16:35:12 +053018441 ENTER();
18442
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018443 if (NULL == pAdapter)
18444 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018446 "%s: HDD adapter is Null", __func__);
18447 return ;
18448 }
18449
18450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18451 if (NULL == pHddCtx)
18452 {
18453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18454 "%s: HDD context is Null!!!", __func__);
18455 return ;
18456 }
18457
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018458 spin_lock(&pHddCtx->schedScan_lock);
18459 if (TRUE == pHddCtx->isWiphySuspended)
18460 {
18461 pHddCtx->isSchedScanUpdatePending = TRUE;
18462 spin_unlock(&pHddCtx->schedScan_lock);
18463 hddLog(VOS_TRACE_LEVEL_INFO,
18464 "%s: Update cfg80211 scan database after it resume", __func__);
18465 return ;
18466 }
18467 spin_unlock(&pHddCtx->schedScan_lock);
18468
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018469 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18470
18471 if (0 > ret)
18472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018473 else
18474 {
18475 /* Acquire wakelock to handle the case where APP's tries to suspend
18476 * immediatly after the driver gets connect request(i.e after pno)
18477 * from supplicant, this result in app's is suspending and not able
18478 * to process the connect request to AP */
18479 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18480 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018481 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18483 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018484}
18485
18486/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018487 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018488 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018489 */
18490static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18491{
18492 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18493 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018494 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018495 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18496 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018497
18498 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18499 {
18500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18501 "%s: PNO is allowed only in STA interface", __func__);
18502 return eHAL_STATUS_FAILURE;
18503 }
18504
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018505 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18506
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018507 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018508 * active sessions. PNO is allowed only in case when sap session
18509 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018510 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018511 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18512 {
18513 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018514 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018515
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018516 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18517 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18518 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18519 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018520 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18521 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018522 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018523 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018524 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018525 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018526 }
18527 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18528 pAdapterNode = pNext;
18529 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018530 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018531}
18532
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018533void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18534{
18535 hdd_adapter_t *pAdapter = callbackContext;
18536 hdd_context_t *pHddCtx;
18537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018538 ENTER();
18539
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018540 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18541 {
18542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18543 FL("Invalid adapter or adapter has invalid magic"));
18544 return;
18545 }
18546
18547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18548 if (0 != wlan_hdd_validate_context(pHddCtx))
18549 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018550 return;
18551 }
18552
c_hpothub53c45d2014-08-18 16:53:14 +053018553 if (VOS_STATUS_SUCCESS != status)
18554 {
18555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018556 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018557 pHddCtx->isPnoEnable = FALSE;
18558 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018559
18560 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18561 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018562 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018563}
18564
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18566 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18567/**
18568 * hdd_config_sched_scan_plan() - configures the sched scan plans
18569 * from the framework.
18570 * @pno_req: pointer to PNO scan request
18571 * @request: pointer to scan request from framework
18572 *
18573 * Return: None
18574 */
18575static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18576 struct cfg80211_sched_scan_request *request,
18577 hdd_context_t *hdd_ctx)
18578{
18579 v_U32_t i = 0;
18580
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018581 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018582 for (i = 0; i < request->n_scan_plans; i++)
18583 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018584 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18585 request->scan_plans[i].iterations;
18586 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18587 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018588 }
18589}
18590#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018591static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018592 struct cfg80211_sched_scan_request *request,
18593 hdd_context_t *hdd_ctx)
18594{
18595 v_U32_t i, temp_int;
18596 /* Driver gets only one time interval which is hardcoded in
18597 * supplicant for 10000ms. Taking power consumption into account 6
18598 * timers will be used, Timervalue is increased exponentially
18599 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18600 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18601 * If it is set to 0 only one timer will be used and PNO scan cycle
18602 * will be repeated after each interval specified by supplicant
18603 * till PNO is disabled.
18604 */
18605 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018606 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018607 HDD_PNO_SCAN_TIMERS_SET_ONE;
18608 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018609 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018610 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18611
18612 temp_int = (request->interval)/1000;
18613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18614 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18615 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018616 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018617 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018618 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018619 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018620 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018621 temp_int *= 2;
18622 }
18623 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018624 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018625}
18626#endif
18627
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018628/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018629 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18630 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018631 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018632static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018633 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18634{
18635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018636 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018637 hdd_context_t *pHddCtx;
18638 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018639 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018640 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18641 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018642 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18643 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018644 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018645 hdd_config_t *pConfig = NULL;
18646 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018648 ENTER();
18649
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018650 if (NULL == pAdapter)
18651 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018653 "%s: HDD adapter is Null", __func__);
18654 return -ENODEV;
18655 }
18656
18657 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018658 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018659
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018660 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018661 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018662 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018663 }
18664
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018665 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018666 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18667 if (NULL == hHal)
18668 {
18669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18670 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018671 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018672 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18674 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18675 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018676 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018677 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018678 {
18679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18680 "%s: aborting the existing scan is unsuccessfull", __func__);
18681 return -EBUSY;
18682 }
18683
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018684 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018685 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018687 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018688 return -EBUSY;
18689 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018690
c_hpothu37f21312014-04-09 21:49:54 +053018691 if (TRUE == pHddCtx->isPnoEnable)
18692 {
18693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18694 FL("already PNO is enabled"));
18695 return -EBUSY;
18696 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018697
18698 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18699 {
18700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18701 "%s: abort ROC failed ", __func__);
18702 return -EBUSY;
18703 }
18704
c_hpothu37f21312014-04-09 21:49:54 +053018705 pHddCtx->isPnoEnable = TRUE;
18706
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018707 pnoRequest.enable = 1; /*Enable PNO */
18708 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018709
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018710 if (( !pnoRequest.ucNetworksCount ) ||
18711 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018712 {
18713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018714 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018715 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018716 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018717 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018718 goto error;
18719 }
18720
18721 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18722 {
18723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018724 "%s: Incorrect number of channels %d",
18725 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018726 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018727 goto error;
18728 }
18729
18730 /* Framework provides one set of channels(all)
18731 * common for all saved profile */
18732 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18733 channels_allowed, &num_channels_allowed))
18734 {
18735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18736 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018737 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018738 goto error;
18739 }
18740 /* Checking each channel against allowed channel list */
18741 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018742 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018743 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018744 char chList [(request->n_channels*5)+1];
18745 int len;
18746 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018747 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018748 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018749 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018750 if (request->channels[i]->hw_value == channels_allowed[indx])
18751 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018752 if ((!pConfig->enableDFSPnoChnlScan) &&
18753 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18754 {
18755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18756 "%s : Dropping DFS channel : %d",
18757 __func__,channels_allowed[indx]);
18758 num_ignore_dfs_ch++;
18759 break;
18760 }
18761
Nirav Shah80830bf2013-12-31 16:35:12 +053018762 valid_ch[num_ch++] = request->channels[i]->hw_value;
18763 len += snprintf(chList+len, 5, "%d ",
18764 request->channels[i]->hw_value);
18765 break ;
18766 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018767 }
18768 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018769 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018770
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018771 /*If all channels are DFS and dropped, then ignore the PNO request*/
18772 if (num_ignore_dfs_ch == request->n_channels)
18773 {
18774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18775 "%s : All requested channels are DFS channels", __func__);
18776 ret = -EINVAL;
18777 goto error;
18778 }
18779 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018780
18781 pnoRequest.aNetworks =
18782 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18783 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018784 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018785 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18786 FL("failed to allocate memory aNetworks %u"),
18787 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18788 goto error;
18789 }
18790 vos_mem_zero(pnoRequest.aNetworks,
18791 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18792
18793 /* Filling per profile params */
18794 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18795 {
18796 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018797 request->match_sets[i].ssid.ssid_len;
18798
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018799 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18800 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018801 {
18802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018803 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018804 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018805 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018806 goto error;
18807 }
18808
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018809 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018810 request->match_sets[i].ssid.ssid,
18811 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18813 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018814 i, pnoRequest.aNetworks[i].ssId.ssId);
18815 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18816 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18817 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018818
18819 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018820 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18821 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018822
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018823 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018824 }
18825
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018826 for (i = 0; i < request->n_ssids; i++)
18827 {
18828 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018829 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018830 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018831 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018832 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018833 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018834 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018835 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018836 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018837 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018838 break;
18839 }
18840 j++;
18841 }
18842 }
18843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18844 "Number of hidden networks being Configured = %d",
18845 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018847 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018848
18849 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18850 if (pnoRequest.p24GProbeTemplate == NULL)
18851 {
18852 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18853 FL("failed to allocate memory p24GProbeTemplate %u"),
18854 SIR_PNO_MAX_PB_REQ_SIZE);
18855 goto error;
18856 }
18857
18858 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18859 if (pnoRequest.p5GProbeTemplate == NULL)
18860 {
18861 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18862 FL("failed to allocate memory p5GProbeTemplate %u"),
18863 SIR_PNO_MAX_PB_REQ_SIZE);
18864 goto error;
18865 }
18866
18867 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18868 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18869
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018870 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18871 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018872 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018873 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18874 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18875 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018876
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018877 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18878 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18879 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018880 }
18881
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018882 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018883
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018884 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018885
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018886 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018887 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
18888 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018889 pAdapter->pno_req_status = 0;
18890
Nirav Shah80830bf2013-12-31 16:35:12 +053018891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18892 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018893 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
18894 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053018895
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018896 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018897 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018898 hdd_cfg80211_sched_scan_done_callback, pAdapter);
18899 if (eHAL_STATUS_SUCCESS != status)
18900 {
18901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018902 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018903 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018904 goto error;
18905 }
18906
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018907 ret = wait_for_completion_timeout(
18908 &pAdapter->pno_comp_var,
18909 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
18910 if (0 >= ret)
18911 {
18912 // Did not receive the response for PNO enable in time.
18913 // Assuming the PNO enable was success.
18914 // Returning error from here, because we timeout, results
18915 // in side effect of Wifi (Wifi Setting) not to work.
18916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18917 FL("Timed out waiting for PNO to be Enabled"));
18918 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018919 }
18920
18921 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053018922 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018923
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018924error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18926 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053018927 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018928 if (pnoRequest.aNetworks)
18929 vos_mem_free(pnoRequest.aNetworks);
18930 if (pnoRequest.p24GProbeTemplate)
18931 vos_mem_free(pnoRequest.p24GProbeTemplate);
18932 if (pnoRequest.p5GProbeTemplate)
18933 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018934
18935 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018936 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018937}
18938
18939/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018940 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
18941 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018942 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018943static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
18944 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18945{
18946 int ret;
18947
18948 vos_ssr_protect(__func__);
18949 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
18950 vos_ssr_unprotect(__func__);
18951
18952 return ret;
18953}
18954
18955/*
18956 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
18957 * Function to disable PNO
18958 */
18959static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018960 struct net_device *dev)
18961{
18962 eHalStatus status = eHAL_STATUS_FAILURE;
18963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18964 hdd_context_t *pHddCtx;
18965 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018966 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018967 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018968
18969 ENTER();
18970
18971 if (NULL == pAdapter)
18972 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018974 "%s: HDD adapter is Null", __func__);
18975 return -ENODEV;
18976 }
18977
18978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018979
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018980 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018981 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018983 "%s: HDD context is Null", __func__);
18984 return -ENODEV;
18985 }
18986
18987 /* The return 0 is intentional when isLogpInProgress and
18988 * isLoadUnloadInProgress. We did observe a crash due to a return of
18989 * failure in sched_scan_stop , especially for a case where the unload
18990 * of the happens at the same time. The function __cfg80211_stop_sched_scan
18991 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
18992 * success. If it returns a failure , then its next invocation due to the
18993 * clean up of the second interface will have the dev pointer corresponding
18994 * to the first one leading to a crash.
18995 */
18996 if (pHddCtx->isLogpInProgress)
18997 {
18998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18999 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019000 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019001 return ret;
19002 }
19003
Mihir Shete18156292014-03-11 15:38:30 +053019004 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019005 {
19006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19007 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19008 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019009 }
19010
19011 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19012 if (NULL == hHal)
19013 {
19014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19015 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019016 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019017 }
19018
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019019 pnoRequest.enable = 0; /* Disable PNO */
19020 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019021
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019022 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19023 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19024 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019025
19026 INIT_COMPLETION(pAdapter->pno_comp_var);
19027 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19028 pnoRequest.callbackContext = pAdapter;
19029 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019030 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019031 pAdapter->sessionId,
19032 NULL, pAdapter);
19033 if (eHAL_STATUS_SUCCESS != status)
19034 {
19035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19036 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019037 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019038 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019039 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019040 ret = wait_for_completion_timeout(
19041 &pAdapter->pno_comp_var,
19042 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19043 if (0 >= ret)
19044 {
19045 // Did not receive the response for PNO disable in time.
19046 // Assuming the PNO disable was success.
19047 // Returning error from here, because we timeout, results
19048 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019050 FL("Timed out waiting for PNO to be disabled"));
19051 ret = 0;
19052 }
19053
19054 ret = pAdapter->pno_req_status;
19055 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019056
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019057error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019059 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019060
19061 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019062 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019063}
19064
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019065/*
19066 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19067 * NL interface to disable PNO
19068 */
19069static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19070 struct net_device *dev)
19071{
19072 int ret;
19073
19074 vos_ssr_protect(__func__);
19075 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19076 vos_ssr_unprotect(__func__);
19077
19078 return ret;
19079}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019080#endif /*FEATURE_WLAN_SCAN_PNO*/
19081
19082
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019083#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019084#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019085static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19086 struct net_device *dev,
19087 u8 *peer, u8 action_code,
19088 u8 dialog_token,
19089 u16 status_code, u32 peer_capability,
19090 const u8 *buf, size_t len)
19091#else /* TDLS_MGMT_VERSION2 */
19092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19093static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19094 struct net_device *dev,
19095 const u8 *peer, u8 action_code,
19096 u8 dialog_token, u16 status_code,
19097 u32 peer_capability, bool initiator,
19098 const u8 *buf, size_t len)
19099#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19100static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19101 struct net_device *dev,
19102 const u8 *peer, u8 action_code,
19103 u8 dialog_token, u16 status_code,
19104 u32 peer_capability, const u8 *buf,
19105 size_t len)
19106#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19107static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19108 struct net_device *dev,
19109 u8 *peer, u8 action_code,
19110 u8 dialog_token,
19111 u16 status_code, u32 peer_capability,
19112 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019113#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019114static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19115 struct net_device *dev,
19116 u8 *peer, u8 action_code,
19117 u8 dialog_token,
19118 u16 status_code, const u8 *buf,
19119 size_t len)
19120#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019121#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019122{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019123 hdd_adapter_t *pAdapter;
19124 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019125 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019126 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019127 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019128 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019129 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019130 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019131#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019132 u32 peer_capability = 0;
19133#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019134 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019135 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019136 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019137
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019138 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19139 if (NULL == pAdapter)
19140 {
19141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19142 "%s: Adapter is NULL",__func__);
19143 return -EINVAL;
19144 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19146 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19147 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019148
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019149 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019150 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019153 "Invalid arguments");
19154 return -EINVAL;
19155 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019156
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019157 if (pHddCtx->isLogpInProgress)
19158 {
19159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19160 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019161 wlan_hdd_tdls_set_link_status(pAdapter,
19162 peer,
19163 eTDLS_LINK_IDLE,
19164 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019165 return -EBUSY;
19166 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019167
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019168 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19169 {
19170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19171 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19172 return -EAGAIN;
19173 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019174
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019175 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19176 if (!pHddTdlsCtx) {
19177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19178 "%s: pHddTdlsCtx not valid.", __func__);
19179 }
19180
Hoonki Lee27511902013-03-14 18:19:06 -070019181 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019182 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019184 "%s: TDLS mode is disabled OR not enabled in FW."
19185 MAC_ADDRESS_STR " action %d declined.",
19186 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019187 return -ENOTSUPP;
19188 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019189
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019190 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19191
19192 if( NULL == pHddStaCtx )
19193 {
19194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19195 "%s: HDD station context NULL ",__func__);
19196 return -EINVAL;
19197 }
19198
19199 /* STA should be connected and authenticated
19200 * before sending any TDLS frames
19201 */
19202 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19203 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19204 {
19205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19206 "STA is not connected or unauthenticated. "
19207 "connState %u, uIsAuthenticated %u",
19208 pHddStaCtx->conn_info.connState,
19209 pHddStaCtx->conn_info.uIsAuthenticated);
19210 return -EAGAIN;
19211 }
19212
Hoonki Lee27511902013-03-14 18:19:06 -070019213 /* other than teardown frame, other mgmt frames are not sent if disabled */
19214 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19215 {
19216 /* if tdls_mode is disabled to respond to peer's request */
19217 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19218 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019220 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019221 " TDLS mode is disabled. action %d declined.",
19222 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019223
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019224 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019225 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019226
19227 if (vos_max_concurrent_connections_reached())
19228 {
19229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19230 return -EINVAL;
19231 }
Hoonki Lee27511902013-03-14 18:19:06 -070019232 }
19233
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019234 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19235 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019236 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019237 {
19238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019239 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019240 " TDLS setup is ongoing. action %d declined.",
19241 __func__, MAC_ADDR_ARRAY(peer), action_code);
19242 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019243 }
19244 }
19245
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019246 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19247 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019248 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019249 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19250 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019251 {
19252 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19253 we return error code at 'add_station()'. Hence we have this
19254 check again in addtion to add_station().
19255 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019256 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019257 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19259 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019260 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19261 __func__, MAC_ADDR_ARRAY(peer), action_code,
19262 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019263 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019264 }
19265 else
19266 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019267 /* maximum reached. tweak to send error code to peer and return
19268 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019269 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19271 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019272 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19273 __func__, MAC_ADDR_ARRAY(peer), status_code,
19274 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019275 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019276 /* fall through to send setup resp with failure status
19277 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019278 }
19279 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019280 else
19281 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019282 mutex_lock(&pHddCtx->tdls_lock);
19283 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019284 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019285 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019286 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019288 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19289 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019290 return -EPERM;
19291 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019292 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019293 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019294 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019295
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019297 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019298 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19299 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019300
Hoonki Leea34dd892013-02-05 22:56:02 -080019301 /*Except teardown responder will not be used so just make 0*/
19302 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019303 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019304 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019305
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019306 mutex_lock(&pHddCtx->tdls_lock);
19307 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019308
19309 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19310 responder = pTdlsPeer->is_responder;
19311 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019312 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019314 "%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 -070019315 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19316 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019317 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019318 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019319 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019320 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019321 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019322
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019323 /* Discard TDLS setup if peer is removed by user app */
19324 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19325 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19326 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19327 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19328
19329 mutex_lock(&pHddCtx->tdls_lock);
19330 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19331 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19332 mutex_unlock(&pHddCtx->tdls_lock);
19333 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19334 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19335 MAC_ADDR_ARRAY(peer), action_code);
19336 return -EINVAL;
19337 }
19338 mutex_unlock(&pHddCtx->tdls_lock);
19339 }
19340
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019341 /* For explicit trigger of DIS_REQ come out of BMPS for
19342 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019343 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019344 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019345 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19346 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019347 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019348 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019350 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19351 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019352 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19353 if (status != VOS_STATUS_SUCCESS) {
19354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019355 } else {
19356 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019357 }
Hoonki Lee14621352013-04-16 17:51:19 -070019358 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019359 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019360 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19362 }
19363 }
Hoonki Lee14621352013-04-16 17:51:19 -070019364 }
19365
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019366 /* make sure doesn't call send_mgmt() while it is pending */
19367 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19368 {
19369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019370 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019371 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019372 ret = -EBUSY;
19373 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019374 }
19375
19376 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019377 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19378
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019379 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19380 pAdapter->sessionId, peer, action_code, dialog_token,
19381 status_code, peer_capability, (tANI_U8 *)buf, len,
19382 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019383
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019384 if (VOS_STATUS_SUCCESS != status)
19385 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19387 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019388 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019389 ret = -EINVAL;
19390 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019391 }
19392
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19394 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19395 WAIT_TIME_TDLS_MGMT);
19396
Hoonki Leed37cbb32013-04-20 00:31:14 -070019397 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19398 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19399
19400 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019401 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019403 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019404 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019405 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019406
19407 if (pHddCtx->isLogpInProgress)
19408 {
19409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19410 "%s: LOGP in Progress. Ignore!!!", __func__);
19411 return -EAGAIN;
19412 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019413 if (rc <= 0)
19414 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19415 WLAN_LOG_INDICATOR_HOST_DRIVER,
19416 WLAN_LOG_REASON_HDD_TIME_OUT,
19417 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019418
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019419 ret = -EINVAL;
19420 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019421 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019422 else
19423 {
19424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19425 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19426 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19427 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019428
Gopichand Nakkala05922802013-03-14 12:23:19 -070019429 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019430 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019431 ret = max_sta_failed;
19432 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019433 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019434
Hoonki Leea34dd892013-02-05 22:56:02 -080019435 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19436 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019437 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19439 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019440 }
19441 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19442 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019443 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19445 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019446 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019447
19448 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019449
19450tx_failed:
19451 /* add_station will be called before sending TDLS_SETUP_REQ and
19452 * TDLS_SETUP_RSP and as part of add_station driver will enable
19453 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19454 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19455 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19456 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19457 */
19458
19459 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19460 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19461 wlan_hdd_tdls_check_bmps(pAdapter);
19462 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019463}
19464
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019465#if TDLS_MGMT_VERSION2
19466static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19467 u8 *peer, u8 action_code, u8 dialog_token,
19468 u16 status_code, u32 peer_capability,
19469 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019470#else /* TDLS_MGMT_VERSION2 */
19471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19472static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19473 struct net_device *dev,
19474 const u8 *peer, u8 action_code,
19475 u8 dialog_token, u16 status_code,
19476 u32 peer_capability, bool initiator,
19477 const u8 *buf, size_t len)
19478#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19479static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19480 struct net_device *dev,
19481 const u8 *peer, u8 action_code,
19482 u8 dialog_token, u16 status_code,
19483 u32 peer_capability, const u8 *buf,
19484 size_t len)
19485#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19486static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19487 struct net_device *dev,
19488 u8 *peer, u8 action_code,
19489 u8 dialog_token,
19490 u16 status_code, u32 peer_capability,
19491 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019492#else
19493static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19494 u8 *peer, u8 action_code, u8 dialog_token,
19495 u16 status_code, const u8 *buf, size_t len)
19496#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019497#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019498{
19499 int ret;
19500
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019501 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019502#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019503 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19504 dialog_token, status_code,
19505 peer_capability, buf, len);
19506#else /* TDLS_MGMT_VERSION2 */
19507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19508 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19509 dialog_token, status_code,
19510 peer_capability, initiator,
19511 buf, len);
19512#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19513 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19514 dialog_token, status_code,
19515 peer_capability, buf, len);
19516#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19517 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19518 dialog_token, status_code,
19519 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019520#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019521 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19522 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019523#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019524#endif
19525 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019526
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019527 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019528}
Atul Mittal115287b2014-07-08 13:26:33 +053019529
19530int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19532 const u8 *peer,
19533#else
Atul Mittal115287b2014-07-08 13:26:33 +053019534 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019535#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019536 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019537 cfg80211_exttdls_callback callback)
19538{
19539
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019540 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019541 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019542 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19544 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19545 __func__, MAC_ADDR_ARRAY(peer));
19546
19547 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19548 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19549
19550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019551 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19552 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19553 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019554 return -ENOTSUPP;
19555 }
19556
19557 /* To cater the requirement of establishing the TDLS link
19558 * irrespective of the data traffic , get an entry of TDLS peer.
19559 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019560 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019561 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19562 if (pTdlsPeer == NULL) {
19563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19564 "%s: peer " MAC_ADDRESS_STR " not existing",
19565 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019566 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019567 return -EINVAL;
19568 }
19569
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019570 /* check FW TDLS Off Channel capability */
19571 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019572 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019573 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019574 {
19575 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19576 pTdlsPeer->peerParams.global_operating_class =
19577 tdls_peer_params->global_operating_class;
19578 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19579 pTdlsPeer->peerParams.min_bandwidth_kbps =
19580 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019581 /* check configured channel is valid, non dfs and
19582 * not current operating channel */
19583 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19584 tdls_peer_params->channel)) &&
19585 (pHddStaCtx) &&
19586 (tdls_peer_params->channel !=
19587 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019588 {
19589 pTdlsPeer->isOffChannelConfigured = TRUE;
19590 }
19591 else
19592 {
19593 pTdlsPeer->isOffChannelConfigured = FALSE;
19594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19595 "%s: Configured Tdls Off Channel is not valid", __func__);
19596
19597 }
19598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019599 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19600 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019601 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019602 pTdlsPeer->isOffChannelConfigured,
19603 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019604 }
19605 else
19606 {
19607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019608 "%s: TDLS off channel FW capability %d, "
19609 "host capab %d or Invalid TDLS Peer Params", __func__,
19610 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19611 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019612 }
19613
Atul Mittal115287b2014-07-08 13:26:33 +053019614 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19615
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019616 mutex_unlock(&pHddCtx->tdls_lock);
19617
Atul Mittal115287b2014-07-08 13:26:33 +053019618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19619 " %s TDLS Add Force Peer Failed",
19620 __func__);
19621 return -EINVAL;
19622 }
19623 /*EXT TDLS*/
19624
19625 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019626 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19628 " %s TDLS set callback Failed",
19629 __func__);
19630 return -EINVAL;
19631 }
19632
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019633 mutex_unlock(&pHddCtx->tdls_lock);
19634
Atul Mittal115287b2014-07-08 13:26:33 +053019635 return(0);
19636
19637}
19638
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019639int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19641 const u8 *peer
19642#else
19643 u8 *peer
19644#endif
19645)
Atul Mittal115287b2014-07-08 13:26:33 +053019646{
19647
19648 hddTdlsPeer_t *pTdlsPeer;
19649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019650
Atul Mittal115287b2014-07-08 13:26:33 +053019651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19652 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19653 __func__, MAC_ADDR_ARRAY(peer));
19654
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019655 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19657 return -EINVAL;
19658 }
19659
Atul Mittal115287b2014-07-08 13:26:33 +053019660 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19661 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19662
19663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019664 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19665 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19666 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019667 return -ENOTSUPP;
19668 }
19669
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019670 mutex_lock(&pHddCtx->tdls_lock);
19671 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019672
19673 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019674 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019676 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019677 __func__, MAC_ADDR_ARRAY(peer));
19678 return -EINVAL;
19679 }
19680 else {
19681 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19682 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019683 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19684 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019685 /* if channel switch is configured, reset
19686 the channel for this peer */
19687 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19688 {
19689 pTdlsPeer->peerParams.channel = 0;
19690 pTdlsPeer->isOffChannelConfigured = FALSE;
19691 }
Atul Mittal115287b2014-07-08 13:26:33 +053019692 }
19693
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019694 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019695 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019697 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019698 }
Atul Mittal115287b2014-07-08 13:26:33 +053019699
19700 /*EXT TDLS*/
19701
19702 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019703 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19705 " %s TDLS set callback Failed",
19706 __func__);
19707 return -EINVAL;
19708 }
Atul Mittal115287b2014-07-08 13:26:33 +053019709
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019710 mutex_unlock(&pHddCtx->tdls_lock);
19711
19712 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019713}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019714static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19716 const u8 *peer,
19717#else
19718 u8 *peer,
19719#endif
19720 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019721{
19722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019724 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019725 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019726
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019727 ENTER();
19728
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019729 if (!pAdapter) {
19730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19731 return -EINVAL;
19732 }
19733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19735 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19736 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019737 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019738 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019740 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019741 return -EINVAL;
19742 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019743
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019745 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019747 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019748 }
19749
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019750
19751 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019752 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019753 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019755 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19756 "Cannot process TDLS commands",
19757 pHddCtx->cfg_ini->fEnableTDLSSupport,
19758 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019759 return -ENOTSUPP;
19760 }
19761
19762 switch (oper) {
19763 case NL80211_TDLS_ENABLE_LINK:
19764 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019765 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019766 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019767 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19768 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019769 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019770 tANI_U16 numCurrTdlsPeers = 0;
19771 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019772 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019773 tSirMacAddr peerMac;
19774 int channel;
19775 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019776
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19778 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19779 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019780
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019781 mutex_lock(&pHddCtx->tdls_lock);
19782 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019783 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019784 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019785 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19787 " (oper %d) not exsting. ignored",
19788 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19789 return -EINVAL;
19790 }
19791
19792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19793 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19794 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19795 "NL80211_TDLS_ENABLE_LINK");
19796
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019797 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19798 {
19799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19800 MAC_ADDRESS_STR " failed",
19801 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019802 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019803 return -EINVAL;
19804 }
19805
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019806 /* before starting tdls connection, set tdls
19807 * off channel established status to default value */
19808 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019809
19810 mutex_unlock(&pHddCtx->tdls_lock);
19811
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019812 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019813 /* TDLS Off Channel, Disable tdls channel switch,
19814 when there are more than one tdls link */
19815 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019816 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019817 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019818 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019819 /* get connected peer and send disable tdls off chan */
19820 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019821 if ((connPeer) &&
19822 (connPeer->isOffChannelSupported == TRUE) &&
19823 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019824 {
19825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19826 "%s: More then one peer connected, Disable "
19827 "TDLS channel switch", __func__);
19828
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019829 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019830 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19831 channel = connPeer->peerParams.channel;
19832
19833 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019834
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019835 ret = sme_SendTdlsChanSwitchReq(
19836 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019837 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019838 peerMac,
19839 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019840 TDLS_OFF_CHANNEL_BW_OFFSET,
19841 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019842 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019843 hddLog(VOS_TRACE_LEVEL_ERROR,
19844 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019845 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019846 }
19847 else
19848 {
19849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19850 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019851 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019852 "isOffChannelConfigured %d",
19853 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019854 (connPeer ? (connPeer->isOffChannelSupported)
19855 : -1),
19856 (connPeer ? (connPeer->isOffChannelConfigured)
19857 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019858 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019859 }
19860 }
19861
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019862 mutex_lock(&pHddCtx->tdls_lock);
19863 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19864 if ( NULL == pTdlsPeer ) {
19865 mutex_unlock(&pHddCtx->tdls_lock);
19866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19867 "%s: " MAC_ADDRESS_STR
19868 " (oper %d) peer got freed in other context. ignored",
19869 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19870 return -EINVAL;
19871 }
19872 peer_status = pTdlsPeer->link_status;
19873 mutex_unlock(&pHddCtx->tdls_lock);
19874
19875 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019876 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019877 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019878
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019879 if (0 != wlan_hdd_tdls_get_link_establish_params(
19880 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019882 return -EINVAL;
19883 }
19884 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019885
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019886 ret = sme_SendTdlsLinkEstablishParams(
19887 WLAN_HDD_GET_HAL_CTX(pAdapter),
19888 pAdapter->sessionId, peer,
19889 &tdlsLinkEstablishParams);
19890 if (ret != VOS_STATUS_SUCCESS) {
19891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
19892 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019893 /* Send TDLS peer UAPSD capabilities to the firmware and
19894 * register with the TL on after the response for this operation
19895 * is received .
19896 */
19897 ret = wait_for_completion_interruptible_timeout(
19898 &pAdapter->tdls_link_establish_req_comp,
19899 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053019900
19901 mutex_lock(&pHddCtx->tdls_lock);
19902 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19903 if ( NULL == pTdlsPeer ) {
19904 mutex_unlock(&pHddCtx->tdls_lock);
19905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19906 "%s %d: " MAC_ADDRESS_STR
19907 " (oper %d) peer got freed in other context. ignored",
19908 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
19909 (int)oper);
19910 return -EINVAL;
19911 }
19912 peer_status = pTdlsPeer->link_status;
19913 mutex_unlock(&pHddCtx->tdls_lock);
19914
19915 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019916 {
19917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019918 FL("Link Establish Request Failed Status %ld"),
19919 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019920 return -EINVAL;
19921 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019922 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019923
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019924 mutex_lock(&pHddCtx->tdls_lock);
19925 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19926 if ( NULL == pTdlsPeer ) {
19927 mutex_unlock(&pHddCtx->tdls_lock);
19928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19929 "%s: " MAC_ADDRESS_STR
19930 " (oper %d) peer got freed in other context. ignored",
19931 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19932 return -EINVAL;
19933 }
19934
Atul Mittal115287b2014-07-08 13:26:33 +053019935 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
19936 eTDLS_LINK_CONNECTED,
19937 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019938 staDesc.ucSTAId = pTdlsPeer->staId;
19939 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053019940
19941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19942 "%s: tdlsLinkEstablishParams of peer "
19943 MAC_ADDRESS_STR "uapsdQueues: %d"
19944 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
19945 "isResponder: %d peerstaId: %d",
19946 __func__,
19947 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
19948 tdlsLinkEstablishParams.uapsdQueues,
19949 tdlsLinkEstablishParams.qos,
19950 tdlsLinkEstablishParams.maxSp,
19951 tdlsLinkEstablishParams.isBufSta,
19952 tdlsLinkEstablishParams.isOffChannelSupported,
19953 tdlsLinkEstablishParams.isResponder,
19954 pTdlsPeer->staId);
19955
19956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19957 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
19958 __func__,
19959 staDesc.ucSTAId,
19960 staDesc.ucQosEnabled);
19961
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019962 ret = WLANTL_UpdateTdlsSTAClient(
19963 pHddCtx->pvosContext,
19964 &staDesc);
19965 if (ret != VOS_STATUS_SUCCESS) {
19966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
19967 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053019968
Gopichand Nakkala471708b2013-06-04 20:03:01 +053019969 /* Mark TDLS client Authenticated .*/
19970 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
19971 pTdlsPeer->staId,
19972 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070019973 if (VOS_STATUS_SUCCESS == status)
19974 {
Hoonki Lee14621352013-04-16 17:51:19 -070019975 if (pTdlsPeer->is_responder == 0)
19976 {
19977 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019978 tdlsConnInfo_t *tdlsInfo;
19979
19980 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
19981
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019982 if (!vos_timer_is_initialized(
19983 &pTdlsPeer->initiatorWaitTimeoutTimer))
19984 {
19985 /* Initialize initiator wait callback */
19986 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053019987 &pTdlsPeer->initiatorWaitTimeoutTimer,
19988 VOS_TIMER_TYPE_SW,
19989 wlan_hdd_tdls_initiator_wait_cb,
19990 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053019991 }
Hoonki Lee14621352013-04-16 17:51:19 -070019992 wlan_hdd_tdls_timer_restart(pAdapter,
19993 &pTdlsPeer->initiatorWaitTimeoutTimer,
19994 WAIT_TIME_TDLS_INITIATOR);
19995 /* suspend initiator TX until it receives direct packet from the
19996 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019997 ret = WLANTL_SuspendDataTx(
19998 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
19999 &staId, NULL);
20000 if (ret != VOS_STATUS_SUCCESS) {
20001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20002 }
Hoonki Lee14621352013-04-16 17:51:19 -070020003 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020004
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020005 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020006 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020007 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020008 suppChannelLen =
20009 tdlsLinkEstablishParams.supportedChannelsLen;
20010
20011 if ((suppChannelLen > 0) &&
20012 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20013 {
20014 tANI_U8 suppPeerChannel = 0;
20015 int i = 0;
20016 for (i = 0U; i < suppChannelLen; i++)
20017 {
20018 suppPeerChannel =
20019 tdlsLinkEstablishParams.supportedChannels[i];
20020
20021 pTdlsPeer->isOffChannelSupported = FALSE;
20022 if (suppPeerChannel ==
20023 pTdlsPeer->peerParams.channel)
20024 {
20025 pTdlsPeer->isOffChannelSupported = TRUE;
20026 break;
20027 }
20028 }
20029 }
20030 else
20031 {
20032 pTdlsPeer->isOffChannelSupported = FALSE;
20033 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020034 }
20035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20036 "%s: TDLS channel switch request for channel "
20037 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020038 "%d isOffChannelSupported %d", __func__,
20039 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020040 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020041 suppChannelLen,
20042 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020043
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020044 /* TDLS Off Channel, Enable tdls channel switch,
20045 when their is only one tdls link and it supports */
20046 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20047 if ((numCurrTdlsPeers == 1) &&
20048 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20049 (TRUE == pTdlsPeer->isOffChannelConfigured))
20050 {
20051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20052 "%s: Send TDLS channel switch request for channel %d",
20053 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020054
20055 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020056 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20057 channel = pTdlsPeer->peerParams.channel;
20058
20059 mutex_unlock(&pHddCtx->tdls_lock);
20060
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020061 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20062 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020063 peerMac,
20064 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020065 TDLS_OFF_CHANNEL_BW_OFFSET,
20066 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020067 if (ret != VOS_STATUS_SUCCESS) {
20068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20069 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020070 }
20071 else
20072 {
20073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20074 "%s: TDLS channel switch request not sent"
20075 " numCurrTdlsPeers %d "
20076 "isOffChannelSupported %d "
20077 "isOffChannelConfigured %d",
20078 __func__, numCurrTdlsPeers,
20079 pTdlsPeer->isOffChannelSupported,
20080 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020081 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020082 }
20083
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020084 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020085 else
20086 mutex_unlock(&pHddCtx->tdls_lock);
20087
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020088 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020089
20090 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020091 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20092 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020093 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020094 int ac;
20095 uint8 ucAc[4] = { WLANTL_AC_VO,
20096 WLANTL_AC_VI,
20097 WLANTL_AC_BK,
20098 WLANTL_AC_BE };
20099 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20100 for(ac=0; ac < 4; ac++)
20101 {
20102 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20103 pTdlsPeer->staId, ucAc[ac],
20104 tlTid[ac], tlTid[ac], 0, 0,
20105 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020106 if (status != VOS_STATUS_SUCCESS) {
20107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20108 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020109 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020110 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020111 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020112
Bhargav Shah66896792015-10-01 18:17:37 +053020113 /* stop TCP delack timer if TDLS is enable */
20114 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20115 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020116 hdd_wlan_tdls_enable_link_event(peer,
20117 pTdlsPeer->isOffChannelSupported,
20118 pTdlsPeer->isOffChannelConfigured,
20119 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020120 }
20121 break;
20122 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020123 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020124 tANI_U16 numCurrTdlsPeers = 0;
20125 hddTdlsPeer_t *connPeer = NULL;
20126
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20128 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20129 __func__, MAC_ADDR_ARRAY(peer));
20130
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020131 mutex_lock(&pHddCtx->tdls_lock);
20132 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020133
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020134
Sunil Dutt41de4e22013-11-14 18:09:02 +053020135 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020136 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20138 " (oper %d) not exsting. ignored",
20139 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20140 return -EINVAL;
20141 }
20142
20143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20144 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20145 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20146 "NL80211_TDLS_DISABLE_LINK");
20147
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020148 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020149 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020150 long status;
20151
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020152 /* set tdls off channel status to false for this peer */
20153 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020154 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20155 eTDLS_LINK_TEARING,
20156 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20157 eTDLS_LINK_UNSPECIFIED:
20158 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020159 mutex_unlock(&pHddCtx->tdls_lock);
20160
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020161 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20162
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020163 status = sme_DeleteTdlsPeerSta(
20164 WLAN_HDD_GET_HAL_CTX(pAdapter),
20165 pAdapter->sessionId, peer );
20166 if (status != VOS_STATUS_SUCCESS) {
20167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20168 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020169
20170 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20171 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020172
20173 mutex_lock(&pHddCtx->tdls_lock);
20174 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20175 if ( NULL == pTdlsPeer ) {
20176 mutex_unlock(&pHddCtx->tdls_lock);
20177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20178 " peer was freed in other context",
20179 __func__, MAC_ADDR_ARRAY(peer));
20180 return -EINVAL;
20181 }
20182
Atul Mittal271a7652014-09-12 13:18:22 +053020183 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020184 eTDLS_LINK_IDLE,
20185 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020186 mutex_unlock(&pHddCtx->tdls_lock);
20187
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020188 if (status <= 0)
20189 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20191 "%s: Del station failed status %ld",
20192 __func__, status);
20193 return -EPERM;
20194 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020195
20196 /* TDLS Off Channel, Enable tdls channel switch,
20197 when their is only one tdls link and it supports */
20198 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20199 if (numCurrTdlsPeers == 1)
20200 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020201 tSirMacAddr peerMac;
20202 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020203
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020204 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020205 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020206
20207 if (connPeer == NULL) {
20208 mutex_unlock(&pHddCtx->tdls_lock);
20209 hddLog(VOS_TRACE_LEVEL_ERROR,
20210 "%s connPeer is NULL", __func__);
20211 return -EINVAL;
20212 }
20213
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020214 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20215 channel = connPeer->peerParams.channel;
20216
20217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20218 "%s: TDLS channel switch "
20219 "isOffChannelSupported %d "
20220 "isOffChannelConfigured %d "
20221 "isOffChannelEstablished %d",
20222 __func__,
20223 (connPeer ? connPeer->isOffChannelSupported : -1),
20224 (connPeer ? connPeer->isOffChannelConfigured : -1),
20225 (connPeer ? connPeer->isOffChannelEstablished : -1));
20226
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020227 if ((connPeer) &&
20228 (connPeer->isOffChannelSupported == TRUE) &&
20229 (connPeer->isOffChannelConfigured == TRUE))
20230 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020231 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020232 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020233 status = sme_SendTdlsChanSwitchReq(
20234 WLAN_HDD_GET_HAL_CTX(pAdapter),
20235 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020236 peerMac,
20237 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020238 TDLS_OFF_CHANNEL_BW_OFFSET,
20239 TDLS_CHANNEL_SWITCH_ENABLE);
20240 if (status != VOS_STATUS_SUCCESS) {
20241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20242 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020243 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020244 else
20245 mutex_unlock(&pHddCtx->tdls_lock);
20246 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020247 else
20248 {
20249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20250 "%s: TDLS channel switch request not sent "
20251 "numCurrTdlsPeers %d ",
20252 __func__, numCurrTdlsPeers);
20253 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020254 }
20255 else
20256 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020257 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20259 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020260 }
Bhargav Shah66896792015-10-01 18:17:37 +053020261 if (numCurrTdlsPeers == 0) {
20262 /* start TCP delack timer if TDLS is disable */
20263 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20264 hdd_manage_delack_timer(pHddCtx);
20265 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020266 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020267 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020268 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020269 {
Atul Mittal115287b2014-07-08 13:26:33 +053020270 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020271
Atul Mittal115287b2014-07-08 13:26:33 +053020272 if (0 != status)
20273 {
20274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020275 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020276 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020277 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020278 break;
20279 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020280 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020281 {
Atul Mittal115287b2014-07-08 13:26:33 +053020282 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20283 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020284 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020285 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020286
Atul Mittal115287b2014-07-08 13:26:33 +053020287 if (0 != status)
20288 {
20289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020290 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020291 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020292 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020293 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020294 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020295 case NL80211_TDLS_DISCOVERY_REQ:
20296 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020298 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020299 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020300 return -ENOTSUPP;
20301 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20303 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020304 return -ENOTSUPP;
20305 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020306
20307 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020308 return 0;
20309}
Chilam NG571c65a2013-01-19 12:27:36 +053020310
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020311static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020312#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20313 const u8 *peer,
20314#else
20315 u8 *peer,
20316#endif
20317 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020318{
20319 int ret;
20320
20321 vos_ssr_protect(__func__);
20322 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20323 vos_ssr_unprotect(__func__);
20324
20325 return ret;
20326}
20327
Chilam NG571c65a2013-01-19 12:27:36 +053020328int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20329 struct net_device *dev, u8 *peer)
20330{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020331 hddLog(VOS_TRACE_LEVEL_INFO,
20332 "tdls send discover req: "MAC_ADDRESS_STR,
20333 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020334#if TDLS_MGMT_VERSION2
20335 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20336 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20337#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20339 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20340 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20341#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20342 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20343 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20344#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20345 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20346 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20347#else
Chilam NG571c65a2013-01-19 12:27:36 +053020348 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20349 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020350#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020351#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020352}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020353#endif
20354
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020355#ifdef WLAN_FEATURE_GTK_OFFLOAD
20356/*
20357 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20358 * Callback rountine called upon receiving response for
20359 * get offload info
20360 */
20361void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20362 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20363{
20364
20365 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020366 tANI_U8 tempReplayCounter[8];
20367 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020368
20369 ENTER();
20370
20371 if (NULL == pAdapter)
20372 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020374 "%s: HDD adapter is Null", __func__);
20375 return ;
20376 }
20377
20378 if (NULL == pGtkOffloadGetInfoRsp)
20379 {
20380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20381 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20382 return ;
20383 }
20384
20385 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20386 {
20387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20388 "%s: wlan Failed to get replay counter value",
20389 __func__);
20390 return ;
20391 }
20392
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020393 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20394 /* Update replay counter */
20395 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20396 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20397
20398 {
20399 /* changing from little to big endian since supplicant
20400 * works on big endian format
20401 */
20402 int i;
20403 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20404
20405 for (i = 0; i < 8; i++)
20406 {
20407 tempReplayCounter[7-i] = (tANI_U8)p[i];
20408 }
20409 }
20410
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020411 /* Update replay counter to NL */
20412 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020413 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020414}
20415
20416/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020417 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020418 * This function is used to offload GTK rekeying job to the firmware.
20419 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020420int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020421 struct cfg80211_gtk_rekey_data *data)
20422{
20423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20424 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20425 hdd_station_ctx_t *pHddStaCtx;
20426 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020427 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020428 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020429 eHalStatus status = eHAL_STATUS_FAILURE;
20430
20431 ENTER();
20432
20433 if (NULL == pAdapter)
20434 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020436 "%s: HDD adapter is Null", __func__);
20437 return -ENODEV;
20438 }
20439
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20441 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20442 pAdapter->sessionId, pAdapter->device_mode));
20443
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020444 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020445 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020447 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020448 }
20449
20450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20451 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20452 if (NULL == hHal)
20453 {
20454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20455 "%s: HAL context is Null!!!", __func__);
20456 return -EAGAIN;
20457 }
20458
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020459 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20460 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20461 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20462 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020463 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020464 {
20465 /* changing from big to little endian since driver
20466 * works on little endian format
20467 */
20468 tANI_U8 *p =
20469 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20470 int i;
20471
20472 for (i = 0; i < 8; i++)
20473 {
20474 p[7-i] = data->replay_ctr[i];
20475 }
20476 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020477
20478 if (TRUE == pHddCtx->hdd_wlan_suspended)
20479 {
20480 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020481 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20482 sizeof (tSirGtkOffloadParams));
20483 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020484 pAdapter->sessionId);
20485
20486 if (eHAL_STATUS_SUCCESS != status)
20487 {
20488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20489 "%s: sme_SetGTKOffload failed, returned %d",
20490 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020491
20492 /* Need to clear any trace of key value in the memory.
20493 * Thus zero out the memory even though it is local
20494 * variable.
20495 */
20496 vos_mem_zero(&hddGtkOffloadReqParams,
20497 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020498 return status;
20499 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20501 "%s: sme_SetGTKOffload successfull", __func__);
20502 }
20503 else
20504 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20506 "%s: wlan not suspended GTKOffload request is stored",
20507 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020508 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020509
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020510 /* Need to clear any trace of key value in the memory.
20511 * Thus zero out the memory even though it is local
20512 * variable.
20513 */
20514 vos_mem_zero(&hddGtkOffloadReqParams,
20515 sizeof(hddGtkOffloadReqParams));
20516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020517 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020518 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020519}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020520
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020521int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20522 struct cfg80211_gtk_rekey_data *data)
20523{
20524 int ret;
20525
20526 vos_ssr_protect(__func__);
20527 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20528 vos_ssr_unprotect(__func__);
20529
20530 return ret;
20531}
20532#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020533/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020534 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020535 * This function is used to set access control policy
20536 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020537static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20538 struct net_device *dev,
20539 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020540{
20541 int i;
20542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20543 hdd_hostapd_state_t *pHostapdState;
20544 tsap_Config_t *pConfig;
20545 v_CONTEXT_t pVosContext = NULL;
20546 hdd_context_t *pHddCtx;
20547 int status;
20548
20549 ENTER();
20550
20551 if (NULL == pAdapter)
20552 {
20553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20554 "%s: HDD adapter is Null", __func__);
20555 return -ENODEV;
20556 }
20557
20558 if (NULL == params)
20559 {
20560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20561 "%s: params is Null", __func__);
20562 return -EINVAL;
20563 }
20564
20565 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20566 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020567 if (0 != status)
20568 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020569 return status;
20570 }
20571
20572 pVosContext = pHddCtx->pvosContext;
20573 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20574
20575 if (NULL == pHostapdState)
20576 {
20577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20578 "%s: pHostapdState is Null", __func__);
20579 return -EINVAL;
20580 }
20581
20582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20583 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020584 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20585 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20586 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020587
20588 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20589 {
20590 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20591
20592 /* default value */
20593 pConfig->num_accept_mac = 0;
20594 pConfig->num_deny_mac = 0;
20595
20596 /**
20597 * access control policy
20598 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20599 * listed in hostapd.deny file.
20600 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20601 * listed in hostapd.accept file.
20602 */
20603 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20604 {
20605 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20606 }
20607 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20608 {
20609 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20610 }
20611 else
20612 {
20613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20614 "%s:Acl Policy : %d is not supported",
20615 __func__, params->acl_policy);
20616 return -ENOTSUPP;
20617 }
20618
20619 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20620 {
20621 pConfig->num_accept_mac = params->n_acl_entries;
20622 for (i = 0; i < params->n_acl_entries; i++)
20623 {
20624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20625 "** Add ACL MAC entry %i in WhiletList :"
20626 MAC_ADDRESS_STR, i,
20627 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20628
20629 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20630 sizeof(qcmacaddr));
20631 }
20632 }
20633 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20634 {
20635 pConfig->num_deny_mac = params->n_acl_entries;
20636 for (i = 0; i < params->n_acl_entries; i++)
20637 {
20638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20639 "** Add ACL MAC entry %i in BlackList :"
20640 MAC_ADDRESS_STR, i,
20641 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20642
20643 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20644 sizeof(qcmacaddr));
20645 }
20646 }
20647
20648 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20649 {
20650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20651 "%s: SAP Set Mac Acl fail", __func__);
20652 return -EINVAL;
20653 }
20654 }
20655 else
20656 {
20657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020658 "%s: Invalid device_mode = %s (%d)",
20659 __func__, hdd_device_modetoString(pAdapter->device_mode),
20660 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020661 return -EINVAL;
20662 }
20663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020664 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020665 return 0;
20666}
20667
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020668static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20669 struct net_device *dev,
20670 const struct cfg80211_acl_data *params)
20671{
20672 int ret;
20673 vos_ssr_protect(__func__);
20674 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20675 vos_ssr_unprotect(__func__);
20676
20677 return ret;
20678}
20679
Leo Chang9056f462013-08-01 19:21:11 -070020680#ifdef WLAN_NL80211_TESTMODE
20681#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020682void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020683(
20684 void *pAdapter,
20685 void *indCont
20686)
20687{
Leo Changd9df8aa2013-09-26 13:32:26 -070020688 tSirLPHBInd *lphbInd;
20689 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020690 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020691
20692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020693 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020694
c_hpothu73f35e62014-04-18 13:40:08 +053020695 if (pAdapter == NULL)
20696 {
20697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20698 "%s: pAdapter is NULL\n",__func__);
20699 return;
20700 }
20701
Leo Chang9056f462013-08-01 19:21:11 -070020702 if (NULL == indCont)
20703 {
20704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020705 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020706 return;
20707 }
20708
c_hpothu73f35e62014-04-18 13:40:08 +053020709 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020710 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020711 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020712 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020713 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020714 GFP_ATOMIC);
20715 if (!skb)
20716 {
20717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20718 "LPHB timeout, NL buffer alloc fail");
20719 return;
20720 }
20721
Leo Changac3ba772013-10-07 09:47:04 -070020722 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020723 {
20724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20725 "WLAN_HDD_TM_ATTR_CMD put fail");
20726 goto nla_put_failure;
20727 }
Leo Changac3ba772013-10-07 09:47:04 -070020728 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020729 {
20730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20731 "WLAN_HDD_TM_ATTR_TYPE put fail");
20732 goto nla_put_failure;
20733 }
Leo Changac3ba772013-10-07 09:47:04 -070020734 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020735 sizeof(tSirLPHBInd), lphbInd))
20736 {
20737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20738 "WLAN_HDD_TM_ATTR_DATA put fail");
20739 goto nla_put_failure;
20740 }
Leo Chang9056f462013-08-01 19:21:11 -070020741 cfg80211_testmode_event(skb, GFP_ATOMIC);
20742 return;
20743
20744nla_put_failure:
20745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20746 "NLA Put fail");
20747 kfree_skb(skb);
20748
20749 return;
20750}
20751#endif /* FEATURE_WLAN_LPHB */
20752
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020753static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020754{
20755 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20756 int err = 0;
20757#ifdef FEATURE_WLAN_LPHB
20758 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020759 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020760
20761 ENTER();
20762
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020763 err = wlan_hdd_validate_context(pHddCtx);
20764 if (0 != err)
20765 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020766 return err;
20767 }
Leo Chang9056f462013-08-01 19:21:11 -070020768#endif /* FEATURE_WLAN_LPHB */
20769
20770 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20771 if (err)
20772 {
20773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20774 "%s Testmode INV ATTR", __func__);
20775 return err;
20776 }
20777
20778 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20779 {
20780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20781 "%s Testmode INV CMD", __func__);
20782 return -EINVAL;
20783 }
20784
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20786 TRACE_CODE_HDD_CFG80211_TESTMODE,
20787 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020788 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20789 {
20790#ifdef FEATURE_WLAN_LPHB
20791 /* Low Power Heartbeat configuration request */
20792 case WLAN_HDD_TM_CMD_WLAN_HB:
20793 {
20794 int buf_len;
20795 void *buf;
20796 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020797 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020798
20799 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20800 {
20801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20802 "%s Testmode INV DATA", __func__);
20803 return -EINVAL;
20804 }
20805
20806 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20807 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020808
Manjeet Singh3c577442017-02-10 19:03:38 +053020809 if (buf_len > sizeof(*hb_params)) {
20810 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20811 buf_len);
20812 return -ERANGE;
20813 }
20814
Amar Singhal05852702014-02-04 14:40:00 -080020815 hb_params_temp =(tSirLPHBReq *)buf;
20816 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20817 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20818 return -EINVAL;
20819
Leo Chang9056f462013-08-01 19:21:11 -070020820 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20821 if (NULL == hb_params)
20822 {
20823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20824 "%s Request Buffer Alloc Fail", __func__);
20825 return -EINVAL;
20826 }
20827
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020828 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020829 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020830 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20831 hb_params,
20832 wlan_hdd_cfg80211_lphb_ind_handler);
20833 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020834 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20836 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020837 vos_mem_free(hb_params);
20838 }
Leo Chang9056f462013-08-01 19:21:11 -070020839 return 0;
20840 }
20841#endif /* FEATURE_WLAN_LPHB */
20842 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20844 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020845 return -EOPNOTSUPP;
20846 }
20847
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020848 EXIT();
20849 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020850}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020851
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020852static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20854 struct wireless_dev *wdev,
20855#endif
20856 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020857{
20858 int ret;
20859
20860 vos_ssr_protect(__func__);
20861 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20862 vos_ssr_unprotect(__func__);
20863
20864 return ret;
20865}
Leo Chang9056f462013-08-01 19:21:11 -070020866#endif /* CONFIG_NL80211_TESTMODE */
20867
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020868extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020869static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020870 struct net_device *dev,
20871 int idx, struct survey_info *survey)
20872{
20873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20874 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020875 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020876 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020877 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020878 v_S7_t snr,rssi;
20879 int status, i, j, filled = 0;
20880
20881 ENTER();
20882
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020883 if (NULL == pAdapter)
20884 {
20885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20886 "%s: HDD adapter is Null", __func__);
20887 return -ENODEV;
20888 }
20889
20890 if (NULL == wiphy)
20891 {
20892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20893 "%s: wiphy is Null", __func__);
20894 return -ENODEV;
20895 }
20896
20897 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20898 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020899 if (0 != status)
20900 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020901 return status;
20902 }
20903
Mihir Sheted9072e02013-08-21 17:02:29 +053020904 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20905
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020906 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053020907 0 != pAdapter->survey_idx ||
20908 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020909 {
20910 /* The survey dump ops when implemented completely is expected to
20911 * return a survey of all channels and the ops is called by the
20912 * kernel with incremental values of the argument 'idx' till it
20913 * returns -ENONET. But we can only support the survey for the
20914 * operating channel for now. survey_idx is used to track
20915 * that the ops is called only once and then return -ENONET for
20916 * the next iteration
20917 */
20918 pAdapter->survey_idx = 0;
20919 return -ENONET;
20920 }
20921
Mukul Sharma9d5233b2015-06-11 20:28:20 +053020922 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
20923 {
20924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20925 "%s: Roaming in progress, hence return ", __func__);
20926 return -ENONET;
20927 }
20928
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020929 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
20930
20931 wlan_hdd_get_snr(pAdapter, &snr);
20932 wlan_hdd_get_rssi(pAdapter, &rssi);
20933
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20935 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
20936 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020937 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
20938 hdd_wlan_get_freq(channel, &freq);
20939
20940
20941 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
20942 {
20943 if (NULL == wiphy->bands[i])
20944 {
20945 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
20946 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
20947 continue;
20948 }
20949
20950 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
20951 {
20952 struct ieee80211_supported_band *band = wiphy->bands[i];
20953
20954 if (band->channels[j].center_freq == (v_U16_t)freq)
20955 {
20956 survey->channel = &band->channels[j];
20957 /* The Rx BDs contain SNR values in dB for the received frames
20958 * while the supplicant expects noise. So we calculate and
20959 * return the value of noise (dBm)
20960 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
20961 */
20962 survey->noise = rssi - snr;
20963 survey->filled = SURVEY_INFO_NOISE_DBM;
20964 filled = 1;
20965 }
20966 }
20967 }
20968
20969 if (filled)
20970 pAdapter->survey_idx = 1;
20971 else
20972 {
20973 pAdapter->survey_idx = 0;
20974 return -ENONET;
20975 }
20976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020977 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020978 return 0;
20979}
20980
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020981static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
20982 struct net_device *dev,
20983 int idx, struct survey_info *survey)
20984{
20985 int ret;
20986
20987 vos_ssr_protect(__func__);
20988 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
20989 vos_ssr_unprotect(__func__);
20990
20991 return ret;
20992}
20993
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020994/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020995 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020996 * this is called when cfg80211 driver resume
20997 * driver updates latest sched_scan scan result(if any) to cfg80211 database
20998 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053020999int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021000{
21001 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21002 hdd_adapter_t *pAdapter;
21003 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21004 VOS_STATUS status = VOS_STATUS_SUCCESS;
21005
21006 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021007
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021008 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021009 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021010 return 0;
21011 }
21012
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021013 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21014 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021015
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021016 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021017 {
21018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21019 "%s: Resume SoftAP", __func__);
21020 hdd_set_wlan_suspend_mode(false);
21021 }
21022
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021023 spin_lock(&pHddCtx->schedScan_lock);
21024 pHddCtx->isWiphySuspended = FALSE;
21025 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21026 {
21027 spin_unlock(&pHddCtx->schedScan_lock);
21028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21029 "%s: Return resume is not due to PNO indication", __func__);
21030 return 0;
21031 }
21032 // Reset flag to avoid updatating cfg80211 data old results again
21033 pHddCtx->isSchedScanUpdatePending = FALSE;
21034 spin_unlock(&pHddCtx->schedScan_lock);
21035
21036 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21037
21038 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21039 {
21040 pAdapter = pAdapterNode->pAdapter;
21041 if ( (NULL != pAdapter) &&
21042 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21043 {
21044 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021045 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21047 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021048 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021049 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021050 {
21051 /* Acquire wakelock to handle the case where APP's tries to
21052 * suspend immediately after updating the scan results. Whis
21053 * results in app's is in suspended state and not able to
21054 * process the connect request to AP
21055 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021056 hdd_prevent_suspend_timeout(2000,
21057 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021058 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021059 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021060
21061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21062 "%s : cfg80211 scan result database updated", __func__);
21063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021064 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021065 return 0;
21066
21067 }
21068 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21069 pAdapterNode = pNext;
21070 }
21071
21072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21073 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021074 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021075 return 0;
21076}
21077
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021078int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21079{
21080 int ret;
21081
21082 vos_ssr_protect(__func__);
21083 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21084 vos_ssr_unprotect(__func__);
21085
21086 return ret;
21087}
21088
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021089/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021090 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021091 * this is called when cfg80211 driver suspends
21092 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021093int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021094 struct cfg80211_wowlan *wow)
21095{
21096 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021097 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021098
21099 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021100
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021101 ret = wlan_hdd_validate_context(pHddCtx);
21102 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021103 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021104 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021105 }
21106
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021107 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21109 "%s: Suspend SoftAP", __func__);
21110 hdd_set_wlan_suspend_mode(true);
21111 }
21112
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021113
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021114 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21115 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21116 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021117 pHddCtx->isWiphySuspended = TRUE;
21118
21119 EXIT();
21120
21121 return 0;
21122}
21123
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021124int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21125 struct cfg80211_wowlan *wow)
21126{
21127 int ret;
21128
21129 vos_ssr_protect(__func__);
21130 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21131 vos_ssr_unprotect(__func__);
21132
21133 return ret;
21134}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021135
21136#ifdef FEATURE_OEM_DATA_SUPPORT
21137static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021138 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021139{
21140 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21141
21142 ENTER();
21143
21144 if (wlan_hdd_validate_context(pHddCtx)) {
21145 return;
21146 }
21147 if (!pMsg)
21148 {
21149 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21150 return;
21151 }
21152
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021153 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021154
21155 EXIT();
21156 return;
21157
21158}
21159
21160void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021161 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021162{
21163 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21164
21165 ENTER();
21166
21167 if (wlan_hdd_validate_context(pHddCtx)) {
21168 return;
21169 }
21170
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021172
21173 switch(evType) {
21174 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021175 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021176 break;
21177 default:
21178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21179 break;
21180 }
21181 EXIT();
21182}
21183#endif
21184
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21186 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021187/**
21188 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21189 * @wiphy: Pointer to wiphy
21190 * @wdev: Pointer to wireless device structure
21191 *
21192 * This function is used to abort an ongoing scan
21193 *
21194 * Return: None
21195 */
21196static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21197 struct wireless_dev *wdev)
21198{
21199 struct net_device *dev = wdev->netdev;
21200 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21201 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21202 int ret;
21203
21204 ENTER();
21205
21206 if (NULL == adapter) {
21207 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21208 return;
21209 }
21210
21211 ret = wlan_hdd_validate_context(hdd_ctx);
21212 if (0 != ret)
21213 return;
21214
21215 wlan_hdd_scan_abort(adapter);
21216
21217 return;
21218}
21219
21220/**
21221 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21222 * @wiphy: Pointer to wiphy
21223 * @wdev: Pointer to wireless device structure
21224 *
21225 * Return: None
21226 */
21227void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21228 struct wireless_dev *wdev)
21229{
21230 vos_ssr_protect(__func__);
21231 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21232 vos_ssr_unprotect(__func__);
21233
21234 return;
21235}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021236#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021237
Abhishek Singh936c6932017-11-07 17:28:23 +053021238#ifdef CHANNEL_SWITCH_SUPPORTED
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 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21254 hdd_context_t *hdd_ctx;
21255 uint8_t channel;
21256 int ret;
21257 v_CONTEXT_t vos_ctx;
21258
21259 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21260
21261 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21262 ret = wlan_hdd_validate_context(hdd_ctx);
21263 if (ret)
21264 return ret;
21265
21266 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21267 if (!vos_ctx) {
21268 hddLog(LOGE, FL("Vos ctx is null"));
21269 return -EINVAL;
21270 }
21271
21272 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21273 (WLAN_HDD_P2P_GO != adapter->device_mode))
21274 return -ENOTSUPP;
21275
21276 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021277 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021278
21279 return ret;
21280}
21281
21282/**
21283 * wlan_hdd_cfg80211_channel_switch()- function to switch
21284 * channel in SAP/GO
21285 * @wiphy: wiphy pointer
21286 * @dev: dev pointer.
21287 * @csa_params: Change channel params
21288 *
21289 * This function is called to switch channel in SAP/GO
21290 *
21291 * Return: 0 if success else return non zero
21292 */
21293static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21294 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21295{
21296 int ret;
21297
21298 vos_ssr_protect(__func__);
21299 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21300 vos_ssr_unprotect(__func__);
21301
21302 return ret;
21303}
21304#endif
21305
Jeff Johnson295189b2012-06-20 16:38:30 -070021306/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021307static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021308{
21309 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21310 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21311 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21312 .change_station = wlan_hdd_change_station,
21313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21314 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21315 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21316 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021317#else
21318 .start_ap = wlan_hdd_cfg80211_start_ap,
21319 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21320 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021321#endif
21322 .change_bss = wlan_hdd_cfg80211_change_bss,
21323 .add_key = wlan_hdd_cfg80211_add_key,
21324 .get_key = wlan_hdd_cfg80211_get_key,
21325 .del_key = wlan_hdd_cfg80211_del_key,
21326 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021327#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021328 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021330 .scan = wlan_hdd_cfg80211_scan,
21331 .connect = wlan_hdd_cfg80211_connect,
21332 .disconnect = wlan_hdd_cfg80211_disconnect,
21333 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21334 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21335 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21336 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21337 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021338 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21339 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021340 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21342 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21343 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21344 .set_txq_params = wlan_hdd_set_txq_params,
21345#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021346 .get_station = wlan_hdd_cfg80211_get_station,
21347 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21348 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021349 .add_station = wlan_hdd_cfg80211_add_station,
21350#ifdef FEATURE_WLAN_LFR
21351 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21352 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21353 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21354#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021355#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21356 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21357#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021358#ifdef FEATURE_WLAN_TDLS
21359 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21360 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21361#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021362#ifdef WLAN_FEATURE_GTK_OFFLOAD
21363 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21364#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021365#ifdef FEATURE_WLAN_SCAN_PNO
21366 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21367 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21368#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021369 .resume = wlan_hdd_cfg80211_resume_wlan,
21370 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021371 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021372#ifdef WLAN_NL80211_TESTMODE
21373 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21374#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021375 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21377 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021378 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021379#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021380#ifdef CHANNEL_SWITCH_SUPPORTED
21381 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21382#endif
21383
Jeff Johnson295189b2012-06-20 16:38:30 -070021384};
21385