blob: b4e5228d18b9e435a6da76098068deaa81e4774c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2197 { .type = NLA_UNSPEC },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2199 { .type = NLA_S32 },
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2201 { .type = NLA_S32 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2203 { .type = NLA_U32 },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2205 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2207 { .type = NLA_U32 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2209 { .type = NLA_BINARY,
2210 .len = IEEE80211_MAX_SSID_LEN + 1 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302212 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2214 { .type = NLA_U32 },
2215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2216 { .type = NLA_U8 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2218 { .type = NLA_S32 },
2219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2220 { .type = NLA_S32 },
2221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2222 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302223};
2224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225/**
2226 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2227 * @ctx: hdd global context
2228 * @data: capabilities data
2229 *
2230 * Return: none
2231 */
2232static void
2233wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302236 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302237 tSirEXTScanCapabilitiesEvent *data =
2238 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
2242 if (wlan_hdd_validate_context(pHddCtx))
2243 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302244 return;
2245 }
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 if (!pMsg)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2250 return;
2251 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302253 vos_spin_lock_acquire(&hdd_context_lock);
2254
2255 context = &pHddCtx->ext_scan_context;
2256 /* validate response received from target*/
2257 if (context->request_id != data->requestId)
2258 {
2259 vos_spin_lock_release(&hdd_context_lock);
2260 hddLog(LOGE,
2261 FL("Target response id did not match: request_id %d resposne_id %d"),
2262 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302265 else
2266 {
2267 context->capability_response = *data;
2268 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 }
2270
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302272
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273 return;
2274}
2275
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302276/*
2277 * define short names for the global vendor params
2278 * used by wlan_hdd_send_ext_scan_capability()
2279 */
2280#define PARAM_REQUEST_ID \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2282#define PARAM_STATUS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2284#define MAX_SCAN_CACHE_SIZE \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2286#define MAX_SCAN_BUCKETS \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2288#define MAX_AP_CACHE_PER_SCAN \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2290#define MAX_RSSI_SAMPLE_SIZE \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2292#define MAX_SCAN_RPT_THRHOLD \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2294#define MAX_HOTLIST_BSSIDS \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2296#define MAX_BSSID_HISTORY_ENTRIES \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2298#define MAX_HOTLIST_SSIDS \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302300#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302302
2303static int wlan_hdd_send_ext_scan_capability(void *ctx)
2304{
2305 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2306 struct sk_buff *skb = NULL;
2307 int ret;
2308 tSirEXTScanCapabilitiesEvent *data;
2309 tANI_U32 nl_buf_len;
2310
2311 ret = wlan_hdd_validate_context(pHddCtx);
2312 if (0 != ret)
2313 {
2314 return ret;
2315 }
2316
2317 data = &(pHddCtx->ext_scan_context.capability_response);
2318
2319 nl_buf_len = NLMSG_HDRLEN;
2320 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2321 (sizeof(data->status) + NLA_HDRLEN) +
2322 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2323 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2324 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2325 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2326 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2327 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2328 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2329 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2330
2331 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2332
2333 if (!skb)
2334 {
2335 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2336 return -ENOMEM;
2337 }
2338
2339 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2340 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2341 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2342 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2343 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2344 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2345 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2346 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2347
2348 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2349 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2350 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2351 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2352 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2353 data->maxApPerScan) ||
2354 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2355 data->maxRssiSampleSize) ||
2356 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2357 data->maxScanReportingThreshold) ||
2358 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2359 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2360 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302361 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2362 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302363 {
2364 hddLog(LOGE, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_cmd_reply(skb);
2369 return 0;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return -EINVAL;;
2374}
2375
2376/*
2377 * done with short names for the global vendor params
2378 * used by wlan_hdd_send_ext_scan_capability()
2379 */
2380#undef PARAM_REQUEST_ID
2381#undef PARAM_STATUS
2382#undef MAX_SCAN_CACHE_SIZE
2383#undef MAX_SCAN_BUCKETS
2384#undef MAX_AP_CACHE_PER_SCAN
2385#undef MAX_RSSI_SAMPLE_SIZE
2386#undef MAX_SCAN_RPT_THRHOLD
2387#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302388#undef MAX_BSSID_HISTORY_ENTRIES
2389#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390
2391static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2392{
2393 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302398 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302400 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302401 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302406 return;
2407 }
2408
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2410 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2411
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302412 context = &pHddCtx->ext_scan_context;
2413 spin_lock(&hdd_context_lock);
2414 if (context->request_id == pData->requestId) {
2415 context->response_status = pData->status ? -EINVAL : 0;
2416 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302417 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302418 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419
2420 /*
2421 * Store the Request ID for comparing with the requestID obtained
2422 * in other requests.HDD shall return a failure is the extscan_stop
2423 * request is issued with a different requestId as that of the
2424 * extscan_start request. Also, This requestId shall be used while
2425 * indicating the full scan results to the upper layers.
2426 * The requestId is stored with the assumption that the firmware
2427 * shall return the ext scan start request's requestId in ext scan
2428 * start response.
2429 */
2430 if (pData->status == 0)
2431 pMac->sme.extScanStartReqId = pData->requestId;
2432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302433 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435}
2436
2437
2438static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2439{
2440 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2441 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302442 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302444 ENTER();
2445
2446 if (wlan_hdd_validate_context(pHddCtx)){
2447 return;
2448 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302450 if (!pMsg)
2451 {
2452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302453 return;
2454 }
2455
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2457 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302459 context = &pHddCtx->ext_scan_context;
2460 spin_lock(&hdd_context_lock);
2461 if (context->request_id == pData->requestId) {
2462 context->response_status = pData->status ? -EINVAL : 0;
2463 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302465 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469}
2470
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2472 void *pMsg)
2473{
2474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302475 tpSirEXTScanSetBssidHotListRspParams pData =
2476 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302477 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479 ENTER();
2480
2481 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302482 return;
2483 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485 if (!pMsg)
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2488 return;
2489 }
2490
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2492 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302494 context = &pHddCtx->ext_scan_context;
2495 spin_lock(&hdd_context_lock);
2496 if (context->request_id == pData->requestId) {
2497 context->response_status = pData->status ? -EINVAL : 0;
2498 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302500 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302502 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504}
2505
2506static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2507 void *pMsg)
2508{
2509 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510 tpSirEXTScanResetBssidHotlistRspParams pData =
2511 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302512 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302514 ENTER();
2515
2516 if (wlan_hdd_validate_context(pHddCtx)) {
2517 return;
2518 }
2519 if (!pMsg)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302522 return;
2523 }
2524
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2526 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302528 context = &pHddCtx->ext_scan_context;
2529 spin_lock(&hdd_context_lock);
2530 if (context->request_id == pData->requestId) {
2531 context->response_status = pData->status ? -EINVAL : 0;
2532 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302534 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302536 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302537 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538}
2539
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302540static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2541 void *pMsg)
2542{
2543 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2544 tpSirEXTScanSetSsidHotListRspParams pData =
2545 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2546 struct hdd_ext_scan_context *context;
2547
2548 if (wlan_hdd_validate_context(pHddCtx)){
2549 return;
2550 }
2551
2552 if (!pMsg)
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2555 return;
2556 }
2557
2558 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2559 pData->status);
2560
2561 context = &pHddCtx->ext_scan_context;
2562 spin_lock(&hdd_context_lock);
2563 if (context->request_id == pData->requestId) {
2564 context->response_status = pData->status ? -EINVAL : 0;
2565 complete(&context->response_event);
2566 }
2567 spin_unlock(&hdd_context_lock);
2568
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 tpSirEXTScanResetSsidHotlistRspParams pData =
2577 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2578 struct hdd_ext_scan_context *context;
2579
2580 if (wlan_hdd_validate_context(pHddCtx)) {
2581 return;
2582 }
2583 if (!pMsg)
2584 {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2586 return;
2587 }
2588
2589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2590 pData->status);
2591
2592 context = &pHddCtx->ext_scan_context;
2593 spin_lock(&hdd_context_lock);
2594 if (context->request_id == pData->requestId) {
2595 context->response_status = pData->status ? -EINVAL : 0;
2596 complete(&context->response_event);
2597 }
2598 spin_unlock(&hdd_context_lock);
2599
2600 return;
2601}
2602
2603
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2605 void *pMsg)
2606{
2607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610 tANI_S32 totalResults;
2611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2613 struct hdd_ext_scan_context *context;
2614 bool ignore_cached_results = false;
2615 tExtscanCachedScanResult *result;
2616 struct nlattr *nla_results;
2617 tANI_U16 ieLength= 0;
2618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302620 ENTER();
2621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302625 if (!pMsg)
2626 {
2627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2628 return;
2629 }
2630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 spin_lock(&hdd_context_lock);
2632 context = &pHddCtx->ext_scan_context;
2633 ignore_cached_results = context->ignore_cached_results;
2634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 if (ignore_cached_results) {
2637 hddLog(LOGE,
2638 FL("Ignore the cached results received after timeout"));
2639 return;
2640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2648 scan_id_index++) {
2649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 totalResults = result->num_results;
2652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2653 result->scan_id, result->flags, totalResults);
2654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302656 do{
2657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2663
2664 if (!skb) {
2665 hddLog(VOS_TRACE_LEVEL_ERROR,
2666 FL("cfg80211_vendor_event_alloc failed"));
2667 return;
2668 }
2669
2670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2671
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u32(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2676 resultsPerEvent)) {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2678 goto fail;
2679 }
2680 if (nla_put_u8(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 {
2684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2685 goto fail;
2686 }
2687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302688 if (nla_put_u32(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2690 result->scan_id)) {
2691 hddLog(LOGE, FL("put fail"));
2692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302695 nla_results = nla_nest_start(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2697 if (!nla_results)
2698 goto fail;
2699
2700 if (resultsPerEvent) {
2701 struct nlattr *aps;
2702 struct nlattr *nla_result;
2703
2704 nla_result = nla_nest_start(skb, scan_id_index);
2705 if(!nla_result)
2706 goto fail;
2707
2708 if (nla_put_u32(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2710 result->scan_id) ||
2711 nla_put_u32(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2713 result->flags) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2716 totalResults)) {
2717 hddLog(LOGE, FL("put fail"));
2718 goto fail;
2719 }
2720
2721 aps = nla_nest_start(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2723 if (!aps)
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2726 goto fail;
2727 }
2728
2729 head_ptr = (tpSirWifiScanResult) &(result->ap);
2730
2731 for (j = 0; j < resultsPerEvent; j++, i++) {
2732 struct nlattr *ap;
2733 pSirWifiScanResult = head_ptr + i;
2734
2735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302736 * Firmware returns timestamp from extscan_start till
2737 * BSSID was cached (in micro seconds). Add this with
2738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302739 * to derive the time since boot when the
2740 * BSSID was cached.
2741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302742 pSirWifiScanResult->ts +=
2743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2745 "Ssid (%s)"
2746 "Bssid: %pM "
2747 "Channel (%u)"
2748 "Rssi (%d)"
2749 "RTT (%u)"
2750 "RTT_SD (%u)"
2751 "Beacon Period %u"
2752 "Capability 0x%x "
2753 "Ie length %d",
2754 i,
2755 pSirWifiScanResult->ts,
2756 pSirWifiScanResult->ssid,
2757 pSirWifiScanResult->bssid,
2758 pSirWifiScanResult->channel,
2759 pSirWifiScanResult->rssi,
2760 pSirWifiScanResult->rtt,
2761 pSirWifiScanResult->rtt_sd,
2762 pSirWifiScanResult->beaconPeriod,
2763 pSirWifiScanResult->capability,
2764 ieLength);
2765
2766 ap = nla_nest_start(skb, j + 1);
2767 if (!ap)
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772
2773 if (nla_put_u64(skb,
2774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2775 pSirWifiScanResult->ts) )
2776 {
2777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2778 goto fail;
2779 }
2780 if (nla_put(skb,
2781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2782 sizeof(pSirWifiScanResult->ssid),
2783 pSirWifiScanResult->ssid) )
2784 {
2785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2786 goto fail;
2787 }
2788 if (nla_put(skb,
2789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2790 sizeof(pSirWifiScanResult->bssid),
2791 pSirWifiScanResult->bssid) )
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2794 goto fail;
2795 }
2796 if (nla_put_u32(skb,
2797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2798 pSirWifiScanResult->channel) )
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2801 goto fail;
2802 }
2803 if (nla_put_s32(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2805 pSirWifiScanResult->rssi) )
2806 {
2807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2808 goto fail;
2809 }
2810 if (nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2812 pSirWifiScanResult->rtt) )
2813 {
2814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2815 goto fail;
2816 }
2817 if (nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2819 pSirWifiScanResult->rtt_sd))
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2822 goto fail;
2823 }
2824 if (nla_put_u32(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2826 pSirWifiScanResult->beaconPeriod))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2829 goto fail;
2830 }
2831 if (nla_put_u32(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2833 pSirWifiScanResult->capability))
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put_u32(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2840 ieLength))
2841 {
2842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2843 goto fail;
2844 }
2845
2846 if (ieLength)
2847 if (nla_put(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2849 ieLength, ie)) {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2851 goto fail;
2852 }
2853
2854 nla_nest_end(skb, ap);
2855 }
2856 nla_nest_end(skb, aps);
2857 nla_nest_end(skb, nla_result);
2858 }
2859
2860 nla_nest_end(skb, nla_results);
2861
2862 cfg80211_vendor_cmd_reply(skb);
2863
2864 } while (totalResults > 0);
2865 }
2866
2867 if (!pData->moreData) {
2868 spin_lock(&hdd_context_lock);
2869 context->response_status = 0;
2870 complete(&context->response_event);
2871 spin_unlock(&hdd_context_lock);
2872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 return;
2876fail:
2877 kfree_skb(skb);
2878 return;
2879}
2880
2881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2882 void *pMsg)
2883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302889 ENTER();
2890
2891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 hddLog(LOGE,
2893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302894 return;
2895 }
2896 if (!pMsg)
2897 {
2898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302899 return;
2900 }
2901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 if (pData->bss_found)
2903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2904 else
2905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2906
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2909 NULL,
2910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302913
2914 if (!skb) {
2915 hddLog(VOS_TRACE_LEVEL_ERROR,
2916 FL("cfg80211_vendor_event_alloc failed"));
2917 return;
2918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2924
2925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2927 "Ssid (%s) "
2928 "Bssid (" MAC_ADDRESS_STR ") "
2929 "Channel (%u) "
2930 "Rssi (%d) "
2931 "RTT (%u) "
2932 "RTT_SD (%u) ",
2933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->bssHotlist[i].ts,
2935 pData->bssHotlist[i].ssid,
2936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2937 pData->bssHotlist[i].channel,
2938 pData->bssHotlist[i].rssi,
2939 pData->bssHotlist[i].rtt,
2940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941 }
2942
2943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2944 pData->requestId) ||
2945 nla_put_u32(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2949 goto fail;
2950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 struct nlattr *aps;
2953
2954 aps = nla_nest_start(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2956 if (!aps)
2957 goto fail;
2958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 struct nlattr *ap;
2961
2962 ap = nla_nest_start(skb, i + 1);
2963 if (!ap)
2964 goto fail;
2965
2966 if (nla_put_u64(skb,
2967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 sizeof(pData->bssHotlist[i].ssid),
2972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 sizeof(pData->bssHotlist[i].bssid),
2976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 nla_put_u32(skb,
2978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302980 nla_put_s32(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302983 nla_put_u32(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 nla_put_u32(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302989 goto fail;
2990
2991 nla_nest_end(skb, ap);
2992 }
2993 nla_nest_end(skb, aps);
2994
2995 if (nla_put_u8(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2997 pData->moreData))
2998 goto fail;
2999 }
3000
3001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 return;
3004
3005fail:
3006 kfree_skb(skb);
3007 return;
3008
3009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303011/**
3012 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3013 * Handle an SSID hotlist match event
3014 * @ctx: HDD context registered with SME
3015 * @event: The SSID hotlist match event
3016 *
3017 * This function will take an SSID match event that was generated by
3018 * firmware and will convert it into a cfg80211 vendor event which is
3019 * sent to userspace.
3020 *
3021 * Return: none
3022 */
3023static void
3024wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3025 void *pMsg)
3026{
3027 hdd_context_t *hdd_ctx = ctx;
3028 struct sk_buff *skb;
3029 tANI_U32 i, index;
3030 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3031
3032 ENTER();
3033
3034 if (wlan_hdd_validate_context(hdd_ctx)) {
3035 hddLog(LOGE,
3036 FL("HDD context is not valid or response"));
3037 return;
3038 }
3039 if (!pMsg)
3040 {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3042 return;
3043 }
3044
3045 if (pData->ssid_found) {
3046 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3047 hddLog(LOG1, "SSID hotlist found");
3048 } else {
3049 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3050 hddLog(LOG1, "SSID hotlist lost");
3051 }
3052
3053 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3055 NULL,
3056#endif
3057 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3058 index, GFP_KERNEL);
3059
3060 if (!skb) {
3061 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3062 return;
3063 }
3064 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3065 pData->requestId, pData->numHotlistSsid, pData->moreData);
3066
3067 for (i = 0; i < pData->numHotlistSsid; i++) {
3068 hddLog(LOG1, "[i=%d] Timestamp %llu "
3069 "Ssid: %s "
3070 "Bssid (" MAC_ADDRESS_STR ") "
3071 "Channel %u "
3072 "Rssi %d "
3073 "RTT %u "
3074 "RTT_SD %u",
3075 i,
3076 pData->ssidHotlist[i].ts,
3077 pData->ssidHotlist[i].ssid,
3078 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3079 pData->ssidHotlist[i].channel,
3080 pData->ssidHotlist[i].rssi,
3081 pData->ssidHotlist[i].rtt,
3082 pData->ssidHotlist[i].rtt_sd);
3083 }
3084
3085 if (nla_put_u32(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3087 pData->requestId) ||
3088 nla_put_u32(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3090 pData->numHotlistSsid)) {
3091 hddLog(LOGE, FL("put fail"));
3092 goto fail;
3093 }
3094
3095 if (pData->numHotlistSsid) {
3096 struct nlattr *aps;
3097 aps = nla_nest_start(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3099 if (!aps) {
3100 hddLog(LOGE, FL("nest fail"));
3101 goto fail;
3102 }
3103
3104 for (i = 0; i < pData->numHotlistSsid; i++) {
3105 struct nlattr *ap;
3106
3107 ap = nla_nest_start(skb, i);
3108 if (!ap) {
3109 hddLog(LOGE, FL("nest fail"));
3110 goto fail;
3111 }
3112
3113 if (nla_put_u64(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3115 pData->ssidHotlist[i].ts) ||
3116 nla_put(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3118 sizeof(pData->ssidHotlist[i].ssid),
3119 pData->ssidHotlist[i].ssid) ||
3120 nla_put(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3122 sizeof(pData->ssidHotlist[i].bssid),
3123 pData->ssidHotlist[i].bssid) ||
3124 nla_put_u32(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3126 pData->ssidHotlist[i].channel) ||
3127 nla_put_s32(skb,
3128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3129 pData->ssidHotlist[i].rssi) ||
3130 nla_put_u32(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3132 pData->ssidHotlist[i].rtt) ||
3133 nla_put_u32(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3135 pData->ssidHotlist[i].rtt_sd)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 nla_nest_end(skb, ap);
3140 }
3141 nla_nest_end(skb, aps);
3142
3143 if (nla_put_u8(skb,
3144 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3145 pData->moreData)) {
3146 hddLog(LOGE, FL("put fail"));
3147 goto fail;
3148 }
3149 }
3150
3151 cfg80211_vendor_event(skb, GFP_KERNEL);
3152 return;
3153
3154fail:
3155 kfree_skb(skb);
3156 return;
3157
3158}
3159
3160
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3162 void *pMsg)
3163{
3164 struct sk_buff *skb;
3165 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3166 tpSirWifiFullScanResultEvent pData =
3167 (tpSirWifiFullScanResultEvent) (pMsg);
3168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303169 ENTER();
3170
3171 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 hddLog(LOGE,
3173 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303174 return;
3175 }
3176 if (!pMsg)
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 return;
3180 }
3181
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 /*
3183 * If the full scan result including IE data exceeds NL 4K size
3184 * limitation, drop that beacon/probe rsp frame.
3185 */
3186 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3187 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3188 return;
3189 }
3190
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3193 NULL,
3194#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3196 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3197 GFP_KERNEL);
3198
3199 if (!skb) {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("cfg80211_vendor_event_alloc failed"));
3202 return;
3203 }
3204
Dino Mycle6fb96c12014-06-10 11:52:40 +05303205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3206 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3207 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3208 "Ssid (%s)"
3209 "Bssid (" MAC_ADDRESS_STR ")"
3210 "Channel (%u)"
3211 "Rssi (%d)"
3212 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 "RTT_SD (%u)"
3214 "Bcn Period %d"
3215 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 pData->ap.ts,
3217 pData->ap.ssid,
3218 MAC_ADDR_ARRAY(pData->ap.bssid),
3219 pData->ap.channel,
3220 pData->ap.rssi,
3221 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303222 pData->ap.rtt_sd,
3223 pData->ap.beaconPeriod,
3224 pData->ap.capability);
3225
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3227 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3228 pData->requestId) ||
3229 nla_put_u64(skb,
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3231 pData->ap.ts) ||
3232 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3233 sizeof(pData->ap.ssid),
3234 pData->ap.ssid) ||
3235 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3236 WNI_CFG_BSSID_LEN,
3237 pData->ap.bssid) ||
3238 nla_put_u32(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3240 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303241 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 pData->ap.rssi) ||
3243 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3244 pData->ap.rtt) ||
3245 nla_put_u32(skb,
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3247 pData->ap.rtt_sd) ||
3248 nla_put_u16(skb,
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3250 pData->ap.beaconPeriod) ||
3251 nla_put_u16(skb,
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3253 pData->ap.capability) ||
3254 nla_put_u32(skb,
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303256 pData->ieLength) ||
3257 nla_put_u8(skb,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3259 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3262 goto nla_put_failure;
3263 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264
3265 if (pData->ieLength) {
3266 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3267 pData->ieLength,
3268 pData->ie))
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3271 goto nla_put_failure;
3272 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3285 void *pMsg)
3286{
3287 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3288 struct sk_buff *skb = NULL;
3289 tpSirEXTScanResultsAvailableIndParams pData =
3290 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 ENTER();
3293
3294 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303295 hddLog(LOGE,
3296 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 return;
3298 }
3299 if (!pMsg)
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303 }
3304
3305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3307 NULL,
3308#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3311 GFP_KERNEL);
3312
3313 if (!skb) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("cfg80211_vendor_event_alloc failed"));
3316 return;
3317 }
3318
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3320 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3321 pData->numResultsAvailable);
3322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3323 pData->requestId) ||
3324 nla_put_u32(skb,
3325 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3326 pData->numResultsAvailable)) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3328 goto nla_put_failure;
3329 }
3330
3331 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303332 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 return;
3334
3335nla_put_failure:
3336 kfree_skb(skb);
3337 return;
3338}
3339
3340static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3341{
3342 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3343 struct sk_buff *skb = NULL;
3344 tpSirEXTScanProgressIndParams pData =
3345 (tpSirEXTScanProgressIndParams) pMsg;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
3349 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303350 hddLog(LOGE,
3351 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 return;
3353 }
3354 if (!pMsg)
3355 {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357 return;
3358 }
3359
3360 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3362 NULL,
3363#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3365 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3366 GFP_KERNEL);
3367
3368 if (!skb) {
3369 hddLog(VOS_TRACE_LEVEL_ERROR,
3370 FL("cfg80211_vendor_event_alloc failed"));
3371 return;
3372 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3375 pData->extScanEventType);
3376 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3377 pData->status);
3378
3379 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3380 pData->extScanEventType) ||
3381 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3383 pData->requestId) ||
3384 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3386 pData->status)) {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3388 goto nla_put_failure;
3389 }
3390
3391 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 return;
3394
3395nla_put_failure:
3396 kfree_skb(skb);
3397 return;
3398}
3399
3400void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3401 void *pMsg)
3402{
3403 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303405 ENTER();
3406
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 return;
3409 }
3410
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3412
3413
3414 switch(evType) {
3415 case SIR_HAL_EXTSCAN_START_RSP:
3416 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3417 break;
3418
3419 case SIR_HAL_EXTSCAN_STOP_RSP:
3420 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3423 /* There is no need to send this response to upper layer
3424 Just log the message */
3425 hddLog(VOS_TRACE_LEVEL_INFO,
3426 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3427 break;
3428 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3429 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3430 break;
3431
3432 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3433 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3434 break;
3435
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303436 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3437 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3438 break;
3439
3440 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3441 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3442 break;
3443
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303445 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 break;
3447 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3448 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3449 break;
3450 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3451 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3452 break;
3453 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3454 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3455 break;
3456 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3457 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3458 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303459 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3460 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3461 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3463 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3464 break;
3465 default:
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3467 break;
3468 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475{
Dino Myclee8843b32014-07-04 14:21:45 +05303476 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 struct net_device *dev = wdev->netdev;
3478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3479 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3480 struct nlattr
3481 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3482 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303483 struct hdd_ext_scan_context *context;
3484 unsigned long rc;
3485 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 ENTER();
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 status = wlan_hdd_validate_context(pHddCtx);
3490 if (0 != status)
3491 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 return -EINVAL;
3493 }
Dino Myclee8843b32014-07-04 14:21:45 +05303494 /* check the EXTScan Capability */
3495 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303496 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3497 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303498 {
3499 hddLog(VOS_TRACE_LEVEL_ERROR,
3500 FL("EXTScan not enabled/supported by Firmware"));
3501 return -EINVAL;
3502 }
3503
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3505 data, dataLen,
3506 wlan_hdd_extscan_config_policy)) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3508 return -EINVAL;
3509 }
3510
3511 /* Parse and fetch request Id */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3514 return -EINVAL;
3515 }
3516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Dino Myclee8843b32014-07-04 14:21:45 +05303521 reqMsg.sessionId = pAdapter->sessionId;
3522 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303524 vos_spin_lock_acquire(&hdd_context_lock);
3525 context = &pHddCtx->ext_scan_context;
3526 context->request_id = reqMsg.requestId;
3527 INIT_COMPLETION(context->response_event);
3528 vos_spin_lock_release(&hdd_context_lock);
3529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 if (!HAL_STATUS_SUCCESS(status)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR,
3533 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return -EINVAL;
3535 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303536
3537 rc = wait_for_completion_timeout(&context->response_event,
3538 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3539 if (!rc) {
3540 hddLog(LOGE, FL("Target response timed out"));
3541 return -ETIMEDOUT;
3542 }
3543
3544 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3545 if (ret)
3546 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3547
3548 return ret;
3549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551 return 0;
3552}
3553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303554static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3555 struct wireless_dev *wdev,
3556 const void *data, int dataLen)
3557{
3558 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303560 vos_ssr_protect(__func__);
3561 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3562 vos_ssr_unprotect(__func__);
3563
3564 return ret;
3565}
3566
3567static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3568 struct wireless_dev *wdev,
3569 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570{
Dino Myclee8843b32014-07-04 14:21:45 +05303571 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572 struct net_device *dev = wdev->netdev;
3573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3574 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3575 struct nlattr
3576 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3577 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 struct hdd_ext_scan_context *context;
3579 unsigned long rc;
3580 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303582 ENTER();
3583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303584 if (VOS_FTM_MODE == hdd_get_conparam()) {
3585 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3586 return -EINVAL;
3587 }
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3597 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303598 {
3599 hddLog(VOS_TRACE_LEVEL_ERROR,
3600 FL("EXTScan not enabled/supported by Firmware"));
3601 return -EINVAL;
3602 }
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3605 data, dataLen,
3606 wlan_hdd_extscan_config_policy)) {
3607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3608 return -EINVAL;
3609 }
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615
Dino Myclee8843b32014-07-04 14:21:45 +05303616 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3618
Dino Myclee8843b32014-07-04 14:21:45 +05303619 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.sessionId = pAdapter->sessionId;
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623
3624 /* Parse and fetch flush parameter */
3625 if (!tb
3626 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3627 {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3629 goto failed;
3630 }
Dino Myclee8843b32014-07-04 14:21:45 +05303631 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 spin_lock(&hdd_context_lock);
3637 context = &pHddCtx->ext_scan_context;
3638 context->request_id = reqMsg.requestId;
3639 context->ignore_cached_results = false;
3640 INIT_COMPLETION(context->response_event);
3641 spin_unlock(&hdd_context_lock);
3642
Dino Myclee8843b32014-07-04 14:21:45 +05303643 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644 if (!HAL_STATUS_SUCCESS(status)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR,
3646 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647 return -EINVAL;
3648 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649
3650 rc = wait_for_completion_timeout(&context->response_event,
3651 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3652 if (!rc) {
3653 hddLog(LOGE, FL("Target response timed out"));
3654 retval = -ETIMEDOUT;
3655 spin_lock(&hdd_context_lock);
3656 context->ignore_cached_results = true;
3657 spin_unlock(&hdd_context_lock);
3658 } else {
3659 spin_lock(&hdd_context_lock);
3660 retval = context->response_status;
3661 spin_unlock(&hdd_context_lock);
3662 }
3663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303664 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303665 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
3667failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668 return -EINVAL;
3669}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303670static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3671 struct wireless_dev *wdev,
3672 const void *data, int dataLen)
3673{
3674 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303676 vos_ssr_protect(__func__);
3677 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3678 vos_ssr_unprotect(__func__);
3679
3680 return ret;
3681}
3682
3683static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303685 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303686{
3687 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3688 struct net_device *dev = wdev->netdev;
3689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3691 struct nlattr
3692 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3693 struct nlattr
3694 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3695 struct nlattr *apTh;
3696 eHalStatus status;
3697 tANI_U8 i = 0;
3698 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303699 struct hdd_ext_scan_context *context;
3700 tANI_U32 request_id;
3701 unsigned long rc;
3702 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303704 ENTER();
3705
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303706 if (VOS_FTM_MODE == hdd_get_conparam()) {
3707 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3708 return -EINVAL;
3709 }
3710
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 status = wlan_hdd_validate_context(pHddCtx);
3712 if (0 != status)
3713 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714 return -EINVAL;
3715 }
Dino Myclee8843b32014-07-04 14:21:45 +05303716 /* check the EXTScan Capability */
3717 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303718 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3719 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303720 {
3721 hddLog(VOS_TRACE_LEVEL_ERROR,
3722 FL("EXTScan not enabled/supported by Firmware"));
3723 return -EINVAL;
3724 }
3725
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3727 data, dataLen,
3728 wlan_hdd_extscan_config_policy)) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3730 return -EINVAL;
3731 }
3732
3733 /* Parse and fetch request Id */
3734 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3736 return -EINVAL;
3737 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3739 vos_mem_malloc(sizeof(*pReqMsg));
3740 if (!pReqMsg) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3742 return -ENOMEM;
3743 }
3744
Dino Myclee8843b32014-07-04 14:21:45 +05303745
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 pReqMsg->requestId = nla_get_u32(
3747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3749
3750 /* Parse and fetch number of APs */
3751 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3753 goto fail;
3754 }
3755
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303756 /* Parse and fetch lost ap sample size */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3758 hddLog(LOGE, FL("attr lost ap sample size failed"));
3759 goto fail;
3760 }
3761
3762 pReqMsg->lostBssidSampleSize = nla_get_u32(
3763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3764 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3765
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 pReqMsg->sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3768
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772
3773 nla_for_each_nested(apTh,
3774 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3775 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3776 nla_data(apTh), nla_len(apTh),
3777 NULL)) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3779 goto fail;
3780 }
3781
3782 /* Parse and fetch MAC address */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3785 goto fail;
3786 }
3787 memcpy(pReqMsg->ap[i].bssid, nla_data(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3789 sizeof(tSirMacAddr));
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3791
3792 /* Parse and fetch low RSSI */
3793 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3795 goto fail;
3796 }
3797 pReqMsg->ap[i].low = nla_get_s32(
3798 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3799 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3800
3801 /* Parse and fetch high RSSI */
3802 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3804 goto fail;
3805 }
3806 pReqMsg->ap[i].high = nla_get_s32(
3807 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3808 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3809 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 i++;
3811 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303812
3813 context = &pHddCtx->ext_scan_context;
3814 spin_lock(&hdd_context_lock);
3815 INIT_COMPLETION(context->response_event);
3816 context->request_id = request_id = pReqMsg->requestId;
3817 spin_unlock(&hdd_context_lock);
3818
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3820 if (!HAL_STATUS_SUCCESS(status)) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR,
3822 FL("sme_SetBssHotlist failed(err=%d)"), status);
3823 vos_mem_free(pReqMsg);
3824 return -EINVAL;
3825 }
3826
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303827 /* request was sent -- wait for the response */
3828 rc = wait_for_completion_timeout(&context->response_event,
3829 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3830
3831 if (!rc) {
3832 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3833 retval = -ETIMEDOUT;
3834 } else {
3835 spin_lock(&hdd_context_lock);
3836 if (context->request_id == request_id)
3837 retval = context->response_status;
3838 else
3839 retval = -EINVAL;
3840 spin_unlock(&hdd_context_lock);
3841 }
3842
Dino Myclee8843b32014-07-04 14:21:45 +05303843 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303844 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303845 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303846
3847fail:
3848 vos_mem_free(pReqMsg);
3849 return -EINVAL;
3850}
3851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303852static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3853 struct wireless_dev *wdev,
3854 const void *data, int dataLen)
3855{
3856 int ret = 0;
3857
3858 vos_ssr_protect(__func__);
3859 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3860 dataLen);
3861 vos_ssr_unprotect(__func__);
3862
3863 return ret;
3864}
3865
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303866/*
3867 * define short names for the global vendor params
3868 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3869 */
3870#define PARAM_MAX \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3872#define PARAM_REQUEST_ID \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3874#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3876#define PARAMS_NUM_SSID \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3878#define THRESHOLD_PARAM \
3879QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3880#define PARAM_SSID \
3881QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3882#define PARAM_BAND \
3883QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3884#define PARAM_RSSI_LOW \
3885QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3886#define PARAM_RSSI_HIGH \
3887QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3888
3889/**
3890 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3891 * @wiphy: Pointer to wireless phy
3892 * @wdev: Pointer to wireless device
3893 * @data: Pointer to data
3894 * @data_len: Data length
3895 *
3896 * Return: 0 on success, negative errno on failure
3897 */
3898static int
3899__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3900 struct wireless_dev *wdev,
3901 const void *data,
3902 int data_len)
3903{
3904 tSirEXTScanSetSsidHotListReqParams *request;
3905 struct net_device *dev = wdev->netdev;
3906 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3907 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3908 struct nlattr *tb[PARAM_MAX + 1];
3909 struct nlattr *tb2[PARAM_MAX + 1];
3910 struct nlattr *ssids;
3911 struct hdd_ext_scan_context *context;
3912 uint32_t request_id;
3913 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3914 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303915 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303916 eHalStatus status;
3917 int i, rem, retval;
3918 unsigned long rc;
3919
3920 ENTER();
3921
3922 if (VOS_FTM_MODE == hdd_get_conparam()) {
3923 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3924 return -EINVAL;
3925 }
3926
3927 retval = wlan_hdd_validate_context(hdd_ctx);
3928 if (0 != retval) {
3929 hddLog(LOGE, FL("HDD context is not valid"));
3930 return -EINVAL;
3931 }
3932
3933 /* check the EXTScan Capability */
3934 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303935 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3936 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR,
3939 FL("EXTScan not enabled/supported by Firmware"));
3940 return -EINVAL;
3941 }
3942
3943 if (nla_parse(tb, PARAM_MAX,
3944 data, data_len,
3945 wlan_hdd_extscan_config_policy)) {
3946 hddLog(LOGE, FL("Invalid ATTR"));
3947 return -EINVAL;
3948 }
3949
3950 request = vos_mem_malloc(sizeof(*request));
3951 if (!request) {
3952 hddLog(LOGE, FL("vos_mem_malloc failed"));
3953 return -ENOMEM;
3954 }
3955
3956 /* Parse and fetch request Id */
3957 if (!tb[PARAM_REQUEST_ID]) {
3958 hddLog(LOGE, FL("attr request id failed"));
3959 goto fail;
3960 }
3961
3962 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3963 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3964
3965 /* Parse and fetch lost SSID sample size */
3966 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3967 hddLog(LOGE, FL("attr number of Ssid failed"));
3968 goto fail;
3969 }
3970 request->lost_ssid_sample_size =
3971 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3972 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3973 request->lost_ssid_sample_size);
3974
3975 /* Parse and fetch number of hotlist SSID */
3976 if (!tb[PARAMS_NUM_SSID]) {
3977 hddLog(LOGE, FL("attr number of Ssid failed"));
3978 goto fail;
3979 }
3980 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3981 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3982
3983 request->session_id = adapter->sessionId;
3984 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3985
3986 i = 0;
3987 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3988 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3989 hddLog(LOGE,
3990 FL("Too Many SSIDs, %d exceeds %d"),
3991 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3992 break;
3993 }
3994 if (nla_parse(tb2, PARAM_MAX,
3995 nla_data(ssids), nla_len(ssids),
3996 wlan_hdd_extscan_config_policy)) {
3997 hddLog(LOGE, FL("nla_parse failed"));
3998 goto fail;
3999 }
4000
4001 /* Parse and fetch SSID */
4002 if (!tb2[PARAM_SSID]) {
4003 hddLog(LOGE, FL("attr ssid failed"));
4004 goto fail;
4005 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05304006 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
4007 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304008 hddLog(LOG1, FL("SSID %s"),
4009 ssid_string);
4010 ssid_len = strlen(ssid_string);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304011 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4012 hddLog(LOGE, FL("Invalid ssid length"));
4013 goto fail;
4014 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304015 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4016 request->ssid[i].ssid.length = ssid_len;
4017 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4018 hddLog(LOG1, FL("After copying SSID %s"),
4019 request->ssid[i].ssid.ssId);
4020 hddLog(LOG1, FL("After copying length: %d"),
4021 ssid_len);
4022
4023 /* Parse and fetch low RSSI */
4024 if (!tb2[PARAM_BAND]) {
4025 hddLog(LOGE, FL("attr band failed"));
4026 goto fail;
4027 }
4028 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4029 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4030
4031 /* Parse and fetch low RSSI */
4032 if (!tb2[PARAM_RSSI_LOW]) {
4033 hddLog(LOGE, FL("attr low RSSI failed"));
4034 goto fail;
4035 }
4036 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4037 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4038
4039 /* Parse and fetch high RSSI */
4040 if (!tb2[PARAM_RSSI_HIGH]) {
4041 hddLog(LOGE, FL("attr high RSSI failed"));
4042 goto fail;
4043 }
4044 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4045 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4046 i++;
4047 }
4048
4049 context = &hdd_ctx->ext_scan_context;
4050 spin_lock(&hdd_context_lock);
4051 INIT_COMPLETION(context->response_event);
4052 context->request_id = request_id = request->request_id;
4053 spin_unlock(&hdd_context_lock);
4054
4055 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4056 if (!HAL_STATUS_SUCCESS(status)) {
4057 hddLog(LOGE,
4058 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4059 goto fail;
4060 }
4061
4062 vos_mem_free(request);
4063
4064 /* request was sent -- wait for the response */
4065 rc = wait_for_completion_timeout(&context->response_event,
4066 msecs_to_jiffies
4067 (WLAN_WAIT_TIME_EXTSCAN));
4068 if (!rc) {
4069 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4070 retval = -ETIMEDOUT;
4071 } else {
4072 spin_lock(&hdd_context_lock);
4073 if (context->request_id == request_id)
4074 retval = context->response_status;
4075 else
4076 retval = -EINVAL;
4077 spin_unlock(&hdd_context_lock);
4078 }
4079
4080 return retval;
4081
4082fail:
4083 vos_mem_free(request);
4084 return -EINVAL;
4085}
4086
4087/*
4088 * done with short names for the global vendor params
4089 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4090 */
4091#undef PARAM_MAX
4092#undef PARAM_REQUEST_ID
4093#undef PARAMS_NUM_SSID
4094#undef THRESHOLD_PARAM
4095#undef PARAM_SSID
4096#undef PARAM_BAND
4097#undef PARAM_RSSI_LOW
4098#undef PARAM_RSSI_HIGH
4099
4100static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 const void *data, int dataLen)
4103{
4104 int ret = 0;
4105
4106 vos_ssr_protect(__func__);
4107 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4108 dataLen);
4109 vos_ssr_unprotect(__func__);
4110
4111 return ret;
4112}
4113
4114static int
4115__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4116 struct wireless_dev *wdev,
4117 const void *data,
4118 int data_len)
4119{
4120 tSirEXTScanResetSsidHotlistReqParams request;
4121 struct net_device *dev = wdev->netdev;
4122 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4123 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4124 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4125 struct hdd_ext_scan_context *context;
4126 uint32_t request_id;
4127 eHalStatus status;
4128 int retval;
4129 unsigned long rc;
4130
4131 ENTER();
4132
4133 if (VOS_FTM_MODE == hdd_get_conparam()) {
4134 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4135 return -EINVAL;
4136 }
4137
4138 retval = wlan_hdd_validate_context(hdd_ctx);
4139 if (0 != retval) {
4140 hddLog(LOGE, FL("HDD context is not valid"));
4141 return -EINVAL;
4142 }
4143
4144 /* check the EXTScan Capability */
4145 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304146 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4147 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304148 {
4149 hddLog(LOGE,
4150 FL("EXTScan not enabled/supported by Firmware"));
4151 return -EINVAL;
4152 }
4153
4154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4155 data, data_len,
4156 wlan_hdd_extscan_config_policy)) {
4157 hddLog(LOGE, FL("Invalid ATTR"));
4158 return -EINVAL;
4159 }
4160
4161 /* Parse and fetch request Id */
4162 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4163 hddLog(LOGE, FL("attr request id failed"));
4164 return -EINVAL;
4165 }
4166
4167 request.requestId = nla_get_u32(
4168 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4169 request.sessionId = adapter->sessionId;
4170 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4171 request.sessionId);
4172
4173 context = &hdd_ctx->ext_scan_context;
4174 spin_lock(&hdd_context_lock);
4175 INIT_COMPLETION(context->response_event);
4176 context->request_id = request_id = request.requestId;
4177 spin_unlock(&hdd_context_lock);
4178
4179 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4180 if (!HAL_STATUS_SUCCESS(status)) {
4181 hddLog(LOGE,
4182 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4183 return -EINVAL;
4184 }
4185
4186 /* request was sent -- wait for the response */
4187 rc = wait_for_completion_timeout(&context->response_event,
4188 msecs_to_jiffies
4189 (WLAN_WAIT_TIME_EXTSCAN));
4190 if (!rc) {
4191 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4192 retval = -ETIMEDOUT;
4193 } else {
4194 spin_lock(&hdd_context_lock);
4195 if (context->request_id == request_id)
4196 retval = context->response_status;
4197 else
4198 retval = -EINVAL;
4199 spin_unlock(&hdd_context_lock);
4200 }
4201
4202 return retval;
4203}
4204
4205static int
4206wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4207 struct wireless_dev *wdev,
4208 const void *data,
4209 int data_len)
4210{
4211 int ret;
4212
4213 vos_ssr_protect(__func__);
4214 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4215 data, data_len);
4216 vos_ssr_unprotect(__func__);
4217
4218 return ret;
4219}
4220
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304221static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304223 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4226 struct net_device *dev = wdev->netdev;
4227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4228 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4229 uint8_t num_channels = 0;
4230 uint8_t num_chan_new = 0;
4231 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304233 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 tWifiBand wifiBand;
4235 eHalStatus status;
4236 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304237 tANI_U8 i,j,k;
4238 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304240 ENTER();
4241
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 status = wlan_hdd_validate_context(pHddCtx);
4243 if (0 != status)
4244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 return -EINVAL;
4246 }
Dino Myclee8843b32014-07-04 14:21:45 +05304247
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4249 data, dataLen,
4250 wlan_hdd_extscan_config_policy)) {
4251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4252 return -EINVAL;
4253 }
4254
4255 /* Parse and fetch request Id */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4258 return -EINVAL;
4259 }
4260 requestId = nla_get_u32(
4261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4263
4264 /* Parse and fetch wifi band */
4265 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4268 return -EINVAL;
4269 }
4270 wifiBand = nla_get_u32(
4271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4273
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274 /* Parse and fetch max channels */
4275 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4276 {
4277 hddLog(LOGE, FL("attr max channels failed"));
4278 return -EINVAL;
4279 }
4280 maxChannels = nla_get_u32(
4281 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4283
Dino Mycle6fb96c12014-06-10 11:52:40 +05304284 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304285 wifiBand, chan_list,
4286 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 if (eHAL_STATUS_SUCCESS != status) {
4288 hddLog(VOS_TRACE_LEVEL_ERROR,
4289 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4290 return -EINVAL;
4291 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304292
Agrawal Ashish16abf782016-08-18 22:42:59 +05304293 num_channels = VOS_MIN(num_channels, maxChannels);
4294 num_chan_new = num_channels;
4295 /* remove the indoor only channels if iface is SAP */
4296 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4297 {
4298 num_chan_new = 0;
4299 for (i = 0; i < num_channels; i++)
4300 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4301 if (wiphy->bands[j] == NULL)
4302 continue;
4303 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4304 if ((chan_list[i] ==
4305 wiphy->bands[j]->channels[k].center_freq) &&
4306 (!(wiphy->bands[j]->channels[k].flags &
4307 IEEE80211_CHAN_INDOOR_ONLY))) {
4308 chan_list[num_chan_new] = chan_list[i];
4309 num_chan_new++;
4310 }
4311 }
4312 }
4313 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304314
Agrawal Ashish16abf782016-08-18 22:42:59 +05304315 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4316 for (i = 0; i < num_chan_new; i++)
4317 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4318 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304319
4320 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304321 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322 NLMSG_HDRLEN);
4323
4324 if (!replySkb) {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("valid channels: buffer alloc fail"));
4327 return -EINVAL;
4328 }
4329 if (nla_put_u32(replySkb,
4330 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304331 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304333 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334
4335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4336 kfree_skb(replySkb);
4337 return -EINVAL;
4338 }
4339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304340 ret = cfg80211_vendor_cmd_reply(replySkb);
4341
4342 EXIT();
4343 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344}
4345
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304346static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
4348 const void *data, int dataLen)
4349{
4350 int ret = 0;
4351
4352 vos_ssr_protect(__func__);
4353 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4354 dataLen);
4355 vos_ssr_unprotect(__func__);
4356
4357 return ret;
4358}
4359
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304360static int hdd_extscan_start_fill_bucket_channel_spec(
4361 hdd_context_t *pHddCtx,
4362 tpSirEXTScanStartReqParams pReqMsg,
4363 struct nlattr **tb)
4364{
4365 struct nlattr *bucket[
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4367 struct nlattr *channel[
4368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4369 struct nlattr *buckets;
4370 struct nlattr *channels;
4371 int rem1, rem2;
4372 eHalStatus status;
4373 tANI_U8 bktIndex, j, numChannels;
4374 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4375 tANI_U32 passive_max_chn_time, active_max_chn_time;
4376
4377 bktIndex = 0;
4378
4379 nla_for_each_nested(buckets,
4380 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4381 if (nla_parse(bucket,
4382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4383 nla_data(buckets), nla_len(buckets), NULL)) {
4384 hddLog(LOGE, FL("nla_parse failed"));
4385 return -EINVAL;
4386 }
4387
4388 /* Parse and fetch bucket spec */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4390 hddLog(LOGE, FL("attr bucket index failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4395 hddLog(LOG1, FL("Bucket spec Index %d"),
4396 pReqMsg->buckets[bktIndex].bucket);
4397
4398 /* Parse and fetch wifi band */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4400 hddLog(LOGE, FL("attr wifi band failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4405 hddLog(LOG1, FL("Wifi band %d"),
4406 pReqMsg->buckets[bktIndex].band);
4407
4408 /* Parse and fetch period */
4409 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4410 hddLog(LOGE, FL("attr period failed"));
4411 return -EINVAL;
4412 }
4413 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4414 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4415 hddLog(LOG1, FL("period %d"),
4416 pReqMsg->buckets[bktIndex].period);
4417
4418 /* Parse and fetch report events */
4419 if (!bucket[
4420 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4421 hddLog(LOGE, FL("attr report events failed"));
4422 return -EINVAL;
4423 }
4424 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4425 bucket[
4426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4427 hddLog(LOG1, FL("report events %d"),
4428 pReqMsg->buckets[bktIndex].reportEvents);
4429
4430 /* Parse and fetch max period */
4431 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4432 hddLog(LOGE, FL("attr max period failed"));
4433 return -EINVAL;
4434 }
4435 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4436 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4437 hddLog(LOG1, FL("max period %u"),
4438 pReqMsg->buckets[bktIndex].max_period);
4439
4440 /* Parse and fetch exponent */
4441 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4442 hddLog(LOGE, FL("attr exponent failed"));
4443 return -EINVAL;
4444 }
4445 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4446 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4447 hddLog(LOG1, FL("exponent %u"),
4448 pReqMsg->buckets[bktIndex].exponent);
4449
4450 /* Parse and fetch step count */
4451 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4452 hddLog(LOGE, FL("attr step count failed"));
4453 return -EINVAL;
4454 }
4455 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4456 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4457 hddLog(LOG1, FL("Step count %u"),
4458 pReqMsg->buckets[bktIndex].step_count);
4459
4460 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4461 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4462
4463 /* Framework shall pass the channel list if the input WiFi band is
4464 * WIFI_BAND_UNSPECIFIED.
4465 * If the input WiFi band is specified (any value other than
4466 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4467 */
4468 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4469 numChannels = 0;
4470 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4471 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4472 pReqMsg->buckets[bktIndex].band,
4473 chanList, &numChannels);
4474 if (!HAL_STATUS_SUCCESS(status)) {
4475 hddLog(LOGE,
4476 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4477 status);
4478 return -EINVAL;
4479 }
4480
4481 pReqMsg->buckets[bktIndex].numChannels =
4482 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4483 hddLog(LOG1, FL("Num channels %d"),
4484 pReqMsg->buckets[bktIndex].numChannels);
4485
4486 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4487 j++) {
4488 pReqMsg->buckets[bktIndex].channels[j].channel =
4489 chanList[j];
4490 pReqMsg->buckets[bktIndex].channels[j].
4491 chnlClass = 0;
4492 if (CSR_IS_CHANNEL_DFS(
4493 vos_freq_to_chan(chanList[j]))) {
4494 pReqMsg->buckets[bktIndex].channels[j].
4495 passive = 1;
4496 pReqMsg->buckets[bktIndex].channels[j].
4497 dwellTimeMs = passive_max_chn_time;
4498 } else {
4499 pReqMsg->buckets[bktIndex].channels[j].
4500 passive = 0;
4501 pReqMsg->buckets[bktIndex].channels[j].
4502 dwellTimeMs = active_max_chn_time;
4503 }
4504
4505 hddLog(LOG1,
4506 "Channel %u Passive %u Dwell time %u ms",
4507 pReqMsg->buckets[bktIndex].channels[j].channel,
4508 pReqMsg->buckets[bktIndex].channels[j].passive,
4509 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4510 }
4511
4512 bktIndex++;
4513 continue;
4514 }
4515
4516 /* Parse and fetch number of channels */
4517 if (!bucket[
4518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4519 hddLog(LOGE, FL("attr num channels failed"));
4520 return -EINVAL;
4521 }
4522
4523 pReqMsg->buckets[bktIndex].numChannels =
4524 nla_get_u32(bucket[
4525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4526 hddLog(LOG1, FL("num channels %d"),
4527 pReqMsg->buckets[bktIndex].numChannels);
4528
4529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4530 hddLog(LOGE, FL("attr channel spec failed"));
4531 return -EINVAL;
4532 }
4533
4534 j = 0;
4535 nla_for_each_nested(channels,
4536 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4537 if (nla_parse(channel,
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4539 nla_data(channels), nla_len(channels),
4540 wlan_hdd_extscan_config_policy)) {
4541 hddLog(LOGE, FL("nla_parse failed"));
4542 return -EINVAL;
4543 }
4544
4545 /* Parse and fetch channel */
4546 if (!channel[
4547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4548 hddLog(LOGE, FL("attr channel failed"));
4549 return -EINVAL;
4550 }
4551 pReqMsg->buckets[bktIndex].channels[j].channel =
4552 nla_get_u32(channel[
4553 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4554 hddLog(LOG1, FL("channel %u"),
4555 pReqMsg->buckets[bktIndex].channels[j].channel);
4556
4557 /* Parse and fetch dwell time */
4558 if (!channel[
4559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4560 hddLog(LOGE, FL("attr dwelltime failed"));
4561 return -EINVAL;
4562 }
4563 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4564 nla_get_u32(channel[
4565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4566
4567 hddLog(LOG1, FL("Dwell time (%u ms)"),
4568 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4569
4570
4571 /* Parse and fetch channel spec passive */
4572 if (!channel[
4573 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4574 hddLog(LOGE,
4575 FL("attr channel spec passive failed"));
4576 return -EINVAL;
4577 }
4578 pReqMsg->buckets[bktIndex].channels[j].passive =
4579 nla_get_u8(channel[
4580 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4581 hddLog(LOG1, FL("Chnl spec passive %u"),
4582 pReqMsg->buckets[bktIndex].channels[j].passive);
4583
4584 j++;
4585 }
4586
4587 bktIndex++;
4588 }
4589
4590 return 0;
4591}
4592
4593
4594/*
4595 * define short names for the global vendor params
4596 * used by wlan_hdd_cfg80211_extscan_start()
4597 */
4598#define PARAM_MAX \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4600#define PARAM_REQUEST_ID \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4602#define PARAM_BASE_PERIOD \
4603QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4604#define PARAM_MAX_AP_PER_SCAN \
4605QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4606#define PARAM_RPT_THRHLD_PERCENT \
4607QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4608#define PARAM_RPT_THRHLD_NUM_SCANS \
4609QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4610#define PARAM_NUM_BUCKETS \
4611QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4612
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304613static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304615 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616{
Dino Myclee8843b32014-07-04 14:21:45 +05304617 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 struct net_device *dev = wdev->netdev;
4619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4621 struct nlattr *tb[PARAM_MAX + 1];
4622 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304624 tANI_U32 request_id;
4625 struct hdd_ext_scan_context *context;
4626 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304628 ENTER();
4629
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304630 if (VOS_FTM_MODE == hdd_get_conparam()) {
4631 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4632 return -EINVAL;
4633 }
4634
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 status = wlan_hdd_validate_context(pHddCtx);
4636 if (0 != status)
4637 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 return -EINVAL;
4639 }
Dino Myclee8843b32014-07-04 14:21:45 +05304640 /* check the EXTScan Capability */
4641 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304642 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4643 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304644 {
4645 hddLog(VOS_TRACE_LEVEL_ERROR,
4646 FL("EXTScan not enabled/supported by Firmware"));
4647 return -EINVAL;
4648 }
4649
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304650 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 data, dataLen,
4652 wlan_hdd_extscan_config_policy)) {
4653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4654 return -EINVAL;
4655 }
4656
4657 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4660 return -EINVAL;
4661 }
4662
Dino Myclee8843b32014-07-04 14:21:45 +05304663 pReqMsg = (tpSirEXTScanStartReqParams)
4664 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4667 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 }
4669
4670 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4673
4674 pReqMsg->sessionId = pAdapter->sessionId;
4675 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4676
4677 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4680 goto fail;
4681 }
4682 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4685 pReqMsg->basePeriod);
4686
4687 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4690 goto fail;
4691 }
4692 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304693 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4695 pReqMsg->maxAPperScan);
4696
4697 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4700 goto fail;
4701 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304702 pReqMsg->reportThresholdPercent = nla_get_u8(
4703 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304705 pReqMsg->reportThresholdPercent);
4706
4707 /* Parse and fetch report threshold num scans */
4708 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4709 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4710 goto fail;
4711 }
4712 pReqMsg->reportThresholdNumScans = nla_get_u8(
4713 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4714 hddLog(LOG1, FL("Report Threshold num scans %d"),
4715 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716
4717 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4720 goto fail;
4721 }
4722 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304723 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4725 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4726 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4727 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4728 }
4729 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4730 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4734 goto fail;
4735 }
4736
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304737 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304739 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4740 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304741
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 context = &pHddCtx->ext_scan_context;
4743 spin_lock(&hdd_context_lock);
4744 INIT_COMPLETION(context->response_event);
4745 context->request_id = request_id = pReqMsg->requestId;
4746 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4749 if (!HAL_STATUS_SUCCESS(status)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR,
4751 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304752 goto fail;
4753 }
4754
Srinivas Dasari91727c12016-03-23 17:59:06 +05304755 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4756
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304757 /* request was sent -- wait for the response */
4758 rc = wait_for_completion_timeout(&context->response_event,
4759 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4760
4761 if (!rc) {
4762 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4763 retval = -ETIMEDOUT;
4764 } else {
4765 spin_lock(&hdd_context_lock);
4766 if (context->request_id == request_id)
4767 retval = context->response_status;
4768 else
4769 retval = -EINVAL;
4770 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771 }
4772
Dino Myclee8843b32014-07-04 14:21:45 +05304773 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304774 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304775 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304776
4777fail:
4778 vos_mem_free(pReqMsg);
4779 return -EINVAL;
4780}
4781
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304782/*
4783 * done with short names for the global vendor params
4784 * used by wlan_hdd_cfg80211_extscan_start()
4785 */
4786#undef PARAM_MAX
4787#undef PARAM_REQUEST_ID
4788#undef PARAM_BASE_PERIOD
4789#undef PARAMS_MAX_AP_PER_SCAN
4790#undef PARAMS_RPT_THRHLD_PERCENT
4791#undef PARAMS_RPT_THRHLD_NUM_SCANS
4792#undef PARAMS_NUM_BUCKETS
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4795 struct wireless_dev *wdev,
4796 const void *data, int dataLen)
4797{
4798 int ret = 0;
4799
4800 vos_ssr_protect(__func__);
4801 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4802 vos_ssr_unprotect(__func__);
4803
4804 return ret;
4805}
4806
4807static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304809 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304810{
Dino Myclee8843b32014-07-04 14:21:45 +05304811 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 struct net_device *dev = wdev->netdev;
4813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4814 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4815 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4816 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304817 int retval;
4818 unsigned long rc;
4819 struct hdd_ext_scan_context *context;
4820 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304822 ENTER();
4823
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304824 if (VOS_FTM_MODE == hdd_get_conparam()) {
4825 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4826 return -EINVAL;
4827 }
4828
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 status = wlan_hdd_validate_context(pHddCtx);
4830 if (0 != status)
4831 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 return -EINVAL;
4833 }
Dino Myclee8843b32014-07-04 14:21:45 +05304834 /* check the EXTScan Capability */
4835 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304836 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4837 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304838 {
4839 hddLog(VOS_TRACE_LEVEL_ERROR,
4840 FL("EXTScan not enabled/supported by Firmware"));
4841 return -EINVAL;
4842 }
4843
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4845 data, dataLen,
4846 wlan_hdd_extscan_config_policy)) {
4847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4848 return -EINVAL;
4849 }
4850
4851 /* Parse and fetch request Id */
4852 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4854 return -EINVAL;
4855 }
4856
Dino Myclee8843b32014-07-04 14:21:45 +05304857 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304858 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304859 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304860
Dino Myclee8843b32014-07-04 14:21:45 +05304861 reqMsg.sessionId = pAdapter->sessionId;
4862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304863
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304864 context = &pHddCtx->ext_scan_context;
4865 spin_lock(&hdd_context_lock);
4866 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304867 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304868 spin_unlock(&hdd_context_lock);
4869
Dino Myclee8843b32014-07-04 14:21:45 +05304870 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304871 if (!HAL_STATUS_SUCCESS(status)) {
4872 hddLog(VOS_TRACE_LEVEL_ERROR,
4873 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 return -EINVAL;
4875 }
4876
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304877 /* request was sent -- wait for the response */
4878 rc = wait_for_completion_timeout(&context->response_event,
4879 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4880
4881 if (!rc) {
4882 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4883 retval = -ETIMEDOUT;
4884 } else {
4885 spin_lock(&hdd_context_lock);
4886 if (context->request_id == request_id)
4887 retval = context->response_status;
4888 else
4889 retval = -EINVAL;
4890 spin_unlock(&hdd_context_lock);
4891 }
4892
4893 return retval;
4894
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304895 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896 return 0;
4897}
4898
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304899static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4900 struct wireless_dev *wdev,
4901 const void *data, int dataLen)
4902{
4903 int ret = 0;
4904
4905 vos_ssr_protect(__func__);
4906 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4907 vos_ssr_unprotect(__func__);
4908
4909 return ret;
4910}
4911
4912static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304914 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304915{
Dino Myclee8843b32014-07-04 14:21:45 +05304916 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917 struct net_device *dev = wdev->netdev;
4918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4919 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4920 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4921 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304922 struct hdd_ext_scan_context *context;
4923 tANI_U32 request_id;
4924 unsigned long rc;
4925 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304927 ENTER();
4928
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 if (VOS_FTM_MODE == hdd_get_conparam()) {
4930 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4931 return -EINVAL;
4932 }
4933
Dino Mycle6fb96c12014-06-10 11:52:40 +05304934 status = wlan_hdd_validate_context(pHddCtx);
4935 if (0 != status)
4936 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304937 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 return -EINVAL;
4939 }
Dino Myclee8843b32014-07-04 14:21:45 +05304940 /* check the EXTScan Capability */
4941 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304942 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4943 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304944 {
4945 hddLog(VOS_TRACE_LEVEL_ERROR,
4946 FL("EXTScan not enabled/supported by Firmware"));
4947 return -EINVAL;
4948 }
4949
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4951 data, dataLen,
4952 wlan_hdd_extscan_config_policy)) {
4953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4954 return -EINVAL;
4955 }
4956
4957 /* Parse and fetch request Id */
4958 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4960 return -EINVAL;
4961 }
4962
Dino Myclee8843b32014-07-04 14:21:45 +05304963 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304964 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304965 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304966
Dino Myclee8843b32014-07-04 14:21:45 +05304967 reqMsg.sessionId = pAdapter->sessionId;
4968 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304969
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304970 context = &pHddCtx->ext_scan_context;
4971 spin_lock(&hdd_context_lock);
4972 INIT_COMPLETION(context->response_event);
4973 context->request_id = request_id = reqMsg.requestId;
4974 spin_unlock(&hdd_context_lock);
4975
Dino Myclee8843b32014-07-04 14:21:45 +05304976 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304977 if (!HAL_STATUS_SUCCESS(status)) {
4978 hddLog(VOS_TRACE_LEVEL_ERROR,
4979 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304980 return -EINVAL;
4981 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304982
4983 /* request was sent -- wait for the response */
4984 rc = wait_for_completion_timeout(&context->response_event,
4985 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4986 if (!rc) {
4987 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4988 retval = -ETIMEDOUT;
4989 } else {
4990 spin_lock(&hdd_context_lock);
4991 if (context->request_id == request_id)
4992 retval = context->response_status;
4993 else
4994 retval = -EINVAL;
4995 spin_unlock(&hdd_context_lock);
4996 }
4997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304998 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304999 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305000}
5001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305002static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5003 struct wireless_dev *wdev,
5004 const void *data, int dataLen)
5005{
5006 int ret = 0;
5007
5008 vos_ssr_protect(__func__);
5009 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5010 vos_ssr_unprotect(__func__);
5011
5012 return ret;
5013}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305014#endif /* WLAN_FEATURE_EXTSCAN */
5015
Atul Mittal115287b2014-07-08 13:26:33 +05305016/*EXT TDLS*/
5017static const struct nla_policy
5018wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5019{
5020 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5021 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5023 {.type = NLA_S32 },
5024 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5025 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5026
5027};
5028
5029static const struct nla_policy
5030wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5031{
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5033
5034};
5035
5036static const struct nla_policy
5037wlan_hdd_tdls_config_state_change_policy[
5038 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5039{
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5041 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5042 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305043 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5045 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305046
5047};
5048
5049static const struct nla_policy
5050wlan_hdd_tdls_config_get_status_policy[
5051 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5052{
5053 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5054 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5055 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305056 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5057 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5058 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305059
5060};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061
5062static const struct nla_policy
5063wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5064{
5065 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5066};
5067
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305068static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305070 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 int data_len)
5072{
5073
5074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305077 ENTER();
5078
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305080 return -EINVAL;
5081 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305082 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305083 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305085 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305086 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305087 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305088 return -ENOTSUPP;
5089 }
5090
5091 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5092 data, data_len, wlan_hdd_mac_config)) {
5093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5094 return -EINVAL;
5095 }
5096
5097 /* Parse and fetch mac address */
5098 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5100 return -EINVAL;
5101 }
5102
5103 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5104 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5105 VOS_MAC_ADDR_LAST_3_BYTES);
5106
Siddharth Bhal76972212014-10-15 16:22:51 +05305107 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5108
5109 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5111 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305112 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5113 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5114 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5115 {
5116 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5117 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5118 VOS_MAC_ADDRESS_LEN);
5119 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305120 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305121
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305122 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5123 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305125 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305126 return 0;
5127}
5128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305129static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5130 struct wireless_dev *wdev,
5131 const void *data,
5132 int data_len)
5133{
5134 int ret = 0;
5135
5136 vos_ssr_protect(__func__);
5137 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5138 vos_ssr_unprotect(__func__);
5139
5140 return ret;
5141}
5142
5143static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305144 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305145 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305146 int data_len)
5147{
5148 u8 peer[6] = {0};
5149 struct net_device *dev = wdev->netdev;
5150 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5152 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5153 eHalStatus ret;
5154 tANI_S32 state;
5155 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305156 tANI_S32 global_operating_class = 0;
5157 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305158 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305159 int retVal;
5160
5161 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305162
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305163 if (!pAdapter) {
5164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5165 return -EINVAL;
5166 }
5167
Atul Mittal115287b2014-07-08 13:26:33 +05305168 ret = wlan_hdd_validate_context(pHddCtx);
5169 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305171 return -EINVAL;
5172 }
5173 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305175 return -ENOTSUPP;
5176 }
5177 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5178 data, data_len,
5179 wlan_hdd_tdls_config_get_status_policy)) {
5180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5181 return -EINVAL;
5182 }
5183
5184 /* Parse and fetch mac address */
5185 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5187 return -EINVAL;
5188 }
5189
5190 memcpy(peer, nla_data(
5191 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5192 sizeof(peer));
5193 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5194
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305195 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305196
Atul Mittal115287b2014-07-08 13:26:33 +05305197 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305198 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305199 NLMSG_HDRLEN);
5200
5201 if (!skb) {
5202 hddLog(VOS_TRACE_LEVEL_ERROR,
5203 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5204 return -EINVAL;
5205 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305206 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 +05305207 reason,
5208 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305209 global_operating_class,
5210 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305211 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305212 if (nla_put_s32(skb,
5213 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5214 state) ||
5215 nla_put_s32(skb,
5216 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5217 reason) ||
5218 nla_put_s32(skb,
5219 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5220 global_operating_class) ||
5221 nla_put_s32(skb,
5222 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5223 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305224
5225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5226 goto nla_put_failure;
5227 }
5228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 retVal = cfg80211_vendor_cmd_reply(skb);
5230 EXIT();
5231 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305232
5233nla_put_failure:
5234 kfree_skb(skb);
5235 return -EINVAL;
5236}
5237
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305238static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5239 struct wireless_dev *wdev,
5240 const void *data,
5241 int data_len)
5242{
5243 int ret = 0;
5244
5245 vos_ssr_protect(__func__);
5246 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5247 vos_ssr_unprotect(__func__);
5248
5249 return ret;
5250}
5251
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305252static int wlan_hdd_cfg80211_exttdls_callback(
5253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5254 const tANI_U8* mac,
5255#else
5256 tANI_U8* mac,
5257#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305258 tANI_S32 state,
5259 tANI_S32 reason,
5260 void *ctx)
5261{
5262 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305263 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305264 tANI_S32 global_operating_class = 0;
5265 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305266 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305268 ENTER();
5269
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305270 if (!pAdapter) {
5271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5272 return -EINVAL;
5273 }
5274
5275 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305276 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305278 return -EINVAL;
5279 }
5280
5281 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305283 return -ENOTSUPP;
5284 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5287 NULL,
5288#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305289 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5290 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5291 GFP_KERNEL);
5292
5293 if (!skb) {
5294 hddLog(VOS_TRACE_LEVEL_ERROR,
5295 FL("cfg80211_vendor_event_alloc failed"));
5296 return -EINVAL;
5297 }
5298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305299 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5300 reason,
5301 state,
5302 global_operating_class,
5303 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5305 MAC_ADDR_ARRAY(mac));
5306
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305307 if (nla_put(skb,
5308 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5309 VOS_MAC_ADDR_SIZE, mac) ||
5310 nla_put_s32(skb,
5311 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5312 state) ||
5313 nla_put_s32(skb,
5314 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5315 reason) ||
5316 nla_put_s32(skb,
5317 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5318 channel) ||
5319 nla_put_s32(skb,
5320 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5321 global_operating_class)
5322 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5324 goto nla_put_failure;
5325 }
5326
5327 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305328 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305329 return (0);
5330
5331nla_put_failure:
5332 kfree_skb(skb);
5333 return -EINVAL;
5334}
5335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305336static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305337 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305338 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305339 int data_len)
5340{
5341 u8 peer[6] = {0};
5342 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305343 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5344 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5345 eHalStatus status;
5346 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305347 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305348 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305349
5350 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305351
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305352 if (!dev) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5354 return -EINVAL;
5355 }
5356
5357 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5358 if (!pAdapter) {
5359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5360 return -EINVAL;
5361 }
5362
Atul Mittal115287b2014-07-08 13:26:33 +05305363 status = wlan_hdd_validate_context(pHddCtx);
5364 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305366 return -EINVAL;
5367 }
5368 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305370 return -ENOTSUPP;
5371 }
5372 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5373 data, data_len,
5374 wlan_hdd_tdls_config_enable_policy)) {
5375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5376 return -EINVAL;
5377 }
5378
5379 /* Parse and fetch mac address */
5380 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5382 return -EINVAL;
5383 }
5384
5385 memcpy(peer, nla_data(
5386 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5387 sizeof(peer));
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5389
5390 /* Parse and fetch channel */
5391 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5393 return -EINVAL;
5394 }
5395 pReqMsg.channel = nla_get_s32(
5396 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5398
5399 /* Parse and fetch global operating class */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5402 return -EINVAL;
5403 }
5404 pReqMsg.global_operating_class = nla_get_s32(
5405 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5407 pReqMsg.global_operating_class);
5408
5409 /* Parse and fetch latency ms */
5410 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5412 return -EINVAL;
5413 }
5414 pReqMsg.max_latency_ms = nla_get_s32(
5415 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5417 pReqMsg.max_latency_ms);
5418
5419 /* Parse and fetch required bandwidth kbps */
5420 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5422 return -EINVAL;
5423 }
5424
5425 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5426 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5427 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5428 pReqMsg.min_bandwidth_kbps);
5429
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305430 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305431 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305432 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305433 wlan_hdd_cfg80211_exttdls_callback);
5434
5435 EXIT();
5436 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305437}
5438
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305439static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5440 struct wireless_dev *wdev,
5441 const void *data,
5442 int data_len)
5443{
5444 int ret = 0;
5445
5446 vos_ssr_protect(__func__);
5447 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5448 vos_ssr_unprotect(__func__);
5449
5450 return ret;
5451}
5452
5453static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305454 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305455 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305456 int data_len)
5457{
5458 u8 peer[6] = {0};
5459 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305460 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5461 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5462 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305463 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305464 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305465
5466 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305467
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305468 if (!dev) {
5469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5470 return -EINVAL;
5471 }
5472
5473 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5474 if (!pAdapter) {
5475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5476 return -EINVAL;
5477 }
5478
Atul Mittal115287b2014-07-08 13:26:33 +05305479 status = wlan_hdd_validate_context(pHddCtx);
5480 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305482 return -EINVAL;
5483 }
5484 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305486 return -ENOTSUPP;
5487 }
5488 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5489 data, data_len,
5490 wlan_hdd_tdls_config_disable_policy)) {
5491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5492 return -EINVAL;
5493 }
5494 /* Parse and fetch mac address */
5495 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5497 return -EINVAL;
5498 }
5499
5500 memcpy(peer, nla_data(
5501 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5502 sizeof(peer));
5503 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5506
5507 EXIT();
5508 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305509}
5510
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305511static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5512 struct wireless_dev *wdev,
5513 const void *data,
5514 int data_len)
5515{
5516 int ret = 0;
5517
5518 vos_ssr_protect(__func__);
5519 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5520 vos_ssr_unprotect(__func__);
5521
5522 return ret;
5523}
5524
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305527 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305528 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529{
5530 struct net_device *dev = wdev->netdev;
5531 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5532 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5533 struct sk_buff *skb = NULL;
5534 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305535 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305537 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305538
5539 ret = wlan_hdd_validate_context(pHddCtx);
5540 if (0 != ret)
5541 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542 return ret;
5543 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305544 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5545 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5546 fset |= WIFI_FEATURE_INFRA;
5547 }
5548
5549 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5550 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5551 fset |= WIFI_FEATURE_INFRA_5G;
5552 }
5553
5554#ifdef WLAN_FEATURE_P2P
5555 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5556 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5557 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5558 fset |= WIFI_FEATURE_P2P;
5559 }
5560#endif
5561
5562 /* Soft-AP is supported currently by default */
5563 fset |= WIFI_FEATURE_SOFT_AP;
5564
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305565 /* HOTSPOT is a supplicant feature, enable it by default */
5566 fset |= WIFI_FEATURE_HOTSPOT;
5567
Dasari Srinivas7875a302014-09-26 17:50:57 +05305568#ifdef WLAN_FEATURE_EXTSCAN
5569 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305570 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5571 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5572 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305573 fset |= WIFI_FEATURE_EXTSCAN;
5574 }
5575#endif
5576
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577 if (sme_IsFeatureSupportedByFW(NAN)) {
5578 hddLog(LOG1, FL("NAN is supported by firmware"));
5579 fset |= WIFI_FEATURE_NAN;
5580 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305581
5582 /* D2D RTT is not supported currently by default */
5583 if (sme_IsFeatureSupportedByFW(RTT)) {
5584 hddLog(LOG1, FL("RTT is supported by firmware"));
5585 fset |= WIFI_FEATURE_D2AP_RTT;
5586 }
5587
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305588 if (sme_IsFeatureSupportedByFW(RTT3)) {
5589 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5590 fset |= WIFI_FEATURE_RTT3;
5591 }
5592
Dasari Srinivas7875a302014-09-26 17:50:57 +05305593#ifdef FEATURE_WLAN_BATCH_SCAN
5594 if (fset & WIFI_FEATURE_EXTSCAN) {
5595 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5596 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5597 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5598 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5599 fset |= WIFI_FEATURE_BATCH_SCAN;
5600 }
5601#endif
5602
5603#ifdef FEATURE_WLAN_SCAN_PNO
5604 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5605 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5606 hddLog(LOG1, FL("PNO is supported by firmware"));
5607 fset |= WIFI_FEATURE_PNO;
5608 }
5609#endif
5610
5611 /* STA+STA is supported currently by default */
5612 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5613
5614#ifdef FEATURE_WLAN_TDLS
5615 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5616 sme_IsFeatureSupportedByFW(TDLS)) {
5617 hddLog(LOG1, FL("TDLS is supported by firmware"));
5618 fset |= WIFI_FEATURE_TDLS;
5619 }
5620
5621 /* TDLS_OFFCHANNEL is not supported currently by default */
5622#endif
5623
5624#ifdef WLAN_AP_STA_CONCURRENCY
5625 /* AP+STA concurrency is supported currently by default */
5626 fset |= WIFI_FEATURE_AP_STA;
5627#endif
5628
Mukul Sharma5add0532015-08-17 15:57:47 +05305629#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5630 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5631 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5632#endif
5633
Dasari Srinivas7875a302014-09-26 17:50:57 +05305634 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5635 NLMSG_HDRLEN);
5636
5637 if (!skb) {
5638 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5639 return -EINVAL;
5640 }
5641 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5642
5643 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5644 hddLog(LOGE, FL("nla put fail"));
5645 goto nla_put_failure;
5646 }
5647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305648 ret = cfg80211_vendor_cmd_reply(skb);
5649 EXIT();
5650 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305651
5652nla_put_failure:
5653 kfree_skb(skb);
5654 return -EINVAL;
5655}
5656
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305657static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305658wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5659 struct wireless_dev *wdev,
5660 const void *data, int data_len)
5661{
5662 int ret = 0;
5663
5664 vos_ssr_protect(__func__);
5665 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5666 vos_ssr_unprotect(__func__);
5667
5668 return ret;
5669}
5670
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305671
5672static const struct
5673nla_policy
5674qca_wlan_vendor_wifi_logger_get_ring_data_policy
5675[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5676 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5677 = {.type = NLA_U32 },
5678};
5679
5680static int
5681 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data,
5684 int data_len)
5685{
5686 int ret;
5687 VOS_STATUS status;
5688 uint32_t ring_id;
5689 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5690 struct nlattr *tb
5691 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5692
5693 ENTER();
5694
5695 ret = wlan_hdd_validate_context(hdd_ctx);
5696 if (0 != ret) {
5697 return ret;
5698 }
5699
5700 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5701 data, data_len,
5702 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5703 hddLog(LOGE, FL("Invalid attribute"));
5704 return -EINVAL;
5705 }
5706
5707 /* Parse and fetch ring id */
5708 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5709 hddLog(LOGE, FL("attr ATTR failed"));
5710 return -EINVAL;
5711 }
5712
5713 ring_id = nla_get_u32(
5714 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5715
5716 hddLog(LOG1, FL("Bug report triggered by framework"));
5717
5718 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5719 WLAN_LOG_INDICATOR_FRAMEWORK,
5720 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305721 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305722 );
5723 if (VOS_STATUS_SUCCESS != status) {
5724 hddLog(LOGE, FL("Failed to trigger bug report"));
5725
5726 return -EINVAL;
5727 }
5728
5729 return 0;
5730
5731
5732}
5733
5734
5735static int
5736 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5737 struct wireless_dev *wdev,
5738 const void *data,
5739 int data_len)
5740{
5741 int ret = 0;
5742
5743 vos_ssr_protect(__func__);
5744 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5745 wdev, data, data_len);
5746 vos_ssr_unprotect(__func__);
5747
5748 return ret;
5749
5750}
5751
5752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753static int
5754__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305755 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305756 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757{
5758 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5759 uint8_t i, feature_sets, max_feature_sets;
5760 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5761 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5763 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764
5765 ENTER();
5766
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767 ret = wlan_hdd_validate_context(pHddCtx);
5768 if (0 != ret)
5769 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305770 return ret;
5771 }
5772
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305773 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5774 data, data_len, NULL)) {
5775 hddLog(LOGE, FL("Invalid ATTR"));
5776 return -EINVAL;
5777 }
5778
5779 /* Parse and fetch max feature set */
5780 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5781 hddLog(LOGE, FL("Attr max feature set size failed"));
5782 return -EINVAL;
5783 }
5784 max_feature_sets = nla_get_u32(
5785 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5786 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5787
5788 /* Fill feature combination matrix */
5789 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305790 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5791 WIFI_FEATURE_P2P;
5792
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305793 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5794 WIFI_FEATURE_SOFT_AP;
5795
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305796 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5797 WIFI_FEATURE_SOFT_AP;
5798
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305799 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5800 WIFI_FEATURE_SOFT_AP |
5801 WIFI_FEATURE_P2P;
5802
5803 /* Add more feature combinations here */
5804
5805 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5806 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5807 hddLog(LOG1, "Feature set matrix");
5808 for (i = 0; i < feature_sets; i++)
5809 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5810
5811 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5812 sizeof(u32) * feature_sets +
5813 NLMSG_HDRLEN);
5814
5815 if (reply_skb) {
5816 if (nla_put_u32(reply_skb,
5817 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5818 feature_sets) ||
5819 nla_put(reply_skb,
5820 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5821 sizeof(u32) * feature_sets, feature_set_matrix)) {
5822 hddLog(LOGE, FL("nla put fail"));
5823 kfree_skb(reply_skb);
5824 return -EINVAL;
5825 }
5826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305827 ret = cfg80211_vendor_cmd_reply(reply_skb);
5828 EXIT();
5829 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305830 }
5831 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5832 return -ENOMEM;
5833
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305834}
5835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305836static int
5837wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5838 struct wireless_dev *wdev,
5839 const void *data, int data_len)
5840{
5841 int ret = 0;
5842
5843 vos_ssr_protect(__func__);
5844 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5845 data_len);
5846 vos_ssr_unprotect(__func__);
5847
5848 return ret;
5849}
5850
c_manjeecfd1efb2015-09-25 19:32:34 +05305851
5852static int
5853__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5854 struct wireless_dev *wdev,
5855 const void *data, int data_len)
5856{
5857 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5858 int ret;
5859 ENTER();
5860
5861 ret = wlan_hdd_validate_context(pHddCtx);
5862 if (0 != ret)
5863 {
5864 return ret;
5865 }
5866
5867 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5868 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5869 {
5870 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5871 return -EINVAL;
5872 }
5873 /*call common API for FW mem dump req*/
5874 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5875
Abhishek Singhc783fa72015-12-09 18:07:34 +05305876 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305877 {
5878 /*indicate to userspace the status of fw mem dump */
5879 wlan_indicate_mem_dump_complete(true);
5880 }
5881 else
5882 {
5883 /*else send failure to userspace */
5884 wlan_indicate_mem_dump_complete(false);
5885 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305886 EXIT();
5887 return ret;
5888}
5889
5890/**
5891 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5892 * @wiphy: pointer to wireless wiphy structure.
5893 * @wdev: pointer to wireless_dev structure.
5894 * @data: Pointer to the NL data.
5895 * @data_len:Length of @data
5896 *
5897 * This is called when wlan driver needs to get the firmware memory dump
5898 * via vendor specific command.
5899 *
5900 * Return: 0 on success, error number otherwise.
5901 */
5902
5903static int
5904wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5905 struct wireless_dev *wdev,
5906 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305907{
5908 int ret = 0;
5909 vos_ssr_protect(__func__);
5910 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5911 data_len);
5912 vos_ssr_unprotect(__func__);
5913 return ret;
5914}
c_manjeecfd1efb2015-09-25 19:32:34 +05305915
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916static const struct
5917nla_policy
5918qca_wlan_vendor_wifi_logger_start_policy
5919[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5920 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5921 = {.type = NLA_U32 },
5922 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5923 = {.type = NLA_U32 },
5924 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5925 = {.type = NLA_U32 },
5926};
5927
5928/**
5929 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5930 * or disable the collection of packet statistics from the firmware
5931 * @wiphy: WIPHY structure pointer
5932 * @wdev: Wireless device structure pointer
5933 * @data: Pointer to the data received
5934 * @data_len: Length of the data received
5935 *
5936 * This function is used to enable or disable the collection of packet
5937 * statistics from the firmware
5938 *
5939 * Return: 0 on success and errno on failure
5940 */
5941static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5942 struct wireless_dev *wdev,
5943 const void *data,
5944 int data_len)
5945{
5946 eHalStatus status;
5947 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5948 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5949 tAniWifiStartLog start_log;
5950
5951 status = wlan_hdd_validate_context(hdd_ctx);
5952 if (0 != status) {
5953 return -EINVAL;
5954 }
5955
5956 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5957 data, data_len,
5958 qca_wlan_vendor_wifi_logger_start_policy)) {
5959 hddLog(LOGE, FL("Invalid attribute"));
5960 return -EINVAL;
5961 }
5962
5963 /* Parse and fetch ring id */
5964 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5965 hddLog(LOGE, FL("attr ATTR failed"));
5966 return -EINVAL;
5967 }
5968 start_log.ringId = nla_get_u32(
5969 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5970 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5971
5972 /* Parse and fetch verbose level */
5973 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5974 hddLog(LOGE, FL("attr verbose_level failed"));
5975 return -EINVAL;
5976 }
5977 start_log.verboseLevel = nla_get_u32(
5978 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5979 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5980
5981 /* Parse and fetch flag */
5982 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5983 hddLog(LOGE, FL("attr flag failed"));
5984 return -EINVAL;
5985 }
5986 start_log.flag = nla_get_u32(
5987 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5988 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5989
5990 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305991 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5992 !vos_isPktStatsEnabled()))
5993
Sushant Kaushik8e644982015-09-23 12:18:54 +05305994 {
5995 hddLog(LOGE, FL("per pkt stats not enabled"));
5996 return -EINVAL;
5997 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305998
Sushant Kaushik33200572015-08-05 16:46:20 +05305999 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306000 return 0;
6001}
6002
6003/**
6004 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6005 * or disable the collection of packet statistics from the firmware
6006 * @wiphy: WIPHY structure pointer
6007 * @wdev: Wireless device structure pointer
6008 * @data: Pointer to the data received
6009 * @data_len: Length of the data received
6010 *
6011 * This function is used to enable or disable the collection of packet
6012 * statistics from the firmware
6013 *
6014 * Return: 0 on success and errno on failure
6015 */
6016static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6017 struct wireless_dev *wdev,
6018 const void *data,
6019 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306020{
6021 int ret = 0;
6022
6023 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306024
6025 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6026 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306027 vos_ssr_unprotect(__func__);
6028
6029 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306030}
6031
6032
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033static const struct nla_policy
6034wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6035 +1] =
6036{
6037 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6038};
6039
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306040static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306041 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306042 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306043 int data_len)
6044{
6045 struct net_device *dev = wdev->netdev;
6046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6047 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6049 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6050 eHalStatus status;
6051 u32 dfsFlag = 0;
6052
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306053 ENTER();
6054
Agarwal Ashish738843c2014-09-25 12:27:56 +05306055 status = wlan_hdd_validate_context(pHddCtx);
6056 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306057 return -EINVAL;
6058 }
6059 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6060 data, data_len,
6061 wlan_hdd_set_no_dfs_flag_config_policy)) {
6062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6063 return -EINVAL;
6064 }
6065
6066 /* Parse and fetch required bandwidth kbps */
6067 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6069 return -EINVAL;
6070 }
6071
6072 dfsFlag = nla_get_u32(
6073 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6074 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6075 dfsFlag);
6076
6077 pHddCtx->disable_dfs_flag = dfsFlag;
6078
6079 sme_disable_dfs_channel(hHal, dfsFlag);
6080 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306081
6082 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306083 return 0;
6084}
Atul Mittal115287b2014-07-08 13:26:33 +05306085
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306086static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6087 struct wireless_dev *wdev,
6088 const void *data,
6089 int data_len)
6090{
6091 int ret = 0;
6092
6093 vos_ssr_protect(__func__);
6094 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6095 vos_ssr_unprotect(__func__);
6096
6097 return ret;
6098
6099}
6100
Mukul Sharma2a271632014-10-13 14:59:01 +05306101const struct
6102nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6103{
6104 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6105 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6106};
6107
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306108static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306109 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306110{
6111
6112 u8 bssid[6] = {0};
6113 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6115 eHalStatus status = eHAL_STATUS_SUCCESS;
6116 v_U32_t isFwrRoamEnabled = FALSE;
6117 int ret;
6118
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 ENTER();
6120
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306121 ret = wlan_hdd_validate_context(pHddCtx);
6122 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306124 }
6125
6126 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6127 data, data_len,
6128 qca_wlan_vendor_attr);
6129 if (ret){
6130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6131 return -EINVAL;
6132 }
6133
6134 /* Parse and fetch Enable flag */
6135 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6137 return -EINVAL;
6138 }
6139
6140 isFwrRoamEnabled = nla_get_u32(
6141 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6142
6143 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6144
6145 /* Parse and fetch bssid */
6146 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6148 return -EINVAL;
6149 }
6150
6151 memcpy(bssid, nla_data(
6152 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6153 sizeof(bssid));
6154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6155
6156 //Update roaming
6157 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306158 if (!HAL_STATUS_SUCCESS(status)) {
6159 hddLog(LOGE,
6160 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6161 return -EINVAL;
6162 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306163 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306164 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306165}
6166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306167static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6168 struct wireless_dev *wdev, const void *data, int data_len)
6169{
6170 int ret = 0;
6171
6172 vos_ssr_protect(__func__);
6173 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6174 vos_ssr_unprotect(__func__);
6175
6176 return ret;
6177}
6178
Sushant Kaushik847890c2015-09-28 16:05:17 +05306179static const struct
6180nla_policy
6181qca_wlan_vendor_get_wifi_info_policy[
6182 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6183 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6184 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6185};
6186
6187
6188/**
6189 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6190 * @wiphy: pointer to wireless wiphy structure.
6191 * @wdev: pointer to wireless_dev structure.
6192 * @data: Pointer to the data to be passed via vendor interface
6193 * @data_len:Length of the data to be passed
6194 *
6195 * This is called when wlan driver needs to send wifi driver related info
6196 * (driver/fw version) to the user space application upon request.
6197 *
6198 * Return: Return the Success or Failure code.
6199 */
6200static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6201 struct wireless_dev *wdev,
6202 const void *data, int data_len)
6203{
6204 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6205 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6206 tSirVersionString version;
6207 uint32 version_len;
6208 uint8 attr;
6209 int status;
6210 struct sk_buff *reply_skb = NULL;
6211
6212 if (VOS_FTM_MODE == hdd_get_conparam()) {
6213 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6214 return -EINVAL;
6215 }
6216
6217 status = wlan_hdd_validate_context(hdd_ctx);
6218 if (0 != status) {
6219 hddLog(LOGE, FL("HDD context is not valid"));
6220 return -EINVAL;
6221 }
6222
6223 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6224 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6225 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6226 return -EINVAL;
6227 }
6228
6229 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6230 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6231 QWLAN_VERSIONSTR);
6232 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6233 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6234 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6235 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6236 hdd_ctx->fw_Version);
6237 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6238 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6239 } else {
6240 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6241 return -EINVAL;
6242 }
6243
6244 version_len = strlen(version);
6245 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6246 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6247 if (!reply_skb) {
6248 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6249 return -ENOMEM;
6250 }
6251
6252 if (nla_put(reply_skb, attr, version_len, version)) {
6253 hddLog(LOGE, FL("nla put fail"));
6254 kfree_skb(reply_skb);
6255 return -EINVAL;
6256 }
6257
6258 return cfg80211_vendor_cmd_reply(reply_skb);
6259}
6260
6261/**
6262 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6263 * @wiphy: pointer to wireless wiphy structure.
6264 * @wdev: pointer to wireless_dev structure.
6265 * @data: Pointer to the data to be passed via vendor interface
6266 * @data_len:Length of the data to be passed
6267 * @data_len: Length of the data received
6268 *
6269 * This function is used to enable or disable the collection of packet
6270 * statistics from the firmware
6271 *
6272 * Return: 0 on success and errno on failure
6273 */
6274
6275static int
6276wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6277 struct wireless_dev *wdev,
6278 const void *data, int data_len)
6279
6280
6281{
6282 int ret = 0;
6283
6284 vos_ssr_protect(__func__);
6285 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6286 wdev, data, data_len);
6287 vos_ssr_unprotect(__func__);
6288
6289 return ret;
6290}
6291
6292
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306293/*
6294 * define short names for the global vendor params
6295 * used by __wlan_hdd_cfg80211_monitor_rssi()
6296 */
6297#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6298#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6299#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6300#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6301#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6302
6303/**---------------------------------------------------------------------------
6304
6305 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6306 monitor start is completed successfully.
6307
6308 \return - None
6309
6310 --------------------------------------------------------------------------*/
6311void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6312{
6313 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6314
6315 if (NULL == pHddCtx)
6316 {
6317 hddLog(VOS_TRACE_LEVEL_ERROR,
6318 "%s: HDD context is NULL",__func__);
6319 return;
6320 }
6321
6322 if (VOS_STATUS_SUCCESS == status)
6323 {
6324 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6325 }
6326 else
6327 {
6328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6329 }
6330
6331 return;
6332}
6333
6334/**---------------------------------------------------------------------------
6335
6336 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6337 stop is completed successfully.
6338
6339 \return - None
6340
6341 --------------------------------------------------------------------------*/
6342void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6343{
6344 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6345
6346 if (NULL == pHddCtx)
6347 {
6348 hddLog(VOS_TRACE_LEVEL_ERROR,
6349 "%s: HDD context is NULL",__func__);
6350 return;
6351 }
6352
6353 if (VOS_STATUS_SUCCESS == status)
6354 {
6355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6356 }
6357 else
6358 {
6359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6360 }
6361
6362 return;
6363}
6364
6365/**
6366 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6367 * @wiphy: Pointer to wireless phy
6368 * @wdev: Pointer to wireless device
6369 * @data: Pointer to data
6370 * @data_len: Data length
6371 *
6372 * Return: 0 on success, negative errno on failure
6373 */
6374
6375static int
6376__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6377 struct wireless_dev *wdev,
6378 const void *data,
6379 int data_len)
6380{
6381 struct net_device *dev = wdev->netdev;
6382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6383 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6384 hdd_station_ctx_t *pHddStaCtx;
6385 struct nlattr *tb[PARAM_MAX + 1];
6386 tpSirRssiMonitorReq pReq;
6387 eHalStatus status;
6388 int ret;
6389 uint32_t control;
6390 static const struct nla_policy policy[PARAM_MAX + 1] = {
6391 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6392 [PARAM_CONTROL] = { .type = NLA_U32 },
6393 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6394 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6395 };
6396
6397 ENTER();
6398
6399 ret = wlan_hdd_validate_context(hdd_ctx);
6400 if (0 != ret) {
6401 return -EINVAL;
6402 }
6403
6404 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6405 hddLog(LOGE, FL("Not in Connected state!"));
6406 return -ENOTSUPP;
6407 }
6408
6409 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6410 hddLog(LOGE, FL("Invalid ATTR"));
6411 return -EINVAL;
6412 }
6413
6414 if (!tb[PARAM_REQUEST_ID]) {
6415 hddLog(LOGE, FL("attr request id failed"));
6416 return -EINVAL;
6417 }
6418
6419 if (!tb[PARAM_CONTROL]) {
6420 hddLog(LOGE, FL("attr control failed"));
6421 return -EINVAL;
6422 }
6423
6424 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6425
6426 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6427 if(NULL == pReq)
6428 {
6429 hddLog(LOGE,
6430 FL("vos_mem_alloc failed "));
6431 return eHAL_STATUS_FAILED_ALLOC;
6432 }
6433 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6434
6435 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6436 pReq->sessionId = pAdapter->sessionId;
6437 pReq->rssiMonitorCbContext = hdd_ctx;
6438 control = nla_get_u32(tb[PARAM_CONTROL]);
6439 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6440
6441 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6442 pReq->requestId, pReq->sessionId, control);
6443
6444 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6445 if (!tb[PARAM_MIN_RSSI]) {
6446 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306447 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306448 }
6449
6450 if (!tb[PARAM_MAX_RSSI]) {
6451 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306452 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306453 }
6454
6455 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6456 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6457 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6458
6459 if (!(pReq->minRssi < pReq->maxRssi)) {
6460 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6461 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306462 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306463 }
6464 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6465 pReq->minRssi, pReq->maxRssi);
6466 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6467
6468 }
6469 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6470 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6471 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6472 }
6473 else {
6474 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306475 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306476 }
6477
6478 if (!HAL_STATUS_SUCCESS(status)) {
6479 hddLog(LOGE,
6480 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306481 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306482 }
6483
6484 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306485fail:
6486 vos_mem_free(pReq);
6487 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306488}
6489
6490/*
6491 * done with short names for the global vendor params
6492 * used by __wlan_hdd_cfg80211_monitor_rssi()
6493 */
6494#undef PARAM_MAX
6495#undef PARAM_CONTROL
6496#undef PARAM_REQUEST_ID
6497#undef PARAM_MAX_RSSI
6498#undef PARAM_MIN_RSSI
6499
6500/**
6501 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6502 * @wiphy: wiphy structure pointer
6503 * @wdev: Wireless device structure pointer
6504 * @data: Pointer to the data received
6505 * @data_len: Length of @data
6506 *
6507 * Return: 0 on success; errno on failure
6508 */
6509static int
6510wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6511 const void *data, int data_len)
6512{
6513 int ret;
6514
6515 vos_ssr_protect(__func__);
6516 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6517 vos_ssr_unprotect(__func__);
6518
6519 return ret;
6520}
6521
6522/**
6523 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6524 * @hddctx: HDD context
6525 * @data: rssi breached event data
6526 *
6527 * This function reads the rssi breached event %data and fill in the skb with
6528 * NL attributes and send up the NL event.
6529 * This callback execute in atomic context and must not invoke any
6530 * blocking calls.
6531 *
6532 * Return: none
6533 */
6534void hdd_rssi_threshold_breached_cb(void *hddctx,
6535 struct rssi_breach_event *data)
6536{
6537 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6538 int status;
6539 struct sk_buff *skb;
6540
6541 ENTER();
6542 status = wlan_hdd_validate_context(pHddCtx);
6543
6544 if (0 != status) {
6545 return;
6546 }
6547
6548 if (!data) {
6549 hddLog(LOGE, FL("data is null"));
6550 return;
6551 }
6552
6553 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6555 NULL,
6556#endif
6557 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6558 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6559 GFP_KERNEL);
6560
6561 if (!skb) {
6562 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6563 return;
6564 }
6565
6566 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6567 data->request_id, data->curr_rssi);
6568 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6569 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6570
6571 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6572 data->request_id) ||
6573 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6574 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6575 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6576 data->curr_rssi)) {
6577 hddLog(LOGE, FL("nla put fail"));
6578 goto fail;
6579 }
6580
6581 cfg80211_vendor_event(skb, GFP_KERNEL);
6582 return;
6583
6584fail:
6585 kfree_skb(skb);
6586 return;
6587}
6588
6589
6590
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306591/**
6592 * __wlan_hdd_cfg80211_setband() - set band
6593 * @wiphy: Pointer to wireless phy
6594 * @wdev: Pointer to wireless device
6595 * @data: Pointer to data
6596 * @data_len: Data length
6597 *
6598 * Return: 0 on success, negative errno on failure
6599 */
6600static int
6601__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6602 struct wireless_dev *wdev,
6603 const void *data,
6604 int data_len)
6605{
6606 struct net_device *dev = wdev->netdev;
6607 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6608 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6609 int ret;
6610 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6611 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6612
6613 ENTER();
6614
6615 ret = wlan_hdd_validate_context(hdd_ctx);
6616 if (0 != ret) {
6617 hddLog(LOGE, FL("HDD context is not valid"));
6618 return ret;
6619 }
6620
6621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6622 policy)) {
6623 hddLog(LOGE, FL("Invalid ATTR"));
6624 return -EINVAL;
6625 }
6626
6627 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6628 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6629 return -EINVAL;
6630 }
6631
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306632 hdd_ctx->isSetBandByNL = TRUE;
6633 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306634 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306635 hdd_ctx->isSetBandByNL = FALSE;
6636
6637 EXIT();
6638 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306639}
6640
6641/**
6642 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6643 * @wiphy: wiphy structure pointer
6644 * @wdev: Wireless device structure pointer
6645 * @data: Pointer to the data received
6646 * @data_len: Length of @data
6647 *
6648 * Return: 0 on success; errno on failure
6649 */
6650static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6651 struct wireless_dev *wdev,
6652 const void *data,
6653 int data_len)
6654{
6655 int ret = 0;
6656
6657 vos_ssr_protect(__func__);
6658 ret = __wlan_hdd_cfg80211_setband(wiphy,
6659 wdev, data, data_len);
6660 vos_ssr_unprotect(__func__);
6661
6662 return ret;
6663}
6664
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306665#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6666/**
6667 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6668 * @hdd_ctx: HDD context
6669 * @request_id: [input] request id
6670 * @pattern_id: [output] pattern id
6671 *
6672 * This function loops through request id to pattern id array
6673 * if the slot is available, store the request id and return pattern id
6674 * if entry exists, return the pattern id
6675 *
6676 * Return: 0 on success and errno on failure
6677 */
6678static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6679 uint32_t request_id,
6680 uint8_t *pattern_id)
6681{
6682 uint32_t i;
6683
6684 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6685 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6686 {
6687 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6688 {
6689 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6690 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6691 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6692 return 0;
6693 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6694 request_id) {
6695 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6696 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6697 return 0;
6698 }
6699 }
6700 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6701 return -EINVAL;
6702}
6703
6704/**
6705 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6706 * @hdd_ctx: HDD context
6707 * @request_id: [input] request id
6708 * @pattern_id: [output] pattern id
6709 *
6710 * This function loops through request id to pattern id array
6711 * reset request id to 0 (slot available again) and
6712 * return pattern id
6713 *
6714 * Return: 0 on success and errno on failure
6715 */
6716static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6717 uint32_t request_id,
6718 uint8_t *pattern_id)
6719{
6720 uint32_t i;
6721
6722 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6723 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6724 {
6725 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6726 {
6727 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6728 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6729 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6730 return 0;
6731 }
6732 }
6733 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6734 return -EINVAL;
6735}
6736
6737
6738/*
6739 * define short names for the global vendor params
6740 * used by __wlan_hdd_cfg80211_offloaded_packets()
6741 */
6742#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6743#define PARAM_REQUEST_ID \
6744 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6745#define PARAM_CONTROL \
6746 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6747#define PARAM_IP_PACKET \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6749#define PARAM_SRC_MAC_ADDR \
6750 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6751#define PARAM_DST_MAC_ADDR \
6752 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6753#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6754
6755/**
6756 * wlan_hdd_add_tx_ptrn() - add tx pattern
6757 * @adapter: adapter pointer
6758 * @hdd_ctx: hdd context
6759 * @tb: nl attributes
6760 *
6761 * This function reads the NL attributes and forms a AddTxPtrn message
6762 * posts it to SME.
6763 *
6764 */
6765static int
6766wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6767 struct nlattr **tb)
6768{
6769 struct sSirAddPeriodicTxPtrn *add_req;
6770 eHalStatus status;
6771 uint32_t request_id, ret, len;
6772 uint8_t pattern_id = 0;
6773 v_MACADDR_t dst_addr;
6774 uint16_t eth_type = htons(ETH_P_IP);
6775
6776 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6777 {
6778 hddLog(LOGE, FL("Not in Connected state!"));
6779 return -ENOTSUPP;
6780 }
6781
6782 add_req = vos_mem_malloc(sizeof(*add_req));
6783 if (!add_req)
6784 {
6785 hddLog(LOGE, FL("memory allocation failed"));
6786 return -ENOMEM;
6787 }
6788
6789 /* Parse and fetch request Id */
6790 if (!tb[PARAM_REQUEST_ID])
6791 {
6792 hddLog(LOGE, FL("attr request id failed"));
6793 goto fail;
6794 }
6795
6796 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6797 hddLog(LOG1, FL("Request Id: %u"), request_id);
6798 if (request_id == 0)
6799 {
6800 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306801 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306802 }
6803
6804 if (!tb[PARAM_PERIOD])
6805 {
6806 hddLog(LOGE, FL("attr period failed"));
6807 goto fail;
6808 }
6809 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6810 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6811 if (add_req->usPtrnIntervalMs == 0)
6812 {
6813 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6814 goto fail;
6815 }
6816
6817 if (!tb[PARAM_SRC_MAC_ADDR])
6818 {
6819 hddLog(LOGE, FL("attr source mac address failed"));
6820 goto fail;
6821 }
6822 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6823 VOS_MAC_ADDR_SIZE);
6824 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6825 MAC_ADDR_ARRAY(add_req->macAddress));
6826
6827 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6828 VOS_MAC_ADDR_SIZE))
6829 {
6830 hddLog(LOGE,
6831 FL("input src mac address and connected ap bssid are different"));
6832 goto fail;
6833 }
6834
6835 if (!tb[PARAM_DST_MAC_ADDR])
6836 {
6837 hddLog(LOGE, FL("attr dst mac address failed"));
6838 goto fail;
6839 }
6840 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6841 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6842 MAC_ADDR_ARRAY(dst_addr.bytes));
6843
6844 if (!tb[PARAM_IP_PACKET])
6845 {
6846 hddLog(LOGE, FL("attr ip packet failed"));
6847 goto fail;
6848 }
6849 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6850 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6851
6852 if (add_req->ucPtrnSize < 0 ||
6853 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6854 HDD_ETH_HEADER_LEN))
6855 {
6856 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6857 add_req->ucPtrnSize);
6858 goto fail;
6859 }
6860
6861 len = 0;
6862 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6863 len += VOS_MAC_ADDR_SIZE;
6864 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6865 VOS_MAC_ADDR_SIZE);
6866 len += VOS_MAC_ADDR_SIZE;
6867 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6868 len += 2;
6869
6870 /*
6871 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6872 * ------------------------------------------------------------
6873 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6874 * ------------------------------------------------------------
6875 */
6876 vos_mem_copy(&add_req->ucPattern[len],
6877 nla_data(tb[PARAM_IP_PACKET]),
6878 add_req->ucPtrnSize);
6879 add_req->ucPtrnSize += len;
6880
6881 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6882 add_req->ucPattern, add_req->ucPtrnSize);
6883
6884 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6885 if (ret)
6886 {
6887 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6888 goto fail;
6889 }
6890 add_req->ucPtrnId = pattern_id;
6891 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6892
6893 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6894 if (!HAL_STATUS_SUCCESS(status))
6895 {
6896 hddLog(LOGE,
6897 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6898 goto fail;
6899 }
6900
6901 EXIT();
6902 vos_mem_free(add_req);
6903 return 0;
6904
6905fail:
6906 vos_mem_free(add_req);
6907 return -EINVAL;
6908}
6909
6910/**
6911 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6912 * @adapter: adapter pointer
6913 * @hdd_ctx: hdd context
6914 * @tb: nl attributes
6915 *
6916 * This function reads the NL attributes and forms a DelTxPtrn message
6917 * posts it to SME.
6918 *
6919 */
6920static int
6921wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6922 struct nlattr **tb)
6923{
6924 struct sSirDelPeriodicTxPtrn *del_req;
6925 eHalStatus status;
6926 uint32_t request_id, ret;
6927 uint8_t pattern_id = 0;
6928
6929 /* Parse and fetch request Id */
6930 if (!tb[PARAM_REQUEST_ID])
6931 {
6932 hddLog(LOGE, FL("attr request id failed"));
6933 return -EINVAL;
6934 }
6935 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6936 if (request_id == 0)
6937 {
6938 hddLog(LOGE, FL("request_id cannot be zero"));
6939 return -EINVAL;
6940 }
6941
6942 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6943 if (ret)
6944 {
6945 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6946 return -EINVAL;
6947 }
6948
6949 del_req = vos_mem_malloc(sizeof(*del_req));
6950 if (!del_req)
6951 {
6952 hddLog(LOGE, FL("memory allocation failed"));
6953 return -ENOMEM;
6954 }
6955
6956 vos_mem_set(del_req, sizeof(*del_req), 0);
6957 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6958 VOS_MAC_ADDR_SIZE);
6959 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6960 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6961 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6962 request_id, pattern_id, del_req->ucPatternIdBitmap);
6963
6964 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6965 if (!HAL_STATUS_SUCCESS(status))
6966 {
6967 hddLog(LOGE,
6968 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6969 goto fail;
6970 }
6971
6972 EXIT();
6973 vos_mem_free(del_req);
6974 return 0;
6975
6976fail:
6977 vos_mem_free(del_req);
6978 return -EINVAL;
6979}
6980
6981
6982/**
6983 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6984 * @wiphy: Pointer to wireless phy
6985 * @wdev: Pointer to wireless device
6986 * @data: Pointer to data
6987 * @data_len: Data length
6988 *
6989 * Return: 0 on success, negative errno on failure
6990 */
6991static int
6992__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6993 struct wireless_dev *wdev,
6994 const void *data,
6995 int data_len)
6996{
6997 struct net_device *dev = wdev->netdev;
6998 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6999 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7000 struct nlattr *tb[PARAM_MAX + 1];
7001 uint8_t control;
7002 int ret;
7003 static const struct nla_policy policy[PARAM_MAX + 1] =
7004 {
7005 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7006 [PARAM_CONTROL] = { .type = NLA_U32 },
7007 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7008 .len = VOS_MAC_ADDR_SIZE },
7009 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7010 .len = VOS_MAC_ADDR_SIZE },
7011 [PARAM_PERIOD] = { .type = NLA_U32 },
7012 };
7013
7014 ENTER();
7015
7016 ret = wlan_hdd_validate_context(hdd_ctx);
7017 if (0 != ret)
7018 {
7019 hddLog(LOGE, FL("HDD context is not valid"));
7020 return ret;
7021 }
7022
7023 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7024 {
7025 hddLog(LOGE,
7026 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7027 return -ENOTSUPP;
7028 }
7029
7030 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7031 {
7032 hddLog(LOGE, FL("Invalid ATTR"));
7033 return -EINVAL;
7034 }
7035
7036 if (!tb[PARAM_CONTROL])
7037 {
7038 hddLog(LOGE, FL("attr control failed"));
7039 return -EINVAL;
7040 }
7041 control = nla_get_u32(tb[PARAM_CONTROL]);
7042 hddLog(LOG1, FL("Control: %d"), control);
7043
7044 if (control == WLAN_START_OFFLOADED_PACKETS)
7045 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7046 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7047 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7048 else
7049 {
7050 hddLog(LOGE, FL("Invalid control: %d"), control);
7051 return -EINVAL;
7052 }
7053}
7054
7055/*
7056 * done with short names for the global vendor params
7057 * used by __wlan_hdd_cfg80211_offloaded_packets()
7058 */
7059#undef PARAM_MAX
7060#undef PARAM_REQUEST_ID
7061#undef PARAM_CONTROL
7062#undef PARAM_IP_PACKET
7063#undef PARAM_SRC_MAC_ADDR
7064#undef PARAM_DST_MAC_ADDR
7065#undef PARAM_PERIOD
7066
7067/**
7068 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7069 * @wiphy: wiphy structure pointer
7070 * @wdev: Wireless device structure pointer
7071 * @data: Pointer to the data received
7072 * @data_len: Length of @data
7073 *
7074 * Return: 0 on success; errno on failure
7075 */
7076static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7077 struct wireless_dev *wdev,
7078 const void *data,
7079 int data_len)
7080{
7081 int ret = 0;
7082
7083 vos_ssr_protect(__func__);
7084 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7085 wdev, data, data_len);
7086 vos_ssr_unprotect(__func__);
7087
7088 return ret;
7089}
7090#endif
7091
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307092static const struct
7093nla_policy
7094qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7096};
7097
7098/**
7099 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7100 * get link properties like nss, rate flags and operating frequency for
7101 * the connection with the given peer.
7102 * @wiphy: WIPHY structure pointer
7103 * @wdev: Wireless device structure pointer
7104 * @data: Pointer to the data received
7105 * @data_len: Length of the data received
7106 *
7107 * This function return the above link properties on success.
7108 *
7109 * Return: 0 on success and errno on failure
7110 */
7111static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7112 struct wireless_dev *wdev,
7113 const void *data,
7114 int data_len)
7115{
7116 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7117 struct net_device *dev = wdev->netdev;
7118 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7119 hdd_station_ctx_t *hdd_sta_ctx;
7120 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7121 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7122 uint32_t sta_id;
7123 struct sk_buff *reply_skb;
7124 uint32_t rate_flags = 0;
7125 uint8_t nss;
7126 uint8_t final_rate_flags = 0;
7127 uint32_t freq;
7128 v_CONTEXT_t pVosContext = NULL;
7129 ptSapContext pSapCtx = NULL;
7130
7131 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7133 return -EINVAL;
7134 }
7135
7136 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7137 qca_wlan_vendor_attr_policy)) {
7138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7139 return -EINVAL;
7140 }
7141
7142 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
7144 FL("Attribute peerMac not provided for mode=%d"),
7145 adapter->device_mode);
7146 return -EINVAL;
7147 }
7148
7149 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7150 sizeof(peer_mac));
7151 hddLog(VOS_TRACE_LEVEL_INFO,
7152 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7153 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7154
7155 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7156 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7157 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7158 if ((hdd_sta_ctx->conn_info.connState !=
7159 eConnectionState_Associated) ||
7160 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7161 VOS_MAC_ADDRESS_LEN)) {
7162 hddLog(VOS_TRACE_LEVEL_ERROR,
7163 FL("Not Associated to mac "MAC_ADDRESS_STR),
7164 MAC_ADDR_ARRAY(peer_mac));
7165 return -EINVAL;
7166 }
7167
7168 nss = 1; //pronto supports only one spatial stream
7169 freq = vos_chan_to_freq(
7170 hdd_sta_ctx->conn_info.operationChannel);
7171 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7172
7173 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7174 adapter->device_mode == WLAN_HDD_SOFTAP) {
7175
7176 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7177 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7178 if(pSapCtx == NULL){
7179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7180 FL("psapCtx is NULL"));
7181 return -ENOENT;
7182 }
7183
7184
7185 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7186 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7187 !vos_is_macaddr_broadcast(
7188 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7189 vos_mem_compare(
7190 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7191 peer_mac, VOS_MAC_ADDRESS_LEN))
7192 break;
7193 }
7194
7195 if (WLAN_MAX_STA_COUNT == sta_id) {
7196 hddLog(VOS_TRACE_LEVEL_ERROR,
7197 FL("No active peer with mac="MAC_ADDRESS_STR),
7198 MAC_ADDR_ARRAY(peer_mac));
7199 return -EINVAL;
7200 }
7201
7202 nss = 1; //pronto supports only one spatial stream
7203 freq = vos_chan_to_freq(
7204 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7205 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7206 } else {
7207 hddLog(VOS_TRACE_LEVEL_ERROR,
7208 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7209 MAC_ADDR_ARRAY(peer_mac));
7210 return -EINVAL;
7211 }
7212
7213 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7214 if (rate_flags & eHAL_TX_RATE_VHT80) {
7215 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7216 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7217 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7218 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7219 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7220 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7221 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7222 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7223 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7224 if (rate_flags & eHAL_TX_RATE_HT40)
7225 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7226 }
7227
7228 if (rate_flags & eHAL_TX_RATE_SGI) {
7229 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7230 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7231 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7232 }
7233 }
7234
7235 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7236 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7237
7238 if (NULL == reply_skb) {
7239 hddLog(VOS_TRACE_LEVEL_ERROR,
7240 FL("getLinkProperties: skb alloc failed"));
7241 return -EINVAL;
7242 }
7243
7244 if (nla_put_u8(reply_skb,
7245 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7246 nss) ||
7247 nla_put_u8(reply_skb,
7248 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7249 final_rate_flags) ||
7250 nla_put_u32(reply_skb,
7251 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7252 freq)) {
7253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7254 kfree_skb(reply_skb);
7255 return -EINVAL;
7256 }
7257
7258 return cfg80211_vendor_cmd_reply(reply_skb);
7259}
7260
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307261#define BEACON_MISS_THRESH_2_4 \
7262 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7263#define BEACON_MISS_THRESH_5_0 \
7264 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307265#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7266#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7267#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7268#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307269#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7270 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307271
7272/**
7273 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7274 * vendor command
7275 *
7276 * @wiphy: wiphy device pointer
7277 * @wdev: wireless device pointer
7278 * @data: Vendor command data buffer
7279 * @data_len: Buffer length
7280 *
7281 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7282 *
7283 * Return: EOK or other error codes.
7284 */
7285
7286static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7287 struct wireless_dev *wdev,
7288 const void *data,
7289 int data_len)
7290{
7291 struct net_device *dev = wdev->netdev;
7292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7293 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7294 hdd_station_ctx_t *pHddStaCtx;
7295 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7296 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307297 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307298 eHalStatus status;
7299 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307300 uint8_t hb_thresh_val;
7301
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307302 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7303 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7304 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307305 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7306 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7307 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307308 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7309 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307310 };
7311
7312 ENTER();
7313
7314 if (VOS_FTM_MODE == hdd_get_conparam()) {
7315 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7316 return -EINVAL;
7317 }
7318
7319 ret_val = wlan_hdd_validate_context(pHddCtx);
7320 if (ret_val) {
7321 return ret_val;
7322 }
7323
7324 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7325
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307326 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7327 hddLog(LOGE, FL("Invalid ATTR"));
7328 return -EINVAL;
7329 }
7330
7331 /* check the Wifi Capability */
7332 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7333 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7334 {
7335 hddLog(VOS_TRACE_LEVEL_ERROR,
7336 FL("WIFICONFIG not supported by Firmware"));
7337 return -EINVAL;
7338 }
7339
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307340 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7341 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7342 modifyRoamParamsReq.value =
7343 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7344
7345 if (eHAL_STATUS_SUCCESS !=
7346 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7349 ret_val = -EINVAL;
7350 }
7351 return ret_val;
7352 }
7353
7354 /* Moved this down in order to provide provision to set beacon
7355 * miss penalty count irrespective of connection state.
7356 */
7357 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7358 hddLog(LOGE, FL("Not in Connected state!"));
7359 return -ENOTSUPP;
7360 }
7361
7362 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307363
7364 if (!pReq) {
7365 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7366 "%s: Not able to allocate memory for tSetWifiConfigParams",
7367 __func__);
7368 return eHAL_STATUS_E_MALLOC_FAILED;
7369 }
7370
7371 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7372
7373 pReq->sessionId = pAdapter->sessionId;
7374 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7375
7376 if (tb[PARAM_MODULATED_DTIM]) {
7377 pReq->paramValue = nla_get_u32(
7378 tb[PARAM_MODULATED_DTIM]);
7379 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7380 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307381 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307382 hdd_set_pwrparams(pHddCtx);
7383 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7384 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7385
7386 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7387 iw_full_power_cbfn, pAdapter,
7388 eSME_FULL_PWR_NEEDED_BY_HDD);
7389 }
7390 else
7391 {
7392 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7393 }
7394 }
7395
7396 if (tb[PARAM_STATS_AVG_FACTOR]) {
7397 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7398 pReq->paramValue = nla_get_u16(
7399 tb[PARAM_STATS_AVG_FACTOR]);
7400 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7401 pReq->paramType, pReq->paramValue);
7402 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7403
7404 if (eHAL_STATUS_SUCCESS != status)
7405 {
7406 vos_mem_free(pReq);
7407 pReq = NULL;
7408 ret_val = -EPERM;
7409 return ret_val;
7410 }
7411 }
7412
7413
7414 if (tb[PARAM_GUARD_TIME]) {
7415 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7416 pReq->paramValue = nla_get_u32(
7417 tb[PARAM_GUARD_TIME]);
7418 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7419 pReq->paramType, pReq->paramValue);
7420 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7421
7422 if (eHAL_STATUS_SUCCESS != status)
7423 {
7424 vos_mem_free(pReq);
7425 pReq = NULL;
7426 ret_val = -EPERM;
7427 return ret_val;
7428 }
7429
7430 }
7431
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307432 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7433 hb_thresh_val = nla_get_u8(
7434 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7435
7436 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7437 hb_thresh_val);
7438 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7439 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7440 NULL, eANI_BOOLEAN_FALSE);
7441
7442 status = sme_update_hb_threshold(
7443 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7444 WNI_CFG_HEART_BEAT_THRESHOLD,
7445 hb_thresh_val, eCSR_BAND_24);
7446 if (eHAL_STATUS_SUCCESS != status) {
7447 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7448 vos_mem_free(pReq);
7449 pReq = NULL;
7450 return -EPERM;
7451 }
7452 }
7453
7454 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7455 hb_thresh_val = nla_get_u8(
7456 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7457
7458 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7459 hb_thresh_val);
7460 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7461 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7462 NULL, eANI_BOOLEAN_FALSE);
7463
7464 status = sme_update_hb_threshold(
7465 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7466 WNI_CFG_HEART_BEAT_THRESHOLD,
7467 hb_thresh_val, eCSR_BAND_5G);
7468 if (eHAL_STATUS_SUCCESS != status) {
7469 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7470 vos_mem_free(pReq);
7471 pReq = NULL;
7472 return -EPERM;
7473 }
7474 }
7475
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307476 EXIT();
7477 return ret_val;
7478}
7479
7480/**
7481 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7482 * vendor command
7483 *
7484 * @wiphy: wiphy device pointer
7485 * @wdev: wireless device pointer
7486 * @data: Vendor command data buffer
7487 * @data_len: Buffer length
7488 *
7489 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7490 *
7491 * Return: EOK or other error codes.
7492 */
7493static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7494 struct wireless_dev *wdev,
7495 const void *data,
7496 int data_len)
7497{
7498 int ret;
7499
7500 vos_ssr_protect(__func__);
7501 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7502 data, data_len);
7503 vos_ssr_unprotect(__func__);
7504
7505 return ret;
7506}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307507const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7508{
Mukul Sharma2a271632014-10-13 14:59:01 +05307509 {
7510 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7511 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7512 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7513 WIPHY_VENDOR_CMD_NEED_NETDEV |
7514 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307515 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307516 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307517
7518 {
7519 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7520 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7521 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7522 WIPHY_VENDOR_CMD_NEED_NETDEV |
7523 WIPHY_VENDOR_CMD_NEED_RUNNING,
7524 .doit = wlan_hdd_cfg80211_nan_request
7525 },
7526
Sunil Duttc69bccb2014-05-26 21:30:20 +05307527#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7528 {
7529 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7530 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7531 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7532 WIPHY_VENDOR_CMD_NEED_NETDEV |
7533 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307534 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307535 },
7536
7537 {
7538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7541 WIPHY_VENDOR_CMD_NEED_NETDEV |
7542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307543 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307544 },
7545
7546 {
7547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7550 WIPHY_VENDOR_CMD_NEED_NETDEV |
7551 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307552 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307553 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307554#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307555#ifdef WLAN_FEATURE_EXTSCAN
7556 {
7557 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7558 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7559 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7560 WIPHY_VENDOR_CMD_NEED_NETDEV |
7561 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307562 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307563 },
7564 {
7565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7568 WIPHY_VENDOR_CMD_NEED_NETDEV |
7569 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307570 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307571 },
7572 {
7573 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7574 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7575 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7576 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307577 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307578 },
7579 {
7580 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7581 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7582 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7583 WIPHY_VENDOR_CMD_NEED_NETDEV |
7584 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307585 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307586 },
7587 {
7588 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7589 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7590 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7591 WIPHY_VENDOR_CMD_NEED_NETDEV |
7592 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307593 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307594 },
7595 {
7596 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7597 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7598 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7599 WIPHY_VENDOR_CMD_NEED_NETDEV |
7600 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307601 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307602 },
7603 {
7604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7607 WIPHY_VENDOR_CMD_NEED_NETDEV |
7608 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307609 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307610 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307611 {
7612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7615 WIPHY_VENDOR_CMD_NEED_NETDEV |
7616 WIPHY_VENDOR_CMD_NEED_RUNNING,
7617 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7618 },
7619 {
7620 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7621 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7622 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7623 WIPHY_VENDOR_CMD_NEED_NETDEV |
7624 WIPHY_VENDOR_CMD_NEED_RUNNING,
7625 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7626 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307627#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307628/*EXT TDLS*/
7629 {
7630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7633 WIPHY_VENDOR_CMD_NEED_NETDEV |
7634 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307635 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307636 },
7637 {
7638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7641 WIPHY_VENDOR_CMD_NEED_NETDEV |
7642 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307643 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307644 },
7645 {
7646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7649 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307650 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307651 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307652 {
7653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7656 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307657 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307658 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307659 {
7660 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7661 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7662 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7663 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307664 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307665 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307666 {
7667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7670 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307671 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307672 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307673 {
7674 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7675 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7676 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7677 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307678 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307679 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307680 {
7681 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307682 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7683 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7684 WIPHY_VENDOR_CMD_NEED_NETDEV |
7685 WIPHY_VENDOR_CMD_NEED_RUNNING,
7686 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7687 },
7688 {
7689 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307690 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7691 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7692 WIPHY_VENDOR_CMD_NEED_NETDEV |
7693 WIPHY_VENDOR_CMD_NEED_RUNNING,
7694 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307695 },
7696 {
7697 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7698 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7699 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7700 WIPHY_VENDOR_CMD_NEED_NETDEV,
7701 .doit = wlan_hdd_cfg80211_wifi_logger_start
7702 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307703 {
7704 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7705 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7706 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7707 WIPHY_VENDOR_CMD_NEED_NETDEV|
7708 WIPHY_VENDOR_CMD_NEED_RUNNING,
7709 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307710 },
7711 {
7712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7715 WIPHY_VENDOR_CMD_NEED_NETDEV |
7716 WIPHY_VENDOR_CMD_NEED_RUNNING,
7717 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307718 },
7719 {
7720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7723 WIPHY_VENDOR_CMD_NEED_NETDEV |
7724 WIPHY_VENDOR_CMD_NEED_RUNNING,
7725 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307726 },
7727#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7728 {
7729 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7730 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7731 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7732 WIPHY_VENDOR_CMD_NEED_NETDEV |
7733 WIPHY_VENDOR_CMD_NEED_RUNNING,
7734 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307735 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307736#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307737 {
7738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7741 WIPHY_VENDOR_CMD_NEED_NETDEV |
7742 WIPHY_VENDOR_CMD_NEED_RUNNING,
7743 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307744 },
7745 {
7746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7749 WIPHY_VENDOR_CMD_NEED_NETDEV |
7750 WIPHY_VENDOR_CMD_NEED_RUNNING,
7751 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307753};
7754
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007755/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307756static const
7757struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007758{
7759#ifdef FEATURE_WLAN_CH_AVOID
7760 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307761 .vendor_id = QCA_NL80211_VENDOR_ID,
7762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007763 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307764#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7765#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7766 {
7767 /* Index = 1*/
7768 .vendor_id = QCA_NL80211_VENDOR_ID,
7769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7770 },
7771 {
7772 /* Index = 2*/
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7775 },
7776 {
7777 /* Index = 3*/
7778 .vendor_id = QCA_NL80211_VENDOR_ID,
7779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7780 },
7781 {
7782 /* Index = 4*/
7783 .vendor_id = QCA_NL80211_VENDOR_ID,
7784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7785 },
7786 {
7787 /* Index = 5*/
7788 .vendor_id = QCA_NL80211_VENDOR_ID,
7789 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7790 },
7791 {
7792 /* Index = 6*/
7793 .vendor_id = QCA_NL80211_VENDOR_ID,
7794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7795 },
7796#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307797#ifdef WLAN_FEATURE_EXTSCAN
7798 {
7799 .vendor_id = QCA_NL80211_VENDOR_ID,
7800 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7801 },
7802 {
7803 .vendor_id = QCA_NL80211_VENDOR_ID,
7804 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7805 },
7806 {
7807 .vendor_id = QCA_NL80211_VENDOR_ID,
7808 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7809 },
7810 {
7811 .vendor_id = QCA_NL80211_VENDOR_ID,
7812 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7813 },
7814 {
7815 .vendor_id = QCA_NL80211_VENDOR_ID,
7816 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7817 },
7818 {
7819 .vendor_id = QCA_NL80211_VENDOR_ID,
7820 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7821 },
7822 {
7823 .vendor_id = QCA_NL80211_VENDOR_ID,
7824 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7825 },
7826 {
7827 .vendor_id = QCA_NL80211_VENDOR_ID,
7828 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7829 },
7830 {
7831 .vendor_id = QCA_NL80211_VENDOR_ID,
7832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7833 },
7834 {
7835 .vendor_id = QCA_NL80211_VENDOR_ID,
7836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7837 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307838 {
7839 .vendor_id = QCA_NL80211_VENDOR_ID,
7840 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7841 },
7842 {
7843 .vendor_id = QCA_NL80211_VENDOR_ID,
7844 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7845 },
7846 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7847 .vendor_id = QCA_NL80211_VENDOR_ID,
7848 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7849 },
7850 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7851 .vendor_id = QCA_NL80211_VENDOR_ID,
7852 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7853 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307854#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307855/*EXT TDLS*/
7856 {
7857 .vendor_id = QCA_NL80211_VENDOR_ID,
7858 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7859 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307860 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7861 .vendor_id = QCA_NL80211_VENDOR_ID,
7862 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7863 },
7864
Srinivas Dasari030bad32015-02-18 23:23:54 +05307865
7866 {
7867 .vendor_id = QCA_NL80211_VENDOR_ID,
7868 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7869 },
7870
Sushant Kaushik084f6592015-09-10 13:11:56 +05307871 {
7872 .vendor_id = QCA_NL80211_VENDOR_ID,
7873 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307874 },
7875 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7876 .vendor_id = QCA_NL80211_VENDOR_ID,
7877 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7878 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307879 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7880 .vendor_id = QCA_NL80211_VENDOR_ID,
7881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7882 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307883
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007884};
7885
Jeff Johnson295189b2012-06-20 16:38:30 -07007886/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307887 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307888 * This function is called by hdd_wlan_startup()
7889 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307890 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307892struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007893{
7894 struct wiphy *wiphy;
7895 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307896 /*
7897 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 */
7899 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7900
7901 if (!wiphy)
7902 {
7903 /* Print error and jump into err label and free the memory */
7904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7905 return NULL;
7906 }
7907
Sunil Duttc69bccb2014-05-26 21:30:20 +05307908
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 return wiphy;
7910}
7911
Anurag Chouhan343af7e2016-12-16 13:11:19 +05307912#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
7913 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
7914/**
7915 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
7916 * @wiphy: pointer to wiphy
7917 * @config: pointer to config
7918 *
7919 * Return: None
7920 */
7921static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7922 hdd_config_t *config)
7923{
7924 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
7925 if (config->max_sched_scan_plan_interval)
7926 wiphy->max_sched_scan_plan_interval =
7927 config->max_sched_scan_plan_interval;
7928 if (config->max_sched_scan_plan_iterations)
7929 wiphy->max_sched_scan_plan_iterations =
7930 config->max_sched_scan_plan_iterations;
7931}
7932#else
7933static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7934 hdd_config_t *config)
7935{
7936}
7937#endif
7938
Jeff Johnson295189b2012-06-20 16:38:30 -07007939/*
7940 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307941 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007942 * private ioctl to change the band value
7943 */
7944int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7945{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307946 int i, j;
7947 eNVChannelEnabledType channelEnabledState;
7948
Jeff Johnsone7245742012-09-05 17:12:55 -07007949 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307950
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307951 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307953
7954 if (NULL == wiphy->bands[i])
7955 {
7956 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7957 __func__, i);
7958 continue;
7959 }
7960
7961 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7962 {
7963 struct ieee80211_supported_band *band = wiphy->bands[i];
7964
7965 channelEnabledState = vos_nv_getChannelEnabledState(
7966 band->channels[j].hw_value);
7967
7968 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7969 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307970 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307971 continue;
7972 }
7973 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7974 {
7975 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7976 continue;
7977 }
7978
7979 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7980 NV_CHANNEL_INVALID == channelEnabledState)
7981 {
7982 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7983 }
7984 else if (NV_CHANNEL_DFS == channelEnabledState)
7985 {
7986 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7987 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7988 }
7989 else
7990 {
7991 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7992 |IEEE80211_CHAN_RADAR);
7993 }
7994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 }
7996 return 0;
7997}
7998/*
7999 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308000 * This function is called by hdd_wlan_startup()
8001 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 * This function is used to initialize and register wiphy structure.
8003 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308004int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 struct wiphy *wiphy,
8006 hdd_config_t *pCfg
8007 )
8008{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308009 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308010 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8011
Jeff Johnsone7245742012-09-05 17:12:55 -07008012 ENTER();
8013
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 /* Now bind the underlying wlan device with wiphy */
8015 set_wiphy_dev(wiphy, dev);
8016
8017 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008018
Kiet Lam6c583332013-10-14 05:37:09 +05308019#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008020 /* the flag for the other case would be initialzed in
8021 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8023 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8024#else
Amar Singhal0a402232013-10-11 20:57:16 -07008025 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308026#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308027#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008028
Amar Singhalfddc28c2013-09-05 13:03:40 -07008029 /* This will disable updating of NL channels from passive to
8030 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308031#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8032 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8033#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008034 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308035#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008036
Amar Singhala49cbc52013-10-08 18:37:44 -07008037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008039 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8040 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8041 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008042 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308044 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308045#else
8046 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8047#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008048#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008049
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008050#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008051 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008052#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008053 || pCfg->isFastRoamIniFeatureEnabled
8054#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008055#ifdef FEATURE_WLAN_ESE
8056 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008057#endif
8058 )
8059 {
8060 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8061 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008062#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008063#ifdef FEATURE_WLAN_TDLS
8064 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8065 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8066#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308067#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308068 if (pCfg->configPNOScanSupport)
8069 {
8070 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8071 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8072 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8073 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8074 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308075#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008076
Abhishek Singh10d85972015-04-17 10:27:23 +05308077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8078 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8079#endif
8080
Amar Singhalfddc28c2013-09-05 13:03:40 -07008081#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008082 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8083 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008084 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008085 driver need to determine what to do with both
8086 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008087
8088 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008089#else
8090 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008091#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008092
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308093 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8094
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308095 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008096
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308097 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8098
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308100 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8101 | BIT(NL80211_IFTYPE_ADHOC)
8102 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8103 | BIT(NL80211_IFTYPE_P2P_GO)
8104 | BIT(NL80211_IFTYPE_AP);
8105
8106 if (VOS_MONITOR_MODE == hdd_get_conparam())
8107 {
8108 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008110
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308111 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008112 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8114 if( pCfg->enableMCC )
8115 {
8116 /* Currently, supports up to two channels */
8117 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008118
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308119 if( !pCfg->allowMCCGODiffBI )
8120 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008121
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308122 }
8123 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8124 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008125#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308126 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008127
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 /* Before registering we need to update the ht capabilitied based
8129 * on ini values*/
8130 if( !pCfg->ShortGI20MhzEnable )
8131 {
8132 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8133 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 }
8135
8136 if( !pCfg->ShortGI40MhzEnable )
8137 {
8138 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8139 }
8140
8141 if( !pCfg->nChannelBondingMode5GHz )
8142 {
8143 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8144 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308145 /*
8146 * In case of static linked driver at the time of driver unload,
8147 * module exit doesn't happens. Module cleanup helps in cleaning
8148 * of static memory.
8149 * If driver load happens statically, at the time of driver unload,
8150 * wiphy flags don't get reset because of static memory.
8151 * It's better not to store channel in static memory.
8152 */
8153 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8154 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8155 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8156 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8157 {
8158 hddLog(VOS_TRACE_LEVEL_ERROR,
8159 FL("Not enough memory to allocate channels"));
8160 return -ENOMEM;
8161 }
8162 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8163 &hdd_channels_2_4_GHZ[0],
8164 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008165
Agrawal Ashish97dec502015-11-26 20:20:58 +05308166 if (true == hdd_is_5g_supported(pHddCtx))
8167 {
8168 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8169 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8170 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8171 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8172 {
8173 hddLog(VOS_TRACE_LEVEL_ERROR,
8174 FL("Not enough memory to allocate channels"));
8175 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8176 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8177 return -ENOMEM;
8178 }
8179 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8180 &hdd_channels_5_GHZ[0],
8181 sizeof(hdd_channels_5_GHZ));
8182 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308183
8184 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8185 {
8186
8187 if (NULL == wiphy->bands[i])
8188 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308189 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308190 __func__, i);
8191 continue;
8192 }
8193
8194 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8195 {
8196 struct ieee80211_supported_band *band = wiphy->bands[i];
8197
8198 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8199 {
8200 // Enable social channels for P2P
8201 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8202 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8203 else
8204 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8205 continue;
8206 }
8207 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8208 {
8209 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8210 continue;
8211 }
8212 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 }
8214 /*Initialise the supported cipher suite details*/
8215 wiphy->cipher_suites = hdd_cipher_suites;
8216 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8217
8218 /*signal strength in mBm (100*dBm) */
8219 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8220
8221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308222 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008224
Sunil Duttc69bccb2014-05-26 21:30:20 +05308225 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8226 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008227 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8228 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8229
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308230 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8231
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308232 EXIT();
8233 return 0;
8234}
8235
8236/* In this function we are registering wiphy. */
8237int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8238{
8239 ENTER();
8240 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 if (0 > wiphy_register(wiphy))
8242 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308243 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8245 return -EIO;
8246 }
8247
8248 EXIT();
8249 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308250}
Jeff Johnson295189b2012-06-20 16:38:30 -07008251
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308252/* In this function we are updating channel list when,
8253 regulatory domain is FCC and country code is US.
8254 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8255 As per FCC smart phone is not a indoor device.
8256 GO should not opeate on indoor channels */
8257void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8258{
8259 int j;
8260 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8261 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8262 //Default counrtycode from NV at the time of wiphy initialization.
8263 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8264 &defaultCountryCode[0]))
8265 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008266 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308267 }
8268 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8269 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308270 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8271 {
8272 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8273 return;
8274 }
8275 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8276 {
8277 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8278 // Mark UNII -1 band channel as passive
8279 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8280 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8281 }
8282 }
8283}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308284/* This function registers for all frame which supplicant is interested in */
8285void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008286{
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8288 /* Register for all P2P action, public action etc frames */
8289 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008290 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308291 /* Register frame indication call back */
8292 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 /* Right now we are registering these frame when driver is getting
8294 initialized. Once we will move to 2.6.37 kernel, in which we have
8295 frame register ops, we will move this code as a part of that */
8296 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308297 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8299
8300 /* GAS Initial Response */
8301 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8302 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308303
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 /* GAS Comeback Request */
8305 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8306 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8307
8308 /* GAS Comeback Response */
8309 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8310 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8311
8312 /* P2P Public Action */
8313 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308314 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008315 P2P_PUBLIC_ACTION_FRAME_SIZE );
8316
8317 /* P2P Action */
8318 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8319 (v_U8_t*)P2P_ACTION_FRAME,
8320 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008321
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308322 /* WNM BSS Transition Request frame */
8323 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8324 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8325 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008326
8327 /* WNM-Notification */
8328 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8329 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8330 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008331}
8332
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308333void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008334{
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8336 /* Register for all P2P action, public action etc frames */
8337 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8338
Jeff Johnsone7245742012-09-05 17:12:55 -07008339 ENTER();
8340
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 /* Right now we are registering these frame when driver is getting
8342 initialized. Once we will move to 2.6.37 kernel, in which we have
8343 frame register ops, we will move this code as a part of that */
8344 /* GAS Initial Request */
8345
8346 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8347 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8348
8349 /* GAS Initial Response */
8350 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8351 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308352
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 /* GAS Comeback Request */
8354 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8355 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8356
8357 /* GAS Comeback Response */
8358 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8359 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8360
8361 /* P2P Public Action */
8362 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308363 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 P2P_PUBLIC_ACTION_FRAME_SIZE );
8365
8366 /* P2P Action */
8367 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8368 (v_U8_t*)P2P_ACTION_FRAME,
8369 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008370 /* WNM-Notification */
8371 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8372 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8373 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008374}
8375
8376#ifdef FEATURE_WLAN_WAPI
8377void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308378 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008379{
8380 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8381 tCsrRoamSetKey setKey;
8382 v_BOOL_t isConnected = TRUE;
8383 int status = 0;
8384 v_U32_t roamId= 0xFF;
8385 tANI_U8 *pKeyPtr = NULL;
8386 int n = 0;
8387
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308388 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8389 __func__, hdd_device_modetoString(pAdapter->device_mode),
8390 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008391
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308392 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 setKey.keyId = key_index; // Store Key ID
8394 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8395 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8396 setKey.paeRole = 0 ; // the PAE role
8397 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8398 {
8399 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8400 }
8401 else
8402 {
8403 isConnected = hdd_connIsConnected(pHddStaCtx);
8404 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8405 }
8406 setKey.keyLength = key_Len;
8407 pKeyPtr = setKey.Key;
8408 memcpy( pKeyPtr, key, key_Len);
8409
Arif Hussain6d2a3322013-11-17 19:50:10 -08008410 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 __func__, key_Len);
8412 for (n = 0 ; n < key_Len; n++)
8413 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8414 __func__,n,setKey.Key[n]);
8415
8416 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8417 if ( isConnected )
8418 {
8419 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8420 pAdapter->sessionId, &setKey, &roamId );
8421 }
8422 if ( status != 0 )
8423 {
8424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8425 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8426 __LINE__, status );
8427 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8428 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308429 /* Need to clear any trace of key value in the memory.
8430 * Thus zero out the memory even though it is local
8431 * variable.
8432 */
8433 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008434}
8435#endif /* FEATURE_WLAN_WAPI*/
8436
8437#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308438int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 beacon_data_t **ppBeacon,
8440 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008441#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443 beacon_data_t **ppBeacon,
8444 struct cfg80211_beacon_data *params,
8445 int dtim_period)
8446#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447{
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 int size;
8449 beacon_data_t *beacon = NULL;
8450 beacon_data_t *old = NULL;
8451 int head_len,tail_len;
8452
Jeff Johnsone7245742012-09-05 17:12:55 -07008453 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308455 {
8456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8457 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008460
8461 old = pAdapter->sessionCtx.ap.beacon;
8462
8463 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308464 {
8465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8466 FL("session(%d) old and new heads points to NULL"),
8467 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308469 }
8470
8471 if (params->tail && !params->tail_len)
8472 {
8473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8474 FL("tail_len is zero but tail is not NULL"));
8475 return -EINVAL;
8476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008477
Jeff Johnson295189b2012-06-20 16:38:30 -07008478#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8479 /* Kernel 3.0 is not updating dtim_period for set beacon */
8480 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308481 {
8482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8483 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008486#endif
8487
8488 if(params->head)
8489 head_len = params->head_len;
8490 else
8491 head_len = old->head_len;
8492
8493 if(params->tail || !old)
8494 tail_len = params->tail_len;
8495 else
8496 tail_len = old->tail_len;
8497
8498 size = sizeof(beacon_data_t) + head_len + tail_len;
8499
8500 beacon = kzalloc(size, GFP_KERNEL);
8501
8502 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 {
8504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8505 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008506 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008508
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008509#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 if(params->dtim_period || !old )
8511 beacon->dtim_period = params->dtim_period;
8512 else
8513 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008514#else
8515 if(dtim_period || !old )
8516 beacon->dtim_period = dtim_period;
8517 else
8518 beacon->dtim_period = old->dtim_period;
8519#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8522 beacon->tail = beacon->head + head_len;
8523 beacon->head_len = head_len;
8524 beacon->tail_len = tail_len;
8525
8526 if(params->head) {
8527 memcpy (beacon->head,params->head,beacon->head_len);
8528 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 if(old)
8531 memcpy (beacon->head,old->head,beacon->head_len);
8532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308533
Jeff Johnson295189b2012-06-20 16:38:30 -07008534 if(params->tail) {
8535 memcpy (beacon->tail,params->tail,beacon->tail_len);
8536 }
8537 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308538 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008539 memcpy (beacon->tail,old->tail,beacon->tail_len);
8540 }
8541
8542 *ppBeacon = beacon;
8543
8544 kfree(old);
8545
8546 return 0;
8547
8548}
Jeff Johnson295189b2012-06-20 16:38:30 -07008549
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308550v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8552 const v_U8_t *pIes,
8553#else
8554 v_U8_t *pIes,
8555#endif
8556 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008557{
8558 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308559 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308561
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308563 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 elem_id = ptr[0];
8565 elem_len = ptr[1];
8566 left -= 2;
8567 if(elem_len > left)
8568 {
8569 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008570 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 eid,elem_len,left);
8572 return NULL;
8573 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308574 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 {
8576 return ptr;
8577 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308578
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 left -= elem_len;
8580 ptr += (elem_len + 2);
8581 }
8582 return NULL;
8583}
8584
Jeff Johnson295189b2012-06-20 16:38:30 -07008585/* Check if rate is 11g rate or not */
8586static int wlan_hdd_rate_is_11g(u8 rate)
8587{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008588 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 u8 i;
8590 for (i = 0; i < 8; i++)
8591 {
8592 if(rate == gRateArray[i])
8593 return TRUE;
8594 }
8595 return FALSE;
8596}
8597
8598/* Check for 11g rate and set proper 11g only mode */
8599static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8600 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8601{
8602 u8 i, num_rates = pIe[0];
8603
8604 pIe += 1;
8605 for ( i = 0; i < num_rates; i++)
8606 {
8607 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8608 {
8609 /* If rate set have 11g rate than change the mode to 11G */
8610 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8611 if (pIe[i] & BASIC_RATE_MASK)
8612 {
8613 /* If we have 11g rate as basic rate, it means mode
8614 is 11g only mode.
8615 */
8616 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8617 *pCheckRatesfor11g = FALSE;
8618 }
8619 }
8620 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8621 {
8622 *require_ht = TRUE;
8623 }
8624 }
8625 return;
8626}
8627
8628static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8629{
8630 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8631 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8632 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8633 u8 checkRatesfor11g = TRUE;
8634 u8 require_ht = FALSE;
8635 u8 *pIe=NULL;
8636
8637 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8638
8639 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8640 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8641 if (pIe != NULL)
8642 {
8643 pIe += 1;
8644 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8645 &pConfig->SapHw_mode);
8646 }
8647
8648 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8649 WLAN_EID_EXT_SUPP_RATES);
8650 if (pIe != NULL)
8651 {
8652
8653 pIe += 1;
8654 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8655 &pConfig->SapHw_mode);
8656 }
8657
8658 if( pConfig->channel > 14 )
8659 {
8660 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8661 }
8662
8663 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8664 WLAN_EID_HT_CAPABILITY);
8665
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308666 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 {
8668 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8669 if(require_ht)
8670 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8671 }
8672}
8673
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308674static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8675 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8676{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008677 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308678 v_U8_t *pIe = NULL;
8679 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8680
8681 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8682 pBeacon->tail, pBeacon->tail_len);
8683
8684 if (pIe)
8685 {
8686 ielen = pIe[1] + 2;
8687 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8688 {
8689 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8690 }
8691 else
8692 {
8693 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8694 return -EINVAL;
8695 }
8696 *total_ielen += ielen;
8697 }
8698 return 0;
8699}
8700
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008701static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8702 v_U8_t *genie, v_U8_t *total_ielen)
8703{
8704 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8705 int left = pBeacon->tail_len;
8706 v_U8_t *ptr = pBeacon->tail;
8707 v_U8_t elem_id, elem_len;
8708 v_U16_t ielen = 0;
8709
8710 if ( NULL == ptr || 0 == left )
8711 return;
8712
8713 while (left >= 2)
8714 {
8715 elem_id = ptr[0];
8716 elem_len = ptr[1];
8717 left -= 2;
8718 if (elem_len > left)
8719 {
8720 hddLog( VOS_TRACE_LEVEL_ERROR,
8721 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8722 elem_id, elem_len, left);
8723 return;
8724 }
8725 if (IE_EID_VENDOR == elem_id)
8726 {
8727 /* skipping the VSIE's which we don't want to include or
8728 * it will be included by existing code
8729 */
8730 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8731#ifdef WLAN_FEATURE_WFD
8732 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8733#endif
8734 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8735 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8736 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8737 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8738 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8739 {
8740 ielen = ptr[1] + 2;
8741 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8742 {
8743 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8744 *total_ielen += ielen;
8745 }
8746 else
8747 {
8748 hddLog( VOS_TRACE_LEVEL_ERROR,
8749 "IE Length is too big "
8750 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8751 elem_id, elem_len, *total_ielen);
8752 }
8753 }
8754 }
8755
8756 left -= elem_len;
8757 ptr += (elem_len + 2);
8758 }
8759 return;
8760}
8761
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008762#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008763static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8764 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008765#else
8766static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8767 struct cfg80211_beacon_data *params)
8768#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008769{
8770 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308771 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008773 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008774
8775 genie = vos_mem_malloc(MAX_GENIE_LEN);
8776
8777 if(genie == NULL) {
8778
8779 return -ENOMEM;
8780 }
8781
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308782 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8783 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308785 hddLog(LOGE,
8786 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308787 ret = -EINVAL;
8788 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 }
8790
8791#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308792 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8793 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8794 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308795 hddLog(LOGE,
8796 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308797 ret = -EINVAL;
8798 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 }
8800#endif
8801
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308802 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8803 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308805 hddLog(LOGE,
8806 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308807 ret = -EINVAL;
8808 goto done;
8809 }
8810
8811 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8812 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008813 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008815
8816 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8817 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8818 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8819 {
8820 hddLog(LOGE,
8821 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008822 ret = -EINVAL;
8823 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008824 }
8825
8826 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8827 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8828 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8829 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8830 ==eHAL_STATUS_FAILURE)
8831 {
8832 hddLog(LOGE,
8833 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008834 ret = -EINVAL;
8835 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 }
8837
8838 // Added for ProResp IE
8839 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8840 {
8841 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8842 u8 probe_rsp_ie_len[3] = {0};
8843 u8 counter = 0;
8844 /* Check Probe Resp Length if it is greater then 255 then Store
8845 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8846 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8847 Store More then 255 bytes into One Variable.
8848 */
8849 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8850 {
8851 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8852 {
8853 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8854 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8855 }
8856 else
8857 {
8858 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8859 rem_probe_resp_ie_len = 0;
8860 }
8861 }
8862
8863 rem_probe_resp_ie_len = 0;
8864
8865 if (probe_rsp_ie_len[0] > 0)
8866 {
8867 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8868 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8869 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8870 probe_rsp_ie_len[0], NULL,
8871 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8872 {
8873 hddLog(LOGE,
8874 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008875 ret = -EINVAL;
8876 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 }
8878 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8879 }
8880
8881 if (probe_rsp_ie_len[1] > 0)
8882 {
8883 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8884 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8885 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8886 probe_rsp_ie_len[1], NULL,
8887 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8888 {
8889 hddLog(LOGE,
8890 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008891 ret = -EINVAL;
8892 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 }
8894 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8895 }
8896
8897 if (probe_rsp_ie_len[2] > 0)
8898 {
8899 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8900 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8901 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8902 probe_rsp_ie_len[2], NULL,
8903 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8904 {
8905 hddLog(LOGE,
8906 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008907 ret = -EINVAL;
8908 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 }
8910 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8911 }
8912
8913 if (probe_rsp_ie_len[1] == 0 )
8914 {
8915 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8916 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8917 eANI_BOOLEAN_FALSE) )
8918 {
8919 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008920 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 }
8922 }
8923
8924 if (probe_rsp_ie_len[2] == 0 )
8925 {
8926 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8927 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8928 eANI_BOOLEAN_FALSE) )
8929 {
8930 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008931 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 }
8933 }
8934
8935 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8936 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8937 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8938 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8939 == eHAL_STATUS_FAILURE)
8940 {
8941 hddLog(LOGE,
8942 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008943 ret = -EINVAL;
8944 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 }
8946 }
8947 else
8948 {
8949 // Reset WNI_CFG_PROBE_RSP Flags
8950 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8951
8952 hddLog(VOS_TRACE_LEVEL_INFO,
8953 "%s: No Probe Response IE received in set beacon",
8954 __func__);
8955 }
8956
8957 // Added for AssocResp IE
8958 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8959 {
8960 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8961 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8962 params->assocresp_ies_len, NULL,
8963 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8964 {
8965 hddLog(LOGE,
8966 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008967 ret = -EINVAL;
8968 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 }
8970
8971 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8972 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8973 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8974 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8975 == eHAL_STATUS_FAILURE)
8976 {
8977 hddLog(LOGE,
8978 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008979 ret = -EINVAL;
8980 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 }
8982 }
8983 else
8984 {
8985 hddLog(VOS_TRACE_LEVEL_INFO,
8986 "%s: No Assoc Response IE received in set beacon",
8987 __func__);
8988
8989 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8990 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8991 eANI_BOOLEAN_FALSE) )
8992 {
8993 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008994 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 }
8996 }
8997
Jeff Johnsone7245742012-09-05 17:12:55 -07008998done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309000 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009001}
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 * FUNCTION: wlan_hdd_validate_operation_channel
9005 * called by wlan_hdd_cfg80211_start_bss() and
9006 * wlan_hdd_cfg80211_set_channel()
9007 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309008 * channel list.
9009 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009010VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009011{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309012
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 v_U32_t num_ch = 0;
9014 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9015 u32 indx = 0;
9016 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309017 v_U8_t fValidChannel = FALSE, count = 0;
9018 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309019
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9021
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309022 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309024 /* Validate the channel */
9025 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309027 if ( channel == rfChannels[count].channelNum )
9028 {
9029 fValidChannel = TRUE;
9030 break;
9031 }
9032 }
9033 if (fValidChannel != TRUE)
9034 {
9035 hddLog(VOS_TRACE_LEVEL_ERROR,
9036 "%s: Invalid Channel [%d]", __func__, channel);
9037 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 }
9039 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309040 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309042 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9043 valid_ch, &num_ch))
9044 {
9045 hddLog(VOS_TRACE_LEVEL_ERROR,
9046 "%s: failed to get valid channel list", __func__);
9047 return VOS_STATUS_E_FAILURE;
9048 }
9049 for (indx = 0; indx < num_ch; indx++)
9050 {
9051 if (channel == valid_ch[indx])
9052 {
9053 break;
9054 }
9055 }
9056
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309057 if (indx >= num_ch)
9058 {
9059 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9060 {
9061 eCsrBand band;
9062 unsigned int freq;
9063
9064 sme_GetFreqBand(hHal, &band);
9065
9066 if (eCSR_BAND_5G == band)
9067 {
9068#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9069 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9070 {
9071 freq = ieee80211_channel_to_frequency(channel,
9072 IEEE80211_BAND_2GHZ);
9073 }
9074 else
9075 {
9076 freq = ieee80211_channel_to_frequency(channel,
9077 IEEE80211_BAND_5GHZ);
9078 }
9079#else
9080 freq = ieee80211_channel_to_frequency(channel);
9081#endif
9082 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9083 return VOS_STATUS_SUCCESS;
9084 }
9085 }
9086
9087 hddLog(VOS_TRACE_LEVEL_ERROR,
9088 "%s: Invalid Channel [%d]", __func__, channel);
9089 return VOS_STATUS_E_FAILURE;
9090 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309092
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309094
Jeff Johnson295189b2012-06-20 16:38:30 -07009095}
9096
Viral Modi3a32cc52013-02-08 11:14:52 -08009097/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309098 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009099 * This function is used to set the channel number
9100 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309101static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009102 struct ieee80211_channel *chan,
9103 enum nl80211_channel_type channel_type
9104 )
9105{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309106 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009107 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009108 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009109 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309110 hdd_context_t *pHddCtx;
9111 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009112
9113 ENTER();
9114
9115 if( NULL == dev )
9116 {
9117 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009118 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009119 return -ENODEV;
9120 }
9121 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309122
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309123 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9124 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9125 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009126 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309127 "%s: device_mode = %s (%d) freq = %d", __func__,
9128 hdd_device_modetoString(pAdapter->device_mode),
9129 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309130
9131 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9132 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309133 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309135 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009136 }
9137
9138 /*
9139 * Do freq to chan conversion
9140 * TODO: for 11a
9141 */
9142
9143 channel = ieee80211_frequency_to_channel(freq);
9144
9145 /* Check freq range */
9146 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9147 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9148 {
9149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009150 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009151 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9152 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9153 return -EINVAL;
9154 }
9155
9156 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9157
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309158 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9159 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009160 {
9161 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9162 {
9163 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009164 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009165 return -EINVAL;
9166 }
9167 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9168 "%s: set channel to [%d] for device mode =%d",
9169 __func__, channel,pAdapter->device_mode);
9170 }
9171 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009172 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009173 )
9174 {
9175 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9176 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9177 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9178
9179 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9180 {
9181 /* Link is up then return cant set channel*/
9182 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009183 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009184 return -EINVAL;
9185 }
9186
9187 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9188 pHddStaCtx->conn_info.operationChannel = channel;
9189 pRoamProfile->ChannelInfo.ChannelList =
9190 &pHddStaCtx->conn_info.operationChannel;
9191 }
9192 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009193 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009194 )
9195 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309196 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9197 {
9198 if(VOS_STATUS_SUCCESS !=
9199 wlan_hdd_validate_operation_channel(pAdapter,channel))
9200 {
9201 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009202 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309203 return -EINVAL;
9204 }
9205 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9206 }
9207 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009208 {
9209 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9210
9211 /* If auto channel selection is configured as enable/ 1 then ignore
9212 channel set by supplicant
9213 */
9214 if ( cfg_param->apAutoChannelSelection )
9215 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309216 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9217 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009218 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309219 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9220 __func__, hdd_device_modetoString(pAdapter->device_mode),
9221 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009222 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309223 else
9224 {
9225 if(VOS_STATUS_SUCCESS !=
9226 wlan_hdd_validate_operation_channel(pAdapter,channel))
9227 {
9228 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009229 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309230 return -EINVAL;
9231 }
9232 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9233 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009234 }
9235 }
9236 else
9237 {
9238 hddLog(VOS_TRACE_LEVEL_FATAL,
9239 "%s: Invalid device mode failed to set valid channel", __func__);
9240 return -EINVAL;
9241 }
9242 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309243 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009244}
9245
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309246static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9247 struct net_device *dev,
9248 struct ieee80211_channel *chan,
9249 enum nl80211_channel_type channel_type
9250 )
9251{
9252 int ret;
9253
9254 vos_ssr_protect(__func__);
9255 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9256 vos_ssr_unprotect(__func__);
9257
9258 return ret;
9259}
9260
Anurag Chouhan83026002016-12-13 22:46:21 +05309261#ifdef DHCP_SERVER_OFFLOAD
9262void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9263 VOS_STATUS status)
9264{
9265 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9266
9267 ENTER();
9268
9269 if (NULL == adapter)
9270 {
9271 hddLog(VOS_TRACE_LEVEL_ERROR,
9272 "%s: adapter is NULL",__func__);
9273 return;
9274 }
9275
9276 adapter->dhcp_status.dhcp_offload_status = status;
9277 vos_event_set(&adapter->dhcp_status.vos_event);
9278 return;
9279}
9280
9281/**
9282 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9283 * @hostapd_adapter: pointer to hostapd adapter.
9284 *
9285 * Return: None
9286 */
9287static VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter)
9288{
9289 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9290 sir_dhcp_srv_offload_info dhcp_srv_info;
9291 tANI_U8 num_entries = 0;
9292 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9293 tANI_U8 num;
9294 tANI_U32 temp;
9295 VOS_STATUS ret;
9296
9297 ENTER();
9298
9299 ret = wlan_hdd_validate_context(hdd_ctx);
9300 if (0 != ret)
9301 return VOS_STATUS_E_INVAL;
9302
9303 /* Prepare the request to send to SME */
9304 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9305 if (NULL == dhcp_srv_info) {
9306 hddLog(VOS_TRACE_LEVEL_ERROR,
9307 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9308 return VOS_STATUS_E_NOMEM;
9309 }
9310
9311 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9312
9313 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9314 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9315 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9316 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9317 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9318 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9319
9320 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9321 srv_ip,
9322 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309323 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309324 if (num_entries != IPADDR_NUM_ENTRIES) {
9325 hddLog(VOS_TRACE_LEVEL_ERROR,
9326 "%s: incorrect IP address (%s) assigned for DHCP server!",
9327 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9328 vos_mem_free(dhcp_srv_info);
9329 return VOS_STATUS_E_FAILURE;
9330 }
9331
9332 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9333 hddLog(VOS_TRACE_LEVEL_ERROR,
9334 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9335 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9336 vos_mem_free(dhcp_srv_info);
9337 return VOS_STATUS_E_FAILURE;
9338 }
9339
9340 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9341 hddLog(VOS_TRACE_LEVEL_ERROR,
9342 "%s: invalid IP address (%s)! The last field must be less than 100!",
9343 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9344 vos_mem_free(dhcp_srv_info);
9345 return VOS_STATUS_E_FAILURE;
9346 }
9347
9348 for (num = 0; num < num_entries; num++) {
9349 temp = srv_ip[num];
9350 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9351 }
9352
9353 if (eHAL_STATUS_SUCCESS !=
9354 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9355 hddLog(VOS_TRACE_LEVEL_ERROR,
9356 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9357 vos_mem_free(dhcp_srv_info);
9358 return VOS_STATUS_E_FAILURE;
9359 }
9360
9361 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9362 "%s: enable DHCP Server offload successfully!", __func__);
9363
9364 vos_mem_free(dhcp_srv_info);
9365 return 0;
9366}
9367#endif /* DHCP_SERVER_OFFLOAD */
9368
Jeff Johnson295189b2012-06-20 16:38:30 -07009369#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9370static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9371 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009372#else
9373static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9374 struct cfg80211_beacon_data *params,
9375 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309376 enum nl80211_hidden_ssid hidden_ssid,
9377 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009378#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009379{
9380 tsap_Config_t *pConfig;
9381 beacon_data_t *pBeacon = NULL;
9382 struct ieee80211_mgmt *pMgmt_frame;
9383 v_U8_t *pIe=NULL;
9384 v_U16_t capab_info;
9385 eCsrAuthType RSNAuthType;
9386 eCsrEncryptionType RSNEncryptType;
9387 eCsrEncryptionType mcRSNEncryptType;
9388 int status = VOS_STATUS_SUCCESS;
9389 tpWLAN_SAPEventCB pSapEventCallback;
9390 hdd_hostapd_state_t *pHostapdState;
9391 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9392 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309393 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309395 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009397 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309398 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009399 v_BOOL_t MFPCapable = VOS_FALSE;
9400 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309401 v_BOOL_t sapEnable11AC =
9402 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 ENTER();
9404
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309405 iniConfig = pHddCtx->cfg_ini;
9406
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9408
9409 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9410
9411 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9412
9413 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9414
9415 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9416
9417 //channel is already set in the set_channel Call back
9418 //pConfig->channel = pCommitConfig->channel;
9419
9420 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9423
9424 pConfig->dtim_period = pBeacon->dtim_period;
9425
Arif Hussain6d2a3322013-11-17 19:50:10 -08009426 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 pConfig->dtim_period);
9428
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009429 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009430 {
9431 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309433 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9434 {
9435 tANI_BOOLEAN restartNeeded;
9436 pConfig->ieee80211d = 1;
9437 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9438 sme_setRegInfo(hHal, pConfig->countryCode);
9439 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9440 }
9441 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009443 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009444 pConfig->ieee80211d = 1;
9445 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9446 sme_setRegInfo(hHal, pConfig->countryCode);
9447 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009449 else
9450 {
9451 pConfig->ieee80211d = 0;
9452 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309453 /*
9454 * If auto channel is configured i.e. channel is 0,
9455 * so skip channel validation.
9456 */
9457 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9458 {
9459 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9460 {
9461 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009462 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309463 return -EINVAL;
9464 }
9465 }
9466 else
9467 {
9468 if(1 != pHddCtx->is_dynamic_channel_range_set)
9469 {
9470 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9471 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9472 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9473 }
9474 pHddCtx->is_dynamic_channel_range_set = 0;
9475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009477 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 {
9479 pConfig->ieee80211d = 0;
9480 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309481
9482#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9483 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9484 pConfig->authType = eSAP_OPEN_SYSTEM;
9485 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9486 pConfig->authType = eSAP_SHARED_KEY;
9487 else
9488 pConfig->authType = eSAP_AUTO_SWITCH;
9489#else
9490 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9491 pConfig->authType = eSAP_OPEN_SYSTEM;
9492 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9493 pConfig->authType = eSAP_SHARED_KEY;
9494 else
9495 pConfig->authType = eSAP_AUTO_SWITCH;
9496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009497
9498 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309499
9500 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309502#ifdef SAP_AUTH_OFFLOAD
9503 /* In case of sap offload, hostapd.conf is configuted with open mode and
9504 * security is configured from ini file. Due to open mode in hostapd.conf
9505 * privacy bit is set to false which will result in not sending,
9506 * data packets as encrypted.
9507 * If enable_sap_auth_offload is enabled in ini and
9508 * sap_auth_offload_sec_type is type of WPA2-PSK,
9509 * driver will set privacy bit to 1.
9510 */
9511 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9512 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9513 pConfig->privacy = VOS_TRUE;
9514#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009515
9516 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9517
9518 /*Set wps station to configured*/
9519 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9520
9521 if(pIe)
9522 {
9523 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9524 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009525 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 return -EINVAL;
9527 }
9528 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9529 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009530 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 /* Check 15 bit of WPS IE as it contain information for wps state
9532 * WPS state
9533 */
9534 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9535 {
9536 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9537 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9538 {
9539 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9540 }
9541 }
9542 }
9543 else
9544 {
9545 pConfig->wps_state = SAP_WPS_DISABLED;
9546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009548
c_hpothufe599e92014-06-16 11:38:55 +05309549 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9550 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9551 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9552 eCSR_ENCRYPT_TYPE_NONE;
9553
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 pConfig->RSNWPAReqIELength = 0;
9555 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 WLAN_EID_RSN);
9558 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309559 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9561 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9562 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309563 /* The actual processing may eventually be more extensive than
9564 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 * by the app.
9566 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309567 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9569 &RSNEncryptType,
9570 &mcRSNEncryptType,
9571 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009572 &MFPCapable,
9573 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 pConfig->pRSNWPAReqIE[1]+2,
9575 pConfig->pRSNWPAReqIE );
9576
9577 if( VOS_STATUS_SUCCESS == status )
9578 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309579 /* Now copy over all the security attributes you have
9580 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 * */
9582 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9583 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9584 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9585 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309586 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009587 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9589 }
9590 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9593 pBeacon->tail, pBeacon->tail_len);
9594
9595 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9596 {
9597 if (pConfig->pRSNWPAReqIE)
9598 {
9599 /*Mixed mode WPA/WPA2*/
9600 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9601 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9602 }
9603 else
9604 {
9605 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9606 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9607 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9610 &RSNEncryptType,
9611 &mcRSNEncryptType,
9612 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009613 &MFPCapable,
9614 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 pConfig->pRSNWPAReqIE[1]+2,
9616 pConfig->pRSNWPAReqIE );
9617
9618 if( VOS_STATUS_SUCCESS == status )
9619 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309620 /* Now copy over all the security attributes you have
9621 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 * */
9623 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9624 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9625 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9626 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309627 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009628 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9630 }
9631 }
9632 }
9633
Jeff Johnson4416a782013-03-25 14:17:50 -07009634 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9635 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9636 return -EINVAL;
9637 }
9638
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9640
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009641#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 if (params->ssid != NULL)
9643 {
9644 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9645 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9646 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9647 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9648 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009649#else
9650 if (ssid != NULL)
9651 {
9652 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9653 pConfig->SSIDinfo.ssid.length = ssid_len;
9654 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9655 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9656 }
9657#endif
9658
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 /* default value */
9663 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9664 pConfig->num_accept_mac = 0;
9665 pConfig->num_deny_mac = 0;
9666
9667 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9668 pBeacon->tail, pBeacon->tail_len);
9669
9670 /* pIe for black list is following form:
9671 type : 1 byte
9672 length : 1 byte
9673 OUI : 4 bytes
9674 acl type : 1 byte
9675 no of mac addr in black list: 1 byte
9676 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309677 */
9678 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 {
9680 pConfig->SapMacaddr_acl = pIe[6];
9681 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009682 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309684 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9685 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9687 for (i = 0; i < pConfig->num_deny_mac; i++)
9688 {
9689 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9690 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 }
9693 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9694 pBeacon->tail, pBeacon->tail_len);
9695
9696 /* pIe for white list is following form:
9697 type : 1 byte
9698 length : 1 byte
9699 OUI : 4 bytes
9700 acl type : 1 byte
9701 no of mac addr in white list: 1 byte
9702 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309703 */
9704 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 {
9706 pConfig->SapMacaddr_acl = pIe[6];
9707 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009708 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309710 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9711 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9713 for (i = 0; i < pConfig->num_accept_mac; i++)
9714 {
9715 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9716 acl_entry++;
9717 }
9718 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9721
Jeff Johnsone7245742012-09-05 17:12:55 -07009722#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009723 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309724 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9725 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309726 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9727 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009728 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9729 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309730 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9731 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009732 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309733 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009734 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309735 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009736
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309737 /* If ACS disable and selected channel <= 14
9738 * OR
9739 * ACS enabled and ACS operating band is choosen as 2.4
9740 * AND
9741 * VHT in 2.4G Disabled
9742 * THEN
9743 * Fallback to 11N mode
9744 */
9745 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9746 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309747 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309748 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009749 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309750 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9751 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009752 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9753 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009754 }
9755#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 // ht_capab is not what the name conveys,this is used for protection bitmap
9758 pConfig->ht_capab =
9759 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9760
9761 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9762 {
9763 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9764 return -EINVAL;
9765 }
9766
9767 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9770 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309771 pConfig->obssProtEnabled =
9772 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009773
Chet Lanctot8cecea22014-02-11 19:09:36 -08009774#ifdef WLAN_FEATURE_11W
9775 pConfig->mfpCapable = MFPCapable;
9776 pConfig->mfpRequired = MFPRequired;
9777 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9778 pConfig->mfpCapable, pConfig->mfpRequired);
9779#endif
9780
Arif Hussain6d2a3322013-11-17 19:50:10 -08009781 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009783 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9784 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9785 (int)pConfig->channel);
9786 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9787 pConfig->SapHw_mode, pConfig->privacy,
9788 pConfig->authType);
9789 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9790 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9791 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9792 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309794 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 {
9796 //Bss already started. just return.
9797 //TODO Probably it should update some beacon params.
9798 hddLog( LOGE, "Bss Already started...Ignore the request");
9799 EXIT();
9800 return 0;
9801 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309802
Agarwal Ashish51325b52014-06-16 16:50:49 +05309803 if (vos_max_concurrent_connections_reached()) {
9804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9805 return -EINVAL;
9806 }
9807
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 pConfig->persona = pHostapdAdapter->device_mode;
9809
Peng Xu2446a892014-09-05 17:21:18 +05309810 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9811 if ( NULL != psmeConfig)
9812 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309813 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309814 sme_GetConfigParam(hHal, psmeConfig);
9815 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309816#ifdef WLAN_FEATURE_AP_HT40_24G
9817 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9818 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9819 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9820 {
9821 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9822 sme_UpdateConfig (hHal, psmeConfig);
9823 }
9824#endif
Peng Xu2446a892014-09-05 17:21:18 +05309825 vos_mem_free(psmeConfig);
9826 }
Peng Xuafc34e32014-09-25 13:23:55 +05309827 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309828
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 pSapEventCallback = hdd_hostapd_SAPEventCB;
9830 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9831 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9832 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009833 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 return -EINVAL;
9835 }
9836
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309837 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9839
9840 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309841
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309843 {
9844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009845 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009846 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 VOS_ASSERT(0);
9848 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309849
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +05309851 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
9852 VOS_STATUS_SUCCESS)
9853 {
9854 hddLog(LOGE,FL("Fail to get Softap sessionID"));
9855 VOS_ASSERT(0);
9856 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309857 /* Initialize WMM configuation */
9858 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309859 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860
Anurag Chouhan83026002016-12-13 22:46:21 +05309861#ifdef DHCP_SERVER_OFFLOAD
9862 /* set dhcp server offload */
9863 if (iniConfig->enable_dhcp_srv_offload &&
9864 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
9865 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
9866 if (!VOS_IS_STATUS_SUCCESS(status))
9867 {
9868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9869 ("HDD DHCP Server Offload Failed!!"));
9870 return -EINVAL;
9871 }
9872 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
9873 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9874 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9875 {
9876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9877 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9878 pHostapdAdapter->dhcp_status.dhcp_offload_status);
9879 return -EINVAL;
9880 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309881#ifdef MDNS_OFFLOAD
9882 if (iniConfig->enable_mdns_offload) {
9883 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
9884 if (VOS_IS_STATUS_SUCCESS(status))
9885 {
9886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9887 ("HDD MDNS Server Offload Failed!!"));
9888 return -EINVAL;
9889 }
9890 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
9891 status = vos_wait_single_event(&pHostapdAdapter->
9892 mdns_status.vos_event, 2000);
9893 if (!VOS_IS_STATUS_SUCCESS(status) ||
9894 pHostapdAdapter->mdns_status.mdns_enable_status ||
9895 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
9896 pHostapdAdapter->mdns_status.mdns_resp_status)
9897 {
9898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9899 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
9900 pHostapdAdapter->mdns_status.mdns_enable_status,
9901 pHostapdAdapter->mdns_status.mdns_fqdn_status,
9902 pHostapdAdapter->mdns_status.mdns_resp_status);
9903 return -EINVAL;
9904 }
9905 }
9906#endif /* MDNS_OFFLOAD */
9907 } else {
9908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9909 ("DHCP Disabled ini %d, FW %d"),
9910 iniConfig->enable_dhcp_srv_offload,
9911 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +05309912 }
9913#endif /* DHCP_SERVER_OFFLOAD */
9914
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009915#ifdef WLAN_FEATURE_P2P_DEBUG
9916 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9917 {
9918 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9919 {
9920 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9921 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009922 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009923 }
9924 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9925 {
9926 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9927 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009928 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009929 }
9930 }
9931#endif
9932
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 pHostapdState->bCommit = TRUE;
9934 EXIT();
9935
9936 return 0;
9937}
9938
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009939#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309940static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 struct beacon_parameters *params)
9943{
9944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309945 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309946 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309949
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9951 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9952 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309953 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9954 hdd_device_modetoString(pAdapter->device_mode),
9955 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009956
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309957 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9958 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309959 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009960 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309961 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009962 }
9963
Agarwal Ashish51325b52014-06-16 16:50:49 +05309964 if (vos_max_concurrent_connections_reached()) {
9965 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9966 return -EINVAL;
9967 }
9968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 )
9972 {
9973 beacon_data_t *old,*new;
9974
9975 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309978 {
9979 hddLog(VOS_TRACE_LEVEL_WARN,
9980 FL("already beacon info added to session(%d)"),
9981 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009984
9985 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9986
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 {
9989 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009990 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 return -EINVAL;
9992 }
9993
9994 pAdapter->sessionCtx.ap.beacon = new;
9995
9996 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9997 }
9998
9999 EXIT();
10000 return status;
10001}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010002
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010003static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
10004 struct net_device *dev,
10005 struct beacon_parameters *params)
10006{
10007 int ret;
10008
10009 vos_ssr_protect(__func__);
10010 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10011 vos_ssr_unprotect(__func__);
10012
10013 return ret;
10014}
10015
10016static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 struct net_device *dev,
10018 struct beacon_parameters *params)
10019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010021 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10022 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010023 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024
10025 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010026
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010027 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10028 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10029 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10031 __func__, hdd_device_modetoString(pAdapter->device_mode),
10032 pAdapter->device_mode);
10033
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010034 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10035 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010036 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010038 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010039 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010040
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010041 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 {
10045 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010046
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010048
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010050 {
10051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10052 FL("session(%d) old and new heads points to NULL"),
10053 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010056
10057 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10058
10059 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010061 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 return -EINVAL;
10063 }
10064
10065 pAdapter->sessionCtx.ap.beacon = new;
10066
10067 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10068 }
10069
10070 EXIT();
10071 return status;
10072}
10073
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010074static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10075 struct net_device *dev,
10076 struct beacon_parameters *params)
10077{
10078 int ret;
10079
10080 vos_ssr_protect(__func__);
10081 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10082 vos_ssr_unprotect(__func__);
10083
10084 return ret;
10085}
10086
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010087#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10088
10089#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010090static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010092#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010093static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010094 struct net_device *dev)
10095#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010096{
10097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010098 hdd_context_t *pHddCtx = NULL;
10099 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010100 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010101 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102
10103 ENTER();
10104
10105 if (NULL == pAdapter)
10106 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010108 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 return -ENODEV;
10110 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010111
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10113 TRACE_CODE_HDD_CFG80211_STOP_AP,
10114 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10116 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010117 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010119 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010120 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010121
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010122 pScanInfo = &pHddCtx->scan_info;
10123
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10125 __func__, hdd_device_modetoString(pAdapter->device_mode),
10126 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010127
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010128 ret = wlan_hdd_scan_abort(pAdapter);
10129
Girish Gowli4bf7a632014-06-12 13:42:11 +053010130 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010131 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10133 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010134
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010135 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010136 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10138 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010139
Jeff Johnsone7245742012-09-05 17:12:55 -070010140 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010141 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010142 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010143 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010144 }
10145
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010146 /* Delete all associated STAs before stopping AP/P2P GO */
10147 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010148 hdd_hostapd_stop(dev);
10149
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 )
10153 {
10154 beacon_data_t *old;
10155
10156 old = pAdapter->sessionCtx.ap.beacon;
10157
10158 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010159 {
10160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10161 FL("session(%d) beacon data points to NULL"),
10162 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010164 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010165
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010167
10168 mutex_lock(&pHddCtx->sap_lock);
10169 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10170 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010171 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 {
10173 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10174
10175 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10176
10177 if (!VOS_IS_STATUS_SUCCESS(status))
10178 {
10179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010180 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010182 }
10183 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010185 /* BSS stopped, clear the active sessions for this device mode */
10186 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 }
10188 mutex_unlock(&pHddCtx->sap_lock);
10189
10190 if(status != VOS_STATUS_SUCCESS)
10191 {
10192 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010193 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 return -EINVAL;
10195 }
10196
Jeff Johnson4416a782013-03-25 14:17:50 -070010197 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10199 ==eHAL_STATUS_FAILURE)
10200 {
10201 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010202 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 }
10204
Jeff Johnson4416a782013-03-25 14:17:50 -070010205 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10207 eANI_BOOLEAN_FALSE) )
10208 {
10209 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010210 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 }
10212
10213 // Reset WNI_CFG_PROBE_RSP Flags
10214 wlan_hdd_reset_prob_rspies(pAdapter);
10215
10216 pAdapter->sessionCtx.ap.beacon = NULL;
10217 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010218#ifdef WLAN_FEATURE_P2P_DEBUG
10219 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10220 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10221 {
10222 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10223 "GO got removed");
10224 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10225 }
10226#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010227 }
10228 EXIT();
10229 return status;
10230}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010231
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010232#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10233static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10234 struct net_device *dev)
10235{
10236 int ret;
10237
10238 vos_ssr_protect(__func__);
10239 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10240 vos_ssr_unprotect(__func__);
10241
10242 return ret;
10243}
10244#else
10245static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10246 struct net_device *dev)
10247{
10248 int ret;
10249
10250 vos_ssr_protect(__func__);
10251 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10252 vos_ssr_unprotect(__func__);
10253
10254 return ret;
10255}
10256#endif
10257
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010258#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10259
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010260static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010261 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010262 struct cfg80211_ap_settings *params)
10263{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010264 hdd_adapter_t *pAdapter;
10265 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010266 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010267
10268 ENTER();
10269
Girish Gowlib143d7a2015-02-18 19:39:55 +053010270 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010271 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010273 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010274 return -ENODEV;
10275 }
10276
10277 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10278 if (NULL == pAdapter)
10279 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010281 "%s: HDD adapter is Null", __func__);
10282 return -ENODEV;
10283 }
10284
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010285 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10286 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10287 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010288 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10289 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010291 "%s: HDD adapter magic is invalid", __func__);
10292 return -ENODEV;
10293 }
10294
10295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010296 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010297 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010298 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010299 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010300 }
10301
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010302 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10303 __func__, hdd_device_modetoString(pAdapter->device_mode),
10304 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010305
10306 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010307 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010308 )
10309 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010310 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010311
10312 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010313
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010314 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010315 {
10316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10317 FL("already beacon info added to session(%d)"),
10318 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010319 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010320 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010321
Girish Gowlib143d7a2015-02-18 19:39:55 +053010322#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10323 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10324 &new,
10325 &params->beacon);
10326#else
10327 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10328 &new,
10329 &params->beacon,
10330 params->dtim_period);
10331#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010332
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010333 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010334 {
10335 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010336 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010337 return -EINVAL;
10338 }
10339 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010340#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010341 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10342#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10343 params->channel, params->channel_type);
10344#else
10345 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10346#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010347#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010348 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010349 params->ssid_len, params->hidden_ssid,
10350 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010351 }
10352
10353 EXIT();
10354 return status;
10355}
10356
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010357static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10358 struct net_device *dev,
10359 struct cfg80211_ap_settings *params)
10360{
10361 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010362
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010363 vos_ssr_protect(__func__);
10364 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10365 vos_ssr_unprotect(__func__);
10366
10367 return ret;
10368}
10369
10370static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010371 struct net_device *dev,
10372 struct cfg80211_beacon_data *params)
10373{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010375 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010376 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010377
10378 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010379
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10381 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10382 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010383 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010384 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010385
10386 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10387 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010388 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010390 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010391 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010392
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010394 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010396 {
10397 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010398
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010399 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010400
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010401 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010402 {
10403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10404 FL("session(%d) beacon data points to NULL"),
10405 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010406 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010407 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010408
10409 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10410
10411 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010413 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010414 return -EINVAL;
10415 }
10416
10417 pAdapter->sessionCtx.ap.beacon = new;
10418
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010419 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10420 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010421 }
10422
10423 EXIT();
10424 return status;
10425}
10426
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010427static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10428 struct net_device *dev,
10429 struct cfg80211_beacon_data *params)
10430{
10431 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010432
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010433 vos_ssr_protect(__func__);
10434 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10435 vos_ssr_unprotect(__func__);
10436
10437 return ret;
10438}
10439
10440#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010441
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010442static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 struct net_device *dev,
10444 struct bss_parameters *params)
10445{
10446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010447 hdd_context_t *pHddCtx;
10448 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010449
10450 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010451
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010452 if (NULL == pAdapter)
10453 {
10454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10455 "%s: HDD adapter is Null", __func__);
10456 return -ENODEV;
10457 }
10458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010459 ret = wlan_hdd_validate_context(pHddCtx);
10460 if (0 != ret)
10461 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010462 return ret;
10463 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10465 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10466 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10468 __func__, hdd_device_modetoString(pAdapter->device_mode),
10469 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010470
10471 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010473 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 {
10475 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10476 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010477 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 {
10479 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010480 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 }
10482
10483 EXIT();
10484 return 0;
10485}
10486
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010487static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10488 struct net_device *dev,
10489 struct bss_parameters *params)
10490{
10491 int ret;
10492
10493 vos_ssr_protect(__func__);
10494 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10495 vos_ssr_unprotect(__func__);
10496
10497 return ret;
10498}
Kiet Lam10841362013-11-01 11:36:50 +053010499/* FUNCTION: wlan_hdd_change_country_code_cd
10500* to wait for contry code completion
10501*/
10502void* wlan_hdd_change_country_code_cb(void *pAdapter)
10503{
10504 hdd_adapter_t *call_back_pAdapter = pAdapter;
10505 complete(&call_back_pAdapter->change_country_code);
10506 return NULL;
10507}
10508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010510 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10512 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010513int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 struct net_device *ndev,
10515 enum nl80211_iftype type,
10516 u32 *flags,
10517 struct vif_params *params
10518 )
10519{
10520 struct wireless_dev *wdev;
10521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010522 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010523 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 tCsrRoamProfile *pRoamProfile = NULL;
10525 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010526 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 eMib_dot11DesiredBssType connectedBssType;
10528 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010529 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010530
10531 ENTER();
10532
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010533 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010534 {
10535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10536 "%s: Adapter context is null", __func__);
10537 return VOS_STATUS_E_FAILURE;
10538 }
10539
10540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10541 if (!pHddCtx)
10542 {
10543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10544 "%s: HDD context is null", __func__);
10545 return VOS_STATUS_E_FAILURE;
10546 }
10547
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010548 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10549 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10550 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010551 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010552 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010554 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 }
10556
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010557 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10558 __func__, hdd_device_modetoString(pAdapter->device_mode),
10559 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010560
Agarwal Ashish51325b52014-06-16 16:50:49 +053010561 if (vos_max_concurrent_connections_reached()) {
10562 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10563 return -EINVAL;
10564 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010565 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 wdev = ndev->ieee80211_ptr;
10567
10568#ifdef WLAN_BTAMP_FEATURE
10569 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10570 (NL80211_IFTYPE_ADHOC == type)||
10571 (NL80211_IFTYPE_AP == type)||
10572 (NL80211_IFTYPE_P2P_GO == type))
10573 {
10574 pHddCtx->isAmpAllowed = VOS_FALSE;
10575 // stop AMP traffic
10576 status = WLANBAP_StopAmp();
10577 if(VOS_STATUS_SUCCESS != status )
10578 {
10579 pHddCtx->isAmpAllowed = VOS_TRUE;
10580 hddLog(VOS_TRACE_LEVEL_FATAL,
10581 "%s: Failed to stop AMP", __func__);
10582 return -EINVAL;
10583 }
10584 }
10585#endif //WLAN_BTAMP_FEATURE
10586 /* Reset the current device mode bit mask*/
10587 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10588
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010589 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10590 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10591 (type == NL80211_IFTYPE_P2P_GO)))
10592 {
10593 /* Notify Mode change in case of concurrency.
10594 * Below function invokes TDLS teardown Functionality Since TDLS is
10595 * not Supported in case of concurrency i.e Once P2P session
10596 * is detected disable offchannel and teardown TDLS links
10597 */
10598 hddLog(LOG1,
10599 FL("Device mode = %d Interface type = %d"),
10600 pAdapter->device_mode, type);
10601 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10602 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010603
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010606 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 )
10608 {
10609 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010610 if (!pWextState)
10611 {
10612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10613 "%s: pWextState is null", __func__);
10614 return VOS_STATUS_E_FAILURE;
10615 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 pRoamProfile = &pWextState->roamProfile;
10617 LastBSSType = pRoamProfile->BSSType;
10618
10619 switch (type)
10620 {
10621 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010622 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 hddLog(VOS_TRACE_LEVEL_INFO,
10624 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10625 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010626#ifdef WLAN_FEATURE_11AC
10627 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10628 {
10629 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10630 }
10631#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010633 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010635 //Check for sub-string p2p to confirm its a p2p interface
10636 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010637 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010638#ifdef FEATURE_WLAN_TDLS
10639 mutex_lock(&pHddCtx->tdls_lock);
10640 wlan_hdd_tdls_exit(pAdapter, TRUE);
10641 mutex_unlock(&pHddCtx->tdls_lock);
10642#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010643 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10644 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10645 }
10646 else
10647 {
10648 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010649 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010650 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010651 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010652
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 case NL80211_IFTYPE_ADHOC:
10654 hddLog(VOS_TRACE_LEVEL_INFO,
10655 "%s: setting interface Type to ADHOC", __func__);
10656 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10657 pRoamProfile->phyMode =
10658 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010659 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010661 hdd_set_ibss_ops( pAdapter );
10662 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010663
10664 status = hdd_sta_id_hash_attach(pAdapter);
10665 if (VOS_STATUS_SUCCESS != status) {
10666 hddLog(VOS_TRACE_LEVEL_ERROR,
10667 FL("Failed to initialize hash for IBSS"));
10668 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 break;
10670
10671 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 {
10674 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10675 "%s: setting interface Type to %s", __func__,
10676 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10677
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010678 //Cancel any remain on channel for GO mode
10679 if (NL80211_IFTYPE_P2P_GO == type)
10680 {
10681 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10682 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010683 if (NL80211_IFTYPE_AP == type)
10684 {
10685 /* As Loading WLAN Driver one interface being created for p2p device
10686 * address. This will take one HW STA and the max number of clients
10687 * that can connect to softAP will be reduced by one. so while changing
10688 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10689 * interface as it is not required in SoftAP mode.
10690 */
10691
10692 // Get P2P Adapter
10693 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10694
10695 if (pP2pAdapter)
10696 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010697 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010698 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010699 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10700 }
10701 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010702 //Disable IMPS & BMPS for SAP/GO
10703 if(VOS_STATUS_E_FAILURE ==
10704 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10705 {
10706 //Fail to Exit BMPS
10707 VOS_ASSERT(0);
10708 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010709
10710 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10711
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010712#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010713
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010714 /* A Mutex Lock is introduced while changing the mode to
10715 * protect the concurrent access for the Adapters by TDLS
10716 * module.
10717 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010718 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010719#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010721 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10724 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010725#ifdef FEATURE_WLAN_TDLS
10726 mutex_unlock(&pHddCtx->tdls_lock);
10727#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010728 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10729 (pConfig->apRandomBssidEnabled))
10730 {
10731 /* To meet Android requirements create a randomized
10732 MAC address of the form 02:1A:11:Fx:xx:xx */
10733 get_random_bytes(&ndev->dev_addr[3], 3);
10734 ndev->dev_addr[0] = 0x02;
10735 ndev->dev_addr[1] = 0x1A;
10736 ndev->dev_addr[2] = 0x11;
10737 ndev->dev_addr[3] |= 0xF0;
10738 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10739 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010740 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10741 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010742 }
10743
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 hdd_set_ap_ops( pAdapter->dev );
10745
Kiet Lam10841362013-11-01 11:36:50 +053010746 /* This is for only SAP mode where users can
10747 * control country through ini.
10748 * P2P GO follows station country code
10749 * acquired during the STA scanning. */
10750 if((NL80211_IFTYPE_AP == type) &&
10751 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10752 {
10753 int status = 0;
10754 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10755 "%s: setting country code from INI ", __func__);
10756 init_completion(&pAdapter->change_country_code);
10757 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10758 (void *)(tSmeChangeCountryCallback)
10759 wlan_hdd_change_country_code_cb,
10760 pConfig->apCntryCode, pAdapter,
10761 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010762 eSIR_FALSE,
10763 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010764 if (eHAL_STATUS_SUCCESS == status)
10765 {
10766 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010767 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010768 &pAdapter->change_country_code,
10769 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010770 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010771 {
10772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010773 FL("SME Timed out while setting country code %ld"),
10774 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010775
10776 if (pHddCtx->isLogpInProgress)
10777 {
10778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10779 "%s: LOGP in Progress. Ignore!!!", __func__);
10780 return -EAGAIN;
10781 }
Kiet Lam10841362013-11-01 11:36:50 +053010782 }
10783 }
10784 else
10785 {
10786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010787 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010788 return -EINVAL;
10789 }
10790 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 status = hdd_init_ap_mode(pAdapter);
10792 if(status != VOS_STATUS_SUCCESS)
10793 {
10794 hddLog(VOS_TRACE_LEVEL_FATAL,
10795 "%s: Error initializing the ap mode", __func__);
10796 return -EINVAL;
10797 }
10798 hdd_set_conparam(1);
10799
Nirav Shah7e3c8132015-06-22 23:51:42 +053010800 status = hdd_sta_id_hash_attach(pAdapter);
10801 if (VOS_STATUS_SUCCESS != status)
10802 {
10803 hddLog(VOS_TRACE_LEVEL_ERROR,
10804 FL("Failed to initialize hash for AP"));
10805 return -EINVAL;
10806 }
10807
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 /*interface type changed update in wiphy structure*/
10809 if(wdev)
10810 {
10811 wdev->iftype = type;
10812 pHddCtx->change_iface = type;
10813 }
10814 else
10815 {
10816 hddLog(VOS_TRACE_LEVEL_ERROR,
10817 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10818 return -EINVAL;
10819 }
10820 goto done;
10821 }
10822
10823 default:
10824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10825 __func__);
10826 return -EOPNOTSUPP;
10827 }
10828 }
10829 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010830 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 )
10832 {
10833 switch(type)
10834 {
10835 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010838
10839 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010840#ifdef FEATURE_WLAN_TDLS
10841
10842 /* A Mutex Lock is introduced while changing the mode to
10843 * protect the concurrent access for the Adapters by TDLS
10844 * module.
10845 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010846 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010847#endif
c_hpothu002231a2015-02-05 14:58:51 +053010848 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010850 //Check for sub-string p2p to confirm its a p2p interface
10851 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010852 {
10853 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10854 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10855 }
10856 else
10857 {
10858 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010860 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010861
10862 /* set con_mode to STA only when no SAP concurrency mode */
10863 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10864 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10867 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010868#ifdef FEATURE_WLAN_TDLS
10869 mutex_unlock(&pHddCtx->tdls_lock);
10870#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010871 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 if( VOS_STATUS_SUCCESS != status )
10873 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010874 /* In case of JB, for P2P-GO, only change interface will be called,
10875 * This is the right place to enable back bmps_imps()
10876 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010877 if (pHddCtx->hdd_wlan_suspended)
10878 {
10879 hdd_set_pwrparams(pHddCtx);
10880 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010881 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 goto done;
10883 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10887 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 goto done;
10889 default:
10890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10891 __func__);
10892 return -EOPNOTSUPP;
10893
10894 }
10895
10896 }
10897 else
10898 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010899 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10900 __func__, hdd_device_modetoString(pAdapter->device_mode),
10901 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 return -EOPNOTSUPP;
10903 }
10904
10905
10906 if(pRoamProfile)
10907 {
10908 if ( LastBSSType != pRoamProfile->BSSType )
10909 {
10910 /*interface type changed update in wiphy structure*/
10911 wdev->iftype = type;
10912
10913 /*the BSS mode changed, We need to issue disconnect
10914 if connected or in IBSS disconnect state*/
10915 if ( hdd_connGetConnectedBssType(
10916 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10917 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10918 {
10919 /*need to issue a disconnect to CSR.*/
10920 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10921 if( eHAL_STATUS_SUCCESS ==
10922 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10923 pAdapter->sessionId,
10924 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10925 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010926 ret = wait_for_completion_interruptible_timeout(
10927 &pAdapter->disconnect_comp_var,
10928 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10929 if (ret <= 0)
10930 {
10931 hddLog(VOS_TRACE_LEVEL_ERROR,
10932 FL("wait on disconnect_comp_var failed %ld"), ret);
10933 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 }
10935 }
10936 }
10937 }
10938
10939done:
10940 /*set bitmask based on updated value*/
10941 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010942
10943 /* Only STA mode support TM now
10944 * all other mode, TM feature should be disabled */
10945 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10946 (~VOS_STA & pHddCtx->concurrency_mode) )
10947 {
10948 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10949 }
10950
Jeff Johnson295189b2012-06-20 16:38:30 -070010951#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010952 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010953 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 {
10955 //we are ok to do AMP
10956 pHddCtx->isAmpAllowed = VOS_TRUE;
10957 }
10958#endif //WLAN_BTAMP_FEATURE
10959 EXIT();
10960 return 0;
10961}
10962
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010963/*
10964 * FUNCTION: wlan_hdd_cfg80211_change_iface
10965 * wrapper function to protect the actual implementation from SSR.
10966 */
10967int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10968 struct net_device *ndev,
10969 enum nl80211_iftype type,
10970 u32 *flags,
10971 struct vif_params *params
10972 )
10973{
10974 int ret;
10975
10976 vos_ssr_protect(__func__);
10977 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10978 vos_ssr_unprotect(__func__);
10979
10980 return ret;
10981}
10982
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010983#ifdef FEATURE_WLAN_TDLS
10984static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010985 struct net_device *dev,
10986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10987 const u8 *mac,
10988#else
10989 u8 *mac,
10990#endif
10991 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010992{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010993 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010994 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010995 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010996 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010997 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010998 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010999
11000 ENTER();
11001
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011002 if (!dev) {
11003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
11004 return -EINVAL;
11005 }
11006
11007 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11008 if (!pAdapter) {
11009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11010 return -EINVAL;
11011 }
11012
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011013 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011014 {
11015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11016 "Invalid arguments");
11017 return -EINVAL;
11018 }
Hoonki Lee27511902013-03-14 18:19:06 -070011019
11020 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11021 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11022 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011024 "%s: TDLS mode is disabled OR not enabled in FW."
11025 MAC_ADDRESS_STR " Request declined.",
11026 __func__, MAC_ADDR_ARRAY(mac));
11027 return -ENOTSUPP;
11028 }
11029
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011030 if (pHddCtx->isLogpInProgress)
11031 {
11032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11033 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011034 wlan_hdd_tdls_set_link_status(pAdapter,
11035 mac,
11036 eTDLS_LINK_IDLE,
11037 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011038 return -EBUSY;
11039 }
11040
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011041 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011042 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011043
11044 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011046 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11047 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011048 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011049 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011050 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011051
11052 /* in add station, we accept existing valid staId if there is */
11053 if ((0 == update) &&
11054 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11055 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011056 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011058 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011059 " link_status %d. staId %d. add station ignored.",
11060 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011061 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011062 return 0;
11063 }
11064 /* in change station, we accept only when staId is valid */
11065 if ((1 == update) &&
11066 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11067 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11068 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011069 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011071 "%s: " MAC_ADDRESS_STR
11072 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011073 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11074 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11075 mutex_unlock(&pHddCtx->tdls_lock);
11076 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011077 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011078 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011079
11080 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011081 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011082 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11084 "%s: " MAC_ADDRESS_STR
11085 " TDLS setup is ongoing. Request declined.",
11086 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011087 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011088 }
11089
11090 /* first to check if we reached to maximum supported TDLS peer.
11091 TODO: for now, return -EPERM looks working fine,
11092 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011093 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11094 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011095 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11097 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011098 " TDLS Max peer already connected. Request declined."
11099 " Num of peers (%d), Max allowed (%d).",
11100 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11101 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011102 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011103 }
11104 else
11105 {
11106 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011107 mutex_lock(&pHddCtx->tdls_lock);
11108 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011109 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011110 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011111 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11113 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11114 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011115 return -EPERM;
11116 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011117 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011118 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011119 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011120 wlan_hdd_tdls_set_link_status(pAdapter,
11121 mac,
11122 eTDLS_LINK_CONNECTING,
11123 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011124
Jeff Johnsond75fe012013-04-06 10:53:06 -070011125 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011126 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011127 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011129 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011130 if(StaParams->htcap_present)
11131 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011133 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011135 "ht_capa->extended_capabilities: %0x",
11136 StaParams->HTCap.extendedHtCapInfo);
11137 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011139 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011141 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011142 if(StaParams->vhtcap_present)
11143 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011145 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11146 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11147 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11148 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011149 {
11150 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011152 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011154 "[%d]: %x ", i, StaParams->supported_rates[i]);
11155 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011156 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011157 else if ((1 == update) && (NULL == StaParams))
11158 {
11159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11160 "%s : update is true, but staParams is NULL. Error!", __func__);
11161 return -EPERM;
11162 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011163
11164 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11165
11166 if (!update)
11167 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011168 /*Before adding sta make sure that device exited from BMPS*/
11169 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11170 {
11171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11172 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11173 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11174 if (status != VOS_STATUS_SUCCESS) {
11175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11176 }
11177 }
11178
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011179 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011180 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011181 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011182 hddLog(VOS_TRACE_LEVEL_ERROR,
11183 FL("Failed to add TDLS peer STA. Enable Bmps"));
11184 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011185 return -EPERM;
11186 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011187 }
11188 else
11189 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011190 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011191 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011192 if (ret != eHAL_STATUS_SUCCESS) {
11193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11194 return -EPERM;
11195 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011196 }
11197
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011198 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011199 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11200
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011201 mutex_lock(&pHddCtx->tdls_lock);
11202 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11203
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011204 if ((pTdlsPeer != NULL) &&
11205 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011206 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011207 hddLog(VOS_TRACE_LEVEL_ERROR,
11208 FL("peer link status %u"), pTdlsPeer->link_status);
11209 mutex_unlock(&pHddCtx->tdls_lock);
11210 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011211 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011212 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011213
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011214 if (ret <= 0)
11215 {
11216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11217 "%s: timeout waiting for tdls add station indication %ld",
11218 __func__, ret);
11219 goto error;
11220 }
11221
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011222 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11223 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011225 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011226 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011227 }
11228
11229 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011230
11231error:
Atul Mittal115287b2014-07-08 13:26:33 +053011232 wlan_hdd_tdls_set_link_status(pAdapter,
11233 mac,
11234 eTDLS_LINK_IDLE,
11235 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011236 return -EPERM;
11237
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011238}
11239#endif
11240
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011241static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011242 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11244 const u8 *mac,
11245#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011247#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 struct station_parameters *params)
11249{
11250 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011251 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011252 hdd_context_t *pHddCtx;
11253 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011255 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011256#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011257 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011258 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011259 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011260 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011261#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011262
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011263 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011264
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011265 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011266 if ((NULL == pAdapter))
11267 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011269 "invalid adapter ");
11270 return -EINVAL;
11271 }
11272
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011273 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11274 TRACE_CODE_HDD_CHANGE_STATION,
11275 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011276 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011277
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011278 ret = wlan_hdd_validate_context(pHddCtx);
11279 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011280 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011281 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011282 }
11283
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011284 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11285
11286 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011287 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11289 "invalid HDD station context");
11290 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11293
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011294 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11295 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011297 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011299 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 WLANTL_STA_AUTHENTICATED);
11301
Gopichand Nakkala29149562013-05-10 21:43:41 +053011302 if (status != VOS_STATUS_SUCCESS)
11303 {
11304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11305 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11306 return -EINVAL;
11307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 }
11309 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011310 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11311 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011312#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011313 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11314 StaParams.capability = params->capability;
11315 StaParams.uapsd_queues = params->uapsd_queues;
11316 StaParams.max_sp = params->max_sp;
11317
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011318 /* Convert (first channel , number of channels) tuple to
11319 * the total list of channels. This goes with the assumption
11320 * that if the first channel is < 14, then the next channels
11321 * are an incremental of 1 else an incremental of 4 till the number
11322 * of channels.
11323 */
11324 if (0 != params->supported_channels_len) {
11325 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11326 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11327 {
11328 int wifi_chan_index;
11329 StaParams.supported_channels[j] = params->supported_channels[i];
11330 wifi_chan_index =
11331 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11332 no_of_channels = params->supported_channels[i+1];
11333 for(k=1; k <= no_of_channels; k++)
11334 {
11335 StaParams.supported_channels[j+1] =
11336 StaParams.supported_channels[j] + wifi_chan_index;
11337 j+=1;
11338 }
11339 }
11340 StaParams.supported_channels_len = j;
11341 }
11342 vos_mem_copy(StaParams.supported_oper_classes,
11343 params->supported_oper_classes,
11344 params->supported_oper_classes_len);
11345 StaParams.supported_oper_classes_len =
11346 params->supported_oper_classes_len;
11347
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011348 if (0 != params->ext_capab_len)
11349 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11350 sizeof(StaParams.extn_capability));
11351
11352 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011353 {
11354 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011355 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011356 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011357
11358 StaParams.supported_rates_len = params->supported_rates_len;
11359
11360 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11361 * The supported_rates array , for all the structures propogating till Add Sta
11362 * to the firmware has to be modified , if the supplicant (ieee80211) is
11363 * modified to send more rates.
11364 */
11365
11366 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11367 */
11368 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11369 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11370
11371 if (0 != StaParams.supported_rates_len) {
11372 int i = 0;
11373 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11374 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011376 "Supported Rates with Length %d", StaParams.supported_rates_len);
11377 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011379 "[%d]: %0x", i, StaParams.supported_rates[i]);
11380 }
11381
11382 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011383 {
11384 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011385 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011386 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011387
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011388 if (0 != params->ext_capab_len ) {
11389 /*Define A Macro : TODO Sunil*/
11390 if ((1<<4) & StaParams.extn_capability[3]) {
11391 isBufSta = 1;
11392 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011393 /* TDLS Channel Switching Support */
11394 if ((1<<6) & StaParams.extn_capability[3]) {
11395 isOffChannelSupported = 1;
11396 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011397 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011398
11399 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011400 (params->ht_capa || params->vht_capa ||
11401 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011402 /* TDLS Peer is WME/QoS capable */
11403 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011404
11405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11406 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11407 __func__, isQosWmmSta, StaParams.htcap_present);
11408
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011409 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11410 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011411 isOffChannelSupported,
11412 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011413
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011414 if (VOS_STATUS_SUCCESS != status) {
11415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11416 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11417 return -EINVAL;
11418 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011419 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11420
11421 if (VOS_STATUS_SUCCESS != status) {
11422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11423 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11424 return -EINVAL;
11425 }
11426 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011427#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011428 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011429 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 return status;
11431}
11432
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011433#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11434static int wlan_hdd_change_station(struct wiphy *wiphy,
11435 struct net_device *dev,
11436 const u8 *mac,
11437 struct station_parameters *params)
11438#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011439static int wlan_hdd_change_station(struct wiphy *wiphy,
11440 struct net_device *dev,
11441 u8 *mac,
11442 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011443#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011444{
11445 int ret;
11446
11447 vos_ssr_protect(__func__);
11448 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11449 vos_ssr_unprotect(__func__);
11450
11451 return ret;
11452}
11453
Jeff Johnson295189b2012-06-20 16:38:30 -070011454/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011455 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 * This function is used to initialize the key information
11457 */
11458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011459static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 struct net_device *ndev,
11461 u8 key_index, bool pairwise,
11462 const u8 *mac_addr,
11463 struct key_params *params
11464 )
11465#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011466static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 struct net_device *ndev,
11468 u8 key_index, const u8 *mac_addr,
11469 struct key_params *params
11470 )
11471#endif
11472{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 tCsrRoamSetKey setKey;
11475 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011476 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011477 v_U32_t roamId= 0xFF;
11478 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 hdd_hostapd_state_t *pHostapdState;
11480 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011481 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011482 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011483
11484 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011485
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11487 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11488 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011489 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11490 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011491 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011492 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011493 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011494 }
11495
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11497 __func__, hdd_device_modetoString(pAdapter->device_mode),
11498 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011499
11500 if (CSR_MAX_NUM_KEY <= key_index)
11501 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 key_index);
11504
11505 return -EINVAL;
11506 }
11507
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011508 if (CSR_MAX_KEY_LEN < params->key_len)
11509 {
11510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11511 params->key_len);
11512
11513 return -EINVAL;
11514 }
11515
11516 hddLog(VOS_TRACE_LEVEL_INFO,
11517 "%s: called with key index = %d & key length %d",
11518 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519
11520 /*extract key idx, key len and key*/
11521 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11522 setKey.keyId = key_index;
11523 setKey.keyLength = params->key_len;
11524 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11525
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011526 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011527 {
11528 case WLAN_CIPHER_SUITE_WEP40:
11529 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11530 break;
11531
11532 case WLAN_CIPHER_SUITE_WEP104:
11533 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11534 break;
11535
11536 case WLAN_CIPHER_SUITE_TKIP:
11537 {
11538 u8 *pKey = &setKey.Key[0];
11539 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11540
11541 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11542
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011543 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011544
11545 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011546 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 |--------------|----------|----------|
11548 <---16bytes---><--8bytes--><--8bytes-->
11549
11550 */
11551 /*Sme expects the 32 bytes key to be in the below order
11552
11553 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011554 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011555 |--------------|----------|----------|
11556 <---16bytes---><--8bytes--><--8bytes-->
11557 */
11558 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011559 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011560
11561 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011562 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011563
11564 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011565 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011566
11567
11568 break;
11569 }
11570
11571 case WLAN_CIPHER_SUITE_CCMP:
11572 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11573 break;
11574
11575#ifdef FEATURE_WLAN_WAPI
11576 case WLAN_CIPHER_SUITE_SMS4:
11577 {
11578 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11579 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11580 params->key, params->key_len);
11581 return 0;
11582 }
11583#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011585#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 case WLAN_CIPHER_SUITE_KRK:
11587 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11588 break;
11589#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011590
11591#ifdef WLAN_FEATURE_11W
11592 case WLAN_CIPHER_SUITE_AES_CMAC:
11593 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011594 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011595#endif
11596
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011600 status = -EOPNOTSUPP;
11601 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 }
11603
11604 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11605 __func__, setKey.encType);
11606
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011607 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11609 (!pairwise)
11610#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011611 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011612#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011613 )
11614 {
11615 /* set group key*/
11616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11617 "%s- %d: setting Broadcast key",
11618 __func__, __LINE__);
11619 setKey.keyDirection = eSIR_RX_ONLY;
11620 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11621 }
11622 else
11623 {
11624 /* set pairwise key*/
11625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11626 "%s- %d: setting pairwise key",
11627 __func__, __LINE__);
11628 setKey.keyDirection = eSIR_TX_RX;
11629 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11630 }
11631 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11632 {
11633 setKey.keyDirection = eSIR_TX_RX;
11634 /*Set the group key*/
11635 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11636 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011637
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011638 if ( 0 != status )
11639 {
11640 hddLog(VOS_TRACE_LEVEL_ERROR,
11641 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011642 status = -EINVAL;
11643 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011644 }
11645 /*Save the keys here and call sme_RoamSetKey for setting
11646 the PTK after peer joins the IBSS network*/
11647 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11648 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011649 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011650 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011651 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11652 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11653 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011655 if( pHostapdState->bssState == BSS_START )
11656 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011657 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11658 vos_status = wlan_hdd_check_ula_done(pAdapter);
11659
11660 if ( vos_status != VOS_STATUS_SUCCESS )
11661 {
11662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11663 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11664 __LINE__, vos_status );
11665
11666 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11667
11668 status = -EINVAL;
11669 goto end;
11670 }
11671
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11673
11674 if ( status != eHAL_STATUS_SUCCESS )
11675 {
11676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11677 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11678 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011679 status = -EINVAL;
11680 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 }
11682 }
11683
11684 /* Saving WEP keys */
11685 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11686 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11687 {
11688 //Save the wep key in ap context. Issue setkey after the BSS is started.
11689 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11690 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11691 }
11692 else
11693 {
11694 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011695 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11697 }
11698 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011699 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11700 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 {
11702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11704
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011705#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11706 if (!pairwise)
11707#else
11708 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11709#endif
11710 {
11711 /* set group key*/
11712 if (pHddStaCtx->roam_info.deferKeyComplete)
11713 {
11714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11715 "%s- %d: Perform Set key Complete",
11716 __func__, __LINE__);
11717 hdd_PerformRoamSetKeyComplete(pAdapter);
11718 }
11719 }
11720
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11722
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011723 pWextState->roamProfile.Keys.defaultIndex = key_index;
11724
11725
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011726 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 params->key, params->key_len);
11728
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011729
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11731
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734 __func__, setKey.peerMac[0], setKey.peerMac[1],
11735 setKey.peerMac[2], setKey.peerMac[3],
11736 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 setKey.keyDirection);
11738
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011739 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011740
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011741 if ( vos_status != VOS_STATUS_SUCCESS )
11742 {
11743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11745 __LINE__, vos_status );
11746
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011747 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011748
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011749 status = -EINVAL;
11750 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011751
11752 }
11753
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011754#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011755 /* The supplicant may attempt to set the PTK once pre-authentication
11756 is done. Save the key in the UMAC and include it in the ADD BSS
11757 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011758 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011759 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011760 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011761 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11762 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011763 status = 0;
11764 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011765 }
11766 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11767 {
11768 hddLog(VOS_TRACE_LEVEL_ERROR,
11769 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011770 status = -EINVAL;
11771 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011772 }
11773#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011774
11775 /* issue set key request to SME*/
11776 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11777 pAdapter->sessionId, &setKey, &roamId );
11778
11779 if ( 0 != status )
11780 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11783 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011784 status = -EINVAL;
11785 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 }
11787
11788
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 /* in case of IBSS as there was no information available about WEP keys during
11790 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11793 !( ( IW_AUTH_KEY_MGMT_802_1X
11794 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11796 )
11797 &&
11798 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11799 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11800 )
11801 )
11802 {
11803 setKey.keyDirection = eSIR_RX_ONLY;
11804 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11805
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808 __func__, setKey.peerMac[0], setKey.peerMac[1],
11809 setKey.peerMac[2], setKey.peerMac[3],
11810 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 setKey.keyDirection);
11812
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 pAdapter->sessionId, &setKey, &roamId );
11815
11816 if ( 0 != status )
11817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818 hddLog(VOS_TRACE_LEVEL_ERROR,
11819 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 __func__, status);
11821 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011822 status = -EINVAL;
11823 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 }
11825 }
11826 }
11827
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011828end:
11829 /* Need to clear any trace of key value in the memory.
11830 * Thus zero out the memory even though it is local
11831 * variable.
11832 */
11833 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011834 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011835 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011836}
11837
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11839static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11840 struct net_device *ndev,
11841 u8 key_index, bool pairwise,
11842 const u8 *mac_addr,
11843 struct key_params *params
11844 )
11845#else
11846static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11847 struct net_device *ndev,
11848 u8 key_index, const u8 *mac_addr,
11849 struct key_params *params
11850 )
11851#endif
11852{
11853 int ret;
11854 vos_ssr_protect(__func__);
11855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11856 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11857 mac_addr, params);
11858#else
11859 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11860 params);
11861#endif
11862 vos_ssr_unprotect(__func__);
11863
11864 return ret;
11865}
11866
Jeff Johnson295189b2012-06-20 16:38:30 -070011867/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011868 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 * This function is used to get the key information
11870 */
11871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011872static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 const u8 *mac_addr, void *cookie,
11877 void (*callback)(void *cookie, struct key_params*)
11878 )
11879#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011880static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011881 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 struct net_device *ndev,
11883 u8 key_index, const u8 *mac_addr, void *cookie,
11884 void (*callback)(void *cookie, struct key_params*)
11885 )
11886#endif
11887{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011889 hdd_wext_state_t *pWextState = NULL;
11890 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011892 hdd_context_t *pHddCtx;
11893 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011894
11895 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011896
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011897 if (NULL == pAdapter)
11898 {
11899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11900 "%s: HDD adapter is Null", __func__);
11901 return -ENODEV;
11902 }
11903
11904 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11905 ret = wlan_hdd_validate_context(pHddCtx);
11906 if (0 != ret)
11907 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011908 return ret;
11909 }
11910
11911 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11912 pRoamProfile = &(pWextState->roamProfile);
11913
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11915 __func__, hdd_device_modetoString(pAdapter->device_mode),
11916 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011917
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 memset(&params, 0, sizeof(params));
11919
11920 if (CSR_MAX_NUM_KEY <= key_index)
11921 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011925
11926 switch(pRoamProfile->EncryptionType.encryptionType[0])
11927 {
11928 case eCSR_ENCRYPT_TYPE_NONE:
11929 params.cipher = IW_AUTH_CIPHER_NONE;
11930 break;
11931
11932 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11933 case eCSR_ENCRYPT_TYPE_WEP40:
11934 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11935 break;
11936
11937 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11938 case eCSR_ENCRYPT_TYPE_WEP104:
11939 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11940 break;
11941
11942 case eCSR_ENCRYPT_TYPE_TKIP:
11943 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11944 break;
11945
11946 case eCSR_ENCRYPT_TYPE_AES:
11947 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11948 break;
11949
11950 default:
11951 params.cipher = IW_AUTH_CIPHER_NONE;
11952 break;
11953 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011954
c_hpothuaaf19692014-05-17 17:01:48 +053011955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11956 TRACE_CODE_HDD_CFG80211_GET_KEY,
11957 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011958
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11960 params.seq_len = 0;
11961 params.seq = NULL;
11962 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11963 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011964 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 return 0;
11966}
11967
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11969static int wlan_hdd_cfg80211_get_key(
11970 struct wiphy *wiphy,
11971 struct net_device *ndev,
11972 u8 key_index, bool pairwise,
11973 const u8 *mac_addr, void *cookie,
11974 void (*callback)(void *cookie, struct key_params*)
11975 )
11976#else
11977static int wlan_hdd_cfg80211_get_key(
11978 struct wiphy *wiphy,
11979 struct net_device *ndev,
11980 u8 key_index, const u8 *mac_addr, void *cookie,
11981 void (*callback)(void *cookie, struct key_params*)
11982 )
11983#endif
11984{
11985 int ret;
11986
11987 vos_ssr_protect(__func__);
11988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11989 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11990 mac_addr, cookie, callback);
11991#else
11992 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11993 callback);
11994#endif
11995 vos_ssr_unprotect(__func__);
11996
11997 return ret;
11998}
11999
Jeff Johnson295189b2012-06-20 16:38:30 -070012000/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012001 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 * This function is used to delete the key information
12003 */
12004#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012005static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 u8 key_index,
12008 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 const u8 *mac_addr
12010 )
12011#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012012static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 struct net_device *ndev,
12014 u8 key_index,
12015 const u8 *mac_addr
12016 )
12017#endif
12018{
12019 int status = 0;
12020
12021 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012022 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 //it is observed that this is invalidating peer
12024 //key index whenever re-key is done. This is affecting data link.
12025 //It should be ok to ignore del_key.
12026#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12028 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12030 tCsrRoamSetKey setKey;
12031 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012032
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 ENTER();
12034
12035 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12036 __func__,pAdapter->device_mode);
12037
12038 if (CSR_MAX_NUM_KEY <= key_index)
12039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 key_index);
12042
12043 return -EINVAL;
12044 }
12045
12046 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12047 setKey.keyId = key_index;
12048
12049 if (mac_addr)
12050 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12051 else
12052 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12053
12054 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12055
12056 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012058 )
12059 {
12060
12061 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12063 if( pHostapdState->bssState == BSS_START)
12064 {
12065 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012066
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 if ( status != eHAL_STATUS_SUCCESS )
12068 {
12069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12070 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12071 __LINE__, status );
12072 }
12073 }
12074 }
12075 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 )
12078 {
12079 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12080
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012081 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12082
12083 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012085 __func__, setKey.peerMac[0], setKey.peerMac[1],
12086 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012088 if(pAdapter->sessionCtx.station.conn_info.connState ==
12089 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012093
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 if ( 0 != status )
12095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 "%s: sme_RoamSetKey failure, returned %d",
12098 __func__, status);
12099 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12100 return -EINVAL;
12101 }
12102 }
12103 }
12104#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012105 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 return status;
12107}
12108
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012109#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12110static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12111 struct net_device *ndev,
12112 u8 key_index,
12113 bool pairwise,
12114 const u8 *mac_addr
12115 )
12116#else
12117static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12118 struct net_device *ndev,
12119 u8 key_index,
12120 const u8 *mac_addr
12121 )
12122#endif
12123{
12124 int ret;
12125
12126 vos_ssr_protect(__func__);
12127#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12128 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12129 mac_addr);
12130#else
12131 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12132#endif
12133 vos_ssr_unprotect(__func__);
12134
12135 return ret;
12136}
12137
Jeff Johnson295189b2012-06-20 16:38:30 -070012138/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012139 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 * This function is used to set the default tx key index
12141 */
12142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012143static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 struct net_device *ndev,
12145 u8 key_index,
12146 bool unicast, bool multicast)
12147#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012148static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 struct net_device *ndev,
12150 u8 key_index)
12151#endif
12152{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012154 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012155 hdd_wext_state_t *pWextState;
12156 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012157 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012158
12159 ENTER();
12160
Gopichand Nakkala29149562013-05-10 21:43:41 +053012161 if ((NULL == pAdapter))
12162 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012164 "invalid adapter");
12165 return -EINVAL;
12166 }
12167
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12169 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12170 pAdapter->sessionId, key_index));
12171
Gopichand Nakkala29149562013-05-10 21:43:41 +053012172 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12173 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12174
12175 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12176 {
12177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12178 "invalid Wext state or HDD context");
12179 return -EINVAL;
12180 }
12181
Arif Hussain6d2a3322013-11-17 19:50:10 -080012182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012184
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 if (CSR_MAX_NUM_KEY <= key_index)
12186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 key_index);
12189
12190 return -EINVAL;
12191 }
12192
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012193 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12194 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012195 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012196 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012197 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012198 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012204 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012205 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012206 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012207 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012209 {
12210 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 tCsrRoamSetKey setKey;
12214 v_U32_t roamId= 0xFF;
12215 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216
12217 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 Keys->defaultIndex = (u8)key_index;
12221 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12222 setKey.keyId = key_index;
12223 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012224
12225 vos_mem_copy(&setKey.Key[0],
12226 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012228
Gopichand Nakkala29149562013-05-10 21:43:41 +053012229 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012230
12231 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 &pHddStaCtx->conn_info.bssId[0],
12233 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234
Gopichand Nakkala29149562013-05-10 21:43:41 +053012235 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12236 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12237 eCSR_ENCRYPT_TYPE_WEP104)
12238 {
12239 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12240 even though ap is configured for WEP-40 encryption. In this canse the key length
12241 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12242 type(104) and switching encryption type to 40*/
12243 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12244 eCSR_ENCRYPT_TYPE_WEP40;
12245 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12246 eCSR_ENCRYPT_TYPE_WEP40;
12247 }
12248
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012249 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 if ( 0 != status )
12257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012258 hddLog(VOS_TRACE_LEVEL_ERROR,
12259 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 status);
12261 return -EINVAL;
12262 }
12263 }
12264 }
12265
12266 /* In SoftAp mode setting key direction for default mode */
12267 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12268 {
12269 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12270 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12271 (eCSR_ENCRYPT_TYPE_AES !=
12272 pWextState->roamProfile.EncryptionType.encryptionType[0])
12273 )
12274 {
12275 /* Saving key direction for default key index to TX default */
12276 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12277 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12278 }
12279 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012280 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 return status;
12282}
12283
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012284#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12285static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12286 struct net_device *ndev,
12287 u8 key_index,
12288 bool unicast, bool multicast)
12289#else
12290static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12291 struct net_device *ndev,
12292 u8 key_index)
12293#endif
12294{
12295 int ret;
12296 vos_ssr_protect(__func__);
12297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12298 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12299 multicast);
12300#else
12301 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12302#endif
12303 vos_ssr_unprotect(__func__);
12304
12305 return ret;
12306}
12307
Jeff Johnson295189b2012-06-20 16:38:30 -070012308/*
12309 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12310 * This function is used to inform the BSS details to nl80211 interface.
12311 */
12312static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12313 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12314{
12315 struct net_device *dev = pAdapter->dev;
12316 struct wireless_dev *wdev = dev->ieee80211_ptr;
12317 struct wiphy *wiphy = wdev->wiphy;
12318 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12319 int chan_no;
12320 int ie_length;
12321 const char *ie;
12322 unsigned int freq;
12323 struct ieee80211_channel *chan;
12324 int rssi = 0;
12325 struct cfg80211_bss *bss = NULL;
12326
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 if( NULL == pBssDesc )
12328 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012329 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 return bss;
12331 }
12332
12333 chan_no = pBssDesc->channelId;
12334 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12335 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12336
12337 if( NULL == ie )
12338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012339 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 return bss;
12341 }
12342
12343#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12344 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12345 {
12346 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12347 }
12348 else
12349 {
12350 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12351 }
12352#else
12353 freq = ieee80211_channel_to_frequency(chan_no);
12354#endif
12355
12356 chan = __ieee80211_get_channel(wiphy, freq);
12357
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012358 if (!chan) {
12359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12360 return NULL;
12361 }
12362
Abhishek Singhaee43942014-06-16 18:55:47 +053012363 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012364
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012365 return cfg80211_inform_bss(wiphy, chan,
12366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12367 CFG80211_BSS_FTYPE_UNKNOWN,
12368#endif
12369 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012370 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 pBssDesc->capabilityInfo,
12372 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012373 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012374}
12375
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012376/*
12377 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12378 * interface that BSS might have been lost.
12379 * @pAdapter: adaptor
12380 * @bssid: bssid which might have been lost
12381 *
12382 * Return: bss which is unlinked from kernel cache
12383 */
12384struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12385 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12386{
12387 struct net_device *dev = pAdapter->dev;
12388 struct wireless_dev *wdev = dev->ieee80211_ptr;
12389 struct wiphy *wiphy = wdev->wiphy;
12390 struct cfg80211_bss *bss = NULL;
12391
Abhishek Singh5a597e62016-12-05 15:16:30 +053012392 bss = hdd_get_bss_entry(wiphy,
12393 NULL, bssid,
12394 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012395 if (bss == NULL) {
12396 hddLog(LOGE, FL("BSS not present"));
12397 } else {
12398 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12399 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12400 cfg80211_unlink_bss(wiphy, bss);
12401 }
12402 return bss;
12403}
Jeff Johnson295189b2012-06-20 16:38:30 -070012404
12405
12406/*
12407 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12408 * This function is used to inform the BSS details to nl80211 interface.
12409 */
12410struct cfg80211_bss*
12411wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12412 tSirBssDescription *bss_desc
12413 )
12414{
12415 /*
12416 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12417 already exists in bss data base of cfg80211 for that particular BSS ID.
12418 Using cfg80211_inform_bss_frame to update the bss entry instead of
12419 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12420 now there is no possibility to get the mgmt(probe response) frame from PE,
12421 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12422 cfg80211_inform_bss_frame.
12423 */
12424 struct net_device *dev = pAdapter->dev;
12425 struct wireless_dev *wdev = dev->ieee80211_ptr;
12426 struct wiphy *wiphy = wdev->wiphy;
12427 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012428#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12429 qcom_ie_age *qie_age = NULL;
12430 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12431#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012433#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 const char *ie =
12435 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12436 unsigned int freq;
12437 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012438 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 struct cfg80211_bss *bss_status = NULL;
12440 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12441 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012442 hdd_context_t *pHddCtx;
12443 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012444#ifdef WLAN_OPEN_SOURCE
12445 struct timespec ts;
12446#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012448
Wilson Yangf80a0542013-10-07 13:02:37 -070012449 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12450 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012451 if (0 != status)
12452 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012453 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012454 }
12455
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012456 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012457 if (!mgmt)
12458 {
12459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12460 "%s: memory allocation failed ", __func__);
12461 return NULL;
12462 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012463
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012465
12466#ifdef WLAN_OPEN_SOURCE
12467 /* Android does not want the timestamp from the frame.
12468 Instead it wants a monotonic increasing value */
12469 get_monotonic_boottime(&ts);
12470 mgmt->u.probe_resp.timestamp =
12471 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12472#else
12473 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12475 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012476
12477#endif
12478
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12480 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012481
12482#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12483 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12484 /* Assuming this is the last IE, copy at the end */
12485 ie_length -=sizeof(qcom_ie_age);
12486 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12487 qie_age->element_id = QCOM_VENDOR_IE_ID;
12488 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12489 qie_age->oui_1 = QCOM_OUI1;
12490 qie_age->oui_2 = QCOM_OUI2;
12491 qie_age->oui_3 = QCOM_OUI3;
12492 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012493 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12494 * bss related timestamp is in units of ms. Due to this when scan results
12495 * are sent to lowi the scan age is high.To address this, send age in units
12496 * of 1/10 ms.
12497 */
12498 qie_age->age = (vos_timer_get_system_time() -
12499 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012500#endif
12501
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012503 if (bss_desc->fProbeRsp)
12504 {
12505 mgmt->frame_control |=
12506 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12507 }
12508 else
12509 {
12510 mgmt->frame_control |=
12511 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012513
12514#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012515 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12517 {
12518 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12519 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012520 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12522
12523 {
12524 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12525 }
12526 else
12527 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12529 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 kfree(mgmt);
12531 return NULL;
12532 }
12533#else
12534 freq = ieee80211_channel_to_frequency(chan_no);
12535#endif
12536 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012537 /*when the band is changed on the fly using the GUI, three things are done
12538 * 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)
12539 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12540 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12541 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12542 * and discards the channels correponding to previous band and calls back with zero bss results.
12543 * 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
12544 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12545 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12546 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12547 * So drop the bss and continue to next bss.
12548 */
12549 if(chan == NULL)
12550 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012551 hddLog(VOS_TRACE_LEVEL_ERROR,
12552 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12553 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012554 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012555 return NULL;
12556 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012557 /*To keep the rssi icon of the connected AP in the scan window
12558 *and the rssi icon of the wireless networks in sync
12559 * */
12560 if (( eConnectionState_Associated ==
12561 pAdapter->sessionCtx.station.conn_info.connState ) &&
12562 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12563 pAdapter->sessionCtx.station.conn_info.bssId,
12564 WNI_CFG_BSSID_LEN)) &&
12565 (pHddCtx->hdd_wlan_suspended == FALSE))
12566 {
12567 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12568 rssi = (pAdapter->rssi * 100);
12569 }
12570 else
12571 {
12572 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012574
Nirav Shah20ac06f2013-12-12 18:14:06 +053012575 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012576 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12577 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012578
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12580 frame_len, rssi, GFP_KERNEL);
12581 kfree(mgmt);
12582 return bss_status;
12583}
12584
12585/*
12586 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12587 * This function is used to update the BSS data base of CFG8011
12588 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 tCsrRoamInfo *pRoamInfo
12591 )
12592{
12593 tCsrRoamConnectedProfile roamProfile;
12594 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12595 struct cfg80211_bss *bss = NULL;
12596
12597 ENTER();
12598
12599 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12600 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12601
12602 if (NULL != roamProfile.pBssDesc)
12603 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012604 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12605 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012606
12607 if (NULL == bss)
12608 {
12609 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12610 __func__);
12611 }
12612
12613 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12614 }
12615 else
12616 {
12617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12618 __func__);
12619 }
12620 return bss;
12621}
12622
12623/*
12624 * FUNCTION: wlan_hdd_cfg80211_update_bss
12625 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12627 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012629{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012630 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 tCsrScanResultInfo *pScanResult;
12632 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012633 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 tScanResultHandle pResult;
12635 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012636 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012637 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012639
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12641 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12642 NO_SESSION, pAdapter->sessionId));
12643
Wilson Yangf80a0542013-10-07 13:02:37 -070012644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012645 ret = wlan_hdd_validate_context(pHddCtx);
12646 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012648 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012649 }
12650
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012651 if (pAdapter->request != NULL)
12652 {
12653 if ((pAdapter->request->n_ssids == 1)
12654 && (pAdapter->request->ssids != NULL)
12655 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12656 is_p2p_scan = true;
12657 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012658 /*
12659 * start getting scan results and populate cgf80211 BSS database
12660 */
12661 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12662
12663 /* no scan results */
12664 if (NULL == pResult)
12665 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012666 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12667 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012668 wlan_hdd_get_frame_logs(pAdapter,
12669 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 return status;
12671 }
12672
12673 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12674
12675 while (pScanResult)
12676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012677 /*
12678 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12679 * entry already exists in bss data base of cfg80211 for that
12680 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12681 * bss entry instead of cfg80211_inform_bss, But this call expects
12682 * mgmt packet as input. As of now there is no possibility to get
12683 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 * ieee80211_mgmt(probe response) and passing to c
12685 * fg80211_inform_bss_frame.
12686 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012687 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12688 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12689 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012690 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12691 continue; //Skip the non p2p bss entries
12692 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12694 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012695
Jeff Johnson295189b2012-06-20 16:38:30 -070012696
12697 if (NULL == bss_status)
12698 {
12699 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012700 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 }
12702 else
12703 {
Yue Maf49ba872013-08-19 12:04:25 -070012704 cfg80211_put_bss(
12705#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12706 wiphy,
12707#endif
12708 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 }
12710
12711 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12712 }
12713
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012714 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012715 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012717}
12718
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012719void
12720hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12721{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012722 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012723 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012724} /****** end hddPrintMacAddr() ******/
12725
12726void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012727hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012728{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012729 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012730 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012731 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12732 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12733 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012734} /****** end hddPrintPmkId() ******/
12735
12736//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12737//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12738
12739//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12740//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12741
12742#define dump_bssid(bssid) \
12743 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012744 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12745 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012746 }
12747
12748#define dump_pmkid(pMac, pmkid) \
12749 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012750 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12751 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012752 }
12753
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012754#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012755/*
12756 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12757 * This function is used to notify the supplicant of a new PMKSA candidate.
12758 */
12759int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012760 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012761 int index, bool preauth )
12762{
Jeff Johnsone7245742012-09-05 17:12:55 -070012763#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012764 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012765 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012766
12767 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012768 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012769
12770 if( NULL == pRoamInfo )
12771 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012773 return -EINVAL;
12774 }
12775
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012776 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12777 {
12778 dump_bssid(pRoamInfo->bssid);
12779 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012780 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012781 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012782#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012783 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012784}
12785#endif //FEATURE_WLAN_LFR
12786
Yue Maef608272013-04-08 23:09:17 -070012787#ifdef FEATURE_WLAN_LFR_METRICS
12788/*
12789 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12790 * 802.11r/LFR metrics reporting function to report preauth initiation
12791 *
12792 */
12793#define MAX_LFR_METRICS_EVENT_LENGTH 100
12794VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12795 tCsrRoamInfo *pRoamInfo)
12796{
12797 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12798 union iwreq_data wrqu;
12799
12800 ENTER();
12801
12802 if (NULL == pAdapter)
12803 {
12804 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12805 return VOS_STATUS_E_FAILURE;
12806 }
12807
12808 /* create the event */
12809 memset(&wrqu, 0, sizeof(wrqu));
12810 memset(metrics_notification, 0, sizeof(metrics_notification));
12811
12812 wrqu.data.pointer = metrics_notification;
12813 wrqu.data.length = scnprintf(metrics_notification,
12814 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12815 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12816
12817 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12818
12819 EXIT();
12820
12821 return VOS_STATUS_SUCCESS;
12822}
12823
12824/*
12825 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12826 * 802.11r/LFR metrics reporting function to report preauth completion
12827 * or failure
12828 */
12829VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12830 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12831{
12832 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12833 union iwreq_data wrqu;
12834
12835 ENTER();
12836
12837 if (NULL == pAdapter)
12838 {
12839 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12840 return VOS_STATUS_E_FAILURE;
12841 }
12842
12843 /* create the event */
12844 memset(&wrqu, 0, sizeof(wrqu));
12845 memset(metrics_notification, 0, sizeof(metrics_notification));
12846
12847 scnprintf(metrics_notification, sizeof(metrics_notification),
12848 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12849 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12850
12851 if (1 == preauth_status)
12852 strncat(metrics_notification, " TRUE", 5);
12853 else
12854 strncat(metrics_notification, " FALSE", 6);
12855
12856 wrqu.data.pointer = metrics_notification;
12857 wrqu.data.length = strlen(metrics_notification);
12858
12859 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12860
12861 EXIT();
12862
12863 return VOS_STATUS_SUCCESS;
12864}
12865
12866/*
12867 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12868 * 802.11r/LFR metrics reporting function to report handover initiation
12869 *
12870 */
12871VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12872 tCsrRoamInfo *pRoamInfo)
12873{
12874 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12875 union iwreq_data wrqu;
12876
12877 ENTER();
12878
12879 if (NULL == pAdapter)
12880 {
12881 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12882 return VOS_STATUS_E_FAILURE;
12883 }
12884
12885 /* create the event */
12886 memset(&wrqu, 0, sizeof(wrqu));
12887 memset(metrics_notification, 0, sizeof(metrics_notification));
12888
12889 wrqu.data.pointer = metrics_notification;
12890 wrqu.data.length = scnprintf(metrics_notification,
12891 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12892 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12893
12894 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12895
12896 EXIT();
12897
12898 return VOS_STATUS_SUCCESS;
12899}
12900#endif
12901
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012902
12903/**
12904 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12905 * @scan_req: scan request to be checked
12906 *
12907 * Return: true or false
12908 */
12909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12910static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12911 cfg80211_scan_request
12912 *scan_req)
12913{
12914 if (!scan_req || !scan_req->wiphy) {
12915 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12916 return false;
12917 }
12918 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12919 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12920 return false;
12921 }
12922 return true;
12923}
12924#else
12925static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12926 cfg80211_scan_request
12927 *scan_req)
12928{
12929 if (!scan_req || !scan_req->wiphy) {
12930 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12931 return false;
12932 }
12933 return true;
12934}
12935#endif
12936
12937
Jeff Johnson295189b2012-06-20 16:38:30 -070012938/*
12939 * FUNCTION: hdd_cfg80211_scan_done_callback
12940 * scanning callback function, called after finishing scan
12941 *
12942 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012943static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12945{
12946 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012947 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012949 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012950 struct cfg80211_scan_request *req = NULL;
12951 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012952 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12954 bool iface_down = false;
12955#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012956 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012957 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012958 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012959
12960 ENTER();
12961
c_manjee1b4ab9a2016-10-26 11:36:55 +053012962 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12963 !pAdapter->dev) {
12964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12965 return 0;
12966 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012967 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012968 if (NULL == pHddCtx) {
12969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012970 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012971 }
12972
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12974 if (!(pAdapter->dev->flags & IFF_UP))
12975 {
12976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012977 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012978 }
12979#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012980 pScanInfo = &pHddCtx->scan_info;
12981
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 hddLog(VOS_TRACE_LEVEL_INFO,
12983 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012984 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 __func__, halHandle, pContext, (int) scanId, (int) status);
12986
Kiet Lamac06e2c2013-10-23 16:25:07 +053012987 pScanInfo->mScanPendingCounter = 0;
12988
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012990 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 &pScanInfo->scan_req_completion_event,
12992 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012993 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012995 hddLog(VOS_TRACE_LEVEL_ERROR,
12996 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012998 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 }
13000
Yue Maef608272013-04-08 23:09:17 -070013001 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 {
13003 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013004 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013005 }
13006
13007 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013008 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 {
13010 hddLog(VOS_TRACE_LEVEL_INFO,
13011 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013012 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 (int) scanId);
13014 }
13015
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013017 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013018#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013019 {
13020 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13021 pAdapter);
13022 if (0 > ret)
13023 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013024 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013025
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 /* If any client wait scan result through WEXT
13027 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013028 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 {
13030 /* The other scan request waiting for current scan finish
13031 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013032 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013033 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013034 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 }
13036 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013037 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 {
13039 struct net_device *dev = pAdapter->dev;
13040 union iwreq_data wrqu;
13041 int we_event;
13042 char *msg;
13043
13044 memset(&wrqu, '\0', sizeof(wrqu));
13045 we_event = SIOCGIWSCAN;
13046 msg = NULL;
13047 wireless_send_event(dev, we_event, &wrqu, msg);
13048 }
13049 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013050 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013051
13052 /* Get the Scan Req */
13053 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013054 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013055
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013056 /* Scan is no longer pending */
13057 pScanInfo->mScanPending = VOS_FALSE;
13058
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013059 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013060 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13063 iface_down ? "up" : "down");
13064#endif
13065
13066 if (pAdapter->dev) {
13067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13068 pAdapter->dev->name);
13069 }
mukul sharmae7041822015-12-03 15:09:21 +053013070 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013071 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 }
13073
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013074 /* last_scan_timestamp is used to decide if new scan
13075 * is needed or not on station interface. If last station
13076 * scan time and new station scan time is less then
13077 * last_scan_timestamp ; driver will return cached scan.
13078 */
13079 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13080 {
13081 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13082
13083 if ( req->n_channels )
13084 {
13085 for (i = 0; i < req->n_channels ; i++ )
13086 {
13087 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13088 }
13089 /* store no of channel scanned */
13090 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13091 }
13092
13093 }
13094
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013095 /*
13096 * cfg80211_scan_done informing NL80211 about completion
13097 * of scanning
13098 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013099 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13100 {
13101 aborted = true;
13102 }
mukul sharmae7041822015-12-03 15:09:21 +053013103
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13105 if (!iface_down)
13106#endif
13107 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013108
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013109 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013110
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013111allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013112 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13113 ) && (pHddCtx->spoofMacAddr.isEnabled
13114 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013115 /* Generate new random mac addr for next scan */
13116 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013117
13118 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13119 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013120 }
13121
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013122 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013123 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013124
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013125 /* Acquire wakelock to handle the case where APP's tries to suspend
13126 * immediatly after the driver gets connect request(i.e after scan)
13127 * from supplicant, this result in app's is suspending and not able
13128 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013129 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013130
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13132 if (!iface_down)
13133#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013134#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013135 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013136#endif
13137
Jeff Johnson295189b2012-06-20 16:38:30 -070013138 EXIT();
13139 return 0;
13140}
13141
13142/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013143 * FUNCTION: hdd_isConnectionInProgress
13144 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013145 *
13146 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013147v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13148 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013149{
13150 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13151 hdd_station_ctx_t *pHddStaCtx = NULL;
13152 hdd_adapter_t *pAdapter = NULL;
13153 VOS_STATUS status = 0;
13154 v_U8_t staId = 0;
13155 v_U8_t *staMac = NULL;
13156
13157 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13158
13159 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13160 {
13161 pAdapter = pAdapterNode->pAdapter;
13162
13163 if( pAdapter )
13164 {
13165 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013166 "%s: Adapter with device mode %s (%d) exists",
13167 __func__, hdd_device_modetoString(pAdapter->device_mode),
13168 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013169 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013170 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13171 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13172 (eConnectionState_Connecting ==
13173 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13174 {
13175 hddLog(VOS_TRACE_LEVEL_ERROR,
13176 "%s: %p(%d) Connection is in progress", __func__,
13177 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013178 if (session_id && reason)
13179 {
13180 *session_id = pAdapter->sessionId;
13181 *reason = eHDD_CONNECTION_IN_PROGRESS;
13182 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013183 return VOS_TRUE;
13184 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013185 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013186 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013187 {
13188 hddLog(VOS_TRACE_LEVEL_ERROR,
13189 "%s: %p(%d) Reassociation is in progress", __func__,
13190 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013191 if (session_id && reason)
13192 {
13193 *session_id = pAdapter->sessionId;
13194 *reason = eHDD_REASSOC_IN_PROGRESS;
13195 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013196 return VOS_TRUE;
13197 }
13198 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013199 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13200 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013201 {
13202 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13203 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013204 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013205 {
13206 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13207 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013208 "%s: client " MAC_ADDRESS_STR
13209 " is in the middle of WPS/EAPOL exchange.", __func__,
13210 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013211 if (session_id && reason)
13212 {
13213 *session_id = pAdapter->sessionId;
13214 *reason = eHDD_EAPOL_IN_PROGRESS;
13215 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013216 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013217 }
13218 }
13219 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13220 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13221 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013222 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13223 ptSapContext pSapCtx = NULL;
13224 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13225 if(pSapCtx == NULL){
13226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13227 FL("psapCtx is NULL"));
13228 return VOS_FALSE;
13229 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013230 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13231 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013232 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13233 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013234 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013235 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013236
13237 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013238 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13239 "middle of WPS/EAPOL exchange.", __func__,
13240 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013241 if (session_id && reason)
13242 {
13243 *session_id = pAdapter->sessionId;
13244 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13245 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013246 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013247 }
13248 }
13249 }
13250 }
13251 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13252 pAdapterNode = pNext;
13253 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013254 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013255}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013256
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013257/**
13258 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13259 * to the Scan request
13260 * @scanRequest: Pointer to the csr scan request
13261 * @request: Pointer to the scan request from supplicant
13262 *
13263 * Return: None
13264 */
13265#ifdef CFG80211_SCAN_BSSID
13266static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13267 struct cfg80211_scan_request *request)
13268{
13269 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13270}
13271#else
13272static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13273 struct cfg80211_scan_request *request)
13274{
13275}
13276#endif
13277
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013278/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013279 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013280 * this scan respond to scan trigger and update cfg80211 scan database
13281 * later, scan dump command can be used to recieve scan results
13282 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013283int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13285 struct net_device *dev,
13286#endif
13287 struct cfg80211_scan_request *request)
13288{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013289 hdd_adapter_t *pAdapter = NULL;
13290 hdd_context_t *pHddCtx = NULL;
13291 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013292 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013293 tCsrScanRequest scanRequest;
13294 tANI_U8 *channelList = NULL, i;
13295 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013296 int status;
13297 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013299 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013300 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013301 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013302 v_U8_t curr_session_id;
13303 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013304
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013305#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13306 struct net_device *dev = NULL;
13307 if (NULL == request)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_ERROR,
13310 "%s: scan req param null", __func__);
13311 return -EINVAL;
13312 }
13313 dev = request->wdev->netdev;
13314#endif
13315
13316 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13317 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13318 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13319
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 ENTER();
13321
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13323 __func__, hdd_device_modetoString(pAdapter->device_mode),
13324 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013325
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013326 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013327 if (0 != status)
13328 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013329 return status;
13330 }
13331
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013332 if (NULL == pwextBuf)
13333 {
13334 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13335 __func__);
13336 return -EIO;
13337 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013338 cfg_param = pHddCtx->cfg_ini;
13339 pScanInfo = &pHddCtx->scan_info;
13340
Jeff Johnson295189b2012-06-20 16:38:30 -070013341#ifdef WLAN_BTAMP_FEATURE
13342 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013343 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013345 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 "%s: No scanning when AMP is on", __func__);
13347 return -EOPNOTSUPP;
13348 }
13349#endif
13350 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013351 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013353 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013354 "%s: Not scanning on device_mode = %s (%d)",
13355 __func__, hdd_device_modetoString(pAdapter->device_mode),
13356 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 return -EOPNOTSUPP;
13358 }
13359
13360 if (TRUE == pScanInfo->mScanPending)
13361 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013362 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13363 {
13364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13365 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013366 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 }
13368
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013369 // Don't allow scan if PNO scan is going on.
13370 if (pHddCtx->isPnoEnable)
13371 {
13372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13373 FL("pno scan in progress"));
13374 return -EBUSY;
13375 }
13376
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013377 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013378 //Channel and action frame is pending
13379 //Otherwise Cancel Remain On Channel and allow Scan
13380 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013381 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013382 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013383 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013384 return -EBUSY;
13385 }
13386
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13388 {
13389 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013390 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013392 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13394 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013395 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 "%s: MAX TM Level Scan not allowed", __func__);
13397 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013398 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 }
13400 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13401
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013402 /* Check if scan is allowed at this point of time.
13403 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013404 if (TRUE == pHddCtx->btCoexModeSet)
13405 {
13406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13407 FL("BTCoex Mode operation in progress"));
13408 return -EBUSY;
13409 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013410 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013411 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013413 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13414 pHddCtx->last_scan_reject_reason != curr_reason ||
13415 !pHddCtx->last_scan_reject_timestamp)
13416 {
13417 pHddCtx->last_scan_reject_session_id = curr_session_id;
13418 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013419 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013420 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013421 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013422 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013423 pHddCtx->last_scan_reject_timestamp) >=
13424 SCAN_REJECT_THRESHOLD_TIME)
13425 {
13426 pHddCtx->last_scan_reject_timestamp = 0;
13427 if (pHddCtx->cfg_ini->enableFatalEvent)
13428 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13429 WLAN_LOG_INDICATOR_HOST_DRIVER,
13430 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13431 FALSE, FALSE);
13432 else
13433 {
13434 hddLog(LOGE, FL("Triggering SSR"));
13435 vos_wlanRestart();
13436 }
13437 }
13438 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013439 return -EBUSY;
13440 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013441 pHddCtx->last_scan_reject_timestamp = 0;
13442 pHddCtx->last_scan_reject_session_id = 0xFF;
13443 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013444
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13446
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013447 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13448 * Becasue of this, driver is assuming that this is not wildcard scan and so
13449 * is not aging out the scan results.
13450 */
13451 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013453 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013455
13456 if ((request->ssids) && (0 < request->n_ssids))
13457 {
13458 tCsrSSIDInfo *SsidInfo;
13459 int j;
13460 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13461 /* Allocate num_ssid tCsrSSIDInfo structure */
13462 SsidInfo = scanRequest.SSIDs.SSIDList =
13463 ( tCsrSSIDInfo *)vos_mem_malloc(
13464 request->n_ssids*sizeof(tCsrSSIDInfo));
13465
13466 if(NULL == scanRequest.SSIDs.SSIDList)
13467 {
13468 hddLog(VOS_TRACE_LEVEL_ERROR,
13469 "%s: memory alloc failed SSIDInfo buffer", __func__);
13470 return -ENOMEM;
13471 }
13472
13473 /* copy all the ssid's and their length */
13474 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13475 {
13476 /* get the ssid length */
13477 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13478 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13479 SsidInfo->SSID.length);
13480 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13481 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13482 j, SsidInfo->SSID.ssId);
13483 }
13484 /* set the scan type to active */
13485 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13486 }
13487 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013489 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13490 TRACE_CODE_HDD_CFG80211_SCAN,
13491 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013492 /* set the scan type to active */
13493 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013495 else
13496 {
13497 /*Set the scan type to default type, in this case it is ACTIVE*/
13498 scanRequest.scanType = pScanInfo->scan_mode;
13499 }
13500 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13501 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013502
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013503 csr_scan_request_assign_bssid(&scanRequest, request);
13504
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 /* set BSSType to default type */
13506 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13507
13508 /*TODO: scan the requested channels only*/
13509
13510 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013511 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013512 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013513 hddLog(VOS_TRACE_LEVEL_WARN,
13514 "No of Scan Channels exceeded limit: %d", request->n_channels);
13515 request->n_channels = MAX_CHANNEL;
13516 }
13517
13518 hddLog(VOS_TRACE_LEVEL_INFO,
13519 "No of Scan Channels: %d", request->n_channels);
13520
13521
13522 if( request->n_channels )
13523 {
13524 char chList [(request->n_channels*5)+1];
13525 int len;
13526 channelList = vos_mem_malloc( request->n_channels );
13527 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013528 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013529 hddLog(VOS_TRACE_LEVEL_ERROR,
13530 "%s: memory alloc failed channelList", __func__);
13531 status = -ENOMEM;
13532 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013533 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013534
13535 for( i = 0, len = 0; i < request->n_channels ; i++ )
13536 {
13537 channelList[i] = request->channels[i]->hw_value;
13538 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13539 }
13540
Nirav Shah20ac06f2013-12-12 18:14:06 +053013541 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013542 "Channel-List: %s ", chList);
13543 }
c_hpothu53512302014-04-15 18:49:53 +053013544
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013545 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13546 scanRequest.ChannelInfo.ChannelList = channelList;
13547
13548 /* set requestType to full scan */
13549 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13550
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013551 /* if there is back to back scan happening in driver with in
13552 * nDeferScanTimeInterval interval driver should defer new scan request
13553 * and should provide last cached scan results instead of new channel list.
13554 * This rule is not applicable if scan is p2p scan.
13555 * This condition will work only in case when last request no of channels
13556 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013557 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013558 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013559 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013560
Sushant Kaushik86592172015-04-27 16:35:03 +053013561 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13562 /* if wps ie is NULL , then only defer scan */
13563 if ( pWpsIe == NULL &&
13564 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013565 {
13566 if ( pScanInfo->last_scan_timestamp !=0 &&
13567 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13568 {
13569 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13570 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13571 vos_mem_compare(pScanInfo->last_scan_channelList,
13572 channelList, pScanInfo->last_scan_numChannels))
13573 {
13574 hddLog(VOS_TRACE_LEVEL_WARN,
13575 " New and old station scan time differ is less then %u",
13576 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13577
13578 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013579 pAdapter);
13580
Agarwal Ashish57e84372014-12-05 18:26:53 +053013581 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013582 "Return old cached scan as all channels and no of channels are same");
13583
Agarwal Ashish57e84372014-12-05 18:26:53 +053013584 if (0 > ret)
13585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013586
Agarwal Ashish57e84372014-12-05 18:26:53 +053013587 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013588
13589 status = eHAL_STATUS_SUCCESS;
13590 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013591 }
13592 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013593 }
13594
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013595 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13596 * search (Flush on both full scan and social scan but not on single
13597 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13598 */
13599
13600 /* Supplicant does single channel scan after 8-way handshake
13601 * and in that case driver shoudnt flush scan results. If
13602 * driver flushes the scan results here and unfortunately if
13603 * the AP doesnt respond to our probe req then association
13604 * fails which is not desired
13605 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013606 if ((request->n_ssids == 1)
13607 && (request->ssids != NULL)
13608 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13609 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013610
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013611 if( is_p2p_scan ||
13612 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013613 {
13614 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13615 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13616 pAdapter->sessionId );
13617 }
13618
13619 if( request->ie_len )
13620 {
13621 /* save this for future association (join requires this) */
13622 /*TODO: Array needs to be converted to dynamic allocation,
13623 * as multiple ie.s can be sent in cfg80211_scan_request structure
13624 * CR 597966
13625 */
13626 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13627 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13628 pScanInfo->scanAddIE.length = request->ie_len;
13629
13630 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13631 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13632 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013634 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013636 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13637 memcpy( pwextBuf->roamProfile.addIEScan,
13638 request->ie, request->ie_len);
13639 }
13640 else
13641 {
13642 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13643 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 }
13645
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013646 }
13647 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13648 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13649
13650 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13651 request->ie_len);
13652 if (pP2pIe != NULL)
13653 {
13654#ifdef WLAN_FEATURE_P2P_DEBUG
13655 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13656 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13657 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013658 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013659 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13660 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13661 "Go nego completed to Connection is started");
13662 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13663 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013664 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013665 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13666 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013668 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13669 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13670 "Disconnected state to Connection is started");
13671 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13672 "for 4way Handshake");
13673 }
13674#endif
13675
13676 /* no_cck will be set during p2p find to disable 11b rates */
13677 if(TRUE == request->no_cck)
13678 {
13679 hddLog(VOS_TRACE_LEVEL_INFO,
13680 "%s: This is a P2P Search", __func__);
13681 scanRequest.p2pSearch = 1;
13682
13683 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013684 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013685 /* set requestType to P2P Discovery */
13686 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13687 }
13688
13689 /*
13690 Skip Dfs Channel in case of P2P Search
13691 if it is set in ini file
13692 */
13693 if(cfg_param->skipDfsChnlInP2pSearch)
13694 {
13695 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013696 }
13697 else
13698 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013699 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013701
Agarwal Ashish4f616132013-12-30 23:32:50 +053013702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 }
13704 }
13705
13706 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13707
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013708#ifdef FEATURE_WLAN_TDLS
13709 /* if tdls disagree scan right now, return immediately.
13710 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13711 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13712 */
13713 status = wlan_hdd_tdls_scan_callback (pAdapter,
13714 wiphy,
13715#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13716 dev,
13717#endif
13718 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013719 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013720 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013721 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13723 "scan rejected %d", __func__, status);
13724 else
13725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13726 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013727 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013728 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013729 }
13730#endif
13731
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013732 /* acquire the wakelock to avoid the apps suspend during the scan. To
13733 * address the following issues.
13734 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13735 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13736 * for long time, this result in apps running at full power for long time.
13737 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13738 * be stuck in full power because of resume BMPS
13739 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013740 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013741
Nirav Shah20ac06f2013-12-12 18:14:06 +053013742 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13743 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013744 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13745 scanRequest.requestType, scanRequest.scanType,
13746 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013747 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13748
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013749 if (pHddCtx->spoofMacAddr.isEnabled &&
13750 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013751 {
13752 hddLog(VOS_TRACE_LEVEL_INFO,
13753 "%s: MAC Spoofing enabled for current scan", __func__);
13754 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13755 * to fill TxBds for probe request during current scan
13756 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013757 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013758 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013759
13760 if(status != VOS_STATUS_SUCCESS)
13761 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013762 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013763 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013764#ifdef FEATURE_WLAN_TDLS
13765 wlan_hdd_tdls_scan_done_callback(pAdapter);
13766#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013767 goto free_mem;
13768 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013769 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013770 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013771 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 pAdapter->sessionId, &scanRequest, &scanId,
13773 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013774
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 if (eHAL_STATUS_SUCCESS != status)
13776 {
13777 hddLog(VOS_TRACE_LEVEL_ERROR,
13778 "%s: sme_ScanRequest returned error %d", __func__, status);
13779 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013780 if(eHAL_STATUS_RESOURCES == status)
13781 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13783 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013784 status = -EBUSY;
13785 } else {
13786 status = -EIO;
13787 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013788 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013789
13790#ifdef FEATURE_WLAN_TDLS
13791 wlan_hdd_tdls_scan_done_callback(pAdapter);
13792#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 goto free_mem;
13794 }
13795
13796 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013797 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 pAdapter->request = request;
13799 pScanInfo->scanId = scanId;
13800
13801 complete(&pScanInfo->scan_req_completion_event);
13802
13803free_mem:
13804 if( scanRequest.SSIDs.SSIDList )
13805 {
13806 vos_mem_free(scanRequest.SSIDs.SSIDList);
13807 }
13808
13809 if( channelList )
13810 vos_mem_free( channelList );
13811
13812 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 return status;
13814}
13815
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013816int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13818 struct net_device *dev,
13819#endif
13820 struct cfg80211_scan_request *request)
13821{
13822 int ret;
13823
13824 vos_ssr_protect(__func__);
13825 ret = __wlan_hdd_cfg80211_scan(wiphy,
13826#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13827 dev,
13828#endif
13829 request);
13830 vos_ssr_unprotect(__func__);
13831
13832 return ret;
13833}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013834
13835void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13836{
13837 v_U8_t iniDot11Mode =
13838 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13839 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13840
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013841 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13842 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013843 switch ( iniDot11Mode )
13844 {
13845 case eHDD_DOT11_MODE_AUTO:
13846 case eHDD_DOT11_MODE_11ac:
13847 case eHDD_DOT11_MODE_11ac_ONLY:
13848#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013849 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13850 sme_IsFeatureSupportedByFW(DOT11AC) )
13851 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13852 else
13853 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013854#else
13855 hddDot11Mode = eHDD_DOT11_MODE_11n;
13856#endif
13857 break;
13858 case eHDD_DOT11_MODE_11n:
13859 case eHDD_DOT11_MODE_11n_ONLY:
13860 hddDot11Mode = eHDD_DOT11_MODE_11n;
13861 break;
13862 default:
13863 hddDot11Mode = iniDot11Mode;
13864 break;
13865 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013866#ifdef WLAN_FEATURE_AP_HT40_24G
13867 if (operationChannel > SIR_11B_CHANNEL_END)
13868#endif
13869 {
13870 /* This call decides required channel bonding mode */
13871 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013872 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13873 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013874 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013875}
13876
Jeff Johnson295189b2012-06-20 16:38:30 -070013877/*
13878 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013881int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013882 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13883 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013884{
13885 int status = 0;
13886 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013887 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013888 v_U32_t roamId;
13889 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013891 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013892
13893 ENTER();
13894
13895 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013896 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13897
13898 status = wlan_hdd_validate_context(pHddCtx);
13899 if (status)
13900 {
Yue Mae36e3552014-03-05 17:06:20 -080013901 return status;
13902 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903
Jeff Johnson295189b2012-06-20 16:38:30 -070013904 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13905 {
13906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13907 return -EINVAL;
13908 }
13909
13910 pRoamProfile = &pWextState->roamProfile;
13911
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013914 hdd_station_ctx_t *pHddStaCtx;
13915 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013916
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013917 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13918
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013919 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013920 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13921 {
13922 /*QoS not enabled in cfg file*/
13923 pRoamProfile->uapsd_mask = 0;
13924 }
13925 else
13926 {
13927 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13930 }
13931
13932 pRoamProfile->SSIDs.numOfSSIDs = 1;
13933 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13934 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13937 ssid, ssid_len);
13938
13939 if (bssid)
13940 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013941 pValidBssid = bssid;
13942 }
13943 else if (bssid_hint)
13944 {
13945 pValidBssid = bssid_hint;
13946 }
13947 if (pValidBssid)
13948 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013950 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013952 /* Save BSSID in seperate variable as well, as RoamProfile
13953 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 case of join failure we should send valid BSSID to supplicant
13955 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013956 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 WNI_CFG_BSSID_LEN);
13958 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013959 else
13960 {
13961 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13962 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013963
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013964 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13965 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13967 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 /*set gen ie*/
13970 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13971 /*set auth*/
13972 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13973 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013974#ifdef FEATURE_WLAN_WAPI
13975 if (pAdapter->wapi_info.nWapiMode)
13976 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013977 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 switch (pAdapter->wapi_info.wapiAuthMode)
13979 {
13980 case WAPI_AUTH_MODE_PSK:
13981 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013982 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 pAdapter->wapi_info.wapiAuthMode);
13984 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13985 break;
13986 }
13987 case WAPI_AUTH_MODE_CERT:
13988 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013989 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 pAdapter->wapi_info.wapiAuthMode);
13991 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13992 break;
13993 }
13994 } // End of switch
13995 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13996 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13997 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013998 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 pRoamProfile->AuthType.numEntries = 1;
14000 pRoamProfile->EncryptionType.numEntries = 1;
14001 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14002 pRoamProfile->mcEncryptionType.numEntries = 1;
14003 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14004 }
14005 }
14006#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014007#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014008 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014009 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14010 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14011 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014012 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14013 sizeof (tSirGtkOffloadParams));
14014 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014015 }
14016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 pRoamProfile->csrPersona = pAdapter->device_mode;
14018
Jeff Johnson32d95a32012-09-10 13:15:23 -070014019 if( operatingChannel )
14020 {
14021 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14022 pRoamProfile->ChannelInfo.numOfChannels = 1;
14023 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014024 else
14025 {
14026 pRoamProfile->ChannelInfo.ChannelList = NULL;
14027 pRoamProfile->ChannelInfo.numOfChannels = 0;
14028 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014029 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14030 {
14031 hdd_select_cbmode(pAdapter,operatingChannel);
14032 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014033
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014034 /*
14035 * Change conn_state to connecting before sme_RoamConnect(),
14036 * because sme_RoamConnect() has a direct path to call
14037 * hdd_smeRoamCallback(), which will change the conn_state
14038 * If direct path, conn_state will be accordingly changed
14039 * to NotConnected or Associated by either
14040 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14041 * in sme_RoamCallback()
14042 * if sme_RomConnect is to be queued,
14043 * Connecting state will remain until it is completed.
14044 * If connection state is not changed,
14045 * connection state will remain in eConnectionState_NotConnected state.
14046 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14047 * if conn state is eConnectionState_NotConnected.
14048 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14049 * informed of connect result indication which is an issue.
14050 */
14051
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014052 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14053 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014054 {
14055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014056 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014057 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14058 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014059 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 pAdapter->sessionId, pRoamProfile, &roamId);
14062
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014063 if ((eHAL_STATUS_SUCCESS != status) &&
14064 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14065 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014066
14067 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014068 hddLog(VOS_TRACE_LEVEL_ERROR,
14069 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14070 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014071 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014072 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014073 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014074 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014075
14076 pRoamProfile->ChannelInfo.ChannelList = NULL;
14077 pRoamProfile->ChannelInfo.numOfChannels = 0;
14078
Jeff Johnson295189b2012-06-20 16:38:30 -070014079 }
14080 else
14081 {
14082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14083 return -EINVAL;
14084 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014085 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 return status;
14087}
14088
14089/*
14090 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14091 * This function is used to set the authentication type (OPEN/SHARED).
14092 *
14093 */
14094static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14095 enum nl80211_auth_type auth_type)
14096{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014097 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14099
14100 ENTER();
14101
14102 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014103 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014106 hddLog(VOS_TRACE_LEVEL_INFO,
14107 "%s: set authentication type to AUTOSWITCH", __func__);
14108 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14109 break;
14110
14111 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014112#ifdef WLAN_FEATURE_VOWIFI_11R
14113 case NL80211_AUTHTYPE_FT:
14114#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014115 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 "%s: set authentication type to OPEN", __func__);
14117 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14118 break;
14119
14120 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014121 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 "%s: set authentication type to SHARED", __func__);
14123 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14124 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014125#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014127 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 "%s: set authentication type to CCKM WPA", __func__);
14129 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14130 break;
14131#endif
14132
14133
14134 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135 hddLog(VOS_TRACE_LEVEL_ERROR,
14136 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014137 auth_type);
14138 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14139 return -EINVAL;
14140 }
14141
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014142 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014143 pHddStaCtx->conn_info.authType;
14144 return 0;
14145}
14146
14147/*
14148 * FUNCTION: wlan_hdd_set_akm_suite
14149 * This function is used to set the key mgmt type(PSK/8021x).
14150 *
14151 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014152static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 u32 key_mgmt
14154 )
14155{
14156 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14157 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014158 /* Should be in ieee802_11_defs.h */
14159#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
14160#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 /*set key mgmt type*/
14162 switch(key_mgmt)
14163 {
14164 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014165 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014166#ifdef WLAN_FEATURE_VOWIFI_11R
14167 case WLAN_AKM_SUITE_FT_PSK:
14168#endif
14169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014170 __func__);
14171 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14172 break;
14173
14174 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014175 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014176#ifdef WLAN_FEATURE_VOWIFI_11R
14177 case WLAN_AKM_SUITE_FT_8021X:
14178#endif
14179 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 __func__);
14181 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14182 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014183#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014184#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14185#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14186 case WLAN_AKM_SUITE_CCKM:
14187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14188 __func__);
14189 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14190 break;
14191#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014192#ifndef WLAN_AKM_SUITE_OSEN
14193#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14194 case WLAN_AKM_SUITE_OSEN:
14195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14196 __func__);
14197 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14198 break;
14199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014200
14201 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 __func__, key_mgmt);
14204 return -EINVAL;
14205
14206 }
14207 return 0;
14208}
14209
14210/*
14211 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014212 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014213 * (NONE/WEP40/WEP104/TKIP/CCMP).
14214 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014215static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14216 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014217 bool ucast
14218 )
14219{
14220 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014221 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14223
14224 ENTER();
14225
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014226 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014227 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014229 __func__, cipher);
14230 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14231 }
14232 else
14233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014234
Jeff Johnson295189b2012-06-20 16:38:30 -070014235 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014236 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014237 {
14238 case IW_AUTH_CIPHER_NONE:
14239 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14240 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014241
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014243 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014245
Jeff Johnson295189b2012-06-20 16:38:30 -070014246 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014247 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014248 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014249
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 case WLAN_CIPHER_SUITE_TKIP:
14251 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14252 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014253
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 case WLAN_CIPHER_SUITE_CCMP:
14255 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14256 break;
14257#ifdef FEATURE_WLAN_WAPI
14258 case WLAN_CIPHER_SUITE_SMS4:
14259 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14260 break;
14261#endif
14262
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014263#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014264 case WLAN_CIPHER_SUITE_KRK:
14265 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14266 break;
14267#endif
14268 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 __func__, cipher);
14271 return -EOPNOTSUPP;
14272 }
14273 }
14274
14275 if (ucast)
14276 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 __func__, encryptionType);
14279 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14280 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 encryptionType;
14283 }
14284 else
14285 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 __func__, encryptionType);
14288 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14289 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14290 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14291 }
14292
14293 return 0;
14294}
14295
14296
14297/*
14298 * FUNCTION: wlan_hdd_cfg80211_set_ie
14299 * This function is used to parse WPA/RSN IE's.
14300 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014301int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14303 const u8 *ie,
14304#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014305 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014307 size_t ie_len
14308 )
14309{
14310 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14312 const u8 *genie = ie;
14313#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014315#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 v_U16_t remLen = ie_len;
14317#ifdef FEATURE_WLAN_WAPI
14318 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14319 u16 *tmp;
14320 v_U16_t akmsuiteCount;
14321 int *akmlist;
14322#endif
14323 ENTER();
14324
14325 /* clear previous assocAddIE */
14326 pWextState->assocAddIE.length = 0;
14327 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014328 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014329
14330 while (remLen >= 2)
14331 {
14332 v_U16_t eLen = 0;
14333 v_U8_t elementId;
14334 elementId = *genie++;
14335 eLen = *genie++;
14336 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014337
Arif Hussain6d2a3322013-11-17 19:50:10 -080014338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014340
14341 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014343 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014344 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 -070014345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014346 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014347 "%s: Invalid WPA IE", __func__);
14348 return -EINVAL;
14349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014350 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 {
14352 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014353 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014355
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014356 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014358 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14359 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 VOS_ASSERT(0);
14361 return -ENOMEM;
14362 }
14363 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14364 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14365 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014366
Jeff Johnson295189b2012-06-20 16:38:30 -070014367 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14368 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14369 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14370 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014371 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14372 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014373 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14374 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14375 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14376 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14377 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14378 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014379 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014380 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 {
14382 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014383 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014384 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014385
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014386 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014388 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14389 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 VOS_ASSERT(0);
14391 return -ENOMEM;
14392 }
14393 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14394 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14395 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014396
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14398 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014400#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014401 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14402 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 /*Consider WFD IE, only for P2P Client */
14404 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14405 {
14406 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014407 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014410 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014412 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14413 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 VOS_ASSERT(0);
14415 return -ENOMEM;
14416 }
14417 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14418 // WPS IE + P2P IE + WFD IE
14419 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14420 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014421
Jeff Johnson295189b2012-06-20 16:38:30 -070014422 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14423 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14424 }
14425#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014426 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014427 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014428 HS20_OUI_TYPE_SIZE)) )
14429 {
14430 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014431 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014432 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014433
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014434 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014435 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014436 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14437 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014438 VOS_ASSERT(0);
14439 return -ENOMEM;
14440 }
14441 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14442 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014443
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014444 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14445 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14446 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014447 /* Appending OSEN Information Element in Assiciation Request */
14448 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14449 OSEN_OUI_TYPE_SIZE)) )
14450 {
14451 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14452 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14453 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014454
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014455 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014456 {
14457 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14458 "Need bigger buffer space");
14459 VOS_ASSERT(0);
14460 return -ENOMEM;
14461 }
14462 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14463 pWextState->assocAddIE.length += eLen + 2;
14464
14465 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14466 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14467 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14468 }
14469
Abhishek Singh4322e622015-06-10 15:42:54 +053014470 /* Update only for WPA IE */
14471 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14472 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014473
14474 /* populating as ADDIE in beacon frames */
14475 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014476 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014477 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14478 {
14479 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14480 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14481 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14482 {
14483 hddLog(LOGE,
14484 "Coldn't pass "
14485 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14486 }
14487 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14488 else
14489 hddLog(LOGE,
14490 "Could not pass on "
14491 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14492
14493 /* IBSS mode doesn't contain params->proberesp_ies still
14494 beaconIE's need to be populated in probe response frames */
14495 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14496 {
14497 u16 rem_probe_resp_ie_len = eLen + 2;
14498 u8 probe_rsp_ie_len[3] = {0};
14499 u8 counter = 0;
14500
14501 /* Check Probe Resp Length if it is greater then 255 then
14502 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14503 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14504 not able Store More then 255 bytes into One Variable */
14505
14506 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14507 {
14508 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14509 {
14510 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14511 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14512 }
14513 else
14514 {
14515 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14516 rem_probe_resp_ie_len = 0;
14517 }
14518 }
14519
14520 rem_probe_resp_ie_len = 0;
14521
14522 if (probe_rsp_ie_len[0] > 0)
14523 {
14524 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14525 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14526 (tANI_U8*)(genie - 2),
14527 probe_rsp_ie_len[0], NULL,
14528 eANI_BOOLEAN_FALSE)
14529 == eHAL_STATUS_FAILURE)
14530 {
14531 hddLog(LOGE,
14532 "Could not pass"
14533 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14534 }
14535 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14536 }
14537
14538 if (probe_rsp_ie_len[1] > 0)
14539 {
14540 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14541 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14542 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14543 probe_rsp_ie_len[1], NULL,
14544 eANI_BOOLEAN_FALSE)
14545 == eHAL_STATUS_FAILURE)
14546 {
14547 hddLog(LOGE,
14548 "Could not pass"
14549 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14550 }
14551 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14552 }
14553
14554 if (probe_rsp_ie_len[2] > 0)
14555 {
14556 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14557 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14558 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14559 probe_rsp_ie_len[2], NULL,
14560 eANI_BOOLEAN_FALSE)
14561 == eHAL_STATUS_FAILURE)
14562 {
14563 hddLog(LOGE,
14564 "Could not pass"
14565 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14566 }
14567 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14568 }
14569
14570 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14571 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14572 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14573 {
14574 hddLog(LOGE,
14575 "Could not pass"
14576 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14577 }
14578 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014579 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014580 break;
14581 case DOT11F_EID_RSN:
14582 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14583 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14584 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14585 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14586 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14587 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014588
Abhishek Singhb16f3562016-01-20 11:08:32 +053014589 /* Appending extended capabilities with Interworking or
14590 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014591 *
14592 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014593 * interworkingService or bsstransition bit is set to 1.
14594 * Driver is only interested in interworkingService and
14595 * bsstransition capability from supplicant.
14596 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014597 * required from supplicat, it needs to be handled while
14598 * sending Assoc Req in LIM.
14599 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014600 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014601 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014602 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014603 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014604 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014605
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014606 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014607 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014608 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14609 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014610 VOS_ASSERT(0);
14611 return -ENOMEM;
14612 }
14613 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14614 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014615
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014616 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14617 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14618 break;
14619 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014620#ifdef FEATURE_WLAN_WAPI
14621 case WLAN_EID_WAPI:
14622 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014623 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014624 pAdapter->wapi_info.nWapiMode);
14625 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014626 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014627 akmsuiteCount = WPA_GET_LE16(tmp);
14628 tmp = tmp + 1;
14629 akmlist = (int *)(tmp);
14630 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14631 {
14632 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14633 }
14634 else
14635 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014636 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014637 VOS_ASSERT(0);
14638 return -EINVAL;
14639 }
14640
14641 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14642 {
14643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014644 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014645 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014646 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014647 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014648 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014650 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014651 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14652 }
14653 break;
14654#endif
14655 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014658 /* when Unknown IE is received we should break and continue
14659 * to the next IE in the buffer instead we were returning
14660 * so changing this to break */
14661 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014662 }
14663 genie += eLen;
14664 remLen -= eLen;
14665 }
14666 EXIT();
14667 return 0;
14668}
14669
14670/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014671 * FUNCTION: hdd_isWPAIEPresent
14672 * Parse the received IE to find the WPA IE
14673 *
14674 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014675static bool hdd_isWPAIEPresent(
14676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14677 const u8 *ie,
14678#else
14679 u8 *ie,
14680#endif
14681 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014682{
14683 v_U8_t eLen = 0;
14684 v_U16_t remLen = ie_len;
14685 v_U8_t elementId = 0;
14686
14687 while (remLen >= 2)
14688 {
14689 elementId = *ie++;
14690 eLen = *ie++;
14691 remLen -= 2;
14692 if (eLen > remLen)
14693 {
14694 hddLog(VOS_TRACE_LEVEL_ERROR,
14695 "%s: IE length is wrong %d", __func__, eLen);
14696 return FALSE;
14697 }
14698 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14699 {
14700 /* OUI - 0x00 0X50 0XF2
14701 WPA Information Element - 0x01
14702 WPA version - 0x01*/
14703 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14704 return TRUE;
14705 }
14706 ie += eLen;
14707 remLen -= eLen;
14708 }
14709 return FALSE;
14710}
14711
14712/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014714 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 * parameters during connect operation.
14716 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014717int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014719 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014720{
14721 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014722 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014723 ENTER();
14724
14725 /*set wpa version*/
14726 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14727
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014728 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014729 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014730 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014731 {
14732 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14733 }
14734 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14735 {
14736 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14737 }
14738 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014739
14740 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 pWextState->wpaVersion);
14742
14743 /*set authentication type*/
14744 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14745
14746 if (0 > status)
14747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014748 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014749 "%s: failed to set authentication type ", __func__);
14750 return status;
14751 }
14752
14753 /*set key mgmt type*/
14754 if (req->crypto.n_akm_suites)
14755 {
14756 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14757 if (0 > status)
14758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014760 __func__);
14761 return status;
14762 }
14763 }
14764
14765 /*set pairwise cipher type*/
14766 if (req->crypto.n_ciphers_pairwise)
14767 {
14768 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14769 req->crypto.ciphers_pairwise[0], true);
14770 if (0 > status)
14771 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014772 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014773 "%s: failed to set unicast cipher type", __func__);
14774 return status;
14775 }
14776 }
14777 else
14778 {
14779 /*Reset previous cipher suite to none*/
14780 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14781 if (0 > status)
14782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014783 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014784 "%s: failed to set unicast cipher type", __func__);
14785 return status;
14786 }
14787 }
14788
14789 /*set group cipher type*/
14790 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14791 false);
14792
14793 if (0 > status)
14794 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014796 __func__);
14797 return status;
14798 }
14799
Chet Lanctot186b5732013-03-18 10:26:30 -070014800#ifdef WLAN_FEATURE_11W
14801 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14802#endif
14803
Jeff Johnson295189b2012-06-20 16:38:30 -070014804 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14805 if (req->ie_len)
14806 {
14807 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14808 if ( 0 > status)
14809 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014811 __func__);
14812 return status;
14813 }
14814 }
14815
14816 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014817 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014818 {
14819 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14820 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14821 )
14822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014823 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014824 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014827 __func__);
14828 return -EOPNOTSUPP;
14829 }
14830 else
14831 {
14832 u8 key_len = req->key_len;
14833 u8 key_idx = req->key_idx;
14834
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 && (CSR_MAX_NUM_KEY > key_idx)
14837 )
14838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014839 hddLog(VOS_TRACE_LEVEL_INFO,
14840 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014841 __func__, key_idx, key_len);
14842 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014843 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014845 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 (u8)key_len;
14847 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14848 }
14849 }
14850 }
14851 }
14852
14853 return status;
14854}
14855
14856/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014857 * FUNCTION: wlan_hdd_try_disconnect
14858 * This function is used to disconnect from previous
14859 * connection
14860 */
14861static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14862{
14863 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014864 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014865 hdd_station_ctx_t *pHddStaCtx;
14866 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014867 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014868
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014869 ret = wlan_hdd_validate_context(pHddCtx);
14870 if (0 != ret)
14871 {
14872 return ret;
14873 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14875
14876 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14877
14878 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14879 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014880 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014881 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14882 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014883 spin_lock_bh(&pAdapter->lock_for_active_session);
14884 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14885 {
14886 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14887 }
14888 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014889 hdd_connSetConnectionState(pHddStaCtx,
14890 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014891 /* Issue disconnect to CSR */
14892 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014893 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014894 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014895 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14896 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14897 hddLog(LOG1,
14898 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14899 } else if ( 0 != status ) {
14900 hddLog(LOGE,
14901 FL("csrRoamDisconnect failure, returned %d"),
14902 (int)status );
14903 result = -EINVAL;
14904 goto disconnected;
14905 }
14906 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014907 &pAdapter->disconnect_comp_var,
14908 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014909 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14910 hddLog(LOGE,
14911 "%s: Failed to disconnect, timed out", __func__);
14912 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014913 }
14914 }
14915 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14916 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014917 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014918 &pAdapter->disconnect_comp_var,
14919 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014920 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014921 {
14922 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014923 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014924 }
14925 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014926disconnected:
14927 hddLog(LOG1,
14928 FL("Set HDD connState to eConnectionState_NotConnected"));
14929 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14930 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014931}
14932
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014933/**
14934 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14935 * @adapter: Pointer to the HDD adapter
14936 * @req: Pointer to the structure cfg_connect_params receieved from user space
14937 *
14938 * This function will start reassociation if bssid hint, channel hint and
14939 * previous bssid parameters are present in the connect request
14940 *
14941 * Return: success if reassociation is happening
14942 * Error code if reassociation is not permitted or not happening
14943 */
14944#ifdef CFG80211_CONNECT_PREV_BSSID
14945static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14946 struct cfg80211_connect_params *req)
14947{
14948 int status = -EPERM;
14949 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14950 hddLog(VOS_TRACE_LEVEL_INFO,
14951 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14952 req->channel_hint->hw_value,
14953 MAC_ADDR_ARRAY(req->bssid_hint));
14954 status = hdd_reassoc(adapter, req->bssid_hint,
14955 req->channel_hint->hw_value,
14956 CONNECT_CMD_USERSPACE);
14957 }
14958 return status;
14959}
14960#else
14961static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14962 struct cfg80211_connect_params *req)
14963{
14964 return -EPERM;
14965}
14966#endif
14967
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014968/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014969 * FUNCTION: __wlan_hdd_cfg80211_connect
14970 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014972static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 struct net_device *ndev,
14974 struct cfg80211_connect_params *req
14975 )
14976{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014977 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014978 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14980 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014981 const u8 *bssid_hint = req->bssid_hint;
14982#else
14983 const u8 *bssid_hint = NULL;
14984#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014987 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014988
14989 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014990
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014991 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14992 TRACE_CODE_HDD_CFG80211_CONNECT,
14993 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014994 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014995 "%s: device_mode = %s (%d)", __func__,
14996 hdd_device_modetoString(pAdapter->device_mode),
14997 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014998
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015000 if (!pHddCtx)
15001 {
15002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15003 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015004 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015005 }
15006
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015007 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015008 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015010 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015011 }
15012
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015013 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15014 if (0 == status)
15015 return status;
15016
Agarwal Ashish51325b52014-06-16 16:50:49 +053015017
Jeff Johnson295189b2012-06-20 16:38:30 -070015018#ifdef WLAN_BTAMP_FEATURE
15019 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015020 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015022 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015024 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015025 }
15026#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015027
15028 //If Device Mode is Station Concurrent Sessions Exit BMps
15029 //P2P Mode will be taken care in Open/close adapter
15030 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015031 (vos_concurrent_open_sessions_running())) {
15032 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15033 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015034 }
15035
15036 /*Try disconnecting if already in connected state*/
15037 status = wlan_hdd_try_disconnect(pAdapter);
15038 if ( 0 > status)
15039 {
15040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15041 " connection"));
15042 return -EALREADY;
15043 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015044 /* Check for max concurrent connections after doing disconnect if any*/
15045 if (vos_max_concurrent_connections_reached()) {
15046 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15047 return -ECONNREFUSED;
15048 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015049
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015051 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015052
15053 if ( 0 > status)
15054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015056 __func__);
15057 return status;
15058 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015059
15060 if (pHddCtx->spoofMacAddr.isEnabled)
15061 {
15062 hddLog(VOS_TRACE_LEVEL_INFO,
15063 "%s: MAC Spoofing enabled ", __func__);
15064 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15065 * to fill TxBds for probe request during SSID scan which may happen
15066 * as part of connect command
15067 */
15068 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15069 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15070 if (status != VOS_STATUS_SUCCESS)
15071 return -ECONNREFUSED;
15072 }
15073
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015074 if (req->channel)
15075 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015076 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015077 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015078
15079 /* Abort if any scan is going on */
15080 status = wlan_hdd_scan_abort(pAdapter);
15081 if (0 != status)
15082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15083
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015084 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15085 req->ssid_len, req->bssid,
15086 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015087
Sushant Kaushikd7083982015-03-18 14:33:24 +053015088 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015089 {
15090 //ReEnable BMPS if disabled
15091 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15092 (NULL != pHddCtx))
15093 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015094 if (pHddCtx->hdd_wlan_suspended)
15095 {
15096 hdd_set_pwrparams(pHddCtx);
15097 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015098 //ReEnable Bmps and Imps back
15099 hdd_enable_bmps_imps(pHddCtx);
15100 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015102 return status;
15103 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015104 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 EXIT();
15106 return status;
15107}
15108
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015109static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15110 struct net_device *ndev,
15111 struct cfg80211_connect_params *req)
15112{
15113 int ret;
15114 vos_ssr_protect(__func__);
15115 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15116 vos_ssr_unprotect(__func__);
15117
15118 return ret;
15119}
Jeff Johnson295189b2012-06-20 16:38:30 -070015120
15121/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015122 * FUNCTION: wlan_hdd_disconnect
15123 * This function is used to issue a disconnect request to SME
15124 */
15125int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15126{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015127 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015128 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015129 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015130 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015131 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015132
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015133 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015135 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015136 if (0 != status)
15137 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015138 return status;
15139 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015140 /* Indicate sme of disconnect so that in progress connection or preauth
15141 * can be aborted
15142 */
15143 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015144 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015145 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015146
Agarwal Ashish47d18112014-08-04 19:55:07 +053015147 /* Need to apply spin lock before decreasing active sessions
15148 * as there can be chance for double decrement if context switch
15149 * Calls hdd_DisConnectHandler.
15150 */
15151
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015152 prev_conn_state = pHddStaCtx->conn_info.connState;
15153
Agarwal Ashish47d18112014-08-04 19:55:07 +053015154 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015155 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15156 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015157 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15158 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015159 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15160 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015161
Abhishek Singhf4669da2014-05-26 15:07:49 +053015162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015163 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15164
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015165 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015166
Mihir Shete182a0b22014-08-18 16:08:48 +053015167 /*
15168 * stop tx queues before deleting STA/BSS context from the firmware.
15169 * tx has to be disabled because the firmware can get busy dropping
15170 * the tx frames after BSS/STA has been deleted and will not send
15171 * back a response resulting in WDI timeout
15172 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015174 netif_tx_disable(pAdapter->dev);
15175 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015176
Mihir Shete182a0b22014-08-18 16:08:48 +053015177 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015178 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15179 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015180 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15181 prev_conn_state != eConnectionState_Connecting)
15182 {
15183 hddLog(LOG1,
15184 FL("status = %d, already disconnected"), status);
15185 result = 0;
15186 goto disconnected;
15187 }
15188 /*
15189 * Wait here instead of returning directly, this will block the next
15190 * connect command and allow processing of the scan for ssid and
15191 * the previous connect command in CSR. Else we might hit some
15192 * race conditions leading to SME and HDD out of sync.
15193 */
15194 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015195 {
15196 hddLog(LOG1,
15197 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015198 }
15199 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015200 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015201 hddLog(LOGE,
15202 FL("csrRoamDisconnect failure, returned %d"),
15203 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015204 result = -EINVAL;
15205 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015206 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015207 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015208 &pAdapter->disconnect_comp_var,
15209 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015210 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015211 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015212 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015213 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015214 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015215 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015216disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015217 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015218 FL("Set HDD connState to eConnectionState_NotConnected"));
15219 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015220#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15221 /* Sending disconnect event to userspace for kernel version < 3.11
15222 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15223 */
15224 hddLog(LOG1, FL("Send disconnected event to userspace"));
15225
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015226 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015227 WLAN_REASON_UNSPECIFIED);
15228#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015230 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015231 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015232}
15233
15234
15235/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015236 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015237 * This function is used to issue a disconnect request to SME
15238 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015239static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015240 struct net_device *dev,
15241 u16 reason
15242 )
15243{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015244 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015245 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015246 tCsrRoamProfile *pRoamProfile;
15247 hdd_station_ctx_t *pHddStaCtx;
15248 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015249#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015250 tANI_U8 staIdx;
15251#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015252
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015254
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015255 if (!pAdapter) {
15256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15257 return -EINVAL;
15258 }
15259
15260 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15261 if (!pHddStaCtx) {
15262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15263 return -EINVAL;
15264 }
15265
15266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15267 status = wlan_hdd_validate_context(pHddCtx);
15268 if (0 != status)
15269 {
15270 return status;
15271 }
15272
15273 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15274
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15276 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15277 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15279 __func__, hdd_device_modetoString(pAdapter->device_mode),
15280 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015281
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15283 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015284
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 if (NULL != pRoamProfile)
15286 {
15287 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015288 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15289 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015291 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015293 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 switch(reason)
15295 {
15296 case WLAN_REASON_MIC_FAILURE:
15297 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15298 break;
15299
15300 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15301 case WLAN_REASON_DISASSOC_AP_BUSY:
15302 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15303 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15304 break;
15305
15306 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15307 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015308 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15310 break;
15311
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 default:
15313 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15314 break;
15315 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015316 pScanInfo = &pHddCtx->scan_info;
15317 if (pScanInfo->mScanPending)
15318 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015319 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015320 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015321 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015322 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015323 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015324 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015325#ifdef FEATURE_WLAN_TDLS
15326 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015327 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015328 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015329 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15330 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015331 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015332 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015333 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015335 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015336 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015337 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015338 status = sme_DeleteTdlsPeerSta(
15339 WLAN_HDD_GET_HAL_CTX(pAdapter),
15340 pAdapter->sessionId,
15341 mac);
15342 if (status != eHAL_STATUS_SUCCESS) {
15343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15344 return -EPERM;
15345 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015346 }
15347 }
15348#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015349
15350 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15351 reasonCode,
15352 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015353 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15354 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015355 {
15356 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015357 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 __func__, (int)status );
15359 return -EINVAL;
15360 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015362 else
15363 {
15364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15365 "called while in %d state", __func__,
15366 pHddStaCtx->conn_info.connState);
15367 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015368 }
15369 else
15370 {
15371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15372 }
15373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015374 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015375 return status;
15376}
15377
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015378static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15379 struct net_device *dev,
15380 u16 reason
15381 )
15382{
15383 int ret;
15384 vos_ssr_protect(__func__);
15385 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15386 vos_ssr_unprotect(__func__);
15387
15388 return ret;
15389}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015390
Jeff Johnson295189b2012-06-20 16:38:30 -070015391/*
15392 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015393 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 * settings in IBSS mode.
15395 */
15396static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015397 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 struct cfg80211_ibss_params *params
15399 )
15400{
15401 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015402 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015403 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15404 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015405
Jeff Johnson295189b2012-06-20 16:38:30 -070015406 ENTER();
15407
15408 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015409 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015410
15411 if (params->ie_len && ( NULL != params->ie) )
15412 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015413 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15414 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 {
15416 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15417 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15418 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015419 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015420 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015421 tDot11fIEWPA dot11WPAIE;
15422 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015423 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015424
Wilson Yang00256342013-10-10 23:13:38 -070015425 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015426 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15427 params->ie_len, DOT11F_EID_WPA);
15428 if ( NULL != ie )
15429 {
15430 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15431 // Unpack the WPA IE
15432 //Skip past the EID byte and length byte - and four byte WiFi OUI
15433 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15434 &ie[2+4],
15435 ie[1] - 4,
15436 &dot11WPAIE);
15437 /*Extract the multicast cipher, the encType for unicast
15438 cipher for wpa-none is none*/
15439 encryptionType =
15440 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15441 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015443
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15445
15446 if (0 > status)
15447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 __func__);
15450 return status;
15451 }
15452 }
15453
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 pWextState->roamProfile.AuthType.authType[0] =
15455 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15457
15458 if (params->privacy)
15459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460 /* Security enabled IBSS, At this time there is no information available
15461 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015463 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015464 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015465 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 *enable privacy bit in beacons */
15467
15468 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15469 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015470 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15471 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15473 pWextState->roamProfile.EncryptionType.numEntries = 1;
15474 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 return status;
15476}
15477
15478/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015479 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015482static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015483 struct net_device *dev,
15484 struct cfg80211_ibss_params *params
15485 )
15486{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015488 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15489 tCsrRoamProfile *pRoamProfile;
15490 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015491 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15492 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015493 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015494
15495 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015496
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015497 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15498 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15499 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015500 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015501 "%s: device_mode = %s (%d)", __func__,
15502 hdd_device_modetoString(pAdapter->device_mode),
15503 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015504
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015505 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015506 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015508 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 }
15510
15511 if (NULL == pWextState)
15512 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015513 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015514 __func__);
15515 return -EIO;
15516 }
15517
Agarwal Ashish51325b52014-06-16 16:50:49 +053015518 if (vos_max_concurrent_connections_reached()) {
15519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15520 return -ECONNREFUSED;
15521 }
15522
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015523 /*Try disconnecting if already in connected state*/
15524 status = wlan_hdd_try_disconnect(pAdapter);
15525 if ( 0 > status)
15526 {
15527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15528 " IBSS connection"));
15529 return -EALREADY;
15530 }
15531
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 pRoamProfile = &pWextState->roamProfile;
15533
15534 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015536 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015537 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015538 return -EINVAL;
15539 }
15540
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015541 /* BSSID is provided by upper layers hence no need to AUTO generate */
15542 if (NULL != params->bssid) {
15543 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15544 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15545 hddLog (VOS_TRACE_LEVEL_ERROR,
15546 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15547 return -EIO;
15548 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015549 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015550 }
krunal sonie9002db2013-11-25 14:24:17 -080015551 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15552 {
15553 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15554 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15555 {
15556 hddLog (VOS_TRACE_LEVEL_ERROR,
15557 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15558 return -EIO;
15559 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015560
15561 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015562 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015563 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015564 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015565
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015567 if (NULL !=
15568#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15569 params->chandef.chan)
15570#else
15571 params->channel)
15572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 {
15574 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015575 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15576 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15577 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15578 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015579
15580 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015581 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015582 ieee80211_frequency_to_channel(
15583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15584 params->chandef.chan->center_freq);
15585#else
15586 params->channel->center_freq);
15587#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015588
15589 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15590 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015591 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15593 __func__);
15594 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015595 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015596
15597 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015598 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015599 if (channelNum == validChan[indx])
15600 {
15601 break;
15602 }
15603 }
15604 if (indx >= numChans)
15605 {
15606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015607 __func__, channelNum);
15608 return -EINVAL;
15609 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015610 /* Set the Operational Channel */
15611 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15612 channelNum);
15613 pRoamProfile->ChannelInfo.numOfChannels = 1;
15614 pHddStaCtx->conn_info.operationChannel = channelNum;
15615 pRoamProfile->ChannelInfo.ChannelList =
15616 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015617 }
15618
15619 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015620 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015621 if (status < 0)
15622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 __func__);
15625 return status;
15626 }
15627
15628 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015629 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015630 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015631 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015632
15633 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015636 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015637 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015638}
15639
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015640static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15641 struct net_device *dev,
15642 struct cfg80211_ibss_params *params
15643 )
15644{
15645 int ret = 0;
15646
15647 vos_ssr_protect(__func__);
15648 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15649 vos_ssr_unprotect(__func__);
15650
15651 return ret;
15652}
15653
Jeff Johnson295189b2012-06-20 16:38:30 -070015654/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015655 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015656 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015657 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015658static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 struct net_device *dev
15660 )
15661{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015663 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15664 tCsrRoamProfile *pRoamProfile;
15665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015666 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015667 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015668#ifdef WLAN_FEATURE_RMC
15669 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15670#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015671
15672 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15675 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15676 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015677 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015678 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015679 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015680 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015681 }
15682
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15684 hdd_device_modetoString(pAdapter->device_mode),
15685 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015686 if (NULL == pWextState)
15687 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015688 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015689 __func__);
15690 return -EIO;
15691 }
15692
15693 pRoamProfile = &pWextState->roamProfile;
15694
15695 /* Issue disconnect only if interface type is set to IBSS */
15696 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015698 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 __func__);
15700 return -EINVAL;
15701 }
15702
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015703#ifdef WLAN_FEATURE_RMC
15704 /* Clearing add IE of beacon */
15705 if (ccmCfgSetStr(pHddCtx->hHal,
15706 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15707 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15708 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15709 {
15710 hddLog (VOS_TRACE_LEVEL_ERROR,
15711 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15712 return -EINVAL;
15713 }
15714 if (ccmCfgSetInt(pHddCtx->hHal,
15715 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15716 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15717 {
15718 hddLog (VOS_TRACE_LEVEL_ERROR,
15719 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15720 __func__);
15721 return -EINVAL;
15722 }
15723
15724 // Reset WNI_CFG_PROBE_RSP Flags
15725 wlan_hdd_reset_prob_rspies(pAdapter);
15726
15727 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15728 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15729 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15730 {
15731 hddLog (VOS_TRACE_LEVEL_ERROR,
15732 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15733 __func__);
15734 return -EINVAL;
15735 }
15736#endif
15737
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 /* Issue Disconnect request */
15739 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015740 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15741 pAdapter->sessionId,
15742 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15743 if (!HAL_STATUS_SUCCESS(hal_status)) {
15744 hddLog(LOGE,
15745 FL("sme_RoamDisconnect failed hal_status(%d)"),
15746 hal_status);
15747 return -EAGAIN;
15748 }
15749 status = wait_for_completion_timeout(
15750 &pAdapter->disconnect_comp_var,
15751 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15752 if (!status) {
15753 hddLog(LOGE,
15754 FL("wait on disconnect_comp_var failed"));
15755 return -ETIMEDOUT;
15756 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015757
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015758 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015759 return 0;
15760}
15761
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015762static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15763 struct net_device *dev
15764 )
15765{
15766 int ret = 0;
15767
15768 vos_ssr_protect(__func__);
15769 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15770 vos_ssr_unprotect(__func__);
15771
15772 return ret;
15773}
15774
Jeff Johnson295189b2012-06-20 16:38:30 -070015775/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015776 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015777 * This function is used to set the phy parameters
15778 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15779 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015780static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015781 u32 changed)
15782{
15783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15784 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015785 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015786
15787 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015788
15789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015790 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15791 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015792
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015794 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015796 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015797 }
15798
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15800 {
15801 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15802 WNI_CFG_RTS_THRESHOLD_STAMAX :
15803 wiphy->rts_threshold;
15804
15805 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015806 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015808 hddLog(VOS_TRACE_LEVEL_ERROR,
15809 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 __func__, rts_threshold);
15811 return -EINVAL;
15812 }
15813
15814 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15815 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015818 hddLog(VOS_TRACE_LEVEL_ERROR,
15819 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015820 __func__, rts_threshold);
15821 return -EIO;
15822 }
15823
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015824 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015825 rts_threshold);
15826 }
15827
15828 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15829 {
15830 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15831 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15832 wiphy->frag_threshold;
15833
15834 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015835 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015836 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015837 hddLog(VOS_TRACE_LEVEL_ERROR,
15838 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015839 frag_threshold);
15840 return -EINVAL;
15841 }
15842
15843 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15844 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015845 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847 hddLog(VOS_TRACE_LEVEL_ERROR,
15848 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015849 __func__, frag_threshold);
15850 return -EIO;
15851 }
15852
15853 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15854 frag_threshold);
15855 }
15856
15857 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15858 || (changed & WIPHY_PARAM_RETRY_LONG))
15859 {
15860 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15861 wiphy->retry_short :
15862 wiphy->retry_long;
15863
15864 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15865 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 __func__, retry_value);
15869 return -EINVAL;
15870 }
15871
15872 if (changed & WIPHY_PARAM_RETRY_SHORT)
15873 {
15874 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15875 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015876 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015878 hddLog(VOS_TRACE_LEVEL_ERROR,
15879 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 __func__, retry_value);
15881 return -EIO;
15882 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015883 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015884 __func__, retry_value);
15885 }
15886 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15887 {
15888 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15889 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015890 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015892 hddLog(VOS_TRACE_LEVEL_ERROR,
15893 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015894 __func__, retry_value);
15895 return -EIO;
15896 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015897 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 __func__, retry_value);
15899 }
15900 }
15901
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015902 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 return 0;
15904}
15905
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015906static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15907 u32 changed)
15908{
15909 int ret;
15910
15911 vos_ssr_protect(__func__);
15912 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15913 vos_ssr_unprotect(__func__);
15914
15915 return ret;
15916}
15917
Jeff Johnson295189b2012-06-20 16:38:30 -070015918/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015919 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015920 * This function is used to set the txpower
15921 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015922static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015923#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15924 struct wireless_dev *wdev,
15925#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015926#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015927 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015928#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015929 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015930#endif
15931 int dbm)
15932{
15933 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015934 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015935 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15936 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015937 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015938
15939 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015940
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015941 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15942 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15943 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015944 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015945 if (0 != status)
15946 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015947 return status;
15948 }
15949
15950 hHal = pHddCtx->hHal;
15951
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015952 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15953 dbm, ccmCfgSetCallback,
15954 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015956 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015957 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15958 return -EIO;
15959 }
15960
15961 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15962 dbm);
15963
15964 switch(type)
15965 {
15966 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15967 /* Fall through */
15968 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15969 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15972 __func__);
15973 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015974 }
15975 break;
15976 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015978 __func__);
15979 return -EOPNOTSUPP;
15980 break;
15981 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15983 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 return -EIO;
15985 }
15986
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015987 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 return 0;
15989}
15990
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015991static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15992#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15993 struct wireless_dev *wdev,
15994#endif
15995#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15996 enum tx_power_setting type,
15997#else
15998 enum nl80211_tx_power_setting type,
15999#endif
16000 int dbm)
16001{
16002 int ret;
16003 vos_ssr_protect(__func__);
16004 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16005#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16006 wdev,
16007#endif
16008#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16009 type,
16010#else
16011 type,
16012#endif
16013 dbm);
16014 vos_ssr_unprotect(__func__);
16015
16016 return ret;
16017}
16018
Jeff Johnson295189b2012-06-20 16:38:30 -070016019/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016020 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 * This function is used to read the txpower
16022 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016023static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016024#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16025 struct wireless_dev *wdev,
16026#endif
16027 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016028{
16029
16030 hdd_adapter_t *pAdapter;
16031 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016032 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016033
Jeff Johnsone7245742012-09-05 17:12:55 -070016034 ENTER();
16035
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016037 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016039 *dbm = 0;
16040 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016041 }
16042
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16044 if (NULL == pAdapter)
16045 {
16046 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16047 return -ENOENT;
16048 }
16049
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16051 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16052 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016053 wlan_hdd_get_classAstats(pAdapter);
16054 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16055
Jeff Johnsone7245742012-09-05 17:12:55 -070016056 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016057 return 0;
16058}
16059
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016060static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16061#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16062 struct wireless_dev *wdev,
16063#endif
16064 int *dbm)
16065{
16066 int ret;
16067
16068 vos_ssr_protect(__func__);
16069 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16070#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16071 wdev,
16072#endif
16073 dbm);
16074 vos_ssr_unprotect(__func__);
16075
16076 return ret;
16077}
16078
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016079static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016080#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16081 const u8* mac,
16082#else
16083 u8* mac,
16084#endif
16085 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016086{
16087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16088 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16089 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016090 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016091
16092 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16093 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016094
16095 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16096 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16097 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16098 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16099 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16100 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16101 tANI_U16 maxRate = 0;
16102 tANI_U16 myRate;
16103 tANI_U16 currentRate = 0;
16104 tANI_U8 maxSpeedMCS = 0;
16105 tANI_U8 maxMCSIdx = 0;
16106 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016107 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016108 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016109 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016110
Leo Chang6f8870f2013-03-26 18:11:36 -070016111#ifdef WLAN_FEATURE_11AC
16112 tANI_U32 vht_mcs_map;
16113 eDataRate11ACMaxMcs vhtMaxMcs;
16114#endif /* WLAN_FEATURE_11AC */
16115
Jeff Johnsone7245742012-09-05 17:12:55 -070016116 ENTER();
16117
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16119 (0 == ssidlen))
16120 {
16121 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16122 " Invalid ssidlen, %d", __func__, ssidlen);
16123 /*To keep GUI happy*/
16124 return 0;
16125 }
16126
Mukul Sharma811205f2014-07-09 21:07:30 +053016127 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16128 {
16129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16130 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016131 /* return a cached value */
16132 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016133 return 0;
16134 }
16135
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016136 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016137 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016138 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016139 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016140 }
16141
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016142 wlan_hdd_get_station_stats(pAdapter);
16143 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016144
Kiet Lam3b17fc82013-09-27 05:24:08 +053016145 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16146 sinfo->filled |= STATION_INFO_SIGNAL;
16147
c_hpothu09f19542014-05-30 21:53:31 +053016148 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016149 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16150 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016151 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016152 {
16153 rate_flags = pAdapter->maxRateFlags;
16154 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016155
Jeff Johnson295189b2012-06-20 16:38:30 -070016156 //convert to the UI units of 100kbps
16157 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16158
16159#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016160 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 -070016161 sinfo->signal,
16162 pCfg->reportMaxLinkSpeed,
16163 myRate,
16164 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016165 (int) pCfg->linkSpeedRssiMid,
16166 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016167 (int) rate_flags,
16168 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016169#endif //LINKSPEED_DEBUG_ENABLED
16170
16171 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16172 {
16173 // we do not want to necessarily report the current speed
16174 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16175 {
16176 // report the max possible speed
16177 rssidx = 0;
16178 }
16179 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16180 {
16181 // report the max possible speed with RSSI scaling
16182 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16183 {
16184 // report the max possible speed
16185 rssidx = 0;
16186 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016187 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 {
16189 // report middle speed
16190 rssidx = 1;
16191 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016192 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16193 {
16194 // report middle speed
16195 rssidx = 2;
16196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016197 else
16198 {
16199 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016200 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 }
16202 }
16203 else
16204 {
16205 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16206 hddLog(VOS_TRACE_LEVEL_ERROR,
16207 "%s: Invalid value for reportMaxLinkSpeed: %u",
16208 __func__, pCfg->reportMaxLinkSpeed);
16209 rssidx = 0;
16210 }
16211
16212 maxRate = 0;
16213
16214 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016215 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16216 OperationalRates, &ORLeng))
16217 {
16218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16219 /*To keep GUI happy*/
16220 return 0;
16221 }
16222
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 for (i = 0; i < ORLeng; i++)
16224 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016225 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016226 {
16227 /* Validate Rate Set */
16228 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16229 {
16230 currentRate = supported_data_rate[j].supported_rate[rssidx];
16231 break;
16232 }
16233 }
16234 /* Update MAX rate */
16235 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16236 }
16237
16238 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016239 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16240 ExtendedRates, &ERLeng))
16241 {
16242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16243 /*To keep GUI happy*/
16244 return 0;
16245 }
16246
Jeff Johnson295189b2012-06-20 16:38:30 -070016247 for (i = 0; i < ERLeng; i++)
16248 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016249 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 {
16251 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16252 {
16253 currentRate = supported_data_rate[j].supported_rate[rssidx];
16254 break;
16255 }
16256 }
16257 /* Update MAX rate */
16258 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16259 }
c_hpothu79aab322014-07-14 21:11:01 +053016260
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016261 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016262 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016263 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016264 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016265 {
c_hpothu79aab322014-07-14 21:11:01 +053016266 if (rate_flags & eHAL_TX_RATE_VHT80)
16267 mode = 2;
16268 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16269 mode = 1;
16270 else
16271 mode = 0;
16272
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016273 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16274 MCSRates, &MCSLeng))
16275 {
16276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16277 /*To keep GUI happy*/
16278 return 0;
16279 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016281#ifdef WLAN_FEATURE_11AC
16282 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016283 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016284 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016285 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016286 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016287 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016288 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016289 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016290 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016291 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016293 maxMCSIdx = 7;
16294 }
16295 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16296 {
16297 maxMCSIdx = 8;
16298 }
16299 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16300 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016301 //VHT20 is supporting 0~8
16302 if (rate_flags & eHAL_TX_RATE_VHT20)
16303 maxMCSIdx = 8;
16304 else
16305 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016306 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016307
c_hpothu79aab322014-07-14 21:11:01 +053016308 if (0 != rssidx)/*check for scaled */
16309 {
16310 //get middle rate MCS index if rssi=1/2
16311 for (i=0; i <= maxMCSIdx; i++)
16312 {
16313 if (sinfo->signal <= rssiMcsTbl[mode][i])
16314 {
16315 maxMCSIdx = i;
16316 break;
16317 }
16318 }
16319 }
16320
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016321 if (rate_flags & eHAL_TX_RATE_VHT80)
16322 {
16323 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16324 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16325 }
16326 else if (rate_flags & eHAL_TX_RATE_VHT40)
16327 {
16328 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16329 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16330 }
16331 else if (rate_flags & eHAL_TX_RATE_VHT20)
16332 {
16333 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16334 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16335 }
16336
Leo Chang6f8870f2013-03-26 18:11:36 -070016337 maxSpeedMCS = 1;
16338 if (currentRate > maxRate)
16339 {
16340 maxRate = currentRate;
16341 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016342
Leo Chang6f8870f2013-03-26 18:11:36 -070016343 }
16344 else
16345#endif /* WLAN_FEATURE_11AC */
16346 {
16347 if (rate_flags & eHAL_TX_RATE_HT40)
16348 {
16349 rateFlag |= 1;
16350 }
16351 if (rate_flags & eHAL_TX_RATE_SGI)
16352 {
16353 rateFlag |= 2;
16354 }
16355
Girish Gowli01abcee2014-07-31 20:18:55 +053016356 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016357 if (rssidx == 1 || rssidx == 2)
16358 {
16359 //get middle rate MCS index if rssi=1/2
16360 for (i=0; i <= 7; i++)
16361 {
16362 if (sinfo->signal <= rssiMcsTbl[mode][i])
16363 {
16364 temp = i+1;
16365 break;
16366 }
16367 }
16368 }
c_hpothu79aab322014-07-14 21:11:01 +053016369
16370 for (i = 0; i < MCSLeng; i++)
16371 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016372 for (j = 0; j < temp; j++)
16373 {
16374 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16375 {
16376 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016377 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016378 break;
16379 }
16380 }
16381 if ((j < temp) && (currentRate > maxRate))
16382 {
16383 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016386 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 }
16388 }
16389
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016390 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16391 {
16392 maxRate = myRate;
16393 maxSpeedMCS = 1;
16394 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016396 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016397 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016398 {
16399 maxRate = myRate;
16400 if (rate_flags & eHAL_TX_RATE_LEGACY)
16401 {
16402 maxSpeedMCS = 0;
16403 }
16404 else
16405 {
16406 maxSpeedMCS = 1;
16407 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16408 }
16409 }
16410
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016411 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016412 {
16413 sinfo->txrate.legacy = maxRate;
16414#ifdef LINKSPEED_DEBUG_ENABLED
16415 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16416#endif //LINKSPEED_DEBUG_ENABLED
16417 }
16418 else
16419 {
16420 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016421#ifdef WLAN_FEATURE_11AC
16422 sinfo->txrate.nss = 1;
16423 if (rate_flags & eHAL_TX_RATE_VHT80)
16424 {
16425 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016426 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016427 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016428 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016429 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016430 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16431 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16432 }
16433 else if (rate_flags & eHAL_TX_RATE_VHT20)
16434 {
16435 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16436 }
16437#endif /* WLAN_FEATURE_11AC */
16438 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16439 {
16440 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16441 if (rate_flags & eHAL_TX_RATE_HT40)
16442 {
16443 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16444 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016446 if (rate_flags & eHAL_TX_RATE_SGI)
16447 {
16448 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16449 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016450
Jeff Johnson295189b2012-06-20 16:38:30 -070016451#ifdef LINKSPEED_DEBUG_ENABLED
16452 pr_info("Reporting MCS rate %d flags %x\n",
16453 sinfo->txrate.mcs,
16454 sinfo->txrate.flags );
16455#endif //LINKSPEED_DEBUG_ENABLED
16456 }
16457 }
16458 else
16459 {
16460 // report current rate instead of max rate
16461
16462 if (rate_flags & eHAL_TX_RATE_LEGACY)
16463 {
16464 //provide to the UI in units of 100kbps
16465 sinfo->txrate.legacy = myRate;
16466#ifdef LINKSPEED_DEBUG_ENABLED
16467 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16468#endif //LINKSPEED_DEBUG_ENABLED
16469 }
16470 else
16471 {
16472 //must be MCS
16473 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016474#ifdef WLAN_FEATURE_11AC
16475 sinfo->txrate.nss = 1;
16476 if (rate_flags & eHAL_TX_RATE_VHT80)
16477 {
16478 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16479 }
16480 else
16481#endif /* WLAN_FEATURE_11AC */
16482 {
16483 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016485 if (rate_flags & eHAL_TX_RATE_SGI)
16486 {
16487 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16488 }
16489 if (rate_flags & eHAL_TX_RATE_HT40)
16490 {
16491 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16492 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016493#ifdef WLAN_FEATURE_11AC
16494 else if (rate_flags & eHAL_TX_RATE_VHT80)
16495 {
16496 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16497 }
16498#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016499#ifdef LINKSPEED_DEBUG_ENABLED
16500 pr_info("Reporting actual MCS rate %d flags %x\n",
16501 sinfo->txrate.mcs,
16502 sinfo->txrate.flags );
16503#endif //LINKSPEED_DEBUG_ENABLED
16504 }
16505 }
16506 sinfo->filled |= STATION_INFO_TX_BITRATE;
16507
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016508 sinfo->tx_packets =
16509 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16510 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16511 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16512 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16513
16514 sinfo->tx_retries =
16515 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16516 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16517 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16518 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16519
16520 sinfo->tx_failed =
16521 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16522 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16523 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16524 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16525
16526 sinfo->filled |=
16527 STATION_INFO_TX_PACKETS |
16528 STATION_INFO_TX_RETRIES |
16529 STATION_INFO_TX_FAILED;
16530
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016531 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16532 sinfo->filled |= STATION_INFO_RX_PACKETS;
16533
16534 if (rate_flags & eHAL_TX_RATE_LEGACY)
16535 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16536 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16537 sinfo->rx_packets);
16538 else
16539 hddLog(LOG1,
16540 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16541 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16542 sinfo->tx_packets, sinfo->rx_packets);
16543
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016544 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16545 TRACE_CODE_HDD_CFG80211_GET_STA,
16546 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016547 EXIT();
16548 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016549}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16551static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16552 const u8* mac, struct station_info *sinfo)
16553#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016554static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16555 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016556#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016557{
16558 int ret;
16559
16560 vos_ssr_protect(__func__);
16561 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16562 vos_ssr_unprotect(__func__);
16563
16564 return ret;
16565}
16566
16567static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016568 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016569{
16570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016571 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016572 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016573 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016574
Jeff Johnsone7245742012-09-05 17:12:55 -070016575 ENTER();
16576
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 if (NULL == pAdapter)
16578 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 return -ENODEV;
16581 }
16582
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016583 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16584 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16585 pAdapter->sessionId, timeout));
16586
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016587 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016588 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016589 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016590 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016591 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016592 }
16593
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016594 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16595 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16596 (pHddCtx->cfg_ini->fhostArpOffload) &&
16597 (eConnectionState_Associated ==
16598 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16599 {
Amar Singhald53568e2013-09-26 11:03:45 -070016600
16601 hddLog(VOS_TRACE_LEVEL_INFO,
16602 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016603 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016604 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16605 {
16606 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016607 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016608 __func__, vos_status);
16609 }
16610 }
16611
Jeff Johnson295189b2012-06-20 16:38:30 -070016612 /**The get power cmd from the supplicant gets updated by the nl only
16613 *on successful execution of the function call
16614 *we are oppositely mapped w.r.t mode in the driver
16615 **/
16616 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16617
16618 if (VOS_STATUS_E_FAILURE == vos_status)
16619 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16621 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016622 return -EINVAL;
16623 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016624 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016625 return 0;
16626}
16627
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016628static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16629 struct net_device *dev, bool mode, int timeout)
16630{
16631 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016632
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016633 vos_ssr_protect(__func__);
16634 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16635 vos_ssr_unprotect(__func__);
16636
16637 return ret;
16638}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016639
Jeff Johnson295189b2012-06-20 16:38:30 -070016640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016641static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16642 struct net_device *netdev,
16643 u8 key_index)
16644{
16645 ENTER();
16646 return 0;
16647}
16648
Jeff Johnson295189b2012-06-20 16:38:30 -070016649static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016650 struct net_device *netdev,
16651 u8 key_index)
16652{
16653 int ret;
16654 vos_ssr_protect(__func__);
16655 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16656 vos_ssr_unprotect(__func__);
16657 return ret;
16658}
16659#endif //LINUX_VERSION_CODE
16660
16661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16662static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16663 struct net_device *dev,
16664 struct ieee80211_txq_params *params)
16665{
16666 ENTER();
16667 return 0;
16668}
16669#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16670static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16671 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016672{
Jeff Johnsone7245742012-09-05 17:12:55 -070016673 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 return 0;
16675}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016676#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016677
16678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16679static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016680 struct net_device *dev,
16681 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016682{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016683 int ret;
16684
16685 vos_ssr_protect(__func__);
16686 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16687 vos_ssr_unprotect(__func__);
16688 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016689}
16690#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16691static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16692 struct ieee80211_txq_params *params)
16693{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016694 int ret;
16695
16696 vos_ssr_protect(__func__);
16697 ret = __wlan_hdd_set_txq_params(wiphy, params);
16698 vos_ssr_unprotect(__func__);
16699 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016700}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016701#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016702
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016703static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016704 struct net_device *dev,
16705 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016706{
16707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016708 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016709 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016710 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016711 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016712 v_CONTEXT_t pVosContext = NULL;
16713 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016714
Jeff Johnsone7245742012-09-05 17:12:55 -070016715 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016716
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016717 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016718 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016720 return -EINVAL;
16721 }
16722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16724 TRACE_CODE_HDD_CFG80211_DEL_STA,
16725 pAdapter->sessionId, pAdapter->device_mode));
16726
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16728 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016729 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016730 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016731 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016732 }
16733
Jeff Johnson295189b2012-06-20 16:38:30 -070016734 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016736 )
16737 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016738 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16739 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16740 if(pSapCtx == NULL){
16741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16742 FL("psapCtx is NULL"));
16743 return -ENOENT;
16744 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016745 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016746 {
16747 v_U16_t i;
16748 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16749 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016750 if ((pSapCtx->aStaInfo[i].isUsed) &&
16751 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016752 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016753 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016754 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016755 ETHER_ADDR_LEN);
16756
Jeff Johnson295189b2012-06-20 16:38:30 -070016757 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016758 "%s: Delete STA with MAC::"
16759 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016760 __func__,
16761 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16762 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016763 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016764 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016765 }
16766 }
16767 }
16768 else
16769 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016770
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016771 vos_status = hdd_softap_GetStaId(pAdapter,
16772 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016773 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16774 {
16775 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016776 "%s: Skip this DEL STA as this is not used::"
16777 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016778 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016779 return -ENOENT;
16780 }
16781
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016782 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016783 {
16784 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016785 "%s: Skip this DEL STA as deauth is in progress::"
16786 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016787 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016788 return -ENOENT;
16789 }
16790
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016791 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016792
Jeff Johnson295189b2012-06-20 16:38:30 -070016793 hddLog(VOS_TRACE_LEVEL_INFO,
16794 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016795 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016796 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016797 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016798
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016799 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016800 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16801 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016802 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016803 hddLog(VOS_TRACE_LEVEL_INFO,
16804 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016805 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016806 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016807 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016808 return -ENOENT;
16809 }
16810
Jeff Johnson295189b2012-06-20 16:38:30 -070016811 }
16812 }
16813
16814 EXIT();
16815
16816 return 0;
16817}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016818
16819#ifdef CFG80211_DEL_STA_V2
16820static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16821 struct net_device *dev,
16822 struct station_del_parameters *param)
16823#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16825static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16826 struct net_device *dev, const u8 *mac)
16827#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016828static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16829 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016830#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016831#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016832{
16833 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016834 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016835
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016836 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016837
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016838#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016839 if (NULL == param) {
16840 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016841 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016842 return -EINVAL;
16843 }
16844
16845 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16846 param->subtype, &delStaParams);
16847
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016848#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016849 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016850 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016851#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016852 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16853
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016854 vos_ssr_unprotect(__func__);
16855
16856 return ret;
16857}
16858
16859static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016860 struct net_device *dev,
16861#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16862 const u8 *mac,
16863#else
16864 u8 *mac,
16865#endif
16866 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016867{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016868 hdd_adapter_t *pAdapter;
16869 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016870 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016871#ifdef FEATURE_WLAN_TDLS
16872 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016873
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016874 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016875
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016876 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16877 if (NULL == pAdapter)
16878 {
16879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16880 "%s: Adapter is NULL",__func__);
16881 return -EINVAL;
16882 }
16883 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16884 status = wlan_hdd_validate_context(pHddCtx);
16885 if (0 != status)
16886 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016887 return status;
16888 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016889
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016890 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16891 TRACE_CODE_HDD_CFG80211_ADD_STA,
16892 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016893 mask = params->sta_flags_mask;
16894
16895 set = params->sta_flags_set;
16896
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016898 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16899 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016900
16901 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16902 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016903 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016904 }
16905 }
16906#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016907 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016908 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016909}
16910
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16912static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16913 struct net_device *dev, const u8 *mac,
16914 struct station_parameters *params)
16915#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016916static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16917 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016918#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016919{
16920 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016921
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016922 vos_ssr_protect(__func__);
16923 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16924 vos_ssr_unprotect(__func__);
16925
16926 return ret;
16927}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016928#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016929
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016930static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016931 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016932{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16934 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016935 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016936 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016937 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016938 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016939
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016940 ENTER();
16941
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016942 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016943 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016944 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016946 return -EINVAL;
16947 }
16948
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016949 if (!pmksa) {
16950 hddLog(LOGE, FL("pmksa is NULL"));
16951 return -EINVAL;
16952 }
16953
16954 if (!pmksa->bssid || !pmksa->pmkid) {
16955 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16956 pmksa->bssid, pmksa->pmkid);
16957 return -EINVAL;
16958 }
16959
16960 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16961 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16962
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016963 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16964 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016965 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016967 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016968 }
16969
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016970 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016971 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16972
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016973 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16974 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016975
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016976 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016977 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016978 &pmk_id, 1, FALSE);
16979
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16981 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16982 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016983
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016984 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016985 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016986}
16987
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016988static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16989 struct cfg80211_pmksa *pmksa)
16990{
16991 int ret;
16992
16993 vos_ssr_protect(__func__);
16994 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16995 vos_ssr_unprotect(__func__);
16996
16997 return ret;
16998}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016999
Wilson Yang6507c4e2013-10-01 20:11:19 -070017000
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017001static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017002 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017003{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17005 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017006 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017007 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017009 ENTER();
17010
Wilson Yang6507c4e2013-10-01 20:11:19 -070017011 /* Validate pAdapter */
17012 if (NULL == pAdapter)
17013 {
17014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17015 return -EINVAL;
17016 }
17017
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017018 if (!pmksa) {
17019 hddLog(LOGE, FL("pmksa is NULL"));
17020 return -EINVAL;
17021 }
17022
17023 if (!pmksa->bssid) {
17024 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17025 return -EINVAL;
17026 }
17027
Kiet Lam98c46a12014-10-31 15:34:57 -070017028 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17029 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17030
Wilson Yang6507c4e2013-10-01 20:11:19 -070017031 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17032 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017033 if (0 != status)
17034 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017035 return status;
17036 }
17037
17038 /*Retrieve halHandle*/
17039 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17040
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17042 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17043 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017044 /* Delete the PMKID CSR cache */
17045 if (eHAL_STATUS_SUCCESS !=
17046 sme_RoamDelPMKIDfromCache(halHandle,
17047 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17048 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17049 MAC_ADDR_ARRAY(pmksa->bssid));
17050 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017051 }
17052
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017053 EXIT();
17054 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017055}
17056
Wilson Yang6507c4e2013-10-01 20:11:19 -070017057
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017058static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17059 struct cfg80211_pmksa *pmksa)
17060{
17061 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017062
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017063 vos_ssr_protect(__func__);
17064 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17065 vos_ssr_unprotect(__func__);
17066
17067 return ret;
17068
17069}
17070
17071static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017072{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17074 tHalHandle halHandle;
17075 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017076 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017077
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017078 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017079
17080 /* Validate pAdapter */
17081 if (NULL == pAdapter)
17082 {
17083 hddLog(VOS_TRACE_LEVEL_ERROR,
17084 "%s: Invalid Adapter" ,__func__);
17085 return -EINVAL;
17086 }
17087
17088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17089 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017090 if (0 != status)
17091 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017092 return status;
17093 }
17094
17095 /*Retrieve halHandle*/
17096 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17097
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017098 /* Flush the PMKID cache in CSR */
17099 if (eHAL_STATUS_SUCCESS !=
17100 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17102 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017103 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017104 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017105 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017106}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017107
17108static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17109{
17110 int ret;
17111
17112 vos_ssr_protect(__func__);
17113 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17114 vos_ssr_unprotect(__func__);
17115
17116 return ret;
17117}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017118#endif
17119
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017120#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017121static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17122 struct net_device *dev,
17123 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017124{
17125 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17126 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017127 hdd_context_t *pHddCtx;
17128 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017129
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017130 ENTER();
17131
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017132 if (NULL == pAdapter)
17133 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017135 return -ENODEV;
17136 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017137 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17138 ret = wlan_hdd_validate_context(pHddCtx);
17139 if (0 != ret)
17140 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017141 return ret;
17142 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017143 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017144 if (NULL == pHddStaCtx)
17145 {
17146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17147 return -EINVAL;
17148 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017149
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17151 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17152 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017153 // Added for debug on reception of Re-assoc Req.
17154 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17155 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017156 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017157 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017158 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017159 }
17160
17161#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017162 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017163 ftie->ie_len);
17164#endif
17165
17166 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017167 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17168 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017169 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017170
17171 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017172 return 0;
17173}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017174
17175static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17176 struct net_device *dev,
17177 struct cfg80211_update_ft_ies_params *ftie)
17178{
17179 int ret;
17180
17181 vos_ssr_protect(__func__);
17182 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17183 vos_ssr_unprotect(__func__);
17184
17185 return ret;
17186}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017187#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017188
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017189#ifdef FEATURE_WLAN_SCAN_PNO
17190
17191void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17192 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17193{
17194 int ret;
17195 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17196 hdd_context_t *pHddCtx;
17197
Nirav Shah80830bf2013-12-31 16:35:12 +053017198 ENTER();
17199
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017200 if (NULL == pAdapter)
17201 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017203 "%s: HDD adapter is Null", __func__);
17204 return ;
17205 }
17206
17207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17208 if (NULL == pHddCtx)
17209 {
17210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17211 "%s: HDD context is Null!!!", __func__);
17212 return ;
17213 }
17214
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017215 spin_lock(&pHddCtx->schedScan_lock);
17216 if (TRUE == pHddCtx->isWiphySuspended)
17217 {
17218 pHddCtx->isSchedScanUpdatePending = TRUE;
17219 spin_unlock(&pHddCtx->schedScan_lock);
17220 hddLog(VOS_TRACE_LEVEL_INFO,
17221 "%s: Update cfg80211 scan database after it resume", __func__);
17222 return ;
17223 }
17224 spin_unlock(&pHddCtx->schedScan_lock);
17225
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017226 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17227
17228 if (0 > ret)
17229 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017230 else
17231 {
17232 /* Acquire wakelock to handle the case where APP's tries to suspend
17233 * immediatly after the driver gets connect request(i.e after pno)
17234 * from supplicant, this result in app's is suspending and not able
17235 * to process the connect request to AP */
17236 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17237 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017238 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17240 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017241}
17242
17243/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017244 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017245 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017246 */
17247static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17248{
17249 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17250 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017251 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17253 int status = 0;
17254 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17255
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017256 /* The current firmware design does not allow PNO during any
17257 * active sessions. Hence, determine the active sessions
17258 * and return a failure.
17259 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017260 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17261 {
17262 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017263 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017264
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017265 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17266 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17267 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17268 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
17269 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017270 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017271 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017272 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017273 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017274 }
17275 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17276 pAdapterNode = pNext;
17277 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017278 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017279}
17280
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017281void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17282{
17283 hdd_adapter_t *pAdapter = callbackContext;
17284 hdd_context_t *pHddCtx;
17285
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017286 ENTER();
17287
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017288 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17289 {
17290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17291 FL("Invalid adapter or adapter has invalid magic"));
17292 return;
17293 }
17294
17295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17296 if (0 != wlan_hdd_validate_context(pHddCtx))
17297 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017298 return;
17299 }
17300
c_hpothub53c45d2014-08-18 16:53:14 +053017301 if (VOS_STATUS_SUCCESS != status)
17302 {
17303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017304 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017305 pHddCtx->isPnoEnable = FALSE;
17306 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017307
17308 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17309 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017310 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017311}
17312
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17314 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17315/**
17316 * hdd_config_sched_scan_plan() - configures the sched scan plans
17317 * from the framework.
17318 * @pno_req: pointer to PNO scan request
17319 * @request: pointer to scan request from framework
17320 *
17321 * Return: None
17322 */
17323static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17324 struct cfg80211_sched_scan_request *request,
17325 hdd_context_t *hdd_ctx)
17326{
17327 v_U32_t i = 0;
17328
17329 pno_req.scanTimers.ucScanTimersCount = n_scan_plans;
17330 for (i = 0; i < request->n_scan_plans; i++)
17331 {
17332 pno_req.scanTimers.aTimerValues[i].uTimerRepeat =
17333 request->scan_plans[i]->iterations;
17334 pno_req.scanTimers.aTimerValues[i].uTimerValue =
17335 request->scan_plans[i]->interval;
17336 }
17337}
17338#else
17339static void hdd_config_sched_scan_plan(tSirPNOScanReq pno_req,
17340 struct cfg80211_sched_scan_request *request,
17341 hdd_context_t *hdd_ctx)
17342{
17343 v_U32_t i, temp_int;
17344 /* Driver gets only one time interval which is hardcoded in
17345 * supplicant for 10000ms. Taking power consumption into account 6
17346 * timers will be used, Timervalue is increased exponentially
17347 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17348 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17349 * If it is set to 0 only one timer will be used and PNO scan cycle
17350 * will be repeated after each interval specified by supplicant
17351 * till PNO is disabled.
17352 */
17353 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
17354 pno_req.scanTimers.ucScanTimersCount =
17355 HDD_PNO_SCAN_TIMERS_SET_ONE;
17356 else
17357 pno_req.scanTimers.ucScanTimersCount =
17358 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17359
17360 temp_int = (request->interval)/1000;
17361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17362 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17363 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
17364 for ( i = 0; i < pno_req.scanTimers.ucScanTimersCount; i++)
17365 {
17366 pno_req.scanTimers.aTimerValues[i].uTimerRepeat =
17367 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
17368 pno_req.scanTimers.aTimerValues[i].uTimerValue = temp_int;
17369 temp_int *= 2;
17370 }
17371 //Repeat last timer until pno disabled.
17372 pno_req.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
17373}
17374#endif
17375
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017376/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017377 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17378 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017379 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017380static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017381 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17382{
17383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017384 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017385 hdd_context_t *pHddCtx;
17386 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017387 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017388 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17389 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017390 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17391 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017392 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017393 hdd_config_t *pConfig = NULL;
17394 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017396 ENTER();
17397
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017398 if (NULL == pAdapter)
17399 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017401 "%s: HDD adapter is Null", __func__);
17402 return -ENODEV;
17403 }
17404
17405 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017406 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017407
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017408 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017409 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017410 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017411 }
17412
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017413 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017414 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17415 if (NULL == hHal)
17416 {
17417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17418 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017419 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017420 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017421 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17422 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17423 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017424 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017425 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017426 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017427 {
17428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17429 "%s: aborting the existing scan is unsuccessfull", __func__);
17430 return -EBUSY;
17431 }
17432
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017433 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017434 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017436 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017437 return -EBUSY;
17438 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017439
c_hpothu37f21312014-04-09 21:49:54 +053017440 if (TRUE == pHddCtx->isPnoEnable)
17441 {
17442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17443 FL("already PNO is enabled"));
17444 return -EBUSY;
17445 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017446
17447 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17448 {
17449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17450 "%s: abort ROC failed ", __func__);
17451 return -EBUSY;
17452 }
17453
c_hpothu37f21312014-04-09 21:49:54 +053017454 pHddCtx->isPnoEnable = TRUE;
17455
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017456 pnoRequest.enable = 1; /*Enable PNO */
17457 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017458
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017459 if (( !pnoRequest.ucNetworksCount ) ||
17460 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017461 {
17462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017463 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017464 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017465 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017466 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017467 goto error;
17468 }
17469
17470 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17471 {
17472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017473 "%s: Incorrect number of channels %d",
17474 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017475 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017476 goto error;
17477 }
17478
17479 /* Framework provides one set of channels(all)
17480 * common for all saved profile */
17481 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17482 channels_allowed, &num_channels_allowed))
17483 {
17484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17485 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017486 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017487 goto error;
17488 }
17489 /* Checking each channel against allowed channel list */
17490 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017491 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017492 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017493 char chList [(request->n_channels*5)+1];
17494 int len;
17495 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017496 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017497 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017498 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017499 if (request->channels[i]->hw_value == channels_allowed[indx])
17500 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017501 if ((!pConfig->enableDFSPnoChnlScan) &&
17502 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17503 {
17504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17505 "%s : Dropping DFS channel : %d",
17506 __func__,channels_allowed[indx]);
17507 num_ignore_dfs_ch++;
17508 break;
17509 }
17510
Nirav Shah80830bf2013-12-31 16:35:12 +053017511 valid_ch[num_ch++] = request->channels[i]->hw_value;
17512 len += snprintf(chList+len, 5, "%d ",
17513 request->channels[i]->hw_value);
17514 break ;
17515 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017516 }
17517 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017518 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017519
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017520 /*If all channels are DFS and dropped, then ignore the PNO request*/
17521 if (num_ignore_dfs_ch == request->n_channels)
17522 {
17523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17524 "%s : All requested channels are DFS channels", __func__);
17525 ret = -EINVAL;
17526 goto error;
17527 }
17528 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017529
17530 pnoRequest.aNetworks =
17531 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17532 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017533 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017534 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17535 FL("failed to allocate memory aNetworks %u"),
17536 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17537 goto error;
17538 }
17539 vos_mem_zero(pnoRequest.aNetworks,
17540 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17541
17542 /* Filling per profile params */
17543 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17544 {
17545 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017546 request->match_sets[i].ssid.ssid_len;
17547
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017548 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17549 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017550 {
17551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017552 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017553 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017554 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017555 goto error;
17556 }
17557
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017558 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017559 request->match_sets[i].ssid.ssid,
17560 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17562 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017563 i, pnoRequest.aNetworks[i].ssId.ssId);
17564 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17565 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17566 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017567
17568 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017569 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17570 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017571
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017572 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017573 }
17574
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017575 for (i = 0; i < request->n_ssids; i++)
17576 {
17577 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017578 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017579 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017580 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017581 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017582 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017583 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017584 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017585 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017586 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017587 break;
17588 }
17589 j++;
17590 }
17591 }
17592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17593 "Number of hidden networks being Configured = %d",
17594 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017596 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017597
17598 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17599 if (pnoRequest.p24GProbeTemplate == NULL)
17600 {
17601 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17602 FL("failed to allocate memory p24GProbeTemplate %u"),
17603 SIR_PNO_MAX_PB_REQ_SIZE);
17604 goto error;
17605 }
17606
17607 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17608 if (pnoRequest.p5GProbeTemplate == NULL)
17609 {
17610 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17611 FL("failed to allocate memory p5GProbeTemplate %u"),
17612 SIR_PNO_MAX_PB_REQ_SIZE);
17613 goto error;
17614 }
17615
17616 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17617 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17618
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017619 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17620 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017621 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017622 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17623 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17624 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017625
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017626 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17627 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17628 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017629 }
17630
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017631 hdd_config_sched_scan_plan(pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017632
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017633 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017634
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017635 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017636 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17637 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017638 pAdapter->pno_req_status = 0;
17639
Nirav Shah80830bf2013-12-31 16:35:12 +053017640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17641 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017642 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17643 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017644
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017645 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017646 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017647 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17648 if (eHAL_STATUS_SUCCESS != status)
17649 {
17650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017651 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017652 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017653 goto error;
17654 }
17655
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017656 ret = wait_for_completion_timeout(
17657 &pAdapter->pno_comp_var,
17658 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17659 if (0 >= ret)
17660 {
17661 // Did not receive the response for PNO enable in time.
17662 // Assuming the PNO enable was success.
17663 // Returning error from here, because we timeout, results
17664 // in side effect of Wifi (Wifi Setting) not to work.
17665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17666 FL("Timed out waiting for PNO to be Enabled"));
17667 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017668 }
17669
17670 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017671 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017672
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017673error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17675 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017676 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017677 if (pnoRequest.aNetworks)
17678 vos_mem_free(pnoRequest.aNetworks);
17679 if (pnoRequest.p24GProbeTemplate)
17680 vos_mem_free(pnoRequest.p24GProbeTemplate);
17681 if (pnoRequest.p5GProbeTemplate)
17682 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017683
17684 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017685 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017686}
17687
17688/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017689 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17690 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017691 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017692static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17693 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17694{
17695 int ret;
17696
17697 vos_ssr_protect(__func__);
17698 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17699 vos_ssr_unprotect(__func__);
17700
17701 return ret;
17702}
17703
17704/*
17705 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17706 * Function to disable PNO
17707 */
17708static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017709 struct net_device *dev)
17710{
17711 eHalStatus status = eHAL_STATUS_FAILURE;
17712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17713 hdd_context_t *pHddCtx;
17714 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017715 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017716 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017717
17718 ENTER();
17719
17720 if (NULL == pAdapter)
17721 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017723 "%s: HDD adapter is Null", __func__);
17724 return -ENODEV;
17725 }
17726
17727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017728
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017729 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017730 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017732 "%s: HDD context is Null", __func__);
17733 return -ENODEV;
17734 }
17735
17736 /* The return 0 is intentional when isLogpInProgress and
17737 * isLoadUnloadInProgress. We did observe a crash due to a return of
17738 * failure in sched_scan_stop , especially for a case where the unload
17739 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17740 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17741 * success. If it returns a failure , then its next invocation due to the
17742 * clean up of the second interface will have the dev pointer corresponding
17743 * to the first one leading to a crash.
17744 */
17745 if (pHddCtx->isLogpInProgress)
17746 {
17747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17748 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017749 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017750 return ret;
17751 }
17752
Mihir Shete18156292014-03-11 15:38:30 +053017753 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017754 {
17755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17756 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17757 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017758 }
17759
17760 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17761 if (NULL == hHal)
17762 {
17763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17764 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017765 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017766 }
17767
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017768 pnoRequest.enable = 0; /* Disable PNO */
17769 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017770
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17772 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17773 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017774
17775 INIT_COMPLETION(pAdapter->pno_comp_var);
17776 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17777 pnoRequest.callbackContext = pAdapter;
17778 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017779 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017780 pAdapter->sessionId,
17781 NULL, pAdapter);
17782 if (eHAL_STATUS_SUCCESS != status)
17783 {
17784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17785 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017786 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017787 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017788 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017789 ret = wait_for_completion_timeout(
17790 &pAdapter->pno_comp_var,
17791 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17792 if (0 >= ret)
17793 {
17794 // Did not receive the response for PNO disable in time.
17795 // Assuming the PNO disable was success.
17796 // Returning error from here, because we timeout, results
17797 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017799 FL("Timed out waiting for PNO to be disabled"));
17800 ret = 0;
17801 }
17802
17803 ret = pAdapter->pno_req_status;
17804 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017805
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017806error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017808 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017809
17810 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017811 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017812}
17813
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017814/*
17815 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17816 * NL interface to disable PNO
17817 */
17818static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17819 struct net_device *dev)
17820{
17821 int ret;
17822
17823 vos_ssr_protect(__func__);
17824 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17825 vos_ssr_unprotect(__func__);
17826
17827 return ret;
17828}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017829#endif /*FEATURE_WLAN_SCAN_PNO*/
17830
17831
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017832#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017833#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017834static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17835 struct net_device *dev,
17836 u8 *peer, u8 action_code,
17837 u8 dialog_token,
17838 u16 status_code, u32 peer_capability,
17839 const u8 *buf, size_t len)
17840#else /* TDLS_MGMT_VERSION2 */
17841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17842static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17843 struct net_device *dev,
17844 const u8 *peer, u8 action_code,
17845 u8 dialog_token, u16 status_code,
17846 u32 peer_capability, bool initiator,
17847 const u8 *buf, size_t len)
17848#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17849static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17850 struct net_device *dev,
17851 const u8 *peer, u8 action_code,
17852 u8 dialog_token, u16 status_code,
17853 u32 peer_capability, const u8 *buf,
17854 size_t len)
17855#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17856static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17857 struct net_device *dev,
17858 u8 *peer, u8 action_code,
17859 u8 dialog_token,
17860 u16 status_code, u32 peer_capability,
17861 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017862#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017863static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17864 struct net_device *dev,
17865 u8 *peer, u8 action_code,
17866 u8 dialog_token,
17867 u16 status_code, const u8 *buf,
17868 size_t len)
17869#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017870#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017871{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017872 hdd_adapter_t *pAdapter;
17873 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017874 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017875 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017876 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017877 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017878 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017879 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017880#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017881 u32 peer_capability = 0;
17882#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017883 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017884 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017885
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017886 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17887 if (NULL == pAdapter)
17888 {
17889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17890 "%s: Adapter is NULL",__func__);
17891 return -EINVAL;
17892 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017893 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17894 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17895 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017896
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017897 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017898 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017901 "Invalid arguments");
17902 return -EINVAL;
17903 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017904
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017905 if (pHddCtx->isLogpInProgress)
17906 {
17907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17908 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017909 wlan_hdd_tdls_set_link_status(pAdapter,
17910 peer,
17911 eTDLS_LINK_IDLE,
17912 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017913 return -EBUSY;
17914 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017915
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017916 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17917 {
17918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17919 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17920 return -EAGAIN;
17921 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017922
Hoonki Lee27511902013-03-14 18:19:06 -070017923 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017924 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017926 "%s: TDLS mode is disabled OR not enabled in FW."
17927 MAC_ADDRESS_STR " action %d declined.",
17928 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017929 return -ENOTSUPP;
17930 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017931
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017932 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17933
17934 if( NULL == pHddStaCtx )
17935 {
17936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17937 "%s: HDD station context NULL ",__func__);
17938 return -EINVAL;
17939 }
17940
17941 /* STA should be connected and authenticated
17942 * before sending any TDLS frames
17943 */
17944 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17945 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17946 {
17947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17948 "STA is not connected or unauthenticated. "
17949 "connState %u, uIsAuthenticated %u",
17950 pHddStaCtx->conn_info.connState,
17951 pHddStaCtx->conn_info.uIsAuthenticated);
17952 return -EAGAIN;
17953 }
17954
Hoonki Lee27511902013-03-14 18:19:06 -070017955 /* other than teardown frame, other mgmt frames are not sent if disabled */
17956 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17957 {
17958 /* if tdls_mode is disabled to respond to peer's request */
17959 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17960 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017962 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017963 " TDLS mode is disabled. action %d declined.",
17964 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017965
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017966 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017967 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017968
17969 if (vos_max_concurrent_connections_reached())
17970 {
17971 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17972 return -EINVAL;
17973 }
Hoonki Lee27511902013-03-14 18:19:06 -070017974 }
17975
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017976 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17977 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017978 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017979 {
17980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017981 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017982 " TDLS setup is ongoing. action %d declined.",
17983 __func__, MAC_ADDR_ARRAY(peer), action_code);
17984 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017985 }
17986 }
17987
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017988 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17989 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017990 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017991 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17992 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017993 {
17994 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17995 we return error code at 'add_station()'. Hence we have this
17996 check again in addtion to add_station().
17997 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017998 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017999 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18001 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018002 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18003 __func__, MAC_ADDR_ARRAY(peer), action_code,
18004 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018005 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018006 }
18007 else
18008 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018009 /* maximum reached. tweak to send error code to peer and return
18010 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018011 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18013 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018014 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18015 __func__, MAC_ADDR_ARRAY(peer), status_code,
18016 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018017 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018018 /* fall through to send setup resp with failure status
18019 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018020 }
18021 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018022 else
18023 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018024 mutex_lock(&pHddCtx->tdls_lock);
18025 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018026 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018027 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018028 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018030 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18031 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018032 return -EPERM;
18033 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018034 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018035 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018036 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018037
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018039 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018040 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18041 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018042
Hoonki Leea34dd892013-02-05 22:56:02 -080018043 /*Except teardown responder will not be used so just make 0*/
18044 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018045 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018046 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018047
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018048 mutex_lock(&pHddCtx->tdls_lock);
18049 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018050
18051 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18052 responder = pTdlsPeer->is_responder;
18053 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018054 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018056 "%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 -070018057 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18058 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018059 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018060 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018061 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018062 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018063 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018064
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018065 /* Discard TDLS setup if peer is removed by user app */
18066 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18067 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18068 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18069 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18070
18071 mutex_lock(&pHddCtx->tdls_lock);
18072 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18073 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18074 mutex_unlock(&pHddCtx->tdls_lock);
18075 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18076 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18077 MAC_ADDR_ARRAY(peer), action_code);
18078 return -EINVAL;
18079 }
18080 mutex_unlock(&pHddCtx->tdls_lock);
18081 }
18082
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018083 /* For explicit trigger of DIS_REQ come out of BMPS for
18084 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018085 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018086 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018087 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18088 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018089 {
18090 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
18091 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018093 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018094 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18095 if (status != VOS_STATUS_SUCCESS) {
18096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
18097 }
Hoonki Lee14621352013-04-16 17:51:19 -070018098 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018099 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018100 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18102 }
18103 }
Hoonki Lee14621352013-04-16 17:51:19 -070018104 }
18105
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018106 /* make sure doesn't call send_mgmt() while it is pending */
18107 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18108 {
18109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018110 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018111 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018112 ret = -EBUSY;
18113 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018114 }
18115
18116 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018117 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18118
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018119 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18120 pAdapter->sessionId, peer, action_code, dialog_token,
18121 status_code, peer_capability, (tANI_U8 *)buf, len,
18122 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018123
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018124 if (VOS_STATUS_SUCCESS != status)
18125 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18127 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018128 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018129 ret = -EINVAL;
18130 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018131 }
18132
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18134 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18135 WAIT_TIME_TDLS_MGMT);
18136
Hoonki Leed37cbb32013-04-20 00:31:14 -070018137 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18138 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18139
18140 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018141 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018143 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018144 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018145 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018146
18147 if (pHddCtx->isLogpInProgress)
18148 {
18149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18150 "%s: LOGP in Progress. Ignore!!!", __func__);
18151 return -EAGAIN;
18152 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018153 if (rc <= 0)
18154 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18155 WLAN_LOG_INDICATOR_HOST_DRIVER,
18156 WLAN_LOG_REASON_HDD_TIME_OUT,
18157 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018158
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018159 ret = -EINVAL;
18160 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018161 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018162 else
18163 {
18164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18165 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18166 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18167 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018168
Gopichand Nakkala05922802013-03-14 12:23:19 -070018169 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018170 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018171 ret = max_sta_failed;
18172 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018173 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018174
Hoonki Leea34dd892013-02-05 22:56:02 -080018175 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18176 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018177 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18179 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018180 }
18181 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18182 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018183 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18185 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018186 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018187
18188 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018189
18190tx_failed:
18191 /* add_station will be called before sending TDLS_SETUP_REQ and
18192 * TDLS_SETUP_RSP and as part of add_station driver will enable
18193 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18194 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18195 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18196 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18197 */
18198
18199 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18200 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18201 wlan_hdd_tdls_check_bmps(pAdapter);
18202 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018203}
18204
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018205#if TDLS_MGMT_VERSION2
18206static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18207 u8 *peer, u8 action_code, u8 dialog_token,
18208 u16 status_code, u32 peer_capability,
18209 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018210#else /* TDLS_MGMT_VERSION2 */
18211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18212static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18213 struct net_device *dev,
18214 const u8 *peer, u8 action_code,
18215 u8 dialog_token, u16 status_code,
18216 u32 peer_capability, bool initiator,
18217 const u8 *buf, size_t len)
18218#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18219static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18220 struct net_device *dev,
18221 const u8 *peer, u8 action_code,
18222 u8 dialog_token, u16 status_code,
18223 u32 peer_capability, const u8 *buf,
18224 size_t len)
18225#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18226static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18227 struct net_device *dev,
18228 u8 *peer, u8 action_code,
18229 u8 dialog_token,
18230 u16 status_code, u32 peer_capability,
18231 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018232#else
18233static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18234 u8 *peer, u8 action_code, u8 dialog_token,
18235 u16 status_code, const u8 *buf, size_t len)
18236#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018237#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018238{
18239 int ret;
18240
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018241 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018242#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018243 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18244 dialog_token, status_code,
18245 peer_capability, buf, len);
18246#else /* TDLS_MGMT_VERSION2 */
18247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18248 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18249 dialog_token, status_code,
18250 peer_capability, initiator,
18251 buf, len);
18252#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18253 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18254 dialog_token, status_code,
18255 peer_capability, buf, len);
18256#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18257 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18258 dialog_token, status_code,
18259 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018260#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018261 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18262 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018263#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018264#endif
18265 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018266
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018267 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018268}
Atul Mittal115287b2014-07-08 13:26:33 +053018269
18270int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18272 const u8 *peer,
18273#else
Atul Mittal115287b2014-07-08 13:26:33 +053018274 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018275#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018276 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018277 cfg80211_exttdls_callback callback)
18278{
18279
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018280 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018281 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018282 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18284 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18285 __func__, MAC_ADDR_ARRAY(peer));
18286
18287 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18288 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18289
18290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018291 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18292 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18293 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018294 return -ENOTSUPP;
18295 }
18296
18297 /* To cater the requirement of establishing the TDLS link
18298 * irrespective of the data traffic , get an entry of TDLS peer.
18299 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018300 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018301 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18302 if (pTdlsPeer == NULL) {
18303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18304 "%s: peer " MAC_ADDRESS_STR " not existing",
18305 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018306 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018307 return -EINVAL;
18308 }
18309
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018310 /* check FW TDLS Off Channel capability */
18311 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018312 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018313 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018314 {
18315 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18316 pTdlsPeer->peerParams.global_operating_class =
18317 tdls_peer_params->global_operating_class;
18318 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18319 pTdlsPeer->peerParams.min_bandwidth_kbps =
18320 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018321 /* check configured channel is valid, non dfs and
18322 * not current operating channel */
18323 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18324 tdls_peer_params->channel)) &&
18325 (pHddStaCtx) &&
18326 (tdls_peer_params->channel !=
18327 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018328 {
18329 pTdlsPeer->isOffChannelConfigured = TRUE;
18330 }
18331 else
18332 {
18333 pTdlsPeer->isOffChannelConfigured = FALSE;
18334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18335 "%s: Configured Tdls Off Channel is not valid", __func__);
18336
18337 }
18338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018339 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18340 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018341 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018342 pTdlsPeer->isOffChannelConfigured,
18343 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018344 }
18345 else
18346 {
18347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018348 "%s: TDLS off channel FW capability %d, "
18349 "host capab %d or Invalid TDLS Peer Params", __func__,
18350 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18351 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018352 }
18353
Atul Mittal115287b2014-07-08 13:26:33 +053018354 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18355
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018356 mutex_unlock(&pHddCtx->tdls_lock);
18357
Atul Mittal115287b2014-07-08 13:26:33 +053018358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18359 " %s TDLS Add Force Peer Failed",
18360 __func__);
18361 return -EINVAL;
18362 }
18363 /*EXT TDLS*/
18364
18365 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018366 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18368 " %s TDLS set callback Failed",
18369 __func__);
18370 return -EINVAL;
18371 }
18372
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018373 mutex_unlock(&pHddCtx->tdls_lock);
18374
Atul Mittal115287b2014-07-08 13:26:33 +053018375 return(0);
18376
18377}
18378
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018379int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18381 const u8 *peer
18382#else
18383 u8 *peer
18384#endif
18385)
Atul Mittal115287b2014-07-08 13:26:33 +053018386{
18387
18388 hddTdlsPeer_t *pTdlsPeer;
18389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018390
Atul Mittal115287b2014-07-08 13:26:33 +053018391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18392 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18393 __func__, MAC_ADDR_ARRAY(peer));
18394
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018395 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18397 return -EINVAL;
18398 }
18399
Atul Mittal115287b2014-07-08 13:26:33 +053018400 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18401 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18402
18403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018404 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18405 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18406 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018407 return -ENOTSUPP;
18408 }
18409
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018410 mutex_lock(&pHddCtx->tdls_lock);
18411 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018412
18413 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018414 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018415 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018416 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018417 __func__, MAC_ADDR_ARRAY(peer));
18418 return -EINVAL;
18419 }
18420 else {
18421 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18422 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018423 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18424 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018425 /* if channel switch is configured, reset
18426 the channel for this peer */
18427 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18428 {
18429 pTdlsPeer->peerParams.channel = 0;
18430 pTdlsPeer->isOffChannelConfigured = FALSE;
18431 }
Atul Mittal115287b2014-07-08 13:26:33 +053018432 }
18433
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018434 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018435 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018437 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018438 }
Atul Mittal115287b2014-07-08 13:26:33 +053018439
18440 /*EXT TDLS*/
18441
18442 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018443 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18445 " %s TDLS set callback Failed",
18446 __func__);
18447 return -EINVAL;
18448 }
Atul Mittal115287b2014-07-08 13:26:33 +053018449
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018450 mutex_unlock(&pHddCtx->tdls_lock);
18451
18452 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018453}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018454static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018455#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18456 const u8 *peer,
18457#else
18458 u8 *peer,
18459#endif
18460 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018461{
18462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18463 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018464 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018465 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018467 ENTER();
18468
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018469 if (!pAdapter) {
18470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18471 return -EINVAL;
18472 }
18473
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018474 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18475 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18476 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018477 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018478 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018480 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018481 return -EINVAL;
18482 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018483
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018484 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018485 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018486 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018487 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018488 }
18489
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018490
18491 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018492 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018493 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018495 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18496 "Cannot process TDLS commands",
18497 pHddCtx->cfg_ini->fEnableTDLSSupport,
18498 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018499 return -ENOTSUPP;
18500 }
18501
18502 switch (oper) {
18503 case NL80211_TDLS_ENABLE_LINK:
18504 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018505 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018506 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018507 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18508 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018509 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018510 tANI_U16 numCurrTdlsPeers = 0;
18511 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018512 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018513 tSirMacAddr peerMac;
18514 int channel;
18515 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018516
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18518 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18519 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018520
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018521 mutex_lock(&pHddCtx->tdls_lock);
18522 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018523 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018524 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018525 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18527 " (oper %d) not exsting. ignored",
18528 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18529 return -EINVAL;
18530 }
18531
18532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18533 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18534 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18535 "NL80211_TDLS_ENABLE_LINK");
18536
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018537 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18538 {
18539 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18540 MAC_ADDRESS_STR " failed",
18541 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018542 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018543 return -EINVAL;
18544 }
18545
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018546 /* before starting tdls connection, set tdls
18547 * off channel established status to default value */
18548 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018549
18550 mutex_unlock(&pHddCtx->tdls_lock);
18551
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018552 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018553 /* TDLS Off Channel, Disable tdls channel switch,
18554 when there are more than one tdls link */
18555 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018556 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018557 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018558 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018559 /* get connected peer and send disable tdls off chan */
18560 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018561 if ((connPeer) &&
18562 (connPeer->isOffChannelSupported == TRUE) &&
18563 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018564 {
18565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18566 "%s: More then one peer connected, Disable "
18567 "TDLS channel switch", __func__);
18568
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018569 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018570 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18571 channel = connPeer->peerParams.channel;
18572
18573 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018574
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018575 ret = sme_SendTdlsChanSwitchReq(
18576 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018577 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018578 peerMac,
18579 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018580 TDLS_OFF_CHANNEL_BW_OFFSET,
18581 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018582 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018583 hddLog(VOS_TRACE_LEVEL_ERROR,
18584 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018585 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018586 }
18587 else
18588 {
18589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18590 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018591 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018592 "isOffChannelConfigured %d",
18593 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018594 (connPeer ? (connPeer->isOffChannelSupported)
18595 : -1),
18596 (connPeer ? (connPeer->isOffChannelConfigured)
18597 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018598 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018599 }
18600 }
18601
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018602 mutex_lock(&pHddCtx->tdls_lock);
18603 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18604 if ( NULL == pTdlsPeer ) {
18605 mutex_unlock(&pHddCtx->tdls_lock);
18606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18607 "%s: " MAC_ADDRESS_STR
18608 " (oper %d) peer got freed in other context. ignored",
18609 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18610 return -EINVAL;
18611 }
18612 peer_status = pTdlsPeer->link_status;
18613 mutex_unlock(&pHddCtx->tdls_lock);
18614
18615 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018616 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018617 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018618
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018619 if (0 != wlan_hdd_tdls_get_link_establish_params(
18620 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018622 return -EINVAL;
18623 }
18624 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018625
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018626 ret = sme_SendTdlsLinkEstablishParams(
18627 WLAN_HDD_GET_HAL_CTX(pAdapter),
18628 pAdapter->sessionId, peer,
18629 &tdlsLinkEstablishParams);
18630 if (ret != VOS_STATUS_SUCCESS) {
18631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18632 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018633 /* Send TDLS peer UAPSD capabilities to the firmware and
18634 * register with the TL on after the response for this operation
18635 * is received .
18636 */
18637 ret = wait_for_completion_interruptible_timeout(
18638 &pAdapter->tdls_link_establish_req_comp,
18639 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018640
18641 mutex_lock(&pHddCtx->tdls_lock);
18642 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18643 if ( NULL == pTdlsPeer ) {
18644 mutex_unlock(&pHddCtx->tdls_lock);
18645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18646 "%s %d: " MAC_ADDRESS_STR
18647 " (oper %d) peer got freed in other context. ignored",
18648 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18649 (int)oper);
18650 return -EINVAL;
18651 }
18652 peer_status = pTdlsPeer->link_status;
18653 mutex_unlock(&pHddCtx->tdls_lock);
18654
18655 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018656 {
18657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018658 FL("Link Establish Request Failed Status %ld"),
18659 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018660 return -EINVAL;
18661 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018662 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018663
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018664 mutex_lock(&pHddCtx->tdls_lock);
18665 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18666 if ( NULL == pTdlsPeer ) {
18667 mutex_unlock(&pHddCtx->tdls_lock);
18668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18669 "%s: " MAC_ADDRESS_STR
18670 " (oper %d) peer got freed in other context. ignored",
18671 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18672 return -EINVAL;
18673 }
18674
Atul Mittal115287b2014-07-08 13:26:33 +053018675 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18676 eTDLS_LINK_CONNECTED,
18677 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018678 staDesc.ucSTAId = pTdlsPeer->staId;
18679 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018680
18681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18682 "%s: tdlsLinkEstablishParams of peer "
18683 MAC_ADDRESS_STR "uapsdQueues: %d"
18684 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18685 "isResponder: %d peerstaId: %d",
18686 __func__,
18687 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18688 tdlsLinkEstablishParams.uapsdQueues,
18689 tdlsLinkEstablishParams.qos,
18690 tdlsLinkEstablishParams.maxSp,
18691 tdlsLinkEstablishParams.isBufSta,
18692 tdlsLinkEstablishParams.isOffChannelSupported,
18693 tdlsLinkEstablishParams.isResponder,
18694 pTdlsPeer->staId);
18695
18696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18697 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18698 __func__,
18699 staDesc.ucSTAId,
18700 staDesc.ucQosEnabled);
18701
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018702 ret = WLANTL_UpdateTdlsSTAClient(
18703 pHddCtx->pvosContext,
18704 &staDesc);
18705 if (ret != VOS_STATUS_SUCCESS) {
18706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18707 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018708
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018709 /* Mark TDLS client Authenticated .*/
18710 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18711 pTdlsPeer->staId,
18712 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018713 if (VOS_STATUS_SUCCESS == status)
18714 {
Hoonki Lee14621352013-04-16 17:51:19 -070018715 if (pTdlsPeer->is_responder == 0)
18716 {
18717 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018718 tdlsConnInfo_t *tdlsInfo;
18719
18720 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18721
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018722 if (!vos_timer_is_initialized(
18723 &pTdlsPeer->initiatorWaitTimeoutTimer))
18724 {
18725 /* Initialize initiator wait callback */
18726 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018727 &pTdlsPeer->initiatorWaitTimeoutTimer,
18728 VOS_TIMER_TYPE_SW,
18729 wlan_hdd_tdls_initiator_wait_cb,
18730 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018731 }
Hoonki Lee14621352013-04-16 17:51:19 -070018732 wlan_hdd_tdls_timer_restart(pAdapter,
18733 &pTdlsPeer->initiatorWaitTimeoutTimer,
18734 WAIT_TIME_TDLS_INITIATOR);
18735 /* suspend initiator TX until it receives direct packet from the
18736 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018737 ret = WLANTL_SuspendDataTx(
18738 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18739 &staId, NULL);
18740 if (ret != VOS_STATUS_SUCCESS) {
18741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18742 }
Hoonki Lee14621352013-04-16 17:51:19 -070018743 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018744
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018745 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018746 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018747 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018748 suppChannelLen =
18749 tdlsLinkEstablishParams.supportedChannelsLen;
18750
18751 if ((suppChannelLen > 0) &&
18752 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18753 {
18754 tANI_U8 suppPeerChannel = 0;
18755 int i = 0;
18756 for (i = 0U; i < suppChannelLen; i++)
18757 {
18758 suppPeerChannel =
18759 tdlsLinkEstablishParams.supportedChannels[i];
18760
18761 pTdlsPeer->isOffChannelSupported = FALSE;
18762 if (suppPeerChannel ==
18763 pTdlsPeer->peerParams.channel)
18764 {
18765 pTdlsPeer->isOffChannelSupported = TRUE;
18766 break;
18767 }
18768 }
18769 }
18770 else
18771 {
18772 pTdlsPeer->isOffChannelSupported = FALSE;
18773 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018774 }
18775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18776 "%s: TDLS channel switch request for channel "
18777 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018778 "%d isOffChannelSupported %d", __func__,
18779 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018780 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018781 suppChannelLen,
18782 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018783
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018784 /* TDLS Off Channel, Enable tdls channel switch,
18785 when their is only one tdls link and it supports */
18786 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18787 if ((numCurrTdlsPeers == 1) &&
18788 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18789 (TRUE == pTdlsPeer->isOffChannelConfigured))
18790 {
18791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18792 "%s: Send TDLS channel switch request for channel %d",
18793 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018794
18795 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018796 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18797 channel = pTdlsPeer->peerParams.channel;
18798
18799 mutex_unlock(&pHddCtx->tdls_lock);
18800
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018801 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18802 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018803 peerMac,
18804 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018805 TDLS_OFF_CHANNEL_BW_OFFSET,
18806 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018807 if (ret != VOS_STATUS_SUCCESS) {
18808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18809 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018810 }
18811 else
18812 {
18813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18814 "%s: TDLS channel switch request not sent"
18815 " numCurrTdlsPeers %d "
18816 "isOffChannelSupported %d "
18817 "isOffChannelConfigured %d",
18818 __func__, numCurrTdlsPeers,
18819 pTdlsPeer->isOffChannelSupported,
18820 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018821 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018822 }
18823
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018824 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018825 else
18826 mutex_unlock(&pHddCtx->tdls_lock);
18827
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018828 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018829
18830 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018831 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18832 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018833 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018834 int ac;
18835 uint8 ucAc[4] = { WLANTL_AC_VO,
18836 WLANTL_AC_VI,
18837 WLANTL_AC_BK,
18838 WLANTL_AC_BE };
18839 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18840 for(ac=0; ac < 4; ac++)
18841 {
18842 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18843 pTdlsPeer->staId, ucAc[ac],
18844 tlTid[ac], tlTid[ac], 0, 0,
18845 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018846 if (status != VOS_STATUS_SUCCESS) {
18847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18848 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018849 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018850 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018851 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018852
Bhargav Shah66896792015-10-01 18:17:37 +053018853 /* stop TCP delack timer if TDLS is enable */
18854 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18855 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018856 hdd_wlan_tdls_enable_link_event(peer,
18857 pTdlsPeer->isOffChannelSupported,
18858 pTdlsPeer->isOffChannelConfigured,
18859 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018860 }
18861 break;
18862 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018863 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018864 tANI_U16 numCurrTdlsPeers = 0;
18865 hddTdlsPeer_t *connPeer = NULL;
18866
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18868 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18869 __func__, MAC_ADDR_ARRAY(peer));
18870
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018871 mutex_lock(&pHddCtx->tdls_lock);
18872 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018873
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018874
Sunil Dutt41de4e22013-11-14 18:09:02 +053018875 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018876 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18878 " (oper %d) not exsting. ignored",
18879 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18880 return -EINVAL;
18881 }
18882
18883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18884 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18885 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18886 "NL80211_TDLS_DISABLE_LINK");
18887
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018888 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018889 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018890 long status;
18891
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018892 /* set tdls off channel status to false for this peer */
18893 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018894 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18895 eTDLS_LINK_TEARING,
18896 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18897 eTDLS_LINK_UNSPECIFIED:
18898 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018899 mutex_unlock(&pHddCtx->tdls_lock);
18900
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018901 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18902
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018903 status = sme_DeleteTdlsPeerSta(
18904 WLAN_HDD_GET_HAL_CTX(pAdapter),
18905 pAdapter->sessionId, peer );
18906 if (status != VOS_STATUS_SUCCESS) {
18907 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18908 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018909
18910 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18911 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018912
18913 mutex_lock(&pHddCtx->tdls_lock);
18914 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18915 if ( NULL == pTdlsPeer ) {
18916 mutex_unlock(&pHddCtx->tdls_lock);
18917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18918 " peer was freed in other context",
18919 __func__, MAC_ADDR_ARRAY(peer));
18920 return -EINVAL;
18921 }
18922
Atul Mittal271a7652014-09-12 13:18:22 +053018923 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018924 eTDLS_LINK_IDLE,
18925 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018926 mutex_unlock(&pHddCtx->tdls_lock);
18927
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018928 if (status <= 0)
18929 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18931 "%s: Del station failed status %ld",
18932 __func__, status);
18933 return -EPERM;
18934 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018935
18936 /* TDLS Off Channel, Enable tdls channel switch,
18937 when their is only one tdls link and it supports */
18938 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18939 if (numCurrTdlsPeers == 1)
18940 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018941 tSirMacAddr peerMac;
18942 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018943
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018944 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018945 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018946
18947 if (connPeer == NULL) {
18948 mutex_unlock(&pHddCtx->tdls_lock);
18949 hddLog(VOS_TRACE_LEVEL_ERROR,
18950 "%s connPeer is NULL", __func__);
18951 return -EINVAL;
18952 }
18953
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018954 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18955 channel = connPeer->peerParams.channel;
18956
18957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18958 "%s: TDLS channel switch "
18959 "isOffChannelSupported %d "
18960 "isOffChannelConfigured %d "
18961 "isOffChannelEstablished %d",
18962 __func__,
18963 (connPeer ? connPeer->isOffChannelSupported : -1),
18964 (connPeer ? connPeer->isOffChannelConfigured : -1),
18965 (connPeer ? connPeer->isOffChannelEstablished : -1));
18966
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018967 if ((connPeer) &&
18968 (connPeer->isOffChannelSupported == TRUE) &&
18969 (connPeer->isOffChannelConfigured == TRUE))
18970 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018971 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018972 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018973 status = sme_SendTdlsChanSwitchReq(
18974 WLAN_HDD_GET_HAL_CTX(pAdapter),
18975 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018976 peerMac,
18977 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018978 TDLS_OFF_CHANNEL_BW_OFFSET,
18979 TDLS_CHANNEL_SWITCH_ENABLE);
18980 if (status != VOS_STATUS_SUCCESS) {
18981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18982 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018983 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018984 else
18985 mutex_unlock(&pHddCtx->tdls_lock);
18986 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018987 else
18988 {
18989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18990 "%s: TDLS channel switch request not sent "
18991 "numCurrTdlsPeers %d ",
18992 __func__, numCurrTdlsPeers);
18993 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018994 }
18995 else
18996 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018997 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18999 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019000 }
Bhargav Shah66896792015-10-01 18:17:37 +053019001 if (numCurrTdlsPeers == 0) {
19002 /* start TCP delack timer if TDLS is disable */
19003 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19004 hdd_manage_delack_timer(pHddCtx);
19005 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019006 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019007 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019008 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019009 {
Atul Mittal115287b2014-07-08 13:26:33 +053019010 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019011
Atul Mittal115287b2014-07-08 13:26:33 +053019012 if (0 != status)
19013 {
19014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019015 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019016 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019017 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019018 break;
19019 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019020 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019021 {
Atul Mittal115287b2014-07-08 13:26:33 +053019022 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19023 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019024 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019025 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019026
Atul Mittal115287b2014-07-08 13:26:33 +053019027 if (0 != status)
19028 {
19029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019030 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019031 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019032 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019033 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019034 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019035 case NL80211_TDLS_DISCOVERY_REQ:
19036 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019038 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019039 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019040 return -ENOTSUPP;
19041 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19043 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019044 return -ENOTSUPP;
19045 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019046
19047 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019048 return 0;
19049}
Chilam NG571c65a2013-01-19 12:27:36 +053019050
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019051static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19053 const u8 *peer,
19054#else
19055 u8 *peer,
19056#endif
19057 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019058{
19059 int ret;
19060
19061 vos_ssr_protect(__func__);
19062 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19063 vos_ssr_unprotect(__func__);
19064
19065 return ret;
19066}
19067
Chilam NG571c65a2013-01-19 12:27:36 +053019068int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19069 struct net_device *dev, u8 *peer)
19070{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019071 hddLog(VOS_TRACE_LEVEL_INFO,
19072 "tdls send discover req: "MAC_ADDRESS_STR,
19073 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019074#if TDLS_MGMT_VERSION2
19075 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19076 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19077#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19079 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19080 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19081#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19082 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19083 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19084#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19085 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19086 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19087#else
Chilam NG571c65a2013-01-19 12:27:36 +053019088 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19089 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019090#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019091#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019092}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019093#endif
19094
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019095#ifdef WLAN_FEATURE_GTK_OFFLOAD
19096/*
19097 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19098 * Callback rountine called upon receiving response for
19099 * get offload info
19100 */
19101void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19102 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19103{
19104
19105 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019106 tANI_U8 tempReplayCounter[8];
19107 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019108
19109 ENTER();
19110
19111 if (NULL == pAdapter)
19112 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019114 "%s: HDD adapter is Null", __func__);
19115 return ;
19116 }
19117
19118 if (NULL == pGtkOffloadGetInfoRsp)
19119 {
19120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19121 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19122 return ;
19123 }
19124
19125 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19126 {
19127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19128 "%s: wlan Failed to get replay counter value",
19129 __func__);
19130 return ;
19131 }
19132
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19134 /* Update replay counter */
19135 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19136 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19137
19138 {
19139 /* changing from little to big endian since supplicant
19140 * works on big endian format
19141 */
19142 int i;
19143 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19144
19145 for (i = 0; i < 8; i++)
19146 {
19147 tempReplayCounter[7-i] = (tANI_U8)p[i];
19148 }
19149 }
19150
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019151 /* Update replay counter to NL */
19152 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019153 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019154}
19155
19156/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019157 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019158 * This function is used to offload GTK rekeying job to the firmware.
19159 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019160int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019161 struct cfg80211_gtk_rekey_data *data)
19162{
19163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19164 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19165 hdd_station_ctx_t *pHddStaCtx;
19166 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019167 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019168 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019169 eHalStatus status = eHAL_STATUS_FAILURE;
19170
19171 ENTER();
19172
19173 if (NULL == pAdapter)
19174 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019176 "%s: HDD adapter is Null", __func__);
19177 return -ENODEV;
19178 }
19179
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19181 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19182 pAdapter->sessionId, pAdapter->device_mode));
19183
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019184 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019185 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019186 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019187 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019188 }
19189
19190 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19191 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19192 if (NULL == hHal)
19193 {
19194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19195 "%s: HAL context is Null!!!", __func__);
19196 return -EAGAIN;
19197 }
19198
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019199 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19200 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19201 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19202 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019203 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019204 {
19205 /* changing from big to little endian since driver
19206 * works on little endian format
19207 */
19208 tANI_U8 *p =
19209 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19210 int i;
19211
19212 for (i = 0; i < 8; i++)
19213 {
19214 p[7-i] = data->replay_ctr[i];
19215 }
19216 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019217
19218 if (TRUE == pHddCtx->hdd_wlan_suspended)
19219 {
19220 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019221 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19222 sizeof (tSirGtkOffloadParams));
19223 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019224 pAdapter->sessionId);
19225
19226 if (eHAL_STATUS_SUCCESS != status)
19227 {
19228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19229 "%s: sme_SetGTKOffload failed, returned %d",
19230 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019231
19232 /* Need to clear any trace of key value in the memory.
19233 * Thus zero out the memory even though it is local
19234 * variable.
19235 */
19236 vos_mem_zero(&hddGtkOffloadReqParams,
19237 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019238 return status;
19239 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19241 "%s: sme_SetGTKOffload successfull", __func__);
19242 }
19243 else
19244 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19246 "%s: wlan not suspended GTKOffload request is stored",
19247 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019248 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019249
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019250 /* Need to clear any trace of key value in the memory.
19251 * Thus zero out the memory even though it is local
19252 * variable.
19253 */
19254 vos_mem_zero(&hddGtkOffloadReqParams,
19255 sizeof(hddGtkOffloadReqParams));
19256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019257 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019258 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019259}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019261int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19262 struct cfg80211_gtk_rekey_data *data)
19263{
19264 int ret;
19265
19266 vos_ssr_protect(__func__);
19267 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19268 vos_ssr_unprotect(__func__);
19269
19270 return ret;
19271}
19272#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019273/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019274 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019275 * This function is used to set access control policy
19276 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019277static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19278 struct net_device *dev,
19279 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019280{
19281 int i;
19282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19283 hdd_hostapd_state_t *pHostapdState;
19284 tsap_Config_t *pConfig;
19285 v_CONTEXT_t pVosContext = NULL;
19286 hdd_context_t *pHddCtx;
19287 int status;
19288
19289 ENTER();
19290
19291 if (NULL == pAdapter)
19292 {
19293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19294 "%s: HDD adapter is Null", __func__);
19295 return -ENODEV;
19296 }
19297
19298 if (NULL == params)
19299 {
19300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19301 "%s: params is Null", __func__);
19302 return -EINVAL;
19303 }
19304
19305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19306 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019307 if (0 != status)
19308 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019309 return status;
19310 }
19311
19312 pVosContext = pHddCtx->pvosContext;
19313 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19314
19315 if (NULL == pHostapdState)
19316 {
19317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19318 "%s: pHostapdState is Null", __func__);
19319 return -EINVAL;
19320 }
19321
19322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19323 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019324 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19325 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19326 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019327
19328 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19329 {
19330 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19331
19332 /* default value */
19333 pConfig->num_accept_mac = 0;
19334 pConfig->num_deny_mac = 0;
19335
19336 /**
19337 * access control policy
19338 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19339 * listed in hostapd.deny file.
19340 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19341 * listed in hostapd.accept file.
19342 */
19343 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19344 {
19345 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19346 }
19347 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19348 {
19349 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19350 }
19351 else
19352 {
19353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19354 "%s:Acl Policy : %d is not supported",
19355 __func__, params->acl_policy);
19356 return -ENOTSUPP;
19357 }
19358
19359 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19360 {
19361 pConfig->num_accept_mac = params->n_acl_entries;
19362 for (i = 0; i < params->n_acl_entries; i++)
19363 {
19364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19365 "** Add ACL MAC entry %i in WhiletList :"
19366 MAC_ADDRESS_STR, i,
19367 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19368
19369 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19370 sizeof(qcmacaddr));
19371 }
19372 }
19373 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19374 {
19375 pConfig->num_deny_mac = params->n_acl_entries;
19376 for (i = 0; i < params->n_acl_entries; i++)
19377 {
19378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19379 "** Add ACL MAC entry %i in BlackList :"
19380 MAC_ADDRESS_STR, i,
19381 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19382
19383 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19384 sizeof(qcmacaddr));
19385 }
19386 }
19387
19388 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19389 {
19390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19391 "%s: SAP Set Mac Acl fail", __func__);
19392 return -EINVAL;
19393 }
19394 }
19395 else
19396 {
19397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019398 "%s: Invalid device_mode = %s (%d)",
19399 __func__, hdd_device_modetoString(pAdapter->device_mode),
19400 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019401 return -EINVAL;
19402 }
19403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019404 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019405 return 0;
19406}
19407
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019408static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19409 struct net_device *dev,
19410 const struct cfg80211_acl_data *params)
19411{
19412 int ret;
19413 vos_ssr_protect(__func__);
19414 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19415 vos_ssr_unprotect(__func__);
19416
19417 return ret;
19418}
19419
Leo Chang9056f462013-08-01 19:21:11 -070019420#ifdef WLAN_NL80211_TESTMODE
19421#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019422void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019423(
19424 void *pAdapter,
19425 void *indCont
19426)
19427{
Leo Changd9df8aa2013-09-26 13:32:26 -070019428 tSirLPHBInd *lphbInd;
19429 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019430 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019431
19432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019433 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019434
c_hpothu73f35e62014-04-18 13:40:08 +053019435 if (pAdapter == NULL)
19436 {
19437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19438 "%s: pAdapter is NULL\n",__func__);
19439 return;
19440 }
19441
Leo Chang9056f462013-08-01 19:21:11 -070019442 if (NULL == indCont)
19443 {
19444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019445 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019446 return;
19447 }
19448
c_hpothu73f35e62014-04-18 13:40:08 +053019449 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019450 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019451 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019452 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019453 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019454 GFP_ATOMIC);
19455 if (!skb)
19456 {
19457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19458 "LPHB timeout, NL buffer alloc fail");
19459 return;
19460 }
19461
Leo Changac3ba772013-10-07 09:47:04 -070019462 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019463 {
19464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19465 "WLAN_HDD_TM_ATTR_CMD put fail");
19466 goto nla_put_failure;
19467 }
Leo Changac3ba772013-10-07 09:47:04 -070019468 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019469 {
19470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19471 "WLAN_HDD_TM_ATTR_TYPE put fail");
19472 goto nla_put_failure;
19473 }
Leo Changac3ba772013-10-07 09:47:04 -070019474 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019475 sizeof(tSirLPHBInd), lphbInd))
19476 {
19477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19478 "WLAN_HDD_TM_ATTR_DATA put fail");
19479 goto nla_put_failure;
19480 }
Leo Chang9056f462013-08-01 19:21:11 -070019481 cfg80211_testmode_event(skb, GFP_ATOMIC);
19482 return;
19483
19484nla_put_failure:
19485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19486 "NLA Put fail");
19487 kfree_skb(skb);
19488
19489 return;
19490}
19491#endif /* FEATURE_WLAN_LPHB */
19492
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019493static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019494{
19495 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19496 int err = 0;
19497#ifdef FEATURE_WLAN_LPHB
19498 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019499 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019500
19501 ENTER();
19502
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019503 err = wlan_hdd_validate_context(pHddCtx);
19504 if (0 != err)
19505 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019506 return err;
19507 }
Leo Chang9056f462013-08-01 19:21:11 -070019508#endif /* FEATURE_WLAN_LPHB */
19509
19510 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19511 if (err)
19512 {
19513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19514 "%s Testmode INV ATTR", __func__);
19515 return err;
19516 }
19517
19518 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19519 {
19520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19521 "%s Testmode INV CMD", __func__);
19522 return -EINVAL;
19523 }
19524
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19526 TRACE_CODE_HDD_CFG80211_TESTMODE,
19527 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019528 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19529 {
19530#ifdef FEATURE_WLAN_LPHB
19531 /* Low Power Heartbeat configuration request */
19532 case WLAN_HDD_TM_CMD_WLAN_HB:
19533 {
19534 int buf_len;
19535 void *buf;
19536 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019537 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019538
19539 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19540 {
19541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19542 "%s Testmode INV DATA", __func__);
19543 return -EINVAL;
19544 }
19545
19546 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19547 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019548
19549 hb_params_temp =(tSirLPHBReq *)buf;
19550 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19551 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19552 return -EINVAL;
19553
Leo Chang9056f462013-08-01 19:21:11 -070019554 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19555 if (NULL == hb_params)
19556 {
19557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19558 "%s Request Buffer Alloc Fail", __func__);
19559 return -EINVAL;
19560 }
19561
19562 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019563 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19564 hb_params,
19565 wlan_hdd_cfg80211_lphb_ind_handler);
19566 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019567 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19569 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019570 vos_mem_free(hb_params);
19571 }
Leo Chang9056f462013-08-01 19:21:11 -070019572 return 0;
19573 }
19574#endif /* FEATURE_WLAN_LPHB */
19575 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19577 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019578 return -EOPNOTSUPP;
19579 }
19580
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019581 EXIT();
19582 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019583}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019584
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019585static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19587 struct wireless_dev *wdev,
19588#endif
19589 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019590{
19591 int ret;
19592
19593 vos_ssr_protect(__func__);
19594 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19595 vos_ssr_unprotect(__func__);
19596
19597 return ret;
19598}
Leo Chang9056f462013-08-01 19:21:11 -070019599#endif /* CONFIG_NL80211_TESTMODE */
19600
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019601extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019602static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019603 struct net_device *dev,
19604 int idx, struct survey_info *survey)
19605{
19606 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19607 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019608 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019609 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019610 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019611 v_S7_t snr,rssi;
19612 int status, i, j, filled = 0;
19613
19614 ENTER();
19615
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019616 if (NULL == pAdapter)
19617 {
19618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19619 "%s: HDD adapter is Null", __func__);
19620 return -ENODEV;
19621 }
19622
19623 if (NULL == wiphy)
19624 {
19625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19626 "%s: wiphy is Null", __func__);
19627 return -ENODEV;
19628 }
19629
19630 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19631 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019632 if (0 != status)
19633 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019634 return status;
19635 }
19636
Mihir Sheted9072e02013-08-21 17:02:29 +053019637 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19638
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019639 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019640 0 != pAdapter->survey_idx ||
19641 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019642 {
19643 /* The survey dump ops when implemented completely is expected to
19644 * return a survey of all channels and the ops is called by the
19645 * kernel with incremental values of the argument 'idx' till it
19646 * returns -ENONET. But we can only support the survey for the
19647 * operating channel for now. survey_idx is used to track
19648 * that the ops is called only once and then return -ENONET for
19649 * the next iteration
19650 */
19651 pAdapter->survey_idx = 0;
19652 return -ENONET;
19653 }
19654
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019655 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19656 {
19657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19658 "%s: Roaming in progress, hence return ", __func__);
19659 return -ENONET;
19660 }
19661
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019662 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19663
19664 wlan_hdd_get_snr(pAdapter, &snr);
19665 wlan_hdd_get_rssi(pAdapter, &rssi);
19666
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19668 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19669 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019670 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19671 hdd_wlan_get_freq(channel, &freq);
19672
19673
19674 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19675 {
19676 if (NULL == wiphy->bands[i])
19677 {
19678 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19679 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19680 continue;
19681 }
19682
19683 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19684 {
19685 struct ieee80211_supported_band *band = wiphy->bands[i];
19686
19687 if (band->channels[j].center_freq == (v_U16_t)freq)
19688 {
19689 survey->channel = &band->channels[j];
19690 /* The Rx BDs contain SNR values in dB for the received frames
19691 * while the supplicant expects noise. So we calculate and
19692 * return the value of noise (dBm)
19693 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19694 */
19695 survey->noise = rssi - snr;
19696 survey->filled = SURVEY_INFO_NOISE_DBM;
19697 filled = 1;
19698 }
19699 }
19700 }
19701
19702 if (filled)
19703 pAdapter->survey_idx = 1;
19704 else
19705 {
19706 pAdapter->survey_idx = 0;
19707 return -ENONET;
19708 }
19709
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019710 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019711 return 0;
19712}
19713
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019714static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19715 struct net_device *dev,
19716 int idx, struct survey_info *survey)
19717{
19718 int ret;
19719
19720 vos_ssr_protect(__func__);
19721 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19722 vos_ssr_unprotect(__func__);
19723
19724 return ret;
19725}
19726
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019727/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019728 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019729 * this is called when cfg80211 driver resume
19730 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19731 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019732int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019733{
19734 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19735 hdd_adapter_t *pAdapter;
19736 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19737 VOS_STATUS status = VOS_STATUS_SUCCESS;
19738
19739 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019740
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019741 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019742 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019743 return 0;
19744 }
19745
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019746 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19747 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019748
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019749 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019750 {
19751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19752 "%s: Resume SoftAP", __func__);
19753 hdd_set_wlan_suspend_mode(false);
19754 }
19755
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019756 spin_lock(&pHddCtx->schedScan_lock);
19757 pHddCtx->isWiphySuspended = FALSE;
19758 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19759 {
19760 spin_unlock(&pHddCtx->schedScan_lock);
19761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19762 "%s: Return resume is not due to PNO indication", __func__);
19763 return 0;
19764 }
19765 // Reset flag to avoid updatating cfg80211 data old results again
19766 pHddCtx->isSchedScanUpdatePending = FALSE;
19767 spin_unlock(&pHddCtx->schedScan_lock);
19768
19769 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19770
19771 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19772 {
19773 pAdapter = pAdapterNode->pAdapter;
19774 if ( (NULL != pAdapter) &&
19775 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19776 {
19777 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019778 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19780 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019781 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019782 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019783 {
19784 /* Acquire wakelock to handle the case where APP's tries to
19785 * suspend immediately after updating the scan results. Whis
19786 * results in app's is in suspended state and not able to
19787 * process the connect request to AP
19788 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019789 hdd_prevent_suspend_timeout(2000,
19790 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019791 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019792 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019793
19794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19795 "%s : cfg80211 scan result database updated", __func__);
19796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019797 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019798 return 0;
19799
19800 }
19801 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19802 pAdapterNode = pNext;
19803 }
19804
19805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19806 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019807 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019808 return 0;
19809}
19810
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019811int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19812{
19813 int ret;
19814
19815 vos_ssr_protect(__func__);
19816 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19817 vos_ssr_unprotect(__func__);
19818
19819 return ret;
19820}
19821
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019822/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019823 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019824 * this is called when cfg80211 driver suspends
19825 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019826int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019827 struct cfg80211_wowlan *wow)
19828{
19829 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019830 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019831
19832 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019833
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019834 ret = wlan_hdd_validate_context(pHddCtx);
19835 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019836 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019837 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019838 }
19839
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019840 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19842 "%s: Suspend SoftAP", __func__);
19843 hdd_set_wlan_suspend_mode(true);
19844 }
19845
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019846
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19848 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19849 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019850 pHddCtx->isWiphySuspended = TRUE;
19851
19852 EXIT();
19853
19854 return 0;
19855}
19856
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019857int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19858 struct cfg80211_wowlan *wow)
19859{
19860 int ret;
19861
19862 vos_ssr_protect(__func__);
19863 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19864 vos_ssr_unprotect(__func__);
19865
19866 return ret;
19867}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019868
19869#ifdef FEATURE_OEM_DATA_SUPPORT
19870static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019871 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019872{
19873 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19874
19875 ENTER();
19876
19877 if (wlan_hdd_validate_context(pHddCtx)) {
19878 return;
19879 }
19880 if (!pMsg)
19881 {
19882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19883 return;
19884 }
19885
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019886 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019887
19888 EXIT();
19889 return;
19890
19891}
19892
19893void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019894 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019895{
19896 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19897
19898 ENTER();
19899
19900 if (wlan_hdd_validate_context(pHddCtx)) {
19901 return;
19902 }
19903
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019905
19906 switch(evType) {
19907 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019908 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019909 break;
19910 default:
19911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19912 break;
19913 }
19914 EXIT();
19915}
19916#endif
19917
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19919 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019920/**
19921 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19922 * @wiphy: Pointer to wiphy
19923 * @wdev: Pointer to wireless device structure
19924 *
19925 * This function is used to abort an ongoing scan
19926 *
19927 * Return: None
19928 */
19929static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19930 struct wireless_dev *wdev)
19931{
19932 struct net_device *dev = wdev->netdev;
19933 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19934 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19935 int ret;
19936
19937 ENTER();
19938
19939 if (NULL == adapter) {
19940 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19941 return;
19942 }
19943
19944 ret = wlan_hdd_validate_context(hdd_ctx);
19945 if (0 != ret)
19946 return;
19947
19948 wlan_hdd_scan_abort(adapter);
19949
19950 return;
19951}
19952
19953/**
19954 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19955 * @wiphy: Pointer to wiphy
19956 * @wdev: Pointer to wireless device structure
19957 *
19958 * Return: None
19959 */
19960void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19961 struct wireless_dev *wdev)
19962{
19963 vos_ssr_protect(__func__);
19964 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19965 vos_ssr_unprotect(__func__);
19966
19967 return;
19968}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019969#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019970
Jeff Johnson295189b2012-06-20 16:38:30 -070019971/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019972static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019973{
19974 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19975 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19976 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19977 .change_station = wlan_hdd_change_station,
19978#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19979 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19980 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19981 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019982#else
19983 .start_ap = wlan_hdd_cfg80211_start_ap,
19984 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19985 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019986#endif
19987 .change_bss = wlan_hdd_cfg80211_change_bss,
19988 .add_key = wlan_hdd_cfg80211_add_key,
19989 .get_key = wlan_hdd_cfg80211_get_key,
19990 .del_key = wlan_hdd_cfg80211_del_key,
19991 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019992#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019993 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019994#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019995 .scan = wlan_hdd_cfg80211_scan,
19996 .connect = wlan_hdd_cfg80211_connect,
19997 .disconnect = wlan_hdd_cfg80211_disconnect,
19998 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19999 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20000 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20001 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20002 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020003 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20004 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020005 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20007 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20008 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20009 .set_txq_params = wlan_hdd_set_txq_params,
20010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020011 .get_station = wlan_hdd_cfg80211_get_station,
20012 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20013 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020014 .add_station = wlan_hdd_cfg80211_add_station,
20015#ifdef FEATURE_WLAN_LFR
20016 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20017 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20018 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20019#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020020#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20021 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20022#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020023#ifdef FEATURE_WLAN_TDLS
20024 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20025 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20026#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020027#ifdef WLAN_FEATURE_GTK_OFFLOAD
20028 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20029#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020030#ifdef FEATURE_WLAN_SCAN_PNO
20031 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20032 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20033#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020034 .resume = wlan_hdd_cfg80211_resume_wlan,
20035 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020036 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020037#ifdef WLAN_NL80211_TESTMODE
20038 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20039#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020040 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20042 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020043 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020045};
20046