blob: 0e5ed0dfd7ab7f236813462d837e773c6680c5b3 [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
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530186
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530187static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700188{
189 WLAN_CIPHER_SUITE_WEP40,
190 WLAN_CIPHER_SUITE_WEP104,
191 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800192#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700193#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
194 WLAN_CIPHER_SUITE_KRK,
195 WLAN_CIPHER_SUITE_CCMP,
196#else
197 WLAN_CIPHER_SUITE_CCMP,
198#endif
199#ifdef FEATURE_WLAN_WAPI
200 WLAN_CIPHER_SUITE_SMS4,
201#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700202#ifdef WLAN_FEATURE_11W
203 WLAN_CIPHER_SUITE_AES_CMAC,
204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700205};
206
207static inline int is_broadcast_ether_addr(const u8 *addr)
208{
209 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
210 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
211}
212
Agrawal Ashish97dec502015-11-26 20:20:58 +0530213const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530214{
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 HDD2GHZCHAN(2412, 1, 0) ,
216 HDD2GHZCHAN(2417, 2, 0) ,
217 HDD2GHZCHAN(2422, 3, 0) ,
218 HDD2GHZCHAN(2427, 4, 0) ,
219 HDD2GHZCHAN(2432, 5, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2442, 7, 0) ,
222 HDD2GHZCHAN(2447, 8, 0) ,
223 HDD2GHZCHAN(2452, 9, 0) ,
224 HDD2GHZCHAN(2457, 10, 0) ,
225 HDD2GHZCHAN(2462, 11, 0) ,
226 HDD2GHZCHAN(2467, 12, 0) ,
227 HDD2GHZCHAN(2472, 13, 0) ,
228 HDD2GHZCHAN(2484, 14, 0) ,
229};
230
Agrawal Ashish97dec502015-11-26 20:20:58 +0530231const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700232{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700233 HDD5GHZCHAN(4920, 240, 0) ,
234 HDD5GHZCHAN(4940, 244, 0) ,
235 HDD5GHZCHAN(4960, 248, 0) ,
236 HDD5GHZCHAN(4980, 252, 0) ,
237 HDD5GHZCHAN(5040, 208, 0) ,
238 HDD5GHZCHAN(5060, 212, 0) ,
239 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 HDD5GHZCHAN(5180, 36, 0) ,
241 HDD5GHZCHAN(5200, 40, 0) ,
242 HDD5GHZCHAN(5220, 44, 0) ,
243 HDD5GHZCHAN(5240, 48, 0) ,
244 HDD5GHZCHAN(5260, 52, 0) ,
245 HDD5GHZCHAN(5280, 56, 0) ,
246 HDD5GHZCHAN(5300, 60, 0) ,
247 HDD5GHZCHAN(5320, 64, 0) ,
248 HDD5GHZCHAN(5500,100, 0) ,
249 HDD5GHZCHAN(5520,104, 0) ,
250 HDD5GHZCHAN(5540,108, 0) ,
251 HDD5GHZCHAN(5560,112, 0) ,
252 HDD5GHZCHAN(5580,116, 0) ,
253 HDD5GHZCHAN(5600,120, 0) ,
254 HDD5GHZCHAN(5620,124, 0) ,
255 HDD5GHZCHAN(5640,128, 0) ,
256 HDD5GHZCHAN(5660,132, 0) ,
257 HDD5GHZCHAN(5680,136, 0) ,
258 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800259#ifdef FEATURE_WLAN_CH144
260 HDD5GHZCHAN(5720,144, 0) ,
261#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 HDD5GHZCHAN(5745,149, 0) ,
263 HDD5GHZCHAN(5765,153, 0) ,
264 HDD5GHZCHAN(5785,157, 0) ,
265 HDD5GHZCHAN(5805,161, 0) ,
266 HDD5GHZCHAN(5825,165, 0) ,
267};
268
269static struct ieee80211_rate g_mode_rates[] =
270{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271 HDD_G_MODE_RATETAB(10, 0x1, 0),
272 HDD_G_MODE_RATETAB(20, 0x2, 0),
273 HDD_G_MODE_RATETAB(55, 0x4, 0),
274 HDD_G_MODE_RATETAB(110, 0x8, 0),
275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_rate a_mode_rates[] =
286{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287 HDD_G_MODE_RATETAB(60, 0x10, 0),
288 HDD_G_MODE_RATETAB(90, 0x20, 0),
289 HDD_G_MODE_RATETAB(120, 0x40, 0),
290 HDD_G_MODE_RATETAB(180, 0x80, 0),
291 HDD_G_MODE_RATETAB(240, 0x100, 0),
292 HDD_G_MODE_RATETAB(360, 0x200, 0),
293 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 HDD_G_MODE_RATETAB(540, 0x800, 0),
295};
296
297static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
298{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530299 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
301 .band = IEEE80211_BAND_2GHZ,
302 .bitrates = g_mode_rates,
303 .n_bitrates = g_mode_rates_size,
304 .ht_cap.ht_supported = 1,
305 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
306 | IEEE80211_HT_CAP_GRN_FLD
307 | IEEE80211_HT_CAP_DSSSCCK40
308 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
314};
315
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
317{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530318 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
320 .band = IEEE80211_BAND_5GHZ,
321 .bitrates = a_mode_rates,
322 .n_bitrates = a_mode_rates_size,
323 .ht_cap.ht_supported = 1,
324 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
325 | IEEE80211_HT_CAP_GRN_FLD
326 | IEEE80211_HT_CAP_DSSSCCK40
327 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
328 | IEEE80211_HT_CAP_SGI_40
329 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
330 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
331 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
332 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
333 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
334 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
335};
336
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530337/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 TX/RX direction for each kind of interface */
339static const struct ieee80211_txrx_stypes
340wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
341 [NL80211_IFTYPE_STATION] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ACTION) |
344 BIT(SIR_MAC_MGMT_PROBE_REQ),
345 },
346 [NL80211_IFTYPE_AP] = {
347 .tx = 0xffff,
348 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
350 BIT(SIR_MAC_MGMT_PROBE_REQ) |
351 BIT(SIR_MAC_MGMT_DISASSOC) |
352 BIT(SIR_MAC_MGMT_AUTH) |
353 BIT(SIR_MAC_MGMT_DEAUTH) |
354 BIT(SIR_MAC_MGMT_ACTION),
355 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700356 [NL80211_IFTYPE_ADHOC] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_PROBE_REQ) |
361 BIT(SIR_MAC_MGMT_DISASSOC) |
362 BIT(SIR_MAC_MGMT_AUTH) |
363 BIT(SIR_MAC_MGMT_DEAUTH) |
364 BIT(SIR_MAC_MGMT_ACTION),
365 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 [NL80211_IFTYPE_P2P_CLIENT] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ACTION) |
369 BIT(SIR_MAC_MGMT_PROBE_REQ),
370 },
371 [NL80211_IFTYPE_P2P_GO] = {
372 /* This is also same as for SoftAP */
373 .tx = 0xffff,
374 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ) |
377 BIT(SIR_MAC_MGMT_DISASSOC) |
378 BIT(SIR_MAC_MGMT_AUTH) |
379 BIT(SIR_MAC_MGMT_DEAUTH) |
380 BIT(SIR_MAC_MGMT_ACTION),
381 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700382};
383
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800385static const struct ieee80211_iface_limit
386wlan_hdd_iface_limit[] = {
387 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800388 /* max = 3 ; Our driver create two interfaces during driver init
389 * wlan0 and p2p0 interfaces. p2p0 is considered as station
390 * interface until a group is formed. In JB architecture, once the
391 * group is formed, interface type of p2p0 is changed to P2P GO or
392 * Client.
393 * When supplicant remove the group, it first issue a set interface
394 * cmd to change the mode back to Station. In JB this works fine as
395 * we advertize two station type interface during driver init.
396 * Some vendors create separate interface for P2P GO/Client,
397 * after group formation(Third one). But while group remove
398 * supplicant first tries to change the mode(3rd interface) to STATION
399 * But as we advertized only two sta type interfaces nl80211 was
400 * returning error for the third one which was leading to failure in
401 * delete interface. Ideally while removing the group, supplicant
402 * should not try to change the 3rd interface mode to Station type.
403 * Till we get a fix in wpa_supplicant, we advertize max STA
404 * interface type to 3
405 */
406 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407 .types = BIT(NL80211_IFTYPE_STATION),
408 },
409 {
410 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700411 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800412 },
413 {
414 .max = 1,
415 .types = BIT(NL80211_IFTYPE_P2P_GO) |
416 BIT(NL80211_IFTYPE_P2P_CLIENT),
417 },
418};
419
420/* By default, only single channel concurrency is allowed */
421static struct ieee80211_iface_combination
422wlan_hdd_iface_combination = {
423 .limits = wlan_hdd_iface_limit,
424 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800425 /*
426 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
427 * and p2p0 interfaces during driver init
428 * Some vendors create separate interface for P2P operations.
429 * wlan0: STA interface
430 * p2p0: P2P Device interface, action frames goes
431 * through this interface.
432 * p2p-xx: P2P interface, After GO negotiation this interface is
433 * created for p2p operations(GO/CLIENT interface).
434 */
435 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800436 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
437 .beacon_int_infra_match = false,
438};
439#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440
Jeff Johnson295189b2012-06-20 16:38:30 -0700441static struct cfg80211_ops wlan_hdd_cfg80211_ops;
442
443/* Data rate 100KBPS based on IE Index */
444struct index_data_rate_type
445{
446 v_U8_t beacon_rate_index;
447 v_U16_t supported_rate[4];
448};
449
450/* 11B, 11G Rate table include Basic rate and Extended rate
451 The IDX field is the rate index
452 The HI field is the rate when RSSI is strong or being ignored
453 (in this case we report actual rate)
454 The MID field is the rate when RSSI is moderate
455 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
456 The LO field is the rate when RSSI is low
457 (in this case we don't report rates, actual current rate used)
458 */
459static const struct
460{
461 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700462 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700463} supported_data_rate[] =
464{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700465/* IDX HI HM LM LO (RSSI-based index */
466 {2, { 10, 10, 10, 0}},
467 {4, { 20, 20, 10, 0}},
468 {11, { 55, 20, 10, 0}},
469 {12, { 60, 55, 20, 0}},
470 {18, { 90, 55, 20, 0}},
471 {22, {110, 55, 20, 0}},
472 {24, {120, 90, 60, 0}},
473 {36, {180, 120, 60, 0}},
474 {44, {220, 180, 60, 0}},
475 {48, {240, 180, 90, 0}},
476 {66, {330, 180, 90, 0}},
477 {72, {360, 240, 90, 0}},
478 {96, {480, 240, 120, 0}},
479 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700480};
481
482/* MCS Based rate table */
483static struct index_data_rate_type supported_mcs_rate[] =
484{
485/* MCS L20 L40 S20 S40 */
486 {0, {65, 135, 72, 150}},
487 {1, {130, 270, 144, 300}},
488 {2, {195, 405, 217, 450}},
489 {3, {260, 540, 289, 600}},
490 {4, {390, 810, 433, 900}},
491 {5, {520, 1080, 578, 1200}},
492 {6, {585, 1215, 650, 1350}},
493 {7, {650, 1350, 722, 1500}}
494};
495
Leo Chang6f8870f2013-03-26 18:11:36 -0700496#ifdef WLAN_FEATURE_11AC
497
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530498#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700499
500struct index_vht_data_rate_type
501{
502 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530503 v_U16_t supported_VHT80_rate[2];
504 v_U16_t supported_VHT40_rate[2];
505 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700506};
507
508typedef enum
509{
510 DATA_RATE_11AC_MAX_MCS_7,
511 DATA_RATE_11AC_MAX_MCS_8,
512 DATA_RATE_11AC_MAX_MCS_9,
513 DATA_RATE_11AC_MAX_MCS_NA
514} eDataRate11ACMaxMcs;
515
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530516/* SSID broadcast type */
517typedef enum eSSIDBcastType
518{
519 eBCAST_UNKNOWN = 0,
520 eBCAST_NORMAL = 1,
521 eBCAST_HIDDEN = 2,
522} tSSIDBcastType;
523
Leo Chang6f8870f2013-03-26 18:11:36 -0700524/* MCS Based VHT rate table */
525static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
526{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530527/* MCS L80 S80 L40 S40 L20 S40*/
528 {0, {293, 325}, {135, 150}, {65, 72}},
529 {1, {585, 650}, {270, 300}, {130, 144}},
530 {2, {878, 975}, {405, 450}, {195, 217}},
531 {3, {1170, 1300}, {540, 600}, {260, 289}},
532 {4, {1755, 1950}, {810, 900}, {390, 433}},
533 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
534 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
535 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
536 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
537 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700538};
539#endif /* WLAN_FEATURE_11AC */
540
c_hpothu79aab322014-07-14 21:11:01 +0530541/*array index points to MCS and array value points respective rssi*/
542static int rssiMcsTbl[][10] =
543{
544/*MCS 0 1 2 3 4 5 6 7 8 9*/
545 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
546 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
547 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
548};
549
Jeff Johnson295189b2012-06-20 16:38:30 -0700550extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530551#ifdef FEATURE_WLAN_SCAN_PNO
552static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700554
Leo Chang9056f462013-08-01 19:21:11 -0700555#ifdef WLAN_NL80211_TESTMODE
556enum wlan_hdd_tm_attr
557{
558 WLAN_HDD_TM_ATTR_INVALID = 0,
559 WLAN_HDD_TM_ATTR_CMD = 1,
560 WLAN_HDD_TM_ATTR_DATA = 2,
561 WLAN_HDD_TM_ATTR_TYPE = 3,
562 /* keep last */
563 WLAN_HDD_TM_ATTR_AFTER_LAST,
564 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
565};
566
567enum wlan_hdd_tm_cmd
568{
569 WLAN_HDD_TM_CMD_WLAN_HB = 1,
570};
571
572#define WLAN_HDD_TM_DATA_MAX_LEN 5000
573
574static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
575{
576 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
577 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
578 .len = WLAN_HDD_TM_DATA_MAX_LEN },
579};
580#endif /* WLAN_NL80211_TESTMODE */
581
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800582#ifdef FEATURE_WLAN_CH_AVOID
583/*
584 * FUNCTION: wlan_hdd_send_avoid_freq_event
585 * This is called when wlan driver needs to send vendor specific
586 * avoid frequency range event to userspace
587 */
588int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
589 tHddAvoidFreqList *pAvoidFreqList)
590{
591 struct sk_buff *vendor_event;
592
593 ENTER();
594
595 if (!pHddCtx)
596 {
597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
598 "%s: HDD context is null", __func__);
599 return -1;
600 }
601
602 if (!pAvoidFreqList)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
605 "%s: pAvoidFreqList is null", __func__);
606 return -1;
607 }
608
609 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530610#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
611 NULL,
612#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800613 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530614 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800615 GFP_KERNEL);
616 if (!vendor_event)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: cfg80211_vendor_event_alloc failed", __func__);
620 return -1;
621 }
622
623 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
624 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
625
626 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
627
628 EXIT();
629 return 0;
630}
631#endif /* FEATURE_WLAN_CH_AVOID */
632
Srinivas Dasari030bad32015-02-18 23:23:54 +0530633/*
634 * FUNCTION: __wlan_hdd_cfg80211_nan_request
635 * This is called when wlan driver needs to send vendor specific
636 * nan request event.
637 */
638static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
639 struct wireless_dev *wdev,
640 const void *data, int data_len)
641{
642 tNanRequestReq nan_req;
643 VOS_STATUS status;
644 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530645 struct net_device *dev = wdev->netdev;
646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
647 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
649
650 if (0 == data_len)
651 {
652 hddLog(VOS_TRACE_LEVEL_ERROR,
653 FL("NAN - Invalid Request, length = 0"));
654 return ret_val;
655 }
656
657 if (NULL == data)
658 {
659 hddLog(VOS_TRACE_LEVEL_ERROR,
660 FL("NAN - Invalid Request, data is NULL"));
661 return ret_val;
662 }
663
664 status = wlan_hdd_validate_context(pHddCtx);
665 if (0 != status)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("HDD context is not valid"));
669 return -EINVAL;
670 }
671
672 hddLog(LOG1, FL("Received NAN command"));
673 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
674 (tANI_U8 *)data, data_len);
675
676 /* check the NAN Capability */
677 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("NAN is not supported by Firmware"));
681 return -EINVAL;
682 }
683
684 nan_req.request_data_len = data_len;
685 nan_req.request_data = data;
686
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530687 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530688 if (VOS_STATUS_SUCCESS == status)
689 {
690 ret_val = 0;
691 }
692 return ret_val;
693}
694
695/*
696 * FUNCTION: wlan_hdd_cfg80211_nan_request
697 * Wrapper to protect the nan vendor command from ssr
698 */
699static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
700 struct wireless_dev *wdev,
701 const void *data, int data_len)
702{
703 int ret;
704
705 vos_ssr_protect(__func__);
706 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
707 vos_ssr_unprotect(__func__);
708
709 return ret;
710}
711
712/*
713 * FUNCTION: wlan_hdd_cfg80211_nan_callback
714 * This is a callback function and it gets called
715 * when we need to report nan response event to
716 * upper layers.
717 */
718static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
719{
720 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
721 struct sk_buff *vendor_event;
722 int status;
723 tSirNanEvent *data;
724
725 ENTER();
726 if (NULL == msg)
727 {
728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
729 FL(" msg received here is null"));
730 return;
731 }
732 data = msg;
733
734 status = wlan_hdd_validate_context(pHddCtx);
735
736 if (0 != status)
737 {
738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
739 FL("HDD context is not valid"));
740 return;
741 }
742
743 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
745 NULL,
746#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530747 data->event_data_len +
748 NLMSG_HDRLEN,
749 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
750 GFP_KERNEL);
751
752 if (!vendor_event)
753 {
754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
755 FL("cfg80211_vendor_event_alloc failed"));
756 return;
757 }
758 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
759 data->event_data_len, data->event_data))
760 {
761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
762 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
763 kfree_skb(vendor_event);
764 return;
765 }
766 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
767 EXIT();
768}
769
770/*
771 * FUNCTION: wlan_hdd_cfg80211_nan_init
772 * This function is called to register the callback to sme layer
773 */
774inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
775{
776 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
777}
778
779
Sunil Duttc69bccb2014-05-26 21:30:20 +0530780#ifdef WLAN_FEATURE_LINK_LAYER_STATS
781
782static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
783 struct sk_buff *vendor_event)
784{
785 if (nla_put_u8(vendor_event,
786 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
787 stats->rate.preamble) ||
788 nla_put_u8(vendor_event,
789 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
790 stats->rate.nss) ||
791 nla_put_u8(vendor_event,
792 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
793 stats->rate.bw) ||
794 nla_put_u8(vendor_event,
795 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
796 stats->rate.rateMcsIdx) ||
797 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
798 stats->rate.bitrate ) ||
799 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
800 stats->txMpdu ) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
802 stats->rxMpdu ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
804 stats->mpduLost ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
806 stats->retries) ||
807 nla_put_u32(vendor_event,
808 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
809 stats->retriesShort ) ||
810 nla_put_u32(vendor_event,
811 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
812 stats->retriesLong))
813 {
814 hddLog(VOS_TRACE_LEVEL_ERROR,
815 FL("QCA_WLAN_VENDOR_ATTR put fail"));
816 return FALSE;
817 }
818 return TRUE;
819}
820
821static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
822 struct sk_buff *vendor_event)
823{
824 u32 i = 0;
825 struct nlattr *rateInfo;
826 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
827 stats->type) ||
828 nla_put(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
830 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
833 stats->capabilities) ||
834 nla_put_u32(vendor_event,
835 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
836 stats->numRate))
837 {
838 hddLog(VOS_TRACE_LEVEL_ERROR,
839 FL("QCA_WLAN_VENDOR_ATTR put fail"));
840 goto error;
841 }
842
843 rateInfo = nla_nest_start(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530845 if(!rateInfo)
846 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530847 for (i = 0; i < stats->numRate; i++)
848 {
849 struct nlattr *rates;
850 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
851 stats->rateStats +
852 (i * sizeof(tSirWifiRateStat)));
853 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530854 if(!rates)
855 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530856
857 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
858 {
859 hddLog(VOS_TRACE_LEVEL_ERROR,
860 FL("QCA_WLAN_VENDOR_ATTR put fail"));
861 return FALSE;
862 }
863 nla_nest_end(vendor_event, rates);
864 }
865 nla_nest_end(vendor_event, rateInfo);
866
867 return TRUE;
868error:
869 return FALSE;
870}
871
872static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
873 struct sk_buff *vendor_event)
874{
875 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
876 stats->ac ) ||
877 nla_put_u32(vendor_event,
878 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
879 stats->txMpdu ) ||
880 nla_put_u32(vendor_event,
881 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
882 stats->rxMpdu ) ||
883 nla_put_u32(vendor_event,
884 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
885 stats->txMcast ) ||
886 nla_put_u32(vendor_event,
887 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
888 stats->rxMcast ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
891 stats->rxAmpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
894 stats->txAmpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
897 stats->mpduLost )||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
900 stats->retries ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
903 stats->retriesShort ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
906 stats->retriesLong ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
909 stats->contentionTimeMin ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
912 stats->contentionTimeMax ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
915 stats->contentionTimeAvg ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
918 stats->contentionNumSamples ))
919 {
920 hddLog(VOS_TRACE_LEVEL_ERROR,
921 FL("QCA_WLAN_VENDOR_ATTR put fail") );
922 return FALSE;
923 }
924 return TRUE;
925}
926
927static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
928 struct sk_buff *vendor_event)
929{
Dino Myclec8f3f332014-07-21 16:48:27 +0530930 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530931 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
932 nla_put(vendor_event,
933 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
934 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
935 nla_put_u32(vendor_event,
936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
937 stats->state ) ||
938 nla_put_u32(vendor_event,
939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
940 stats->roaming ) ||
941 nla_put_u32(vendor_event,
942 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
943 stats->capabilities ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
946 strlen(stats->ssid), stats->ssid) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
949 WNI_CFG_BSSID_LEN, stats->bssid) ||
950 nla_put(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
952 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
953 nla_put(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
955 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
956 )
957 {
958 hddLog(VOS_TRACE_LEVEL_ERROR,
959 FL("QCA_WLAN_VENDOR_ATTR put fail") );
960 return FALSE;
961 }
962 return TRUE;
963}
964
Dino Mycle3b9536d2014-07-09 22:05:24 +0530965static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
966 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530967 struct sk_buff *vendor_event)
968{
969 int i = 0;
970 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530971 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
972 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530973 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530974
Sunil Duttc69bccb2014-05-26 21:30:20 +0530975 if (FALSE == put_wifi_interface_info(
976 &pWifiIfaceStat->info,
977 vendor_event))
978 {
979 hddLog(VOS_TRACE_LEVEL_ERROR,
980 FL("QCA_WLAN_VENDOR_ATTR put fail") );
981 return FALSE;
982
983 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530984 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
985 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
986 if (NULL == pWifiIfaceStatTL)
987 {
988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
989 return FALSE;
990 }
991
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530992 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
995 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
996
997 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1000 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301001
1002 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1003 {
1004 if (VOS_STATUS_SUCCESS ==
1005 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1006 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1007 {
1008 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1009 * obtained from TL structure
1010 */
1011
1012 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1013 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301014 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1015
Srinivas Dasari98947432014-11-07 19:41:24 +05301016 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1017 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1018 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1019 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1020 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301024
Srinivas Dasari98947432014-11-07 19:41:24 +05301025 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1026 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1027 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1028 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1029 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301033
Srinivas Dasari98947432014-11-07 19:41:24 +05301034 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1036 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1037 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1038 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301042 }
1043 else
1044 {
1045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1046 }
1047
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1049 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1051 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1056 }
1057 else
1058 {
1059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1060 }
1061
1062
Sunil Duttc69bccb2014-05-26 21:30:20 +05301063
1064 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1066 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1067 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301068 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1069 pWifiIfaceStat->beaconRx) ||
1070 nla_put_u32(vendor_event,
1071 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1072 pWifiIfaceStat->mgmtRx) ||
1073 nla_put_u32(vendor_event,
1074 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1075 pWifiIfaceStat->mgmtActionRx) ||
1076 nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1078 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301079 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1081 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301082 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1084 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301085 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1087 pWifiIfaceStat->rssiAck))
1088 {
1089 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301090 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1091 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 return FALSE;
1093 }
1094
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301095#ifdef FEATURE_EXT_LL_STAT
1096 /*
1097 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1098 * then host should send Leaky AP stats to upper layer,
1099 * otherwise no need to send these stats.
1100 */
1101 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1102 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1103 )
1104 {
1105 hddLog(VOS_TRACE_LEVEL_INFO,
1106 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1107 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1108 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1109 pWifiIfaceStat->leakyApStat.rx_leak_window,
1110 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1111 if (nla_put_u32(vendor_event,
1112 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1113 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1114 nla_put_u32(vendor_event,
1115 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1116 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1117 nla_put_u32(vendor_event,
1118 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1119 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1120 nla_put_u64(vendor_event,
1121 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1122 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1123 {
1124 hddLog(VOS_TRACE_LEVEL_ERROR,
1125 FL("EXT_LL_STAT put fail"));
1126 vos_mem_free(pWifiIfaceStatTL);
1127 return FALSE;
1128 }
1129 }
1130#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301131 wmmInfo = nla_nest_start(vendor_event,
1132 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301133 if(!wmmInfo)
1134 {
1135 vos_mem_free(pWifiIfaceStatTL);
1136 return FALSE;
1137 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301138 for (i = 0; i < WIFI_AC_MAX; i++)
1139 {
1140 struct nlattr *wmmStats;
1141 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301142 if(!wmmStats)
1143 {
1144 vos_mem_free(pWifiIfaceStatTL);
1145 return FALSE;
1146 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301147 if (FALSE == put_wifi_wmm_ac_stat(
1148 &pWifiIfaceStat->AccessclassStats[i],
1149 vendor_event))
1150 {
1151 hddLog(VOS_TRACE_LEVEL_ERROR,
1152 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301153 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 return FALSE;
1155 }
1156
1157 nla_nest_end(vendor_event, wmmStats);
1158 }
1159 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301160 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301161 return TRUE;
1162}
1163
1164static tSirWifiInterfaceMode
1165 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1166{
1167 switch (deviceMode)
1168 {
1169 case WLAN_HDD_INFRA_STATION:
1170 return WIFI_INTERFACE_STA;
1171 case WLAN_HDD_SOFTAP:
1172 return WIFI_INTERFACE_SOFTAP;
1173 case WLAN_HDD_P2P_CLIENT:
1174 return WIFI_INTERFACE_P2P_CLIENT;
1175 case WLAN_HDD_P2P_GO:
1176 return WIFI_INTERFACE_P2P_GO;
1177 case WLAN_HDD_IBSS:
1178 return WIFI_INTERFACE_IBSS;
1179 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301180 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301181 }
1182}
1183
1184static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1185 tpSirWifiInterfaceInfo pInfo)
1186{
1187 v_U8_t *staMac = NULL;
1188 hdd_station_ctx_t *pHddStaCtx;
1189 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1190 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1191
1192 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1193
1194 vos_mem_copy(pInfo->macAddr,
1195 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1196
1197 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1199 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1200 {
1201 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1202 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_DISCONNECTED;
1205 }
1206 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1207 {
1208 hddLog(VOS_TRACE_LEVEL_ERROR,
1209 "%s: Session ID %d, Connection is in progress", __func__,
1210 pAdapter->sessionId);
1211 pInfo->state = WIFI_ASSOCIATING;
1212 }
1213 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1214 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1215 {
1216 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1217 hddLog(VOS_TRACE_LEVEL_ERROR,
1218 "%s: client " MAC_ADDRESS_STR
1219 " is in the middle of WPS/EAPOL exchange.", __func__,
1220 MAC_ADDR_ARRAY(staMac));
1221 pInfo->state = WIFI_AUTHENTICATING;
1222 }
1223 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1224 {
1225 pInfo->state = WIFI_ASSOCIATED;
1226 vos_mem_copy(pInfo->bssid,
1227 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1228 vos_mem_copy(pInfo->ssid,
1229 pHddStaCtx->conn_info.SSID.SSID.ssId,
1230 pHddStaCtx->conn_info.SSID.SSID.length);
1231 //NULL Terminate the string.
1232 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1233 }
1234 }
1235 vos_mem_copy(pInfo->countryStr,
1236 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1237
1238 vos_mem_copy(pInfo->apCountryStr,
1239 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1240
1241 return TRUE;
1242}
1243
1244/*
1245 * hdd_link_layer_process_peer_stats () - This function is called after
1246 * receiving Link Layer Peer statistics from FW.This function converts
1247 * the firmware data to the NL data and sends the same to the kernel/upper
1248 * layers.
1249 */
1250static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1251 v_VOID_t *pData)
1252{
1253 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301254 tpSirWifiPeerStat pWifiPeerStat;
1255 tpSirWifiPeerInfo pWifiPeerInfo;
1256 struct nlattr *peerInfo;
1257 struct sk_buff *vendor_event;
1258 int status, i;
1259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301260 ENTER();
1261
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 status = wlan_hdd_validate_context(pHddCtx);
1263 if (0 != status)
1264 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301265 return;
1266 }
1267
1268 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1269
1270 hddLog(VOS_TRACE_LEVEL_INFO,
1271 "LL_STATS_PEER_ALL : numPeers %u",
1272 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 /*
1274 * Allocate a size of 4096 for the peer stats comprising
1275 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1276 * sizeof (tSirWifiRateStat).Each field is put with an
1277 * NL attribute.The size of 4096 is considered assuming
1278 * that number of rates shall not exceed beyond 50 with
1279 * the sizeof (tSirWifiRateStat) being 32.
1280 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301281 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1282 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301283 if (!vendor_event)
1284 {
1285 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301286 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 __func__);
1288 return;
1289 }
1290 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1292 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1293 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301294 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1295 pWifiPeerStat->numPeers))
1296 {
1297 hddLog(VOS_TRACE_LEVEL_ERROR,
1298 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1299 kfree_skb(vendor_event);
1300 return;
1301 }
1302
1303 peerInfo = nla_nest_start(vendor_event,
1304 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301305 if(!peerInfo)
1306 {
1307 hddLog(VOS_TRACE_LEVEL_ERROR,
1308 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1309 __func__);
1310 kfree_skb(vendor_event);
1311 return;
1312 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301313
1314 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1315 pWifiPeerStat->peerInfo);
1316
1317 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1318 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301319 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301320 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301321
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301322 if(!peers)
1323 {
1324 hddLog(VOS_TRACE_LEVEL_ERROR,
1325 "%s: peer stats put fail",
1326 __func__);
1327 kfree_skb(vendor_event);
1328 return;
1329 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301330 if (FALSE == put_wifi_peer_info(
1331 pWifiPeerInfo, vendor_event))
1332 {
1333 hddLog(VOS_TRACE_LEVEL_ERROR,
1334 "%s: put_wifi_peer_info put fail", __func__);
1335 kfree_skb(vendor_event);
1336 return;
1337 }
1338
1339 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1340 pWifiPeerStat->peerInfo +
1341 (i * sizeof(tSirWifiPeerInfo)) +
1342 (numRate * sizeof (tSirWifiRateStat)));
1343 nla_nest_end(vendor_event, peers);
1344 }
1345 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301346 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301347 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348}
1349
1350/*
1351 * hdd_link_layer_process_iface_stats () - This function is called after
1352 * receiving Link Layer Interface statistics from FW.This function converts
1353 * the firmware data to the NL data and sends the same to the kernel/upper
1354 * layers.
1355 */
1356static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1357 v_VOID_t *pData)
1358{
1359 tpSirWifiIfaceStat pWifiIfaceStat;
1360 struct sk_buff *vendor_event;
1361 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1362 int status;
1363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301364 ENTER();
1365
Sunil Duttc69bccb2014-05-26 21:30:20 +05301366 status = wlan_hdd_validate_context(pHddCtx);
1367 if (0 != status)
1368 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301369 return;
1370 }
1371 /*
1372 * Allocate a size of 4096 for the interface stats comprising
1373 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1374 * assuming that all these fit with in the limit.Please take
1375 * a call on the limit based on the data requirements on
1376 * interface statistics.
1377 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301378 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1379 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301380 if (!vendor_event)
1381 {
1382 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301383 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 return;
1385 }
1386
1387 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1388
Dino Mycle3b9536d2014-07-09 22:05:24 +05301389
1390 if (FALSE == hdd_get_interface_info( pAdapter,
1391 &pWifiIfaceStat->info))
1392 {
1393 hddLog(VOS_TRACE_LEVEL_ERROR,
1394 FL("hdd_get_interface_info get fail") );
1395 kfree_skb(vendor_event);
1396 return;
1397 }
1398
1399 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1400 vendor_event))
1401 {
1402 hddLog(VOS_TRACE_LEVEL_ERROR,
1403 FL("put_wifi_iface_stats fail") );
1404 kfree_skb(vendor_event);
1405 return;
1406 }
1407
Sunil Duttc69bccb2014-05-26 21:30:20 +05301408 hddLog(VOS_TRACE_LEVEL_INFO,
1409 "WMI_LINK_STATS_IFACE Data");
1410
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301411 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301412
1413 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301414}
1415
1416/*
1417 * hdd_link_layer_process_radio_stats () - This function is called after
1418 * receiving Link Layer Radio statistics from FW.This function converts
1419 * the firmware data to the NL data and sends the same to the kernel/upper
1420 * layers.
1421 */
1422static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1423 v_VOID_t *pData)
1424{
1425 int status, i;
1426 tpSirWifiRadioStat pWifiRadioStat;
1427 tpSirWifiChannelStats pWifiChannelStats;
1428 struct sk_buff *vendor_event;
1429 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1430 struct nlattr *chList;
1431
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301432 ENTER();
1433
Sunil Duttc69bccb2014-05-26 21:30:20 +05301434 status = wlan_hdd_validate_context(pHddCtx);
1435 if (0 != status)
1436 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301437 return;
1438 }
1439 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1440
1441 hddLog(VOS_TRACE_LEVEL_INFO,
1442 "LL_STATS_RADIO"
1443 " radio is %d onTime is %u "
1444 " txTime is %u rxTime is %u "
1445 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301446 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 " onTimePnoScan is %u onTimeHs20 is %u "
1448 " numChannels is %u",
1449 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1450 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1451 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301452 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301453 pWifiRadioStat->onTimeRoamScan,
1454 pWifiRadioStat->onTimePnoScan,
1455 pWifiRadioStat->onTimeHs20,
1456 pWifiRadioStat->numChannels);
1457 /*
1458 * Allocate a size of 4096 for the Radio stats comprising
1459 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1460 * (tSirWifiChannelStats).Each channel data is put with an
1461 * NL attribute.The size of 4096 is considered assuming that
1462 * number of channels shall not exceed beyond 60 with the
1463 * sizeof (tSirWifiChannelStats) being 24 bytes.
1464 */
1465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301466 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1467 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301468 if (!vendor_event)
1469 {
1470 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301471 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301472 return;
1473 }
1474
1475 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1477 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1478 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1480 pWifiRadioStat->radio) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1483 pWifiRadioStat->onTime) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1486 pWifiRadioStat->txTime) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1489 pWifiRadioStat->rxTime) ||
1490 nla_put_u32(vendor_event,
1491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1492 pWifiRadioStat->onTimeScan) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1495 pWifiRadioStat->onTimeNbd) ||
1496 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1498 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1501 pWifiRadioStat->onTimeRoamScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1504 pWifiRadioStat->onTimePnoScan) ||
1505 nla_put_u32(vendor_event,
1506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1507 pWifiRadioStat->onTimeHs20) ||
1508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1510 pWifiRadioStat->numChannels))
1511 {
1512 hddLog(VOS_TRACE_LEVEL_ERROR,
1513 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1514 kfree_skb(vendor_event);
1515 return ;
1516 }
1517
1518 chList = nla_nest_start(vendor_event,
1519 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301520 if(!chList)
1521 {
1522 hddLog(VOS_TRACE_LEVEL_ERROR,
1523 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1524 __func__);
1525 kfree_skb(vendor_event);
1526 return;
1527 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301528 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1529 {
1530 struct nlattr *chInfo;
1531
1532 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1533 pWifiRadioStat->channels +
1534 (i * sizeof(tSirWifiChannelStats)));
1535
Sunil Duttc69bccb2014-05-26 21:30:20 +05301536 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301537 if(!chInfo)
1538 {
1539 hddLog(VOS_TRACE_LEVEL_ERROR,
1540 "%s: failed to put chInfo",
1541 __func__);
1542 kfree_skb(vendor_event);
1543 return;
1544 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545
1546 if (nla_put_u32(vendor_event,
1547 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1548 pWifiChannelStats->channel.width) ||
1549 nla_put_u32(vendor_event,
1550 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1551 pWifiChannelStats->channel.centerFreq) ||
1552 nla_put_u32(vendor_event,
1553 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1554 pWifiChannelStats->channel.centerFreq0) ||
1555 nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1557 pWifiChannelStats->channel.centerFreq1) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1560 pWifiChannelStats->onTime) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1563 pWifiChannelStats->ccaBusyTime))
1564 {
1565 hddLog(VOS_TRACE_LEVEL_ERROR,
1566 FL("cfg80211_vendor_event_alloc failed") );
1567 kfree_skb(vendor_event);
1568 return ;
1569 }
1570 nla_nest_end(vendor_event, chInfo);
1571 }
1572 nla_nest_end(vendor_event, chList);
1573
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301574 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301575
1576 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 return;
1578}
1579
1580/*
1581 * hdd_link_layer_stats_ind_callback () - This function is called after
1582 * receiving Link Layer indications from FW.This callback converts the firmware
1583 * data to the NL data and send the same to the kernel/upper layers.
1584 */
1585static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1586 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301587 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588{
Dino Mycled3d50022014-07-07 12:58:25 +05301589 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1590 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301591 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301592 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593 int status;
1594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301595 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301597 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301598 if (0 != status)
1599 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601 }
1602
Dino Mycled3d50022014-07-07 12:58:25 +05301603 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1604 if (NULL == pAdapter)
1605 {
1606 hddLog(VOS_TRACE_LEVEL_ERROR,
1607 FL(" MAC address %pM does not exist with host"),
1608 macAddr);
1609 return;
1610 }
1611
Sunil Duttc69bccb2014-05-26 21:30:20 +05301612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301613 "%s: Interface: %s LLStats indType: %d", __func__,
1614 pAdapter->dev->name, indType);
1615
Sunil Duttc69bccb2014-05-26 21:30:20 +05301616 switch (indType)
1617 {
1618 case SIR_HAL_LL_STATS_RESULTS_RSP:
1619 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301620 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301621 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1622 "respId = %u, moreResultToFollow = %u",
1623 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1624 macAddr, linkLayerStatsResults->respId,
1625 linkLayerStatsResults->moreResultToFollow);
1626
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301627 spin_lock(&hdd_context_lock);
1628 context = &pHddCtx->ll_stats_context;
1629 /* validate response received from target */
1630 if ((context->request_id != linkLayerStatsResults->respId) ||
1631 !(context->request_bitmap & linkLayerStatsResults->paramId))
1632 {
1633 spin_unlock(&hdd_context_lock);
1634 hddLog(LOGE,
1635 FL("Error : Request id %d response id %d request bitmap 0x%x"
1636 "response bitmap 0x%x"),
1637 context->request_id, linkLayerStatsResults->respId,
1638 context->request_bitmap, linkLayerStatsResults->paramId);
1639 return;
1640 }
1641 spin_unlock(&hdd_context_lock);
1642
Sunil Duttc69bccb2014-05-26 21:30:20 +05301643 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1644 {
1645 hdd_link_layer_process_radio_stats(pAdapter,
1646 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301647 spin_lock(&hdd_context_lock);
1648 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1649 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301650 }
1651 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1652 {
1653 hdd_link_layer_process_iface_stats(pAdapter,
1654 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301655 spin_lock(&hdd_context_lock);
1656 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1657 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301658 }
1659 else if ( linkLayerStatsResults->paramId &
1660 WMI_LINK_STATS_ALL_PEER )
1661 {
1662 hdd_link_layer_process_peer_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_ALL_PEER);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 } /* WMI_LINK_STATS_ALL_PEER */
1668 else
1669 {
1670 hddLog(VOS_TRACE_LEVEL_ERROR,
1671 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1672 }
1673
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301674 spin_lock(&hdd_context_lock);
1675 /* complete response event if all requests are completed */
1676 if (0 == context->request_bitmap)
1677 complete(&context->response_event);
1678 spin_unlock(&hdd_context_lock);
1679
Sunil Duttc69bccb2014-05-26 21:30:20 +05301680 break;
1681 }
1682 default:
1683 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1684 break;
1685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301686
1687 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 return;
1689}
1690
1691const struct
1692nla_policy
1693qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1694{
1695 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1696 { .type = NLA_U32 },
1697 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1698 { .type = NLA_U32 },
1699};
1700
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301701static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1702 struct wireless_dev *wdev,
1703 const void *data,
1704 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301705{
1706 int status;
1707 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301708 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301709 struct net_device *dev = wdev->netdev;
1710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1711 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301713 ENTER();
1714
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715 status = wlan_hdd_validate_context(pHddCtx);
1716 if (0 != status)
1717 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 return -EINVAL;
1719 }
1720
1721 if (NULL == pAdapter)
1722 {
1723 hddLog(VOS_TRACE_LEVEL_ERROR,
1724 FL("HDD adapter is Null"));
1725 return -ENODEV;
1726 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301727 /* check the LLStats Capability */
1728 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1729 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR,
1732 FL("Link Layer Statistics not supported by Firmware"));
1733 return -EINVAL;
1734 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735
1736 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1737 (struct nlattr *)data,
1738 data_len, qca_wlan_vendor_ll_set_policy))
1739 {
1740 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1741 return -EINVAL;
1742 }
1743 if (!tb_vendor
1744 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1747 return -EINVAL;
1748 }
1749 if (!tb_vendor[
1750 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1751 {
1752 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1753 return -EINVAL;
1754 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301756 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757
Dino Mycledf0a5d92014-07-04 09:41:55 +05301758 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 nla_get_u32(
1760 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1761
Dino Mycledf0a5d92014-07-04 09:41:55 +05301762 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301763 nla_get_u32(
1764 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1765
Dino Mycled3d50022014-07-07 12:58:25 +05301766 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1767 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768
1769
1770 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301771 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1772 "Statistics Gathering = %d ",
1773 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1774 linkLayerStatsSetReq.mpduSizeThreshold,
1775 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301776
1777 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1778 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301779 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 {
1781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1782 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301783 return -EINVAL;
1784
1785 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301786
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301788 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793 }
1794
1795 pAdapter->isLinkLayerStatsSet = 1;
1796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301797 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 return 0;
1799}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301800static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1801 struct wireless_dev *wdev,
1802 const void *data,
1803 int data_len)
1804{
1805 int ret = 0;
1806
1807 vos_ssr_protect(__func__);
1808 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1809 vos_ssr_unprotect(__func__);
1810
1811 return ret;
1812}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813
1814const struct
1815nla_policy
1816qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1817{
1818 /* Unsigned 32bit value provided by the caller issuing the GET stats
1819 * command. When reporting
1820 * the stats results, the driver uses the same value to indicate
1821 * which GET request the results
1822 * correspond to.
1823 */
1824 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1825
1826 /* Unsigned 32bit value . bit mask to identify what statistics are
1827 requested for retrieval */
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1829};
1830
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301831static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1832 struct wireless_dev *wdev,
1833 const void *data,
1834 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301836 unsigned long rc;
1837 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301838 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1839 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301840 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301841 struct net_device *dev = wdev->netdev;
1842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301843 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 int status;
1845
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301846 ENTER();
1847
Sunil Duttc69bccb2014-05-26 21:30:20 +05301848 status = wlan_hdd_validate_context(pHddCtx);
1849 if (0 != status)
1850 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301851 return -EINVAL ;
1852 }
1853
1854 if (NULL == pAdapter)
1855 {
1856 hddLog(VOS_TRACE_LEVEL_FATAL,
1857 "%s: HDD adapter is Null", __func__);
1858 return -ENODEV;
1859 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301860
1861 if (pHddStaCtx == NULL)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,
1864 "%s: HddStaCtx is Null", __func__);
1865 return -ENODEV;
1866 }
1867
Dino Mycledf0a5d92014-07-04 09:41:55 +05301868 /* check the LLStats Capability */
1869 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1870 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1871 {
1872 hddLog(VOS_TRACE_LEVEL_ERROR,
1873 FL("Link Layer Statistics not supported by Firmware"));
1874 return -EINVAL;
1875 }
1876
Sunil Duttc69bccb2014-05-26 21:30:20 +05301877
1878 if (!pAdapter->isLinkLayerStatsSet)
1879 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301880 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301881 "%s: isLinkLayerStatsSet : %d",
1882 __func__, pAdapter->isLinkLayerStatsSet);
1883 return -EINVAL;
1884 }
1885
Mukul Sharma10313ba2015-07-29 19:14:39 +05301886 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1887 {
1888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1889 "%s: Roaming in progress, so unable to proceed this request", __func__);
1890 return -EBUSY;
1891 }
1892
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1894 (struct nlattr *)data,
1895 data_len, qca_wlan_vendor_ll_get_policy))
1896 {
1897 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1898 return -EINVAL;
1899 }
1900
1901 if (!tb_vendor
1902 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1903 {
1904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1905 return -EINVAL;
1906 }
1907
1908 if (!tb_vendor
1909 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1910 {
1911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1912 return -EINVAL;
1913 }
1914
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915
Dino Mycledf0a5d92014-07-04 09:41:55 +05301916 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 nla_get_u32( tb_vendor[
1918 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301919 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 nla_get_u32( tb_vendor[
1921 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1922
Dino Mycled3d50022014-07-07 12:58:25 +05301923 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1924 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925
1926 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301927 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1928 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301929 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301931 spin_lock(&hdd_context_lock);
1932 context = &pHddCtx->ll_stats_context;
1933 context->request_id = linkLayerStatsGetReq.reqId;
1934 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1935 INIT_COMPLETION(context->response_event);
1936 spin_unlock(&hdd_context_lock);
1937
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301939 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301940 {
1941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1942 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943 return -EINVAL;
1944 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301945
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301946 rc = wait_for_completion_timeout(&context->response_event,
1947 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1948 if (!rc)
1949 {
1950 hddLog(LOGE,
1951 FL("Target response timed out request id %d request bitmap 0x%x"),
1952 context->request_id, context->request_bitmap);
1953 return -ETIMEDOUT;
1954 }
1955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301956 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957 return 0;
1958}
1959
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301960static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1961 struct wireless_dev *wdev,
1962 const void *data,
1963 int data_len)
1964{
1965 int ret = 0;
1966
1967 vos_ssr_protect(__func__);
1968 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1969 vos_ssr_unprotect(__func__);
1970
1971 return ret;
1972}
1973
Sunil Duttc69bccb2014-05-26 21:30:20 +05301974const struct
1975nla_policy
1976qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1977{
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1981 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1982};
1983
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301984static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1985 struct wireless_dev *wdev,
1986 const void *data,
1987 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301988{
1989 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1990 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301992 struct net_device *dev = wdev->netdev;
1993 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1994 u32 statsClearReqMask;
1995 u8 stopReq;
1996 int status;
1997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301998 ENTER();
1999
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 status = wlan_hdd_validate_context(pHddCtx);
2001 if (0 != status)
2002 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003 return -EINVAL;
2004 }
2005
2006 if (NULL == pAdapter)
2007 {
2008 hddLog(VOS_TRACE_LEVEL_FATAL,
2009 "%s: HDD adapter is Null", __func__);
2010 return -ENODEV;
2011 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302012 /* check the LLStats Capability */
2013 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2014 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2015 {
2016 hddLog(VOS_TRACE_LEVEL_ERROR,
2017 FL("Enable LLStats Capability"));
2018 return -EINVAL;
2019 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302020
2021 if (!pAdapter->isLinkLayerStatsSet)
2022 {
2023 hddLog(VOS_TRACE_LEVEL_FATAL,
2024 "%s: isLinkLayerStatsSet : %d",
2025 __func__, pAdapter->isLinkLayerStatsSet);
2026 return -EINVAL;
2027 }
2028
2029 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2030 (struct nlattr *)data,
2031 data_len, qca_wlan_vendor_ll_clr_policy))
2032 {
2033 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2034 return -EINVAL;
2035 }
2036
2037 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2038
2039 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2040 {
2041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2042 return -EINVAL;
2043
2044 }
2045
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046
Dino Mycledf0a5d92014-07-04 09:41:55 +05302047 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 nla_get_u32(
2049 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2050
Dino Mycledf0a5d92014-07-04 09:41:55 +05302051 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 nla_get_u8(
2053 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2054
2055 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057
Dino Mycled3d50022014-07-07 12:58:25 +05302058 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2059 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302060
2061 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302062 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2063 "statsClearReqMask = 0x%X, stopReq = %d",
2064 linkLayerStatsClearReq.reqId,
2065 linkLayerStatsClearReq.macAddr,
2066 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302067 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302068
2069 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302070 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 {
2072 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302073 hdd_station_ctx_t *pHddStaCtx;
2074
2075 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2076 if (VOS_STATUS_SUCCESS !=
2077 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2078 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2079 {
2080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2081 "WLANTL_ClearInterfaceStats Failed", __func__);
2082 return -EINVAL;
2083 }
2084 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2085 (statsClearReqMask & WIFI_STATS_IFACE)) {
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2089 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2090 }
2091
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2093 2 * sizeof(u32) +
2094 NLMSG_HDRLEN);
2095
2096 if (temp_skbuff != NULL)
2097 {
2098
2099 if (nla_put_u32(temp_skbuff,
2100 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2101 statsClearReqMask) ||
2102 nla_put_u32(temp_skbuff,
2103 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2104 stopReq))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2107 kfree_skb(temp_skbuff);
2108 return -EINVAL;
2109 }
2110 /* If the ask is to stop the stats collection as part of clear
2111 * (stopReq = 1) , ensure that no further requests of get
2112 * go to the firmware by having isLinkLayerStatsSet set to 0.
2113 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302114 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302115 * case the firmware is just asked to clear the statistics.
2116 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302117 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118 pAdapter->isLinkLayerStatsSet = 0;
2119 return cfg80211_vendor_cmd_reply(temp_skbuff);
2120 }
2121 return -ENOMEM;
2122 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302123
2124 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302125 return -EINVAL;
2126}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302127static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2128 struct wireless_dev *wdev,
2129 const void *data,
2130 int data_len)
2131{
2132 int ret = 0;
2133
2134 vos_ssr_protect(__func__);
2135 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2136 vos_ssr_unprotect(__func__);
2137
2138 return ret;
2139
2140
2141}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302142#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2143
Dino Mycle6fb96c12014-06-10 11:52:40 +05302144#ifdef WLAN_FEATURE_EXTSCAN
2145static const struct nla_policy
2146wlan_hdd_extscan_config_policy
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2148{
2149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2155 { .type = NLA_U32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2158
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2163 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2167 { .type = NLA_U32 },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2169 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2171 { .type = NLA_U32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2177 { .type = NLA_U8 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 { .type = NLA_U8 },
2180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2181 { .type = NLA_U8 },
2182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2183 { .type = NLA_U8 },
2184
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2186 { .type = NLA_U32 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2188 { .type = NLA_UNSPEC },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2192 { .type = NLA_S32 },
2193 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2194 { .type = NLA_U32 },
2195 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2196 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302197 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2198 { .type = NLA_U32 },
2199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2200 { .type = NLA_BINARY,
2201 .len = IEEE80211_MAX_SSID_LEN + 1 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302203 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2205 { .type = NLA_U32 },
2206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2207 { .type = NLA_U8 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2209 { .type = NLA_S32 },
2210 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2211 { .type = NLA_S32 },
2212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2213 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214};
2215
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302216/**
2217 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2218 * @ctx: hdd global context
2219 * @data: capabilities data
2220 *
2221 * Return: none
2222 */
2223static void
2224wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302225{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302226 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302227 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302228 tSirEXTScanCapabilitiesEvent *data =
2229 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302231 ENTER();
2232
2233 if (wlan_hdd_validate_context(pHddCtx))
2234 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302235 return;
2236 }
2237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302238 if (!pMsg)
2239 {
2240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2241 return;
2242 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302244 vos_spin_lock_acquire(&hdd_context_lock);
2245
2246 context = &pHddCtx->ext_scan_context;
2247 /* validate response received from target*/
2248 if (context->request_id != data->requestId)
2249 {
2250 vos_spin_lock_release(&hdd_context_lock);
2251 hddLog(LOGE,
2252 FL("Target response id did not match: request_id %d resposne_id %d"),
2253 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302254 return;
2255 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302256 else
2257 {
2258 context->capability_response = *data;
2259 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302260 }
2261
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302262 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263
Dino Mycle6fb96c12014-06-10 11:52:40 +05302264 return;
2265}
2266
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302267/*
2268 * define short names for the global vendor params
2269 * used by wlan_hdd_send_ext_scan_capability()
2270 */
2271#define PARAM_REQUEST_ID \
2272 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2273#define PARAM_STATUS \
2274 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2275#define MAX_SCAN_CACHE_SIZE \
2276 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2277#define MAX_SCAN_BUCKETS \
2278 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2279#define MAX_AP_CACHE_PER_SCAN \
2280 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2281#define MAX_RSSI_SAMPLE_SIZE \
2282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2283#define MAX_SCAN_RPT_THRHOLD \
2284 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2285#define MAX_HOTLIST_BSSIDS \
2286 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2287#define MAX_BSSID_HISTORY_ENTRIES \
2288 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2289#define MAX_HOTLIST_SSIDS \
2290 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302291#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2292 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302293
2294static int wlan_hdd_send_ext_scan_capability(void *ctx)
2295{
2296 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2297 struct sk_buff *skb = NULL;
2298 int ret;
2299 tSirEXTScanCapabilitiesEvent *data;
2300 tANI_U32 nl_buf_len;
2301
2302 ret = wlan_hdd_validate_context(pHddCtx);
2303 if (0 != ret)
2304 {
2305 return ret;
2306 }
2307
2308 data = &(pHddCtx->ext_scan_context.capability_response);
2309
2310 nl_buf_len = NLMSG_HDRLEN;
2311 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2312 (sizeof(data->status) + NLA_HDRLEN) +
2313 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2314 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2315 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2316 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2317 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2318 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2319 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2320 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2321
2322 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2323
2324 if (!skb)
2325 {
2326 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2327 return -ENOMEM;
2328 }
2329
2330 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2331 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2332 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2333 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2334 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2335 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2336 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2337 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2338
2339 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2340 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2341 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2342 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2343 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2344 data->maxApPerScan) ||
2345 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2346 data->maxRssiSampleSize) ||
2347 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2348 data->maxScanReportingThreshold) ||
2349 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2350 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2351 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302352 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2353 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302354 {
2355 hddLog(LOGE, FL("nla put fail"));
2356 goto nla_put_failure;
2357 }
2358
2359 cfg80211_vendor_cmd_reply(skb);
2360 return 0;
2361
2362nla_put_failure:
2363 kfree_skb(skb);
2364 return -EINVAL;;
2365}
2366
2367/*
2368 * done with short names for the global vendor params
2369 * used by wlan_hdd_send_ext_scan_capability()
2370 */
2371#undef PARAM_REQUEST_ID
2372#undef PARAM_STATUS
2373#undef MAX_SCAN_CACHE_SIZE
2374#undef MAX_SCAN_BUCKETS
2375#undef MAX_AP_CACHE_PER_SCAN
2376#undef MAX_RSSI_SAMPLE_SIZE
2377#undef MAX_SCAN_RPT_THRHOLD
2378#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302379#undef MAX_BSSID_HISTORY_ENTRIES
2380#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302381
2382static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2383{
2384 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2385 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302387 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302388
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302389 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302391 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302392 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302394 if (!pMsg)
2395 {
2396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397 return;
2398 }
2399
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2401 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2402
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302403 context = &pHddCtx->ext_scan_context;
2404 spin_lock(&hdd_context_lock);
2405 if (context->request_id == pData->requestId) {
2406 context->response_status = pData->status ? -EINVAL : 0;
2407 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302409 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302410
2411 /*
2412 * Store the Request ID for comparing with the requestID obtained
2413 * in other requests.HDD shall return a failure is the extscan_stop
2414 * request is issued with a different requestId as that of the
2415 * extscan_start request. Also, This requestId shall be used while
2416 * indicating the full scan results to the upper layers.
2417 * The requestId is stored with the assumption that the firmware
2418 * shall return the ext scan start request's requestId in ext scan
2419 * start response.
2420 */
2421 if (pData->status == 0)
2422 pMac->sme.extScanStartReqId = pData->requestId;
2423
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302424 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302426}
2427
2428
2429static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2430{
2431 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2432 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302433 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302435 ENTER();
2436
2437 if (wlan_hdd_validate_context(pHddCtx)){
2438 return;
2439 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302440
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302441 if (!pMsg)
2442 {
2443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302444 return;
2445 }
2446
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302447 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2448 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302450 context = &pHddCtx->ext_scan_context;
2451 spin_lock(&hdd_context_lock);
2452 if (context->request_id == pData->requestId) {
2453 context->response_status = pData->status ? -EINVAL : 0;
2454 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302455 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302456 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302458 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302460}
2461
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2463 void *pMsg)
2464{
2465 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466 tpSirEXTScanSetBssidHotListRspParams pData =
2467 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302468 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302470 ENTER();
2471
2472 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
2474 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476 if (!pMsg)
2477 {
2478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2479 return;
2480 }
2481
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302482 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2483 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302484
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302485 context = &pHddCtx->ext_scan_context;
2486 spin_lock(&hdd_context_lock);
2487 if (context->request_id == pData->requestId) {
2488 context->response_status = pData->status ? -EINVAL : 0;
2489 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302490 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302491 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302493 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302495}
2496
2497static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2498 void *pMsg)
2499{
2500 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302501 tpSirEXTScanResetBssidHotlistRspParams pData =
2502 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302503 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302505 ENTER();
2506
2507 if (wlan_hdd_validate_context(pHddCtx)) {
2508 return;
2509 }
2510 if (!pMsg)
2511 {
2512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513 return;
2514 }
2515
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302516 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2517 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302519 context = &pHddCtx->ext_scan_context;
2520 spin_lock(&hdd_context_lock);
2521 if (context->request_id == pData->requestId) {
2522 context->response_status = pData->status ? -EINVAL : 0;
2523 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302524 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302525 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302527 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302529}
2530
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302531static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2532 void *pMsg)
2533{
2534 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2535 tpSirEXTScanSetSsidHotListRspParams pData =
2536 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2537 struct hdd_ext_scan_context *context;
2538
2539 if (wlan_hdd_validate_context(pHddCtx)){
2540 return;
2541 }
2542
2543 if (!pMsg)
2544 {
2545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2546 return;
2547 }
2548
2549 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2550 pData->status);
2551
2552 context = &pHddCtx->ext_scan_context;
2553 spin_lock(&hdd_context_lock);
2554 if (context->request_id == pData->requestId) {
2555 context->response_status = pData->status ? -EINVAL : 0;
2556 complete(&context->response_event);
2557 }
2558 spin_unlock(&hdd_context_lock);
2559
2560 return;
2561}
2562
2563static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2564 void *pMsg)
2565{
2566 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2567 tpSirEXTScanResetSsidHotlistRspParams pData =
2568 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2569 struct hdd_ext_scan_context *context;
2570
2571 if (wlan_hdd_validate_context(pHddCtx)) {
2572 return;
2573 }
2574 if (!pMsg)
2575 {
2576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2577 return;
2578 }
2579
2580 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2581 pData->status);
2582
2583 context = &pHddCtx->ext_scan_context;
2584 spin_lock(&hdd_context_lock);
2585 if (context->request_id == pData->requestId) {
2586 context->response_status = pData->status ? -EINVAL : 0;
2587 complete(&context->response_event);
2588 }
2589 spin_unlock(&hdd_context_lock);
2590
2591 return;
2592}
2593
2594
Dino Mycle6fb96c12014-06-10 11:52:40 +05302595static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2596 void *pMsg)
2597{
2598 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2599 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302600 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302601 tANI_S32 totalResults;
2602 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302603 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2604 struct hdd_ext_scan_context *context;
2605 bool ignore_cached_results = false;
2606 tExtscanCachedScanResult *result;
2607 struct nlattr *nla_results;
2608 tANI_U16 ieLength= 0;
2609 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302611 ENTER();
2612
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302613 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302616 if (!pMsg)
2617 {
2618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2619 return;
2620 }
2621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302622 spin_lock(&hdd_context_lock);
2623 context = &pHddCtx->ext_scan_context;
2624 ignore_cached_results = context->ignore_cached_results;
2625 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302626
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302627 if (ignore_cached_results) {
2628 hddLog(LOGE,
2629 FL("Ignore the cached results received after timeout"));
2630 return;
2631 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302632
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302633 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2634 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302636 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302637
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302638 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2639 scan_id_index++) {
2640 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 totalResults = result->num_results;
2643 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2644 result->scan_id, result->flags, totalResults);
2645 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 do{
2648 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2649 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2650 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302651
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302652 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2653 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2654
2655 if (!skb) {
2656 hddLog(VOS_TRACE_LEVEL_ERROR,
2657 FL("cfg80211_vendor_event_alloc failed"));
2658 return;
2659 }
2660
2661 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2662
2663 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2664 pData->requestId) ||
2665 nla_put_u32(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2667 resultsPerEvent)) {
2668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2669 goto fail;
2670 }
2671 if (nla_put_u8(skb,
2672 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2673 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2676 goto fail;
2677 }
2678
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302679 if (nla_put_u32(skb,
2680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2681 result->scan_id)) {
2682 hddLog(LOGE, FL("put fail"));
2683 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302686 nla_results = nla_nest_start(skb,
2687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2688 if (!nla_results)
2689 goto fail;
2690
2691 if (resultsPerEvent) {
2692 struct nlattr *aps;
2693 struct nlattr *nla_result;
2694
2695 nla_result = nla_nest_start(skb, scan_id_index);
2696 if(!nla_result)
2697 goto fail;
2698
2699 if (nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2701 result->scan_id) ||
2702 nla_put_u32(skb,
2703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2704 result->flags) ||
2705 nla_put_u32(skb,
2706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2707 totalResults)) {
2708 hddLog(LOGE, FL("put fail"));
2709 goto fail;
2710 }
2711
2712 aps = nla_nest_start(skb,
2713 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2714 if (!aps)
2715 {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2717 goto fail;
2718 }
2719
2720 head_ptr = (tpSirWifiScanResult) &(result->ap);
2721
2722 for (j = 0; j < resultsPerEvent; j++, i++) {
2723 struct nlattr *ap;
2724 pSirWifiScanResult = head_ptr + i;
2725
2726 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302727 * Firmware returns timestamp from extscan_start till
2728 * BSSID was cached (in micro seconds). Add this with
2729 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302730 * to derive the time since boot when the
2731 * BSSID was cached.
2732 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302733 pSirWifiScanResult->ts +=
2734 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302735 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2736 "Ssid (%s)"
2737 "Bssid: %pM "
2738 "Channel (%u)"
2739 "Rssi (%d)"
2740 "RTT (%u)"
2741 "RTT_SD (%u)"
2742 "Beacon Period %u"
2743 "Capability 0x%x "
2744 "Ie length %d",
2745 i,
2746 pSirWifiScanResult->ts,
2747 pSirWifiScanResult->ssid,
2748 pSirWifiScanResult->bssid,
2749 pSirWifiScanResult->channel,
2750 pSirWifiScanResult->rssi,
2751 pSirWifiScanResult->rtt,
2752 pSirWifiScanResult->rtt_sd,
2753 pSirWifiScanResult->beaconPeriod,
2754 pSirWifiScanResult->capability,
2755 ieLength);
2756
2757 ap = nla_nest_start(skb, j + 1);
2758 if (!ap)
2759 {
2760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2761 goto fail;
2762 }
2763
2764 if (nla_put_u64(skb,
2765 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2766 pSirWifiScanResult->ts) )
2767 {
2768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2769 goto fail;
2770 }
2771 if (nla_put(skb,
2772 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2773 sizeof(pSirWifiScanResult->ssid),
2774 pSirWifiScanResult->ssid) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2781 sizeof(pSirWifiScanResult->bssid),
2782 pSirWifiScanResult->bssid) )
2783 {
2784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2785 goto fail;
2786 }
2787 if (nla_put_u32(skb,
2788 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2789 pSirWifiScanResult->channel) )
2790 {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2792 goto fail;
2793 }
2794 if (nla_put_s32(skb,
2795 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2796 pSirWifiScanResult->rssi) )
2797 {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2799 goto fail;
2800 }
2801 if (nla_put_u32(skb,
2802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2803 pSirWifiScanResult->rtt) )
2804 {
2805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2806 goto fail;
2807 }
2808 if (nla_put_u32(skb,
2809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2810 pSirWifiScanResult->rtt_sd))
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2813 goto fail;
2814 }
2815 if (nla_put_u32(skb,
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2817 pSirWifiScanResult->beaconPeriod))
2818 {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822 if (nla_put_u32(skb,
2823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2824 pSirWifiScanResult->capability))
2825 {
2826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2827 goto fail;
2828 }
2829 if (nla_put_u32(skb,
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2831 ieLength))
2832 {
2833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2834 goto fail;
2835 }
2836
2837 if (ieLength)
2838 if (nla_put(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2840 ieLength, ie)) {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2842 goto fail;
2843 }
2844
2845 nla_nest_end(skb, ap);
2846 }
2847 nla_nest_end(skb, aps);
2848 nla_nest_end(skb, nla_result);
2849 }
2850
2851 nla_nest_end(skb, nla_results);
2852
2853 cfg80211_vendor_cmd_reply(skb);
2854
2855 } while (totalResults > 0);
2856 }
2857
2858 if (!pData->moreData) {
2859 spin_lock(&hdd_context_lock);
2860 context->response_status = 0;
2861 complete(&context->response_event);
2862 spin_unlock(&hdd_context_lock);
2863 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302865 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302866 return;
2867fail:
2868 kfree_skb(skb);
2869 return;
2870}
2871
2872static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2873 void *pMsg)
2874{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302875 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2877 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302878 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302879
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302880 ENTER();
2881
2882 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302883 hddLog(LOGE,
2884 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302885 return;
2886 }
2887 if (!pMsg)
2888 {
2889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890 return;
2891 }
2892
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302893 if (pData->bss_found)
2894 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2895 else
2896 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2897
Dino Mycle6fb96c12014-06-10 11:52:40 +05302898 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2900 NULL,
2901#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302902 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302904
2905 if (!skb) {
2906 hddLog(VOS_TRACE_LEVEL_ERROR,
2907 FL("cfg80211_vendor_event_alloc failed"));
2908 return;
2909 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302911 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2913 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2914 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2915
2916 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2918 "Ssid (%s) "
2919 "Bssid (" MAC_ADDRESS_STR ") "
2920 "Channel (%u) "
2921 "Rssi (%d) "
2922 "RTT (%u) "
2923 "RTT_SD (%u) ",
2924 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 pData->bssHotlist[i].ts,
2926 pData->bssHotlist[i].ssid,
2927 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2928 pData->bssHotlist[i].channel,
2929 pData->bssHotlist[i].rssi,
2930 pData->bssHotlist[i].rtt,
2931 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302932 }
2933
2934 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2935 pData->requestId) ||
2936 nla_put_u32(skb,
2937 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302938 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2940 goto fail;
2941 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302942 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302943 struct nlattr *aps;
2944
2945 aps = nla_nest_start(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2947 if (!aps)
2948 goto fail;
2949
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302950 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302951 struct nlattr *ap;
2952
2953 ap = nla_nest_start(skb, i + 1);
2954 if (!ap)
2955 goto fail;
2956
2957 if (nla_put_u64(skb,
2958 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302959 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302960 nla_put(skb,
2961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302962 sizeof(pData->bssHotlist[i].ssid),
2963 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302964 nla_put(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302966 sizeof(pData->bssHotlist[i].bssid),
2967 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302968 nla_put_u32(skb,
2969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302970 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302971 nla_put_s32(skb,
2972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302973 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302974 nla_put_u32(skb,
2975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302976 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302977 nla_put_u32(skb,
2978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302979 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302980 goto fail;
2981
2982 nla_nest_end(skb, ap);
2983 }
2984 nla_nest_end(skb, aps);
2985
2986 if (nla_put_u8(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2988 pData->moreData))
2989 goto fail;
2990 }
2991
2992 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302993 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302994 return;
2995
2996fail:
2997 kfree_skb(skb);
2998 return;
2999
3000}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303002/**
3003 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3004 * Handle an SSID hotlist match event
3005 * @ctx: HDD context registered with SME
3006 * @event: The SSID hotlist match event
3007 *
3008 * This function will take an SSID match event that was generated by
3009 * firmware and will convert it into a cfg80211 vendor event which is
3010 * sent to userspace.
3011 *
3012 * Return: none
3013 */
3014static void
3015wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3016 void *pMsg)
3017{
3018 hdd_context_t *hdd_ctx = ctx;
3019 struct sk_buff *skb;
3020 tANI_U32 i, index;
3021 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3022
3023 ENTER();
3024
3025 if (wlan_hdd_validate_context(hdd_ctx)) {
3026 hddLog(LOGE,
3027 FL("HDD context is not valid or response"));
3028 return;
3029 }
3030 if (!pMsg)
3031 {
3032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3033 return;
3034 }
3035
3036 if (pData->ssid_found) {
3037 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3038 hddLog(LOG1, "SSID hotlist found");
3039 } else {
3040 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3041 hddLog(LOG1, "SSID hotlist lost");
3042 }
3043
3044 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3046 NULL,
3047#endif
3048 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3049 index, GFP_KERNEL);
3050
3051 if (!skb) {
3052 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3053 return;
3054 }
3055 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3056 pData->requestId, pData->numHotlistSsid, pData->moreData);
3057
3058 for (i = 0; i < pData->numHotlistSsid; i++) {
3059 hddLog(LOG1, "[i=%d] Timestamp %llu "
3060 "Ssid: %s "
3061 "Bssid (" MAC_ADDRESS_STR ") "
3062 "Channel %u "
3063 "Rssi %d "
3064 "RTT %u "
3065 "RTT_SD %u",
3066 i,
3067 pData->ssidHotlist[i].ts,
3068 pData->ssidHotlist[i].ssid,
3069 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3070 pData->ssidHotlist[i].channel,
3071 pData->ssidHotlist[i].rssi,
3072 pData->ssidHotlist[i].rtt,
3073 pData->ssidHotlist[i].rtt_sd);
3074 }
3075
3076 if (nla_put_u32(skb,
3077 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3078 pData->requestId) ||
3079 nla_put_u32(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3081 pData->numHotlistSsid)) {
3082 hddLog(LOGE, FL("put fail"));
3083 goto fail;
3084 }
3085
3086 if (pData->numHotlistSsid) {
3087 struct nlattr *aps;
3088 aps = nla_nest_start(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3090 if (!aps) {
3091 hddLog(LOGE, FL("nest fail"));
3092 goto fail;
3093 }
3094
3095 for (i = 0; i < pData->numHotlistSsid; i++) {
3096 struct nlattr *ap;
3097
3098 ap = nla_nest_start(skb, i);
3099 if (!ap) {
3100 hddLog(LOGE, FL("nest fail"));
3101 goto fail;
3102 }
3103
3104 if (nla_put_u64(skb,
3105 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3106 pData->ssidHotlist[i].ts) ||
3107 nla_put(skb,
3108 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3109 sizeof(pData->ssidHotlist[i].ssid),
3110 pData->ssidHotlist[i].ssid) ||
3111 nla_put(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3113 sizeof(pData->ssidHotlist[i].bssid),
3114 pData->ssidHotlist[i].bssid) ||
3115 nla_put_u32(skb,
3116 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3117 pData->ssidHotlist[i].channel) ||
3118 nla_put_s32(skb,
3119 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3120 pData->ssidHotlist[i].rssi) ||
3121 nla_put_u32(skb,
3122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3123 pData->ssidHotlist[i].rtt) ||
3124 nla_put_u32(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3126 pData->ssidHotlist[i].rtt_sd)) {
3127 hddLog(LOGE, FL("put fail"));
3128 goto fail;
3129 }
3130 nla_nest_end(skb, ap);
3131 }
3132 nla_nest_end(skb, aps);
3133
3134 if (nla_put_u8(skb,
3135 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3136 pData->moreData)) {
3137 hddLog(LOGE, FL("put fail"));
3138 goto fail;
3139 }
3140 }
3141
3142 cfg80211_vendor_event(skb, GFP_KERNEL);
3143 return;
3144
3145fail:
3146 kfree_skb(skb);
3147 return;
3148
3149}
3150
3151
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3153 void *pMsg)
3154{
3155 struct sk_buff *skb;
3156 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3157 tpSirWifiFullScanResultEvent pData =
3158 (tpSirWifiFullScanResultEvent) (pMsg);
3159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303160 ENTER();
3161
3162 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303163 hddLog(LOGE,
3164 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303165 return;
3166 }
3167 if (!pMsg)
3168 {
3169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303170 return;
3171 }
3172
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303173 /*
3174 * If the full scan result including IE data exceeds NL 4K size
3175 * limitation, drop that beacon/probe rsp frame.
3176 */
3177 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3178 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3179 return;
3180 }
3181
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3184 NULL,
3185#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303186 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3187 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3188 GFP_KERNEL);
3189
3190 if (!skb) {
3191 hddLog(VOS_TRACE_LEVEL_ERROR,
3192 FL("cfg80211_vendor_event_alloc failed"));
3193 return;
3194 }
3195
Dino Mycle6fb96c12014-06-10 11:52:40 +05303196 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3197 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3198 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3199 "Ssid (%s)"
3200 "Bssid (" MAC_ADDRESS_STR ")"
3201 "Channel (%u)"
3202 "Rssi (%d)"
3203 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303204 "RTT_SD (%u)"
3205 "Bcn Period %d"
3206 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303207 pData->ap.ts,
3208 pData->ap.ssid,
3209 MAC_ADDR_ARRAY(pData->ap.bssid),
3210 pData->ap.channel,
3211 pData->ap.rssi,
3212 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303213 pData->ap.rtt_sd,
3214 pData->ap.beaconPeriod,
3215 pData->ap.capability);
3216
Dino Mycle6fb96c12014-06-10 11:52:40 +05303217 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3218 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3219 pData->requestId) ||
3220 nla_put_u64(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3222 pData->ap.ts) ||
3223 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3224 sizeof(pData->ap.ssid),
3225 pData->ap.ssid) ||
3226 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3227 WNI_CFG_BSSID_LEN,
3228 pData->ap.bssid) ||
3229 nla_put_u32(skb,
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3231 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303232 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303233 pData->ap.rssi) ||
3234 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3235 pData->ap.rtt) ||
3236 nla_put_u32(skb,
3237 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3238 pData->ap.rtt_sd) ||
3239 nla_put_u16(skb,
3240 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3241 pData->ap.beaconPeriod) ||
3242 nla_put_u16(skb,
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3244 pData->ap.capability) ||
3245 nla_put_u32(skb,
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303247 pData->ieLength) ||
3248 nla_put_u8(skb,
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3250 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251 {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3253 goto nla_put_failure;
3254 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303255
3256 if (pData->ieLength) {
3257 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3258 pData->ieLength,
3259 pData->ie))
3260 {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3262 goto nla_put_failure;
3263 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303264 }
3265
3266 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303267 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 return;
3269
3270nla_put_failure:
3271 kfree_skb(skb);
3272 return;
3273}
3274
3275static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3276 void *pMsg)
3277{
3278 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3279 struct sk_buff *skb = NULL;
3280 tpSirEXTScanResultsAvailableIndParams pData =
3281 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303283 ENTER();
3284
3285 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303286 hddLog(LOGE,
3287 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303288 return;
3289 }
3290 if (!pMsg)
3291 {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293 return;
3294 }
3295
3296 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3298 NULL,
3299#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3301 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3302 GFP_KERNEL);
3303
3304 if (!skb) {
3305 hddLog(VOS_TRACE_LEVEL_ERROR,
3306 FL("cfg80211_vendor_event_alloc failed"));
3307 return;
3308 }
3309
Dino Mycle6fb96c12014-06-10 11:52:40 +05303310 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3311 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3312 pData->numResultsAvailable);
3313 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3314 pData->requestId) ||
3315 nla_put_u32(skb,
3316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3317 pData->numResultsAvailable)) {
3318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3319 goto nla_put_failure;
3320 }
3321
3322 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303323 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303324 return;
3325
3326nla_put_failure:
3327 kfree_skb(skb);
3328 return;
3329}
3330
3331static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3332{
3333 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3334 struct sk_buff *skb = NULL;
3335 tpSirEXTScanProgressIndParams pData =
3336 (tpSirEXTScanProgressIndParams) pMsg;
3337
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303338 ENTER();
3339
3340 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303341 hddLog(LOGE,
3342 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303343 return;
3344 }
3345 if (!pMsg)
3346 {
3347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 return;
3349 }
3350
3351 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303352#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3353 NULL,
3354#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3356 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3357 GFP_KERNEL);
3358
3359 if (!skb) {
3360 hddLog(VOS_TRACE_LEVEL_ERROR,
3361 FL("cfg80211_vendor_event_alloc failed"));
3362 return;
3363 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3366 pData->extScanEventType);
3367 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3368 pData->status);
3369
3370 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3371 pData->extScanEventType) ||
3372 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3374 pData->requestId) ||
3375 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3377 pData->status)) {
3378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3379 goto nla_put_failure;
3380 }
3381
3382 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303383 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384 return;
3385
3386nla_put_failure:
3387 kfree_skb(skb);
3388 return;
3389}
3390
3391void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3392 void *pMsg)
3393{
3394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303396 ENTER();
3397
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303399 return;
3400 }
3401
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3403
3404
3405 switch(evType) {
3406 case SIR_HAL_EXTSCAN_START_RSP:
3407 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3408 break;
3409
3410 case SIR_HAL_EXTSCAN_STOP_RSP:
3411 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3412 break;
3413 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3414 /* There is no need to send this response to upper layer
3415 Just log the message */
3416 hddLog(VOS_TRACE_LEVEL_INFO,
3417 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3418 break;
3419 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3420 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3421 break;
3422
3423 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3424 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3425 break;
3426
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303427 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3428 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3429 break;
3430
3431 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3432 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3433 break;
3434
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303436 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303437 break;
3438 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3439 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3440 break;
3441 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3442 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3443 break;
3444 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3445 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3446 break;
3447 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3448 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3449 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303450 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3451 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3452 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3454 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3455 break;
3456 default:
3457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3458 break;
3459 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303460 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461}
3462
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303463static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3464 struct wireless_dev *wdev,
3465 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466{
Dino Myclee8843b32014-07-04 14:21:45 +05303467 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303468 struct net_device *dev = wdev->netdev;
3469 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3470 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3471 struct nlattr
3472 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3473 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303474 struct hdd_ext_scan_context *context;
3475 unsigned long rc;
3476 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303478 ENTER();
3479
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480 status = wlan_hdd_validate_context(pHddCtx);
3481 if (0 != status)
3482 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483 return -EINVAL;
3484 }
Dino Myclee8843b32014-07-04 14:21:45 +05303485 /* check the EXTScan Capability */
3486 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303487 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3488 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303489 {
3490 hddLog(VOS_TRACE_LEVEL_ERROR,
3491 FL("EXTScan not enabled/supported by Firmware"));
3492 return -EINVAL;
3493 }
3494
Dino Mycle6fb96c12014-06-10 11:52:40 +05303495 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3496 data, dataLen,
3497 wlan_hdd_extscan_config_policy)) {
3498 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3499 return -EINVAL;
3500 }
3501
3502 /* Parse and fetch request Id */
3503 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3504 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3505 return -EINVAL;
3506 }
3507
Dino Myclee8843b32014-07-04 14:21:45 +05303508 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303511
Dino Myclee8843b32014-07-04 14:21:45 +05303512 reqMsg.sessionId = pAdapter->sessionId;
3513 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303515 vos_spin_lock_acquire(&hdd_context_lock);
3516 context = &pHddCtx->ext_scan_context;
3517 context->request_id = reqMsg.requestId;
3518 INIT_COMPLETION(context->response_event);
3519 vos_spin_lock_release(&hdd_context_lock);
3520
Dino Myclee8843b32014-07-04 14:21:45 +05303521 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 if (!HAL_STATUS_SUCCESS(status)) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR,
3524 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525 return -EINVAL;
3526 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303527
3528 rc = wait_for_completion_timeout(&context->response_event,
3529 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3530 if (!rc) {
3531 hddLog(LOGE, FL("Target response timed out"));
3532 return -ETIMEDOUT;
3533 }
3534
3535 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3536 if (ret)
3537 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3538
3539 return ret;
3540
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303541 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 return 0;
3543}
3544
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303545static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3546 struct wireless_dev *wdev,
3547 const void *data, int dataLen)
3548{
3549 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303551 vos_ssr_protect(__func__);
3552 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3553 vos_ssr_unprotect(__func__);
3554
3555 return ret;
3556}
3557
3558static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3559 struct wireless_dev *wdev,
3560 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561{
Dino Myclee8843b32014-07-04 14:21:45 +05303562 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 struct net_device *dev = wdev->netdev;
3564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3565 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3566 struct nlattr
3567 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3568 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303569 struct hdd_ext_scan_context *context;
3570 unsigned long rc;
3571 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303573 ENTER();
3574
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303575 if (VOS_FTM_MODE == hdd_get_conparam()) {
3576 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3577 return -EINVAL;
3578 }
3579
Dino Mycle6fb96c12014-06-10 11:52:40 +05303580 status = wlan_hdd_validate_context(pHddCtx);
3581 if (0 != status)
3582 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 return -EINVAL;
3584 }
Dino Myclee8843b32014-07-04 14:21:45 +05303585 /* check the EXTScan Capability */
3586 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303587 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3588 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303589 {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("EXTScan not enabled/supported by Firmware"));
3592 return -EINVAL;
3593 }
3594
Dino Mycle6fb96c12014-06-10 11:52:40 +05303595 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3596 data, dataLen,
3597 wlan_hdd_extscan_config_policy)) {
3598 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3599 return -EINVAL;
3600 }
3601 /* Parse and fetch request Id */
3602 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3604 return -EINVAL;
3605 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303606
Dino Myclee8843b32014-07-04 14:21:45 +05303607 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611
Dino Myclee8843b32014-07-04 14:21:45 +05303612 reqMsg.sessionId = pAdapter->sessionId;
3613 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303614
3615 /* Parse and fetch flush parameter */
3616 if (!tb
3617 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3618 {
3619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3620 goto failed;
3621 }
Dino Myclee8843b32014-07-04 14:21:45 +05303622 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3624
Dino Myclee8843b32014-07-04 14:21:45 +05303625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303627 spin_lock(&hdd_context_lock);
3628 context = &pHddCtx->ext_scan_context;
3629 context->request_id = reqMsg.requestId;
3630 context->ignore_cached_results = false;
3631 INIT_COMPLETION(context->response_event);
3632 spin_unlock(&hdd_context_lock);
3633
Dino Myclee8843b32014-07-04 14:21:45 +05303634 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635 if (!HAL_STATUS_SUCCESS(status)) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR,
3637 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638 return -EINVAL;
3639 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303640
3641 rc = wait_for_completion_timeout(&context->response_event,
3642 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3643 if (!rc) {
3644 hddLog(LOGE, FL("Target response timed out"));
3645 retval = -ETIMEDOUT;
3646 spin_lock(&hdd_context_lock);
3647 context->ignore_cached_results = true;
3648 spin_unlock(&hdd_context_lock);
3649 } else {
3650 spin_lock(&hdd_context_lock);
3651 retval = context->response_status;
3652 spin_unlock(&hdd_context_lock);
3653 }
3654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303655 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303656 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657
3658failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659 return -EINVAL;
3660}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303661static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3662 struct wireless_dev *wdev,
3663 const void *data, int dataLen)
3664{
3665 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303667 vos_ssr_protect(__func__);
3668 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3669 vos_ssr_unprotect(__func__);
3670
3671 return ret;
3672}
3673
3674static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303676 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303677{
3678 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3679 struct net_device *dev = wdev->netdev;
3680 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3681 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3682 struct nlattr
3683 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3684 struct nlattr
3685 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3686 struct nlattr *apTh;
3687 eHalStatus status;
3688 tANI_U8 i = 0;
3689 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303690 struct hdd_ext_scan_context *context;
3691 tANI_U32 request_id;
3692 unsigned long rc;
3693 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303694
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303695 ENTER();
3696
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303697 if (VOS_FTM_MODE == hdd_get_conparam()) {
3698 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3699 return -EINVAL;
3700 }
3701
Dino Mycle6fb96c12014-06-10 11:52:40 +05303702 status = wlan_hdd_validate_context(pHddCtx);
3703 if (0 != status)
3704 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303705 return -EINVAL;
3706 }
Dino Myclee8843b32014-07-04 14:21:45 +05303707 /* check the EXTScan Capability */
3708 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303709 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3710 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303711 {
3712 hddLog(VOS_TRACE_LEVEL_ERROR,
3713 FL("EXTScan not enabled/supported by Firmware"));
3714 return -EINVAL;
3715 }
3716
Dino Mycle6fb96c12014-06-10 11:52:40 +05303717 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3718 data, dataLen,
3719 wlan_hdd_extscan_config_policy)) {
3720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3721 return -EINVAL;
3722 }
3723
3724 /* Parse and fetch request Id */
3725 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3727 return -EINVAL;
3728 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3730 vos_mem_malloc(sizeof(*pReqMsg));
3731 if (!pReqMsg) {
3732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3733 return -ENOMEM;
3734 }
3735
Dino Myclee8843b32014-07-04 14:21:45 +05303736
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737 pReqMsg->requestId = nla_get_u32(
3738 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3739 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3740
3741 /* Parse and fetch number of APs */
3742 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3744 goto fail;
3745 }
3746
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303747 /* Parse and fetch lost ap sample size */
3748 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3749 hddLog(LOGE, FL("attr lost ap sample size failed"));
3750 goto fail;
3751 }
3752
3753 pReqMsg->lostBssidSampleSize = nla_get_u32(
3754 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3755 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3756
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 pReqMsg->sessionId = pAdapter->sessionId;
3758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3759
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303760 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763
3764 nla_for_each_nested(apTh,
3765 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3766 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3767 nla_data(apTh), nla_len(apTh),
3768 NULL)) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3770 goto fail;
3771 }
3772
3773 /* Parse and fetch MAC address */
3774 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3776 goto fail;
3777 }
3778 memcpy(pReqMsg->ap[i].bssid, nla_data(
3779 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3780 sizeof(tSirMacAddr));
3781 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3782
3783 /* Parse and fetch low RSSI */
3784 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3786 goto fail;
3787 }
3788 pReqMsg->ap[i].low = nla_get_s32(
3789 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3791
3792 /* Parse and fetch high RSSI */
3793 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3795 goto fail;
3796 }
3797 pReqMsg->ap[i].high = nla_get_s32(
3798 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3799 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3800 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303801 i++;
3802 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303803
3804 context = &pHddCtx->ext_scan_context;
3805 spin_lock(&hdd_context_lock);
3806 INIT_COMPLETION(context->response_event);
3807 context->request_id = request_id = pReqMsg->requestId;
3808 spin_unlock(&hdd_context_lock);
3809
Dino Mycle6fb96c12014-06-10 11:52:40 +05303810 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3811 if (!HAL_STATUS_SUCCESS(status)) {
3812 hddLog(VOS_TRACE_LEVEL_ERROR,
3813 FL("sme_SetBssHotlist failed(err=%d)"), status);
3814 vos_mem_free(pReqMsg);
3815 return -EINVAL;
3816 }
3817
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303818 /* request was sent -- wait for the response */
3819 rc = wait_for_completion_timeout(&context->response_event,
3820 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3821
3822 if (!rc) {
3823 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3824 retval = -ETIMEDOUT;
3825 } else {
3826 spin_lock(&hdd_context_lock);
3827 if (context->request_id == request_id)
3828 retval = context->response_status;
3829 else
3830 retval = -EINVAL;
3831 spin_unlock(&hdd_context_lock);
3832 }
3833
Dino Myclee8843b32014-07-04 14:21:45 +05303834 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303835 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303836 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303837
3838fail:
3839 vos_mem_free(pReqMsg);
3840 return -EINVAL;
3841}
3842
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303843static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3844 struct wireless_dev *wdev,
3845 const void *data, int dataLen)
3846{
3847 int ret = 0;
3848
3849 vos_ssr_protect(__func__);
3850 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3851 dataLen);
3852 vos_ssr_unprotect(__func__);
3853
3854 return ret;
3855}
3856
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303857/*
3858 * define short names for the global vendor params
3859 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3860 */
3861#define PARAM_MAX \
3862QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3863#define PARAM_REQUEST_ID \
3864QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3865#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3866QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3867#define PARAMS_NUM_SSID \
3868QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3869#define THRESHOLD_PARAM \
3870QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3871#define PARAM_SSID \
3872QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3873#define PARAM_BAND \
3874QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3875#define PARAM_RSSI_LOW \
3876QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3877#define PARAM_RSSI_HIGH \
3878QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3879
3880/**
3881 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3882 * @wiphy: Pointer to wireless phy
3883 * @wdev: Pointer to wireless device
3884 * @data: Pointer to data
3885 * @data_len: Data length
3886 *
3887 * Return: 0 on success, negative errno on failure
3888 */
3889static int
3890__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3891 struct wireless_dev *wdev,
3892 const void *data,
3893 int data_len)
3894{
3895 tSirEXTScanSetSsidHotListReqParams *request;
3896 struct net_device *dev = wdev->netdev;
3897 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3898 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3899 struct nlattr *tb[PARAM_MAX + 1];
3900 struct nlattr *tb2[PARAM_MAX + 1];
3901 struct nlattr *ssids;
3902 struct hdd_ext_scan_context *context;
3903 uint32_t request_id;
3904 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3905 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303906 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303907 eHalStatus status;
3908 int i, rem, retval;
3909 unsigned long rc;
3910
3911 ENTER();
3912
3913 if (VOS_FTM_MODE == hdd_get_conparam()) {
3914 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3915 return -EINVAL;
3916 }
3917
3918 retval = wlan_hdd_validate_context(hdd_ctx);
3919 if (0 != retval) {
3920 hddLog(LOGE, FL("HDD context is not valid"));
3921 return -EINVAL;
3922 }
3923
3924 /* check the EXTScan Capability */
3925 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303926 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3927 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303928 {
3929 hddLog(VOS_TRACE_LEVEL_ERROR,
3930 FL("EXTScan not enabled/supported by Firmware"));
3931 return -EINVAL;
3932 }
3933
3934 if (nla_parse(tb, PARAM_MAX,
3935 data, data_len,
3936 wlan_hdd_extscan_config_policy)) {
3937 hddLog(LOGE, FL("Invalid ATTR"));
3938 return -EINVAL;
3939 }
3940
3941 request = vos_mem_malloc(sizeof(*request));
3942 if (!request) {
3943 hddLog(LOGE, FL("vos_mem_malloc failed"));
3944 return -ENOMEM;
3945 }
3946
3947 /* Parse and fetch request Id */
3948 if (!tb[PARAM_REQUEST_ID]) {
3949 hddLog(LOGE, FL("attr request id failed"));
3950 goto fail;
3951 }
3952
3953 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3954 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3955
3956 /* Parse and fetch lost SSID sample size */
3957 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3958 hddLog(LOGE, FL("attr number of Ssid failed"));
3959 goto fail;
3960 }
3961 request->lost_ssid_sample_size =
3962 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3963 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3964 request->lost_ssid_sample_size);
3965
3966 /* Parse and fetch number of hotlist SSID */
3967 if (!tb[PARAMS_NUM_SSID]) {
3968 hddLog(LOGE, FL("attr number of Ssid failed"));
3969 goto fail;
3970 }
3971 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3972 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3973
3974 request->session_id = adapter->sessionId;
3975 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3976
3977 i = 0;
3978 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3979 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3980 hddLog(LOGE,
3981 FL("Too Many SSIDs, %d exceeds %d"),
3982 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3983 break;
3984 }
3985 if (nla_parse(tb2, PARAM_MAX,
3986 nla_data(ssids), nla_len(ssids),
3987 wlan_hdd_extscan_config_policy)) {
3988 hddLog(LOGE, FL("nla_parse failed"));
3989 goto fail;
3990 }
3991
3992 /* Parse and fetch SSID */
3993 if (!tb2[PARAM_SSID]) {
3994 hddLog(LOGE, FL("attr ssid failed"));
3995 goto fail;
3996 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05303997 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
3998 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303999 hddLog(LOG1, FL("SSID %s"),
4000 ssid_string);
4001 ssid_len = strlen(ssid_string);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304002 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4003 hddLog(LOGE, FL("Invalid ssid length"));
4004 goto fail;
4005 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304006 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4007 request->ssid[i].ssid.length = ssid_len;
4008 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4009 hddLog(LOG1, FL("After copying SSID %s"),
4010 request->ssid[i].ssid.ssId);
4011 hddLog(LOG1, FL("After copying length: %d"),
4012 ssid_len);
4013
4014 /* Parse and fetch low RSSI */
4015 if (!tb2[PARAM_BAND]) {
4016 hddLog(LOGE, FL("attr band failed"));
4017 goto fail;
4018 }
4019 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4020 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4021
4022 /* Parse and fetch low RSSI */
4023 if (!tb2[PARAM_RSSI_LOW]) {
4024 hddLog(LOGE, FL("attr low RSSI failed"));
4025 goto fail;
4026 }
4027 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4028 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4029
4030 /* Parse and fetch high RSSI */
4031 if (!tb2[PARAM_RSSI_HIGH]) {
4032 hddLog(LOGE, FL("attr high RSSI failed"));
4033 goto fail;
4034 }
4035 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4036 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4037 i++;
4038 }
4039
4040 context = &hdd_ctx->ext_scan_context;
4041 spin_lock(&hdd_context_lock);
4042 INIT_COMPLETION(context->response_event);
4043 context->request_id = request_id = request->request_id;
4044 spin_unlock(&hdd_context_lock);
4045
4046 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4047 if (!HAL_STATUS_SUCCESS(status)) {
4048 hddLog(LOGE,
4049 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4050 goto fail;
4051 }
4052
4053 vos_mem_free(request);
4054
4055 /* request was sent -- wait for the response */
4056 rc = wait_for_completion_timeout(&context->response_event,
4057 msecs_to_jiffies
4058 (WLAN_WAIT_TIME_EXTSCAN));
4059 if (!rc) {
4060 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4061 retval = -ETIMEDOUT;
4062 } else {
4063 spin_lock(&hdd_context_lock);
4064 if (context->request_id == request_id)
4065 retval = context->response_status;
4066 else
4067 retval = -EINVAL;
4068 spin_unlock(&hdd_context_lock);
4069 }
4070
4071 return retval;
4072
4073fail:
4074 vos_mem_free(request);
4075 return -EINVAL;
4076}
4077
4078/*
4079 * done with short names for the global vendor params
4080 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4081 */
4082#undef PARAM_MAX
4083#undef PARAM_REQUEST_ID
4084#undef PARAMS_NUM_SSID
4085#undef THRESHOLD_PARAM
4086#undef PARAM_SSID
4087#undef PARAM_BAND
4088#undef PARAM_RSSI_LOW
4089#undef PARAM_RSSI_HIGH
4090
4091static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4092 struct wireless_dev *wdev,
4093 const void *data, int dataLen)
4094{
4095 int ret = 0;
4096
4097 vos_ssr_protect(__func__);
4098 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4099 dataLen);
4100 vos_ssr_unprotect(__func__);
4101
4102 return ret;
4103}
4104
4105static int
4106__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4107 struct wireless_dev *wdev,
4108 const void *data,
4109 int data_len)
4110{
4111 tSirEXTScanResetSsidHotlistReqParams request;
4112 struct net_device *dev = wdev->netdev;
4113 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4114 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4115 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4116 struct hdd_ext_scan_context *context;
4117 uint32_t request_id;
4118 eHalStatus status;
4119 int retval;
4120 unsigned long rc;
4121
4122 ENTER();
4123
4124 if (VOS_FTM_MODE == hdd_get_conparam()) {
4125 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4126 return -EINVAL;
4127 }
4128
4129 retval = wlan_hdd_validate_context(hdd_ctx);
4130 if (0 != retval) {
4131 hddLog(LOGE, FL("HDD context is not valid"));
4132 return -EINVAL;
4133 }
4134
4135 /* check the EXTScan Capability */
4136 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304137 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4138 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304139 {
4140 hddLog(LOGE,
4141 FL("EXTScan not enabled/supported by Firmware"));
4142 return -EINVAL;
4143 }
4144
4145 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4146 data, data_len,
4147 wlan_hdd_extscan_config_policy)) {
4148 hddLog(LOGE, FL("Invalid ATTR"));
4149 return -EINVAL;
4150 }
4151
4152 /* Parse and fetch request Id */
4153 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4154 hddLog(LOGE, FL("attr request id failed"));
4155 return -EINVAL;
4156 }
4157
4158 request.requestId = nla_get_u32(
4159 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4160 request.sessionId = adapter->sessionId;
4161 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4162 request.sessionId);
4163
4164 context = &hdd_ctx->ext_scan_context;
4165 spin_lock(&hdd_context_lock);
4166 INIT_COMPLETION(context->response_event);
4167 context->request_id = request_id = request.requestId;
4168 spin_unlock(&hdd_context_lock);
4169
4170 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4171 if (!HAL_STATUS_SUCCESS(status)) {
4172 hddLog(LOGE,
4173 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4174 return -EINVAL;
4175 }
4176
4177 /* request was sent -- wait for the response */
4178 rc = wait_for_completion_timeout(&context->response_event,
4179 msecs_to_jiffies
4180 (WLAN_WAIT_TIME_EXTSCAN));
4181 if (!rc) {
4182 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4183 retval = -ETIMEDOUT;
4184 } else {
4185 spin_lock(&hdd_context_lock);
4186 if (context->request_id == request_id)
4187 retval = context->response_status;
4188 else
4189 retval = -EINVAL;
4190 spin_unlock(&hdd_context_lock);
4191 }
4192
4193 return retval;
4194}
4195
4196static int
4197wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4198 struct wireless_dev *wdev,
4199 const void *data,
4200 int data_len)
4201{
4202 int ret;
4203
4204 vos_ssr_protect(__func__);
4205 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4206 data, data_len);
4207 vos_ssr_unprotect(__func__);
4208
4209 return ret;
4210}
4211
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304212static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304214 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304216 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4217 struct net_device *dev = wdev->netdev;
4218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4219 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4220 uint8_t num_channels = 0;
4221 uint8_t num_chan_new = 0;
4222 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304224 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 tWifiBand wifiBand;
4226 eHalStatus status;
4227 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304228 tANI_U8 i,j,k;
4229 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304231 ENTER();
4232
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 status = wlan_hdd_validate_context(pHddCtx);
4234 if (0 != status)
4235 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304236 return -EINVAL;
4237 }
Dino Myclee8843b32014-07-04 14:21:45 +05304238
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4240 data, dataLen,
4241 wlan_hdd_extscan_config_policy)) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4243 return -EINVAL;
4244 }
4245
4246 /* Parse and fetch request Id */
4247 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4249 return -EINVAL;
4250 }
4251 requestId = nla_get_u32(
4252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4254
4255 /* Parse and fetch wifi band */
4256 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4257 {
4258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4259 return -EINVAL;
4260 }
4261 wifiBand = nla_get_u32(
4262 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4264
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304265 /* Parse and fetch max channels */
4266 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4267 {
4268 hddLog(LOGE, FL("attr max channels failed"));
4269 return -EINVAL;
4270 }
4271 maxChannels = nla_get_u32(
4272 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4274
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304276 wifiBand, chan_list,
4277 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 if (eHAL_STATUS_SUCCESS != status) {
4279 hddLog(VOS_TRACE_LEVEL_ERROR,
4280 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4281 return -EINVAL;
4282 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304283
Agrawal Ashish16abf782016-08-18 22:42:59 +05304284 num_channels = VOS_MIN(num_channels, maxChannels);
4285 num_chan_new = num_channels;
4286 /* remove the indoor only channels if iface is SAP */
4287 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4288 {
4289 num_chan_new = 0;
4290 for (i = 0; i < num_channels; i++)
4291 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4292 if (wiphy->bands[j] == NULL)
4293 continue;
4294 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4295 if ((chan_list[i] ==
4296 wiphy->bands[j]->channels[k].center_freq) &&
4297 (!(wiphy->bands[j]->channels[k].flags &
4298 IEEE80211_CHAN_INDOOR_ONLY))) {
4299 chan_list[num_chan_new] = chan_list[i];
4300 num_chan_new++;
4301 }
4302 }
4303 }
4304 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304305
Agrawal Ashish16abf782016-08-18 22:42:59 +05304306 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4307 for (i = 0; i < num_chan_new; i++)
4308 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4309 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310
4311 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304312 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313 NLMSG_HDRLEN);
4314
4315 if (!replySkb) {
4316 hddLog(VOS_TRACE_LEVEL_ERROR,
4317 FL("valid channels: buffer alloc fail"));
4318 return -EINVAL;
4319 }
4320 if (nla_put_u32(replySkb,
4321 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304322 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304323 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304324 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325
4326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4327 kfree_skb(replySkb);
4328 return -EINVAL;
4329 }
4330
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304331 ret = cfg80211_vendor_cmd_reply(replySkb);
4332
4333 EXIT();
4334 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304335}
4336
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304337static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4338 struct wireless_dev *wdev,
4339 const void *data, int dataLen)
4340{
4341 int ret = 0;
4342
4343 vos_ssr_protect(__func__);
4344 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4345 dataLen);
4346 vos_ssr_unprotect(__func__);
4347
4348 return ret;
4349}
4350
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304351static int hdd_extscan_start_fill_bucket_channel_spec(
4352 hdd_context_t *pHddCtx,
4353 tpSirEXTScanStartReqParams pReqMsg,
4354 struct nlattr **tb)
4355{
4356 struct nlattr *bucket[
4357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4358 struct nlattr *channel[
4359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4360 struct nlattr *buckets;
4361 struct nlattr *channels;
4362 int rem1, rem2;
4363 eHalStatus status;
4364 tANI_U8 bktIndex, j, numChannels;
4365 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4366 tANI_U32 passive_max_chn_time, active_max_chn_time;
4367
4368 bktIndex = 0;
4369
4370 nla_for_each_nested(buckets,
4371 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4372 if (nla_parse(bucket,
4373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4374 nla_data(buckets), nla_len(buckets), NULL)) {
4375 hddLog(LOGE, FL("nla_parse failed"));
4376 return -EINVAL;
4377 }
4378
4379 /* Parse and fetch bucket spec */
4380 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4381 hddLog(LOGE, FL("attr bucket index failed"));
4382 return -EINVAL;
4383 }
4384 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4385 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4386 hddLog(LOG1, FL("Bucket spec Index %d"),
4387 pReqMsg->buckets[bktIndex].bucket);
4388
4389 /* Parse and fetch wifi band */
4390 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4391 hddLog(LOGE, FL("attr wifi band failed"));
4392 return -EINVAL;
4393 }
4394 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4395 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4396 hddLog(LOG1, FL("Wifi band %d"),
4397 pReqMsg->buckets[bktIndex].band);
4398
4399 /* Parse and fetch period */
4400 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4401 hddLog(LOGE, FL("attr period failed"));
4402 return -EINVAL;
4403 }
4404 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4405 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4406 hddLog(LOG1, FL("period %d"),
4407 pReqMsg->buckets[bktIndex].period);
4408
4409 /* Parse and fetch report events */
4410 if (!bucket[
4411 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4412 hddLog(LOGE, FL("attr report events failed"));
4413 return -EINVAL;
4414 }
4415 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4416 bucket[
4417 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4418 hddLog(LOG1, FL("report events %d"),
4419 pReqMsg->buckets[bktIndex].reportEvents);
4420
4421 /* Parse and fetch max period */
4422 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4423 hddLog(LOGE, FL("attr max period failed"));
4424 return -EINVAL;
4425 }
4426 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4427 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4428 hddLog(LOG1, FL("max period %u"),
4429 pReqMsg->buckets[bktIndex].max_period);
4430
4431 /* Parse and fetch exponent */
4432 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4433 hddLog(LOGE, FL("attr exponent failed"));
4434 return -EINVAL;
4435 }
4436 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4437 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4438 hddLog(LOG1, FL("exponent %u"),
4439 pReqMsg->buckets[bktIndex].exponent);
4440
4441 /* Parse and fetch step count */
4442 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4443 hddLog(LOGE, FL("attr step count failed"));
4444 return -EINVAL;
4445 }
4446 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4447 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4448 hddLog(LOG1, FL("Step count %u"),
4449 pReqMsg->buckets[bktIndex].step_count);
4450
4451 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4452 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4453
4454 /* Framework shall pass the channel list if the input WiFi band is
4455 * WIFI_BAND_UNSPECIFIED.
4456 * If the input WiFi band is specified (any value other than
4457 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4458 */
4459 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4460 numChannels = 0;
4461 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4462 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4463 pReqMsg->buckets[bktIndex].band,
4464 chanList, &numChannels);
4465 if (!HAL_STATUS_SUCCESS(status)) {
4466 hddLog(LOGE,
4467 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4468 status);
4469 return -EINVAL;
4470 }
4471
4472 pReqMsg->buckets[bktIndex].numChannels =
4473 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4474 hddLog(LOG1, FL("Num channels %d"),
4475 pReqMsg->buckets[bktIndex].numChannels);
4476
4477 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4478 j++) {
4479 pReqMsg->buckets[bktIndex].channels[j].channel =
4480 chanList[j];
4481 pReqMsg->buckets[bktIndex].channels[j].
4482 chnlClass = 0;
4483 if (CSR_IS_CHANNEL_DFS(
4484 vos_freq_to_chan(chanList[j]))) {
4485 pReqMsg->buckets[bktIndex].channels[j].
4486 passive = 1;
4487 pReqMsg->buckets[bktIndex].channels[j].
4488 dwellTimeMs = passive_max_chn_time;
4489 } else {
4490 pReqMsg->buckets[bktIndex].channels[j].
4491 passive = 0;
4492 pReqMsg->buckets[bktIndex].channels[j].
4493 dwellTimeMs = active_max_chn_time;
4494 }
4495
4496 hddLog(LOG1,
4497 "Channel %u Passive %u Dwell time %u ms",
4498 pReqMsg->buckets[bktIndex].channels[j].channel,
4499 pReqMsg->buckets[bktIndex].channels[j].passive,
4500 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4501 }
4502
4503 bktIndex++;
4504 continue;
4505 }
4506
4507 /* Parse and fetch number of channels */
4508 if (!bucket[
4509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4510 hddLog(LOGE, FL("attr num channels failed"));
4511 return -EINVAL;
4512 }
4513
4514 pReqMsg->buckets[bktIndex].numChannels =
4515 nla_get_u32(bucket[
4516 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4517 hddLog(LOG1, FL("num channels %d"),
4518 pReqMsg->buckets[bktIndex].numChannels);
4519
4520 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4521 hddLog(LOGE, FL("attr channel spec failed"));
4522 return -EINVAL;
4523 }
4524
4525 j = 0;
4526 nla_for_each_nested(channels,
4527 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4528 if (nla_parse(channel,
4529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4530 nla_data(channels), nla_len(channels),
4531 wlan_hdd_extscan_config_policy)) {
4532 hddLog(LOGE, FL("nla_parse failed"));
4533 return -EINVAL;
4534 }
4535
4536 /* Parse and fetch channel */
4537 if (!channel[
4538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4539 hddLog(LOGE, FL("attr channel failed"));
4540 return -EINVAL;
4541 }
4542 pReqMsg->buckets[bktIndex].channels[j].channel =
4543 nla_get_u32(channel[
4544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4545 hddLog(LOG1, FL("channel %u"),
4546 pReqMsg->buckets[bktIndex].channels[j].channel);
4547
4548 /* Parse and fetch dwell time */
4549 if (!channel[
4550 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4551 hddLog(LOGE, FL("attr dwelltime failed"));
4552 return -EINVAL;
4553 }
4554 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4555 nla_get_u32(channel[
4556 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4557
4558 hddLog(LOG1, FL("Dwell time (%u ms)"),
4559 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4560
4561
4562 /* Parse and fetch channel spec passive */
4563 if (!channel[
4564 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4565 hddLog(LOGE,
4566 FL("attr channel spec passive failed"));
4567 return -EINVAL;
4568 }
4569 pReqMsg->buckets[bktIndex].channels[j].passive =
4570 nla_get_u8(channel[
4571 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4572 hddLog(LOG1, FL("Chnl spec passive %u"),
4573 pReqMsg->buckets[bktIndex].channels[j].passive);
4574
4575 j++;
4576 }
4577
4578 bktIndex++;
4579 }
4580
4581 return 0;
4582}
4583
4584
4585/*
4586 * define short names for the global vendor params
4587 * used by wlan_hdd_cfg80211_extscan_start()
4588 */
4589#define PARAM_MAX \
4590QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4591#define PARAM_REQUEST_ID \
4592QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4593#define PARAM_BASE_PERIOD \
4594QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4595#define PARAM_MAX_AP_PER_SCAN \
4596QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4597#define PARAM_RPT_THRHLD_PERCENT \
4598QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4599#define PARAM_RPT_THRHLD_NUM_SCANS \
4600QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4601#define PARAM_NUM_BUCKETS \
4602QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4603
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304604static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304606 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304607{
Dino Myclee8843b32014-07-04 14:21:45 +05304608 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304609 struct net_device *dev = wdev->netdev;
4610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4611 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4612 struct nlattr *tb[PARAM_MAX + 1];
4613 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304615 tANI_U32 request_id;
4616 struct hdd_ext_scan_context *context;
4617 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304619 ENTER();
4620
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304621 if (VOS_FTM_MODE == hdd_get_conparam()) {
4622 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4623 return -EINVAL;
4624 }
4625
Dino Mycle6fb96c12014-06-10 11:52:40 +05304626 status = wlan_hdd_validate_context(pHddCtx);
4627 if (0 != status)
4628 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 return -EINVAL;
4630 }
Dino Myclee8843b32014-07-04 14:21:45 +05304631 /* check the EXTScan Capability */
4632 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304633 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4634 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304635 {
4636 hddLog(VOS_TRACE_LEVEL_ERROR,
4637 FL("EXTScan not enabled/supported by Firmware"));
4638 return -EINVAL;
4639 }
4640
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304641 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304642 data, dataLen,
4643 wlan_hdd_extscan_config_policy)) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4645 return -EINVAL;
4646 }
4647
4648 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304649 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4651 return -EINVAL;
4652 }
4653
Dino Myclee8843b32014-07-04 14:21:45 +05304654 pReqMsg = (tpSirEXTScanStartReqParams)
4655 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304656 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4658 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 }
4660
4661 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4664
4665 pReqMsg->sessionId = pAdapter->sessionId;
4666 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4667
4668 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304669 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4671 goto fail;
4672 }
4673 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304674 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4676 pReqMsg->basePeriod);
4677
4678 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4681 goto fail;
4682 }
4683 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4686 pReqMsg->maxAPperScan);
4687
4688 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304689 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4691 goto fail;
4692 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304693 pReqMsg->reportThresholdPercent = nla_get_u8(
4694 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304696 pReqMsg->reportThresholdPercent);
4697
4698 /* Parse and fetch report threshold num scans */
4699 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4700 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4701 goto fail;
4702 }
4703 pReqMsg->reportThresholdNumScans = nla_get_u8(
4704 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4705 hddLog(LOG1, FL("Report Threshold num scans %d"),
4706 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304707
4708 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304709 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4711 goto fail;
4712 }
4713 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304715 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4716 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4717 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4718 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4719 }
4720 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4721 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304722
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4725 goto fail;
4726 }
4727
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304728 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304730 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4731 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304732
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304733 context = &pHddCtx->ext_scan_context;
4734 spin_lock(&hdd_context_lock);
4735 INIT_COMPLETION(context->response_event);
4736 context->request_id = request_id = pReqMsg->requestId;
4737 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304738
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4740 if (!HAL_STATUS_SUCCESS(status)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR,
4742 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304743 goto fail;
4744 }
4745
Srinivas Dasari91727c12016-03-23 17:59:06 +05304746 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4747
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304748 /* request was sent -- wait for the response */
4749 rc = wait_for_completion_timeout(&context->response_event,
4750 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4751
4752 if (!rc) {
4753 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4754 retval = -ETIMEDOUT;
4755 } else {
4756 spin_lock(&hdd_context_lock);
4757 if (context->request_id == request_id)
4758 retval = context->response_status;
4759 else
4760 retval = -EINVAL;
4761 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304762 }
4763
Dino Myclee8843b32014-07-04 14:21:45 +05304764 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304765 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304766 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304767
4768fail:
4769 vos_mem_free(pReqMsg);
4770 return -EINVAL;
4771}
4772
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304773/*
4774 * done with short names for the global vendor params
4775 * used by wlan_hdd_cfg80211_extscan_start()
4776 */
4777#undef PARAM_MAX
4778#undef PARAM_REQUEST_ID
4779#undef PARAM_BASE_PERIOD
4780#undef PARAMS_MAX_AP_PER_SCAN
4781#undef PARAMS_RPT_THRHLD_PERCENT
4782#undef PARAMS_RPT_THRHLD_NUM_SCANS
4783#undef PARAMS_NUM_BUCKETS
4784
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304785static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4786 struct wireless_dev *wdev,
4787 const void *data, int dataLen)
4788{
4789 int ret = 0;
4790
4791 vos_ssr_protect(__func__);
4792 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4793 vos_ssr_unprotect(__func__);
4794
4795 return ret;
4796}
4797
4798static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304799 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304800 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304801{
Dino Myclee8843b32014-07-04 14:21:45 +05304802 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304803 struct net_device *dev = wdev->netdev;
4804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4805 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4806 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4807 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304808 int retval;
4809 unsigned long rc;
4810 struct hdd_ext_scan_context *context;
4811 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304813 ENTER();
4814
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304815 if (VOS_FTM_MODE == hdd_get_conparam()) {
4816 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4817 return -EINVAL;
4818 }
4819
Dino Mycle6fb96c12014-06-10 11:52:40 +05304820 status = wlan_hdd_validate_context(pHddCtx);
4821 if (0 != status)
4822 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823 return -EINVAL;
4824 }
Dino Myclee8843b32014-07-04 14:21:45 +05304825 /* check the EXTScan Capability */
4826 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304827 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4828 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304829 {
4830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 FL("EXTScan not enabled/supported by Firmware"));
4832 return -EINVAL;
4833 }
4834
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4836 data, dataLen,
4837 wlan_hdd_extscan_config_policy)) {
4838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4839 return -EINVAL;
4840 }
4841
4842 /* Parse and fetch request Id */
4843 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4845 return -EINVAL;
4846 }
4847
Dino Myclee8843b32014-07-04 14:21:45 +05304848 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304849 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304850 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304851
Dino Myclee8843b32014-07-04 14:21:45 +05304852 reqMsg.sessionId = pAdapter->sessionId;
4853 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304855 context = &pHddCtx->ext_scan_context;
4856 spin_lock(&hdd_context_lock);
4857 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304858 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304859 spin_unlock(&hdd_context_lock);
4860
Dino Myclee8843b32014-07-04 14:21:45 +05304861 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304862 if (!HAL_STATUS_SUCCESS(status)) {
4863 hddLog(VOS_TRACE_LEVEL_ERROR,
4864 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865 return -EINVAL;
4866 }
4867
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304868 /* request was sent -- wait for the response */
4869 rc = wait_for_completion_timeout(&context->response_event,
4870 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4871
4872 if (!rc) {
4873 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4874 retval = -ETIMEDOUT;
4875 } else {
4876 spin_lock(&hdd_context_lock);
4877 if (context->request_id == request_id)
4878 retval = context->response_status;
4879 else
4880 retval = -EINVAL;
4881 spin_unlock(&hdd_context_lock);
4882 }
4883
4884 return retval;
4885
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304886 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887 return 0;
4888}
4889
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304890static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4891 struct wireless_dev *wdev,
4892 const void *data, int dataLen)
4893{
4894 int ret = 0;
4895
4896 vos_ssr_protect(__func__);
4897 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4898 vos_ssr_unprotect(__func__);
4899
4900 return ret;
4901}
4902
4903static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304904 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304905 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304906{
Dino Myclee8843b32014-07-04 14:21:45 +05304907 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908 struct net_device *dev = wdev->netdev;
4909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4910 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4911 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4912 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304913 struct hdd_ext_scan_context *context;
4914 tANI_U32 request_id;
4915 unsigned long rc;
4916 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304918 ENTER();
4919
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304920 if (VOS_FTM_MODE == hdd_get_conparam()) {
4921 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4922 return -EINVAL;
4923 }
4924
Dino Mycle6fb96c12014-06-10 11:52:40 +05304925 status = wlan_hdd_validate_context(pHddCtx);
4926 if (0 != status)
4927 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304928 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304929 return -EINVAL;
4930 }
Dino Myclee8843b32014-07-04 14:21:45 +05304931 /* check the EXTScan Capability */
4932 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304933 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4934 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304935 {
4936 hddLog(VOS_TRACE_LEVEL_ERROR,
4937 FL("EXTScan not enabled/supported by Firmware"));
4938 return -EINVAL;
4939 }
4940
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4942 data, dataLen,
4943 wlan_hdd_extscan_config_policy)) {
4944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4945 return -EINVAL;
4946 }
4947
4948 /* Parse and fetch request Id */
4949 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4951 return -EINVAL;
4952 }
4953
Dino Myclee8843b32014-07-04 14:21:45 +05304954 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304955 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304956 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304957
Dino Myclee8843b32014-07-04 14:21:45 +05304958 reqMsg.sessionId = pAdapter->sessionId;
4959 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304960
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304961 context = &pHddCtx->ext_scan_context;
4962 spin_lock(&hdd_context_lock);
4963 INIT_COMPLETION(context->response_event);
4964 context->request_id = request_id = reqMsg.requestId;
4965 spin_unlock(&hdd_context_lock);
4966
Dino Myclee8843b32014-07-04 14:21:45 +05304967 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304968 if (!HAL_STATUS_SUCCESS(status)) {
4969 hddLog(VOS_TRACE_LEVEL_ERROR,
4970 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304971 return -EINVAL;
4972 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304973
4974 /* request was sent -- wait for the response */
4975 rc = wait_for_completion_timeout(&context->response_event,
4976 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4977 if (!rc) {
4978 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4979 retval = -ETIMEDOUT;
4980 } else {
4981 spin_lock(&hdd_context_lock);
4982 if (context->request_id == request_id)
4983 retval = context->response_status;
4984 else
4985 retval = -EINVAL;
4986 spin_unlock(&hdd_context_lock);
4987 }
4988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304989 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304990 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304991}
4992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304993static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4994 struct wireless_dev *wdev,
4995 const void *data, int dataLen)
4996{
4997 int ret = 0;
4998
4999 vos_ssr_protect(__func__);
5000 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5001 vos_ssr_unprotect(__func__);
5002
5003 return ret;
5004}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305005#endif /* WLAN_FEATURE_EXTSCAN */
5006
Atul Mittal115287b2014-07-08 13:26:33 +05305007/*EXT TDLS*/
5008static const struct nla_policy
5009wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5010{
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5012 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5013 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5014 {.type = NLA_S32 },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5017
5018};
5019
5020static const struct nla_policy
5021wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5022{
5023 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5024
5025};
5026
5027static const struct nla_policy
5028wlan_hdd_tdls_config_state_change_policy[
5029 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5030{
5031 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5033 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305034 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5035 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5036 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305037
5038};
5039
5040static const struct nla_policy
5041wlan_hdd_tdls_config_get_status_policy[
5042 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5043{
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5045 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5046 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305047 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5048 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5049 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305050
5051};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305052
5053static const struct nla_policy
5054wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5055{
5056 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5057};
5058
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305059static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305061 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305062 int data_len)
5063{
5064
5065 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5066 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5067
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305068 ENTER();
5069
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 return -EINVAL;
5072 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305073 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305074 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305076 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305077 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305078 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305079 return -ENOTSUPP;
5080 }
5081
5082 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5083 data, data_len, wlan_hdd_mac_config)) {
5084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5085 return -EINVAL;
5086 }
5087
5088 /* Parse and fetch mac address */
5089 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5091 return -EINVAL;
5092 }
5093
5094 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5095 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5096 VOS_MAC_ADDR_LAST_3_BYTES);
5097
Siddharth Bhal76972212014-10-15 16:22:51 +05305098 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5099
5100 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305101 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5102 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305103 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5104 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5105 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5106 {
5107 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5108 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5109 VOS_MAC_ADDRESS_LEN);
5110 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305111 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305112
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305113 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5114 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305115
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305116 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305117 return 0;
5118}
5119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305120static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5121 struct wireless_dev *wdev,
5122 const void *data,
5123 int data_len)
5124{
5125 int ret = 0;
5126
5127 vos_ssr_protect(__func__);
5128 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5129 vos_ssr_unprotect(__func__);
5130
5131 return ret;
5132}
5133
5134static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305135 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305136 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305137 int data_len)
5138{
5139 u8 peer[6] = {0};
5140 struct net_device *dev = wdev->netdev;
5141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5142 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5143 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5144 eHalStatus ret;
5145 tANI_S32 state;
5146 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305147 tANI_S32 global_operating_class = 0;
5148 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305149 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305150 int retVal;
5151
5152 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305153
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305154 if (!pAdapter) {
5155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5156 return -EINVAL;
5157 }
5158
Atul Mittal115287b2014-07-08 13:26:33 +05305159 ret = wlan_hdd_validate_context(pHddCtx);
5160 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305162 return -EINVAL;
5163 }
5164 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305166 return -ENOTSUPP;
5167 }
5168 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5169 data, data_len,
5170 wlan_hdd_tdls_config_get_status_policy)) {
5171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5172 return -EINVAL;
5173 }
5174
5175 /* Parse and fetch mac address */
5176 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5178 return -EINVAL;
5179 }
5180
5181 memcpy(peer, nla_data(
5182 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5183 sizeof(peer));
5184 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5185
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305186 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305187
Atul Mittal115287b2014-07-08 13:26:33 +05305188 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305189 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305190 NLMSG_HDRLEN);
5191
5192 if (!skb) {
5193 hddLog(VOS_TRACE_LEVEL_ERROR,
5194 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5195 return -EINVAL;
5196 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305197 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 +05305198 reason,
5199 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305200 global_operating_class,
5201 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305202 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305203 if (nla_put_s32(skb,
5204 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5205 state) ||
5206 nla_put_s32(skb,
5207 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5208 reason) ||
5209 nla_put_s32(skb,
5210 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5211 global_operating_class) ||
5212 nla_put_s32(skb,
5213 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5214 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305215
5216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5217 goto nla_put_failure;
5218 }
5219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305220 retVal = cfg80211_vendor_cmd_reply(skb);
5221 EXIT();
5222 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305223
5224nla_put_failure:
5225 kfree_skb(skb);
5226 return -EINVAL;
5227}
5228
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305229static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5230 struct wireless_dev *wdev,
5231 const void *data,
5232 int data_len)
5233{
5234 int ret = 0;
5235
5236 vos_ssr_protect(__func__);
5237 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5238 vos_ssr_unprotect(__func__);
5239
5240 return ret;
5241}
5242
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305243static int wlan_hdd_cfg80211_exttdls_callback(
5244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5245 const tANI_U8* mac,
5246#else
5247 tANI_U8* mac,
5248#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305249 tANI_S32 state,
5250 tANI_S32 reason,
5251 void *ctx)
5252{
5253 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305254 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305255 tANI_S32 global_operating_class = 0;
5256 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305257 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 ENTER();
5260
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305261 if (!pAdapter) {
5262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5263 return -EINVAL;
5264 }
5265
5266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305267 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305269 return -EINVAL;
5270 }
5271
5272 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305274 return -ENOTSUPP;
5275 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305276 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5278 NULL,
5279#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305280 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5281 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5282 GFP_KERNEL);
5283
5284 if (!skb) {
5285 hddLog(VOS_TRACE_LEVEL_ERROR,
5286 FL("cfg80211_vendor_event_alloc failed"));
5287 return -EINVAL;
5288 }
5289 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305290 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5291 reason,
5292 state,
5293 global_operating_class,
5294 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305295 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5296 MAC_ADDR_ARRAY(mac));
5297
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305298 if (nla_put(skb,
5299 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5300 VOS_MAC_ADDR_SIZE, mac) ||
5301 nla_put_s32(skb,
5302 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5303 state) ||
5304 nla_put_s32(skb,
5305 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5306 reason) ||
5307 nla_put_s32(skb,
5308 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5309 channel) ||
5310 nla_put_s32(skb,
5311 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5312 global_operating_class)
5313 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5315 goto nla_put_failure;
5316 }
5317
5318 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305319 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305320 return (0);
5321
5322nla_put_failure:
5323 kfree_skb(skb);
5324 return -EINVAL;
5325}
5326
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305327static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305328 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305329 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305330 int data_len)
5331{
5332 u8 peer[6] = {0};
5333 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305334 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5335 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5336 eHalStatus status;
5337 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305338 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305339 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305340
5341 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305342
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305343 if (!dev) {
5344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5345 return -EINVAL;
5346 }
5347
5348 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5349 if (!pAdapter) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5351 return -EINVAL;
5352 }
5353
Atul Mittal115287b2014-07-08 13:26:33 +05305354 status = wlan_hdd_validate_context(pHddCtx);
5355 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305357 return -EINVAL;
5358 }
5359 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305361 return -ENOTSUPP;
5362 }
5363 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5364 data, data_len,
5365 wlan_hdd_tdls_config_enable_policy)) {
5366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5367 return -EINVAL;
5368 }
5369
5370 /* Parse and fetch mac address */
5371 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5373 return -EINVAL;
5374 }
5375
5376 memcpy(peer, nla_data(
5377 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5378 sizeof(peer));
5379 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5380
5381 /* Parse and fetch channel */
5382 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5384 return -EINVAL;
5385 }
5386 pReqMsg.channel = nla_get_s32(
5387 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5389
5390 /* Parse and fetch global operating class */
5391 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5393 return -EINVAL;
5394 }
5395 pReqMsg.global_operating_class = nla_get_s32(
5396 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5398 pReqMsg.global_operating_class);
5399
5400 /* Parse and fetch latency ms */
5401 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5403 return -EINVAL;
5404 }
5405 pReqMsg.max_latency_ms = nla_get_s32(
5406 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5407 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5408 pReqMsg.max_latency_ms);
5409
5410 /* Parse and fetch required bandwidth kbps */
5411 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5413 return -EINVAL;
5414 }
5415
5416 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5417 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5419 pReqMsg.min_bandwidth_kbps);
5420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305421 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305422 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305423 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305424 wlan_hdd_cfg80211_exttdls_callback);
5425
5426 EXIT();
5427 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305428}
5429
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305430static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5431 struct wireless_dev *wdev,
5432 const void *data,
5433 int data_len)
5434{
5435 int ret = 0;
5436
5437 vos_ssr_protect(__func__);
5438 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5439 vos_ssr_unprotect(__func__);
5440
5441 return ret;
5442}
5443
5444static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305445 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305446 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305447 int data_len)
5448{
5449 u8 peer[6] = {0};
5450 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305451 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5452 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5453 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305454 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305455 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305456
5457 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305458
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305459 if (!dev) {
5460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5461 return -EINVAL;
5462 }
5463
5464 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5465 if (!pAdapter) {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5467 return -EINVAL;
5468 }
5469
Atul Mittal115287b2014-07-08 13:26:33 +05305470 status = wlan_hdd_validate_context(pHddCtx);
5471 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305473 return -EINVAL;
5474 }
5475 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305477 return -ENOTSUPP;
5478 }
5479 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5480 data, data_len,
5481 wlan_hdd_tdls_config_disable_policy)) {
5482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5483 return -EINVAL;
5484 }
5485 /* Parse and fetch mac address */
5486 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5488 return -EINVAL;
5489 }
5490
5491 memcpy(peer, nla_data(
5492 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5493 sizeof(peer));
5494 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5497
5498 EXIT();
5499 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305500}
5501
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305502static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5503 struct wireless_dev *wdev,
5504 const void *data,
5505 int data_len)
5506{
5507 int ret = 0;
5508
5509 vos_ssr_protect(__func__);
5510 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5511 vos_ssr_unprotect(__func__);
5512
5513 return ret;
5514}
5515
Dasari Srinivas7875a302014-09-26 17:50:57 +05305516static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305517__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305518 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305519 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305520{
5521 struct net_device *dev = wdev->netdev;
5522 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5523 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5524 struct sk_buff *skb = NULL;
5525 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305526 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305528 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305529
5530 ret = wlan_hdd_validate_context(pHddCtx);
5531 if (0 != ret)
5532 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305533 return ret;
5534 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305535 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5536 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5537 fset |= WIFI_FEATURE_INFRA;
5538 }
5539
5540 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5541 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5542 fset |= WIFI_FEATURE_INFRA_5G;
5543 }
5544
5545#ifdef WLAN_FEATURE_P2P
5546 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5547 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5548 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5549 fset |= WIFI_FEATURE_P2P;
5550 }
5551#endif
5552
5553 /* Soft-AP is supported currently by default */
5554 fset |= WIFI_FEATURE_SOFT_AP;
5555
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305556 /* HOTSPOT is a supplicant feature, enable it by default */
5557 fset |= WIFI_FEATURE_HOTSPOT;
5558
Dasari Srinivas7875a302014-09-26 17:50:57 +05305559#ifdef WLAN_FEATURE_EXTSCAN
5560 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305561 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5562 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5563 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305564 fset |= WIFI_FEATURE_EXTSCAN;
5565 }
5566#endif
5567
Dasari Srinivas7875a302014-09-26 17:50:57 +05305568 if (sme_IsFeatureSupportedByFW(NAN)) {
5569 hddLog(LOG1, FL("NAN is supported by firmware"));
5570 fset |= WIFI_FEATURE_NAN;
5571 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305572
5573 /* D2D RTT is not supported currently by default */
5574 if (sme_IsFeatureSupportedByFW(RTT)) {
5575 hddLog(LOG1, FL("RTT is supported by firmware"));
5576 fset |= WIFI_FEATURE_D2AP_RTT;
5577 }
5578
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305579 if (sme_IsFeatureSupportedByFW(RTT3)) {
5580 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5581 fset |= WIFI_FEATURE_RTT3;
5582 }
5583
Dasari Srinivas7875a302014-09-26 17:50:57 +05305584#ifdef FEATURE_WLAN_BATCH_SCAN
5585 if (fset & WIFI_FEATURE_EXTSCAN) {
5586 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5587 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5588 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5589 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5590 fset |= WIFI_FEATURE_BATCH_SCAN;
5591 }
5592#endif
5593
5594#ifdef FEATURE_WLAN_SCAN_PNO
5595 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5596 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5597 hddLog(LOG1, FL("PNO is supported by firmware"));
5598 fset |= WIFI_FEATURE_PNO;
5599 }
5600#endif
5601
5602 /* STA+STA is supported currently by default */
5603 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5604
5605#ifdef FEATURE_WLAN_TDLS
5606 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5607 sme_IsFeatureSupportedByFW(TDLS)) {
5608 hddLog(LOG1, FL("TDLS is supported by firmware"));
5609 fset |= WIFI_FEATURE_TDLS;
5610 }
5611
5612 /* TDLS_OFFCHANNEL is not supported currently by default */
5613#endif
5614
5615#ifdef WLAN_AP_STA_CONCURRENCY
5616 /* AP+STA concurrency is supported currently by default */
5617 fset |= WIFI_FEATURE_AP_STA;
5618#endif
5619
Mukul Sharma5add0532015-08-17 15:57:47 +05305620#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5621 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5622 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5623#endif
5624
Dasari Srinivas7875a302014-09-26 17:50:57 +05305625 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5626 NLMSG_HDRLEN);
5627
5628 if (!skb) {
5629 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5630 return -EINVAL;
5631 }
5632 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5633
5634 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5635 hddLog(LOGE, FL("nla put fail"));
5636 goto nla_put_failure;
5637 }
5638
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305639 ret = cfg80211_vendor_cmd_reply(skb);
5640 EXIT();
5641 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305642
5643nla_put_failure:
5644 kfree_skb(skb);
5645 return -EINVAL;
5646}
5647
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305648static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305649wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5650 struct wireless_dev *wdev,
5651 const void *data, int data_len)
5652{
5653 int ret = 0;
5654
5655 vos_ssr_protect(__func__);
5656 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5657 vos_ssr_unprotect(__func__);
5658
5659 return ret;
5660}
5661
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305662
5663static const struct
5664nla_policy
5665qca_wlan_vendor_wifi_logger_get_ring_data_policy
5666[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5667 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5668 = {.type = NLA_U32 },
5669};
5670
5671static int
5672 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5673 struct wireless_dev *wdev,
5674 const void *data,
5675 int data_len)
5676{
5677 int ret;
5678 VOS_STATUS status;
5679 uint32_t ring_id;
5680 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5681 struct nlattr *tb
5682 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5683
5684 ENTER();
5685
5686 ret = wlan_hdd_validate_context(hdd_ctx);
5687 if (0 != ret) {
5688 return ret;
5689 }
5690
5691 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5692 data, data_len,
5693 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5694 hddLog(LOGE, FL("Invalid attribute"));
5695 return -EINVAL;
5696 }
5697
5698 /* Parse and fetch ring id */
5699 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5700 hddLog(LOGE, FL("attr ATTR failed"));
5701 return -EINVAL;
5702 }
5703
5704 ring_id = nla_get_u32(
5705 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5706
5707 hddLog(LOG1, FL("Bug report triggered by framework"));
5708
5709 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5710 WLAN_LOG_INDICATOR_FRAMEWORK,
5711 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305712 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305713 );
5714 if (VOS_STATUS_SUCCESS != status) {
5715 hddLog(LOGE, FL("Failed to trigger bug report"));
5716
5717 return -EINVAL;
5718 }
5719
5720 return 0;
5721
5722
5723}
5724
5725
5726static int
5727 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5728 struct wireless_dev *wdev,
5729 const void *data,
5730 int data_len)
5731{
5732 int ret = 0;
5733
5734 vos_ssr_protect(__func__);
5735 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5736 wdev, data, data_len);
5737 vos_ssr_unprotect(__func__);
5738
5739 return ret;
5740
5741}
5742
5743
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305744static int
5745__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305746 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305747 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305748{
5749 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5750 uint8_t i, feature_sets, max_feature_sets;
5751 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5752 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305753 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5754 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305755
5756 ENTER();
5757
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305758 ret = wlan_hdd_validate_context(pHddCtx);
5759 if (0 != ret)
5760 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305761 return ret;
5762 }
5763
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5765 data, data_len, NULL)) {
5766 hddLog(LOGE, FL("Invalid ATTR"));
5767 return -EINVAL;
5768 }
5769
5770 /* Parse and fetch max feature set */
5771 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5772 hddLog(LOGE, FL("Attr max feature set size failed"));
5773 return -EINVAL;
5774 }
5775 max_feature_sets = nla_get_u32(
5776 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5777 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5778
5779 /* Fill feature combination matrix */
5780 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305781 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5782 WIFI_FEATURE_P2P;
5783
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305784 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5785 WIFI_FEATURE_SOFT_AP;
5786
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305787 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5788 WIFI_FEATURE_SOFT_AP;
5789
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305790 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5791 WIFI_FEATURE_SOFT_AP |
5792 WIFI_FEATURE_P2P;
5793
5794 /* Add more feature combinations here */
5795
5796 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5797 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5798 hddLog(LOG1, "Feature set matrix");
5799 for (i = 0; i < feature_sets; i++)
5800 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5801
5802 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5803 sizeof(u32) * feature_sets +
5804 NLMSG_HDRLEN);
5805
5806 if (reply_skb) {
5807 if (nla_put_u32(reply_skb,
5808 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5809 feature_sets) ||
5810 nla_put(reply_skb,
5811 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5812 sizeof(u32) * feature_sets, feature_set_matrix)) {
5813 hddLog(LOGE, FL("nla put fail"));
5814 kfree_skb(reply_skb);
5815 return -EINVAL;
5816 }
5817
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305818 ret = cfg80211_vendor_cmd_reply(reply_skb);
5819 EXIT();
5820 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305821 }
5822 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5823 return -ENOMEM;
5824
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305825}
5826
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305827static int
5828wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5829 struct wireless_dev *wdev,
5830 const void *data, int data_len)
5831{
5832 int ret = 0;
5833
5834 vos_ssr_protect(__func__);
5835 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5836 data_len);
5837 vos_ssr_unprotect(__func__);
5838
5839 return ret;
5840}
5841
c_manjeecfd1efb2015-09-25 19:32:34 +05305842
5843static int
5844__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5845 struct wireless_dev *wdev,
5846 const void *data, int data_len)
5847{
5848 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5849 int ret;
5850 ENTER();
5851
5852 ret = wlan_hdd_validate_context(pHddCtx);
5853 if (0 != ret)
5854 {
5855 return ret;
5856 }
5857
5858 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5859 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5860 {
5861 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5862 return -EINVAL;
5863 }
5864 /*call common API for FW mem dump req*/
5865 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5866
Abhishek Singhc783fa72015-12-09 18:07:34 +05305867 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305868 {
5869 /*indicate to userspace the status of fw mem dump */
5870 wlan_indicate_mem_dump_complete(true);
5871 }
5872 else
5873 {
5874 /*else send failure to userspace */
5875 wlan_indicate_mem_dump_complete(false);
5876 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305877 EXIT();
5878 return ret;
5879}
5880
5881/**
5882 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5883 * @wiphy: pointer to wireless wiphy structure.
5884 * @wdev: pointer to wireless_dev structure.
5885 * @data: Pointer to the NL data.
5886 * @data_len:Length of @data
5887 *
5888 * This is called when wlan driver needs to get the firmware memory dump
5889 * via vendor specific command.
5890 *
5891 * Return: 0 on success, error number otherwise.
5892 */
5893
5894static int
5895wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5896 struct wireless_dev *wdev,
5897 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305898{
5899 int ret = 0;
5900 vos_ssr_protect(__func__);
5901 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5902 data_len);
5903 vos_ssr_unprotect(__func__);
5904 return ret;
5905}
c_manjeecfd1efb2015-09-25 19:32:34 +05305906
Sushant Kaushik8e644982015-09-23 12:18:54 +05305907static const struct
5908nla_policy
5909qca_wlan_vendor_wifi_logger_start_policy
5910[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5911 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5912 = {.type = NLA_U32 },
5913 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5914 = {.type = NLA_U32 },
5915 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5916 = {.type = NLA_U32 },
5917};
5918
5919/**
5920 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5921 * or disable the collection of packet statistics from the firmware
5922 * @wiphy: WIPHY structure pointer
5923 * @wdev: Wireless device structure pointer
5924 * @data: Pointer to the data received
5925 * @data_len: Length of the data received
5926 *
5927 * This function is used to enable or disable the collection of packet
5928 * statistics from the firmware
5929 *
5930 * Return: 0 on success and errno on failure
5931 */
5932static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5933 struct wireless_dev *wdev,
5934 const void *data,
5935 int data_len)
5936{
5937 eHalStatus status;
5938 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5939 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5940 tAniWifiStartLog start_log;
5941
5942 status = wlan_hdd_validate_context(hdd_ctx);
5943 if (0 != status) {
5944 return -EINVAL;
5945 }
5946
5947 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5948 data, data_len,
5949 qca_wlan_vendor_wifi_logger_start_policy)) {
5950 hddLog(LOGE, FL("Invalid attribute"));
5951 return -EINVAL;
5952 }
5953
5954 /* Parse and fetch ring id */
5955 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5956 hddLog(LOGE, FL("attr ATTR failed"));
5957 return -EINVAL;
5958 }
5959 start_log.ringId = nla_get_u32(
5960 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5961 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5962
5963 /* Parse and fetch verbose level */
5964 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5965 hddLog(LOGE, FL("attr verbose_level failed"));
5966 return -EINVAL;
5967 }
5968 start_log.verboseLevel = nla_get_u32(
5969 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5970 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5971
5972 /* Parse and fetch flag */
5973 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5974 hddLog(LOGE, FL("attr flag failed"));
5975 return -EINVAL;
5976 }
5977 start_log.flag = nla_get_u32(
5978 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5979 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5980
5981 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305982 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5983 !vos_isPktStatsEnabled()))
5984
Sushant Kaushik8e644982015-09-23 12:18:54 +05305985 {
5986 hddLog(LOGE, FL("per pkt stats not enabled"));
5987 return -EINVAL;
5988 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305989
Sushant Kaushik33200572015-08-05 16:46:20 +05305990 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305991 return 0;
5992}
5993
5994/**
5995 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5996 * or disable the collection of packet statistics from the firmware
5997 * @wiphy: WIPHY structure pointer
5998 * @wdev: Wireless device structure pointer
5999 * @data: Pointer to the data received
6000 * @data_len: Length of the data received
6001 *
6002 * This function is used to enable or disable the collection of packet
6003 * statistics from the firmware
6004 *
6005 * Return: 0 on success and errno on failure
6006 */
6007static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6008 struct wireless_dev *wdev,
6009 const void *data,
6010 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306011{
6012 int ret = 0;
6013
6014 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306015
6016 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6017 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306018 vos_ssr_unprotect(__func__);
6019
6020 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306021}
6022
6023
Agarwal Ashish738843c2014-09-25 12:27:56 +05306024static const struct nla_policy
6025wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6026 +1] =
6027{
6028 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6029};
6030
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306031static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306032 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306033 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306034 int data_len)
6035{
6036 struct net_device *dev = wdev->netdev;
6037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6038 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6039 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6040 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6041 eHalStatus status;
6042 u32 dfsFlag = 0;
6043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306044 ENTER();
6045
Agarwal Ashish738843c2014-09-25 12:27:56 +05306046 status = wlan_hdd_validate_context(pHddCtx);
6047 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306048 return -EINVAL;
6049 }
6050 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6051 data, data_len,
6052 wlan_hdd_set_no_dfs_flag_config_policy)) {
6053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6054 return -EINVAL;
6055 }
6056
6057 /* Parse and fetch required bandwidth kbps */
6058 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6060 return -EINVAL;
6061 }
6062
6063 dfsFlag = nla_get_u32(
6064 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6065 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6066 dfsFlag);
6067
6068 pHddCtx->disable_dfs_flag = dfsFlag;
6069
6070 sme_disable_dfs_channel(hHal, dfsFlag);
6071 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306072
6073 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306074 return 0;
6075}
Atul Mittal115287b2014-07-08 13:26:33 +05306076
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306077static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6078 struct wireless_dev *wdev,
6079 const void *data,
6080 int data_len)
6081{
6082 int ret = 0;
6083
6084 vos_ssr_protect(__func__);
6085 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6086 vos_ssr_unprotect(__func__);
6087
6088 return ret;
6089
6090}
6091
Mukul Sharma2a271632014-10-13 14:59:01 +05306092const struct
6093nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6094{
6095 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6096 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6097};
6098
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306099static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306100 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306101{
6102
6103 u8 bssid[6] = {0};
6104 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6105 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6106 eHalStatus status = eHAL_STATUS_SUCCESS;
6107 v_U32_t isFwrRoamEnabled = FALSE;
6108 int ret;
6109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306110 ENTER();
6111
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306112 ret = wlan_hdd_validate_context(pHddCtx);
6113 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306114 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306115 }
6116
6117 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6118 data, data_len,
6119 qca_wlan_vendor_attr);
6120 if (ret){
6121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6122 return -EINVAL;
6123 }
6124
6125 /* Parse and fetch Enable flag */
6126 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6128 return -EINVAL;
6129 }
6130
6131 isFwrRoamEnabled = nla_get_u32(
6132 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6133
6134 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6135
6136 /* Parse and fetch bssid */
6137 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6139 return -EINVAL;
6140 }
6141
6142 memcpy(bssid, nla_data(
6143 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6144 sizeof(bssid));
6145 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6146
6147 //Update roaming
6148 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306149 if (!HAL_STATUS_SUCCESS(status)) {
6150 hddLog(LOGE,
6151 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6152 return -EINVAL;
6153 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306154 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306155 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306156}
6157
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306158static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6159 struct wireless_dev *wdev, const void *data, int data_len)
6160{
6161 int ret = 0;
6162
6163 vos_ssr_protect(__func__);
6164 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6165 vos_ssr_unprotect(__func__);
6166
6167 return ret;
6168}
6169
Sushant Kaushik847890c2015-09-28 16:05:17 +05306170static const struct
6171nla_policy
6172qca_wlan_vendor_get_wifi_info_policy[
6173 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6174 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6175 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6176};
6177
6178
6179/**
6180 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6181 * @wiphy: pointer to wireless wiphy structure.
6182 * @wdev: pointer to wireless_dev structure.
6183 * @data: Pointer to the data to be passed via vendor interface
6184 * @data_len:Length of the data to be passed
6185 *
6186 * This is called when wlan driver needs to send wifi driver related info
6187 * (driver/fw version) to the user space application upon request.
6188 *
6189 * Return: Return the Success or Failure code.
6190 */
6191static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6192 struct wireless_dev *wdev,
6193 const void *data, int data_len)
6194{
6195 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6196 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6197 tSirVersionString version;
6198 uint32 version_len;
6199 uint8 attr;
6200 int status;
6201 struct sk_buff *reply_skb = NULL;
6202
6203 if (VOS_FTM_MODE == hdd_get_conparam()) {
6204 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6205 return -EINVAL;
6206 }
6207
6208 status = wlan_hdd_validate_context(hdd_ctx);
6209 if (0 != status) {
6210 hddLog(LOGE, FL("HDD context is not valid"));
6211 return -EINVAL;
6212 }
6213
6214 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6215 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6216 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6217 return -EINVAL;
6218 }
6219
6220 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6221 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6222 QWLAN_VERSIONSTR);
6223 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6224 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6225 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6226 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6227 hdd_ctx->fw_Version);
6228 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6229 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6230 } else {
6231 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6232 return -EINVAL;
6233 }
6234
6235 version_len = strlen(version);
6236 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6237 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6238 if (!reply_skb) {
6239 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6240 return -ENOMEM;
6241 }
6242
6243 if (nla_put(reply_skb, attr, version_len, version)) {
6244 hddLog(LOGE, FL("nla put fail"));
6245 kfree_skb(reply_skb);
6246 return -EINVAL;
6247 }
6248
6249 return cfg80211_vendor_cmd_reply(reply_skb);
6250}
6251
6252/**
6253 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6254 * @wiphy: pointer to wireless wiphy structure.
6255 * @wdev: pointer to wireless_dev structure.
6256 * @data: Pointer to the data to be passed via vendor interface
6257 * @data_len:Length of the data to be passed
6258 * @data_len: Length of the data received
6259 *
6260 * This function is used to enable or disable the collection of packet
6261 * statistics from the firmware
6262 *
6263 * Return: 0 on success and errno on failure
6264 */
6265
6266static int
6267wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6268 struct wireless_dev *wdev,
6269 const void *data, int data_len)
6270
6271
6272{
6273 int ret = 0;
6274
6275 vos_ssr_protect(__func__);
6276 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6277 wdev, data, data_len);
6278 vos_ssr_unprotect(__func__);
6279
6280 return ret;
6281}
6282
6283
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306284/*
6285 * define short names for the global vendor params
6286 * used by __wlan_hdd_cfg80211_monitor_rssi()
6287 */
6288#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6289#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6290#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6291#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6292#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6293
6294/**---------------------------------------------------------------------------
6295
6296 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6297 monitor start is completed successfully.
6298
6299 \return - None
6300
6301 --------------------------------------------------------------------------*/
6302void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6303{
6304 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6305
6306 if (NULL == pHddCtx)
6307 {
6308 hddLog(VOS_TRACE_LEVEL_ERROR,
6309 "%s: HDD context is NULL",__func__);
6310 return;
6311 }
6312
6313 if (VOS_STATUS_SUCCESS == status)
6314 {
6315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6316 }
6317 else
6318 {
6319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6320 }
6321
6322 return;
6323}
6324
6325/**---------------------------------------------------------------------------
6326
6327 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6328 stop is completed successfully.
6329
6330 \return - None
6331
6332 --------------------------------------------------------------------------*/
6333void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6334{
6335 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6336
6337 if (NULL == pHddCtx)
6338 {
6339 hddLog(VOS_TRACE_LEVEL_ERROR,
6340 "%s: HDD context is NULL",__func__);
6341 return;
6342 }
6343
6344 if (VOS_STATUS_SUCCESS == status)
6345 {
6346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6347 }
6348 else
6349 {
6350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6351 }
6352
6353 return;
6354}
6355
6356/**
6357 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6358 * @wiphy: Pointer to wireless phy
6359 * @wdev: Pointer to wireless device
6360 * @data: Pointer to data
6361 * @data_len: Data length
6362 *
6363 * Return: 0 on success, negative errno on failure
6364 */
6365
6366static int
6367__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6368 struct wireless_dev *wdev,
6369 const void *data,
6370 int data_len)
6371{
6372 struct net_device *dev = wdev->netdev;
6373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6374 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6375 hdd_station_ctx_t *pHddStaCtx;
6376 struct nlattr *tb[PARAM_MAX + 1];
6377 tpSirRssiMonitorReq pReq;
6378 eHalStatus status;
6379 int ret;
6380 uint32_t control;
6381 static const struct nla_policy policy[PARAM_MAX + 1] = {
6382 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6383 [PARAM_CONTROL] = { .type = NLA_U32 },
6384 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6385 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6386 };
6387
6388 ENTER();
6389
6390 ret = wlan_hdd_validate_context(hdd_ctx);
6391 if (0 != ret) {
6392 return -EINVAL;
6393 }
6394
6395 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6396 hddLog(LOGE, FL("Not in Connected state!"));
6397 return -ENOTSUPP;
6398 }
6399
6400 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6401 hddLog(LOGE, FL("Invalid ATTR"));
6402 return -EINVAL;
6403 }
6404
6405 if (!tb[PARAM_REQUEST_ID]) {
6406 hddLog(LOGE, FL("attr request id failed"));
6407 return -EINVAL;
6408 }
6409
6410 if (!tb[PARAM_CONTROL]) {
6411 hddLog(LOGE, FL("attr control failed"));
6412 return -EINVAL;
6413 }
6414
6415 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6416
6417 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6418 if(NULL == pReq)
6419 {
6420 hddLog(LOGE,
6421 FL("vos_mem_alloc failed "));
6422 return eHAL_STATUS_FAILED_ALLOC;
6423 }
6424 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6425
6426 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6427 pReq->sessionId = pAdapter->sessionId;
6428 pReq->rssiMonitorCbContext = hdd_ctx;
6429 control = nla_get_u32(tb[PARAM_CONTROL]);
6430 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6431
6432 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6433 pReq->requestId, pReq->sessionId, control);
6434
6435 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6436 if (!tb[PARAM_MIN_RSSI]) {
6437 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306438 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306439 }
6440
6441 if (!tb[PARAM_MAX_RSSI]) {
6442 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306443 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306444 }
6445
6446 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6447 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6448 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6449
6450 if (!(pReq->minRssi < pReq->maxRssi)) {
6451 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6452 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306453 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306454 }
6455 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6456 pReq->minRssi, pReq->maxRssi);
6457 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6458
6459 }
6460 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6461 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6462 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6463 }
6464 else {
6465 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306466 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306467 }
6468
6469 if (!HAL_STATUS_SUCCESS(status)) {
6470 hddLog(LOGE,
6471 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306472 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306473 }
6474
6475 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306476fail:
6477 vos_mem_free(pReq);
6478 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306479}
6480
6481/*
6482 * done with short names for the global vendor params
6483 * used by __wlan_hdd_cfg80211_monitor_rssi()
6484 */
6485#undef PARAM_MAX
6486#undef PARAM_CONTROL
6487#undef PARAM_REQUEST_ID
6488#undef PARAM_MAX_RSSI
6489#undef PARAM_MIN_RSSI
6490
6491/**
6492 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6493 * @wiphy: wiphy structure pointer
6494 * @wdev: Wireless device structure pointer
6495 * @data: Pointer to the data received
6496 * @data_len: Length of @data
6497 *
6498 * Return: 0 on success; errno on failure
6499 */
6500static int
6501wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6502 const void *data, int data_len)
6503{
6504 int ret;
6505
6506 vos_ssr_protect(__func__);
6507 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6508 vos_ssr_unprotect(__func__);
6509
6510 return ret;
6511}
6512
6513/**
6514 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6515 * @hddctx: HDD context
6516 * @data: rssi breached event data
6517 *
6518 * This function reads the rssi breached event %data and fill in the skb with
6519 * NL attributes and send up the NL event.
6520 * This callback execute in atomic context and must not invoke any
6521 * blocking calls.
6522 *
6523 * Return: none
6524 */
6525void hdd_rssi_threshold_breached_cb(void *hddctx,
6526 struct rssi_breach_event *data)
6527{
6528 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6529 int status;
6530 struct sk_buff *skb;
6531
6532 ENTER();
6533 status = wlan_hdd_validate_context(pHddCtx);
6534
6535 if (0 != status) {
6536 return;
6537 }
6538
6539 if (!data) {
6540 hddLog(LOGE, FL("data is null"));
6541 return;
6542 }
6543
6544 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6546 NULL,
6547#endif
6548 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6549 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6550 GFP_KERNEL);
6551
6552 if (!skb) {
6553 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6554 return;
6555 }
6556
6557 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6558 data->request_id, data->curr_rssi);
6559 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6560 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6561
6562 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6563 data->request_id) ||
6564 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6565 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6566 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6567 data->curr_rssi)) {
6568 hddLog(LOGE, FL("nla put fail"));
6569 goto fail;
6570 }
6571
6572 cfg80211_vendor_event(skb, GFP_KERNEL);
6573 return;
6574
6575fail:
6576 kfree_skb(skb);
6577 return;
6578}
6579
6580
6581
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306582/**
6583 * __wlan_hdd_cfg80211_setband() - set band
6584 * @wiphy: Pointer to wireless phy
6585 * @wdev: Pointer to wireless device
6586 * @data: Pointer to data
6587 * @data_len: Data length
6588 *
6589 * Return: 0 on success, negative errno on failure
6590 */
6591static int
6592__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6593 struct wireless_dev *wdev,
6594 const void *data,
6595 int data_len)
6596{
6597 struct net_device *dev = wdev->netdev;
6598 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6599 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6600 int ret;
6601 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6602 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6603
6604 ENTER();
6605
6606 ret = wlan_hdd_validate_context(hdd_ctx);
6607 if (0 != ret) {
6608 hddLog(LOGE, FL("HDD context is not valid"));
6609 return ret;
6610 }
6611
6612 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6613 policy)) {
6614 hddLog(LOGE, FL("Invalid ATTR"));
6615 return -EINVAL;
6616 }
6617
6618 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6619 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6620 return -EINVAL;
6621 }
6622
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306623 hdd_ctx->isSetBandByNL = TRUE;
6624 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306625 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306626 hdd_ctx->isSetBandByNL = FALSE;
6627
6628 EXIT();
6629 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306630}
6631
6632/**
6633 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6634 * @wiphy: wiphy structure pointer
6635 * @wdev: Wireless device structure pointer
6636 * @data: Pointer to the data received
6637 * @data_len: Length of @data
6638 *
6639 * Return: 0 on success; errno on failure
6640 */
6641static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6642 struct wireless_dev *wdev,
6643 const void *data,
6644 int data_len)
6645{
6646 int ret = 0;
6647
6648 vos_ssr_protect(__func__);
6649 ret = __wlan_hdd_cfg80211_setband(wiphy,
6650 wdev, data, data_len);
6651 vos_ssr_unprotect(__func__);
6652
6653 return ret;
6654}
6655
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306656#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6657/**
6658 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6659 * @hdd_ctx: HDD context
6660 * @request_id: [input] request id
6661 * @pattern_id: [output] pattern id
6662 *
6663 * This function loops through request id to pattern id array
6664 * if the slot is available, store the request id and return pattern id
6665 * if entry exists, return the pattern id
6666 *
6667 * Return: 0 on success and errno on failure
6668 */
6669static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6670 uint32_t request_id,
6671 uint8_t *pattern_id)
6672{
6673 uint32_t i;
6674
6675 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6676 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6677 {
6678 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6679 {
6680 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6681 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6682 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6683 return 0;
6684 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6685 request_id) {
6686 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6687 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6688 return 0;
6689 }
6690 }
6691 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6692 return -EINVAL;
6693}
6694
6695/**
6696 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6697 * @hdd_ctx: HDD context
6698 * @request_id: [input] request id
6699 * @pattern_id: [output] pattern id
6700 *
6701 * This function loops through request id to pattern id array
6702 * reset request id to 0 (slot available again) and
6703 * return pattern id
6704 *
6705 * Return: 0 on success and errno on failure
6706 */
6707static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6708 uint32_t request_id,
6709 uint8_t *pattern_id)
6710{
6711 uint32_t i;
6712
6713 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6714 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6715 {
6716 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6717 {
6718 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6719 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6720 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6721 return 0;
6722 }
6723 }
6724 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6725 return -EINVAL;
6726}
6727
6728
6729/*
6730 * define short names for the global vendor params
6731 * used by __wlan_hdd_cfg80211_offloaded_packets()
6732 */
6733#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6734#define PARAM_REQUEST_ID \
6735 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6736#define PARAM_CONTROL \
6737 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6738#define PARAM_IP_PACKET \
6739 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6740#define PARAM_SRC_MAC_ADDR \
6741 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6742#define PARAM_DST_MAC_ADDR \
6743 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6744#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6745
6746/**
6747 * wlan_hdd_add_tx_ptrn() - add tx pattern
6748 * @adapter: adapter pointer
6749 * @hdd_ctx: hdd context
6750 * @tb: nl attributes
6751 *
6752 * This function reads the NL attributes and forms a AddTxPtrn message
6753 * posts it to SME.
6754 *
6755 */
6756static int
6757wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6758 struct nlattr **tb)
6759{
6760 struct sSirAddPeriodicTxPtrn *add_req;
6761 eHalStatus status;
6762 uint32_t request_id, ret, len;
6763 uint8_t pattern_id = 0;
6764 v_MACADDR_t dst_addr;
6765 uint16_t eth_type = htons(ETH_P_IP);
6766
6767 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6768 {
6769 hddLog(LOGE, FL("Not in Connected state!"));
6770 return -ENOTSUPP;
6771 }
6772
6773 add_req = vos_mem_malloc(sizeof(*add_req));
6774 if (!add_req)
6775 {
6776 hddLog(LOGE, FL("memory allocation failed"));
6777 return -ENOMEM;
6778 }
6779
6780 /* Parse and fetch request Id */
6781 if (!tb[PARAM_REQUEST_ID])
6782 {
6783 hddLog(LOGE, FL("attr request id failed"));
6784 goto fail;
6785 }
6786
6787 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6788 hddLog(LOG1, FL("Request Id: %u"), request_id);
6789 if (request_id == 0)
6790 {
6791 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306792 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306793 }
6794
6795 if (!tb[PARAM_PERIOD])
6796 {
6797 hddLog(LOGE, FL("attr period failed"));
6798 goto fail;
6799 }
6800 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6801 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6802 if (add_req->usPtrnIntervalMs == 0)
6803 {
6804 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6805 goto fail;
6806 }
6807
6808 if (!tb[PARAM_SRC_MAC_ADDR])
6809 {
6810 hddLog(LOGE, FL("attr source mac address failed"));
6811 goto fail;
6812 }
6813 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6814 VOS_MAC_ADDR_SIZE);
6815 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6816 MAC_ADDR_ARRAY(add_req->macAddress));
6817
6818 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6819 VOS_MAC_ADDR_SIZE))
6820 {
6821 hddLog(LOGE,
6822 FL("input src mac address and connected ap bssid are different"));
6823 goto fail;
6824 }
6825
6826 if (!tb[PARAM_DST_MAC_ADDR])
6827 {
6828 hddLog(LOGE, FL("attr dst mac address failed"));
6829 goto fail;
6830 }
6831 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6832 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6833 MAC_ADDR_ARRAY(dst_addr.bytes));
6834
6835 if (!tb[PARAM_IP_PACKET])
6836 {
6837 hddLog(LOGE, FL("attr ip packet failed"));
6838 goto fail;
6839 }
6840 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6841 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6842
6843 if (add_req->ucPtrnSize < 0 ||
6844 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6845 HDD_ETH_HEADER_LEN))
6846 {
6847 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6848 add_req->ucPtrnSize);
6849 goto fail;
6850 }
6851
6852 len = 0;
6853 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6854 len += VOS_MAC_ADDR_SIZE;
6855 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6856 VOS_MAC_ADDR_SIZE);
6857 len += VOS_MAC_ADDR_SIZE;
6858 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6859 len += 2;
6860
6861 /*
6862 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6863 * ------------------------------------------------------------
6864 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6865 * ------------------------------------------------------------
6866 */
6867 vos_mem_copy(&add_req->ucPattern[len],
6868 nla_data(tb[PARAM_IP_PACKET]),
6869 add_req->ucPtrnSize);
6870 add_req->ucPtrnSize += len;
6871
6872 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6873 add_req->ucPattern, add_req->ucPtrnSize);
6874
6875 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6876 if (ret)
6877 {
6878 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6879 goto fail;
6880 }
6881 add_req->ucPtrnId = pattern_id;
6882 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6883
6884 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6885 if (!HAL_STATUS_SUCCESS(status))
6886 {
6887 hddLog(LOGE,
6888 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6889 goto fail;
6890 }
6891
6892 EXIT();
6893 vos_mem_free(add_req);
6894 return 0;
6895
6896fail:
6897 vos_mem_free(add_req);
6898 return -EINVAL;
6899}
6900
6901/**
6902 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6903 * @adapter: adapter pointer
6904 * @hdd_ctx: hdd context
6905 * @tb: nl attributes
6906 *
6907 * This function reads the NL attributes and forms a DelTxPtrn message
6908 * posts it to SME.
6909 *
6910 */
6911static int
6912wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6913 struct nlattr **tb)
6914{
6915 struct sSirDelPeriodicTxPtrn *del_req;
6916 eHalStatus status;
6917 uint32_t request_id, ret;
6918 uint8_t pattern_id = 0;
6919
6920 /* Parse and fetch request Id */
6921 if (!tb[PARAM_REQUEST_ID])
6922 {
6923 hddLog(LOGE, FL("attr request id failed"));
6924 return -EINVAL;
6925 }
6926 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6927 if (request_id == 0)
6928 {
6929 hddLog(LOGE, FL("request_id cannot be zero"));
6930 return -EINVAL;
6931 }
6932
6933 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6934 if (ret)
6935 {
6936 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6937 return -EINVAL;
6938 }
6939
6940 del_req = vos_mem_malloc(sizeof(*del_req));
6941 if (!del_req)
6942 {
6943 hddLog(LOGE, FL("memory allocation failed"));
6944 return -ENOMEM;
6945 }
6946
6947 vos_mem_set(del_req, sizeof(*del_req), 0);
6948 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6949 VOS_MAC_ADDR_SIZE);
6950 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6951 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6952 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6953 request_id, pattern_id, del_req->ucPatternIdBitmap);
6954
6955 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6956 if (!HAL_STATUS_SUCCESS(status))
6957 {
6958 hddLog(LOGE,
6959 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6960 goto fail;
6961 }
6962
6963 EXIT();
6964 vos_mem_free(del_req);
6965 return 0;
6966
6967fail:
6968 vos_mem_free(del_req);
6969 return -EINVAL;
6970}
6971
6972
6973/**
6974 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6975 * @wiphy: Pointer to wireless phy
6976 * @wdev: Pointer to wireless device
6977 * @data: Pointer to data
6978 * @data_len: Data length
6979 *
6980 * Return: 0 on success, negative errno on failure
6981 */
6982static int
6983__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6984 struct wireless_dev *wdev,
6985 const void *data,
6986 int data_len)
6987{
6988 struct net_device *dev = wdev->netdev;
6989 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6990 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6991 struct nlattr *tb[PARAM_MAX + 1];
6992 uint8_t control;
6993 int ret;
6994 static const struct nla_policy policy[PARAM_MAX + 1] =
6995 {
6996 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6997 [PARAM_CONTROL] = { .type = NLA_U32 },
6998 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6999 .len = VOS_MAC_ADDR_SIZE },
7000 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7001 .len = VOS_MAC_ADDR_SIZE },
7002 [PARAM_PERIOD] = { .type = NLA_U32 },
7003 };
7004
7005 ENTER();
7006
7007 ret = wlan_hdd_validate_context(hdd_ctx);
7008 if (0 != ret)
7009 {
7010 hddLog(LOGE, FL("HDD context is not valid"));
7011 return ret;
7012 }
7013
7014 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7015 {
7016 hddLog(LOGE,
7017 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7018 return -ENOTSUPP;
7019 }
7020
7021 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7022 {
7023 hddLog(LOGE, FL("Invalid ATTR"));
7024 return -EINVAL;
7025 }
7026
7027 if (!tb[PARAM_CONTROL])
7028 {
7029 hddLog(LOGE, FL("attr control failed"));
7030 return -EINVAL;
7031 }
7032 control = nla_get_u32(tb[PARAM_CONTROL]);
7033 hddLog(LOG1, FL("Control: %d"), control);
7034
7035 if (control == WLAN_START_OFFLOADED_PACKETS)
7036 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7037 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7038 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7039 else
7040 {
7041 hddLog(LOGE, FL("Invalid control: %d"), control);
7042 return -EINVAL;
7043 }
7044}
7045
7046/*
7047 * done with short names for the global vendor params
7048 * used by __wlan_hdd_cfg80211_offloaded_packets()
7049 */
7050#undef PARAM_MAX
7051#undef PARAM_REQUEST_ID
7052#undef PARAM_CONTROL
7053#undef PARAM_IP_PACKET
7054#undef PARAM_SRC_MAC_ADDR
7055#undef PARAM_DST_MAC_ADDR
7056#undef PARAM_PERIOD
7057
7058/**
7059 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7060 * @wiphy: wiphy structure pointer
7061 * @wdev: Wireless device structure pointer
7062 * @data: Pointer to the data received
7063 * @data_len: Length of @data
7064 *
7065 * Return: 0 on success; errno on failure
7066 */
7067static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7068 struct wireless_dev *wdev,
7069 const void *data,
7070 int data_len)
7071{
7072 int ret = 0;
7073
7074 vos_ssr_protect(__func__);
7075 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7076 wdev, data, data_len);
7077 vos_ssr_unprotect(__func__);
7078
7079 return ret;
7080}
7081#endif
7082
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307083static const struct
7084nla_policy
7085qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7086 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7087};
7088
7089/**
7090 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7091 * get link properties like nss, rate flags and operating frequency for
7092 * the connection with the given peer.
7093 * @wiphy: WIPHY structure pointer
7094 * @wdev: Wireless device structure pointer
7095 * @data: Pointer to the data received
7096 * @data_len: Length of the data received
7097 *
7098 * This function return the above link properties on success.
7099 *
7100 * Return: 0 on success and errno on failure
7101 */
7102static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7103 struct wireless_dev *wdev,
7104 const void *data,
7105 int data_len)
7106{
7107 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7108 struct net_device *dev = wdev->netdev;
7109 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7110 hdd_station_ctx_t *hdd_sta_ctx;
7111 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7112 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7113 uint32_t sta_id;
7114 struct sk_buff *reply_skb;
7115 uint32_t rate_flags = 0;
7116 uint8_t nss;
7117 uint8_t final_rate_flags = 0;
7118 uint32_t freq;
7119 v_CONTEXT_t pVosContext = NULL;
7120 ptSapContext pSapCtx = NULL;
7121
7122 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7124 return -EINVAL;
7125 }
7126
7127 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7128 qca_wlan_vendor_attr_policy)) {
7129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7130 return -EINVAL;
7131 }
7132
7133 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7134 hddLog(VOS_TRACE_LEVEL_ERROR,
7135 FL("Attribute peerMac not provided for mode=%d"),
7136 adapter->device_mode);
7137 return -EINVAL;
7138 }
7139
7140 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7141 sizeof(peer_mac));
7142 hddLog(VOS_TRACE_LEVEL_INFO,
7143 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7144 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7145
7146 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7147 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7148 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7149 if ((hdd_sta_ctx->conn_info.connState !=
7150 eConnectionState_Associated) ||
7151 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7152 VOS_MAC_ADDRESS_LEN)) {
7153 hddLog(VOS_TRACE_LEVEL_ERROR,
7154 FL("Not Associated to mac "MAC_ADDRESS_STR),
7155 MAC_ADDR_ARRAY(peer_mac));
7156 return -EINVAL;
7157 }
7158
7159 nss = 1; //pronto supports only one spatial stream
7160 freq = vos_chan_to_freq(
7161 hdd_sta_ctx->conn_info.operationChannel);
7162 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7163
7164 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7165 adapter->device_mode == WLAN_HDD_SOFTAP) {
7166
7167 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7168 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7169 if(pSapCtx == NULL){
7170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7171 FL("psapCtx is NULL"));
7172 return -ENOENT;
7173 }
7174
7175
7176 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7177 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7178 !vos_is_macaddr_broadcast(
7179 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7180 vos_mem_compare(
7181 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7182 peer_mac, VOS_MAC_ADDRESS_LEN))
7183 break;
7184 }
7185
7186 if (WLAN_MAX_STA_COUNT == sta_id) {
7187 hddLog(VOS_TRACE_LEVEL_ERROR,
7188 FL("No active peer with mac="MAC_ADDRESS_STR),
7189 MAC_ADDR_ARRAY(peer_mac));
7190 return -EINVAL;
7191 }
7192
7193 nss = 1; //pronto supports only one spatial stream
7194 freq = vos_chan_to_freq(
7195 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7196 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7197 } else {
7198 hddLog(VOS_TRACE_LEVEL_ERROR,
7199 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7200 MAC_ADDR_ARRAY(peer_mac));
7201 return -EINVAL;
7202 }
7203
7204 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7205 if (rate_flags & eHAL_TX_RATE_VHT80) {
7206 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7207 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7208 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7209 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7210 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7211 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7212 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7213 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7214 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7215 if (rate_flags & eHAL_TX_RATE_HT40)
7216 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7217 }
7218
7219 if (rate_flags & eHAL_TX_RATE_SGI) {
7220 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7221 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7222 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7223 }
7224 }
7225
7226 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7227 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7228
7229 if (NULL == reply_skb) {
7230 hddLog(VOS_TRACE_LEVEL_ERROR,
7231 FL("getLinkProperties: skb alloc failed"));
7232 return -EINVAL;
7233 }
7234
7235 if (nla_put_u8(reply_skb,
7236 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7237 nss) ||
7238 nla_put_u8(reply_skb,
7239 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7240 final_rate_flags) ||
7241 nla_put_u32(reply_skb,
7242 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7243 freq)) {
7244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7245 kfree_skb(reply_skb);
7246 return -EINVAL;
7247 }
7248
7249 return cfg80211_vendor_cmd_reply(reply_skb);
7250}
7251
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307252#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7253#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7254#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7255#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307256#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7257 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307258
7259/**
7260 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7261 * vendor command
7262 *
7263 * @wiphy: wiphy device pointer
7264 * @wdev: wireless device pointer
7265 * @data: Vendor command data buffer
7266 * @data_len: Buffer length
7267 *
7268 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7269 *
7270 * Return: EOK or other error codes.
7271 */
7272
7273static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7274 struct wireless_dev *wdev,
7275 const void *data,
7276 int data_len)
7277{
7278 struct net_device *dev = wdev->netdev;
7279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7280 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7281 hdd_station_ctx_t *pHddStaCtx;
7282 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7283 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307284 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307285 eHalStatus status;
7286 int ret_val;
7287 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7288 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7289 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307290 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7291 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7292 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307293 };
7294
7295 ENTER();
7296
7297 if (VOS_FTM_MODE == hdd_get_conparam()) {
7298 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7299 return -EINVAL;
7300 }
7301
7302 ret_val = wlan_hdd_validate_context(pHddCtx);
7303 if (ret_val) {
7304 return ret_val;
7305 }
7306
7307 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7308
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307309 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7310 hddLog(LOGE, FL("Invalid ATTR"));
7311 return -EINVAL;
7312 }
7313
7314 /* check the Wifi Capability */
7315 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7316 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7317 {
7318 hddLog(VOS_TRACE_LEVEL_ERROR,
7319 FL("WIFICONFIG not supported by Firmware"));
7320 return -EINVAL;
7321 }
7322
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307323 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7324 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7325 modifyRoamParamsReq.value =
7326 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7327
7328 if (eHAL_STATUS_SUCCESS !=
7329 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7330 {
7331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7332 ret_val = -EINVAL;
7333 }
7334 return ret_val;
7335 }
7336
7337 /* Moved this down in order to provide provision to set beacon
7338 * miss penalty count irrespective of connection state.
7339 */
7340 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7341 hddLog(LOGE, FL("Not in Connected state!"));
7342 return -ENOTSUPP;
7343 }
7344
7345 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307346
7347 if (!pReq) {
7348 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7349 "%s: Not able to allocate memory for tSetWifiConfigParams",
7350 __func__);
7351 return eHAL_STATUS_E_MALLOC_FAILED;
7352 }
7353
7354 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7355
7356 pReq->sessionId = pAdapter->sessionId;
7357 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7358
7359 if (tb[PARAM_MODULATED_DTIM]) {
7360 pReq->paramValue = nla_get_u32(
7361 tb[PARAM_MODULATED_DTIM]);
7362 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7363 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307364 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307365 hdd_set_pwrparams(pHddCtx);
7366 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7367 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7368
7369 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7370 iw_full_power_cbfn, pAdapter,
7371 eSME_FULL_PWR_NEEDED_BY_HDD);
7372 }
7373 else
7374 {
7375 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7376 }
7377 }
7378
7379 if (tb[PARAM_STATS_AVG_FACTOR]) {
7380 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7381 pReq->paramValue = nla_get_u16(
7382 tb[PARAM_STATS_AVG_FACTOR]);
7383 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7384 pReq->paramType, pReq->paramValue);
7385 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7386
7387 if (eHAL_STATUS_SUCCESS != status)
7388 {
7389 vos_mem_free(pReq);
7390 pReq = NULL;
7391 ret_val = -EPERM;
7392 return ret_val;
7393 }
7394 }
7395
7396
7397 if (tb[PARAM_GUARD_TIME]) {
7398 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7399 pReq->paramValue = nla_get_u32(
7400 tb[PARAM_GUARD_TIME]);
7401 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7402 pReq->paramType, pReq->paramValue);
7403 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7404
7405 if (eHAL_STATUS_SUCCESS != status)
7406 {
7407 vos_mem_free(pReq);
7408 pReq = NULL;
7409 ret_val = -EPERM;
7410 return ret_val;
7411 }
7412
7413 }
7414
7415 EXIT();
7416 return ret_val;
7417}
7418
7419/**
7420 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7421 * vendor command
7422 *
7423 * @wiphy: wiphy device pointer
7424 * @wdev: wireless device pointer
7425 * @data: Vendor command data buffer
7426 * @data_len: Buffer length
7427 *
7428 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7429 *
7430 * Return: EOK or other error codes.
7431 */
7432static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7433 struct wireless_dev *wdev,
7434 const void *data,
7435 int data_len)
7436{
7437 int ret;
7438
7439 vos_ssr_protect(__func__);
7440 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7441 data, data_len);
7442 vos_ssr_unprotect(__func__);
7443
7444 return ret;
7445}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307446const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7447{
Mukul Sharma2a271632014-10-13 14:59:01 +05307448 {
7449 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7450 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7451 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7452 WIPHY_VENDOR_CMD_NEED_NETDEV |
7453 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307454 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307455 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307456
7457 {
7458 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7459 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7460 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7461 WIPHY_VENDOR_CMD_NEED_NETDEV |
7462 WIPHY_VENDOR_CMD_NEED_RUNNING,
7463 .doit = wlan_hdd_cfg80211_nan_request
7464 },
7465
Sunil Duttc69bccb2014-05-26 21:30:20 +05307466#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7467 {
7468 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7469 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7470 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7471 WIPHY_VENDOR_CMD_NEED_NETDEV |
7472 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307473 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307474 },
7475
7476 {
7477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7480 WIPHY_VENDOR_CMD_NEED_NETDEV |
7481 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307482 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307483 },
7484
7485 {
7486 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7487 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7488 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7489 WIPHY_VENDOR_CMD_NEED_NETDEV |
7490 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307491 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307492 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307493#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307494#ifdef WLAN_FEATURE_EXTSCAN
7495 {
7496 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7497 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7498 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7499 WIPHY_VENDOR_CMD_NEED_NETDEV |
7500 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307501 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307502 },
7503 {
7504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7507 WIPHY_VENDOR_CMD_NEED_NETDEV |
7508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307509 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307510 },
7511 {
7512 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7513 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7514 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7515 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307516 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307517 },
7518 {
7519 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7520 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7521 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7522 WIPHY_VENDOR_CMD_NEED_NETDEV |
7523 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307524 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307525 },
7526 {
7527 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7528 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7529 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7530 WIPHY_VENDOR_CMD_NEED_NETDEV |
7531 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307532 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307533 },
7534 {
7535 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7536 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7537 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7538 WIPHY_VENDOR_CMD_NEED_NETDEV |
7539 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307540 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307541 },
7542 {
7543 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7544 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7545 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7546 WIPHY_VENDOR_CMD_NEED_NETDEV |
7547 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307548 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307549 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307550 {
7551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7554 WIPHY_VENDOR_CMD_NEED_NETDEV |
7555 WIPHY_VENDOR_CMD_NEED_RUNNING,
7556 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7557 },
7558 {
7559 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7560 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7561 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7562 WIPHY_VENDOR_CMD_NEED_NETDEV |
7563 WIPHY_VENDOR_CMD_NEED_RUNNING,
7564 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7565 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307566#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307567/*EXT TDLS*/
7568 {
7569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7572 WIPHY_VENDOR_CMD_NEED_NETDEV |
7573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307574 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307575 },
7576 {
7577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7580 WIPHY_VENDOR_CMD_NEED_NETDEV |
7581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307582 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307583 },
7584 {
7585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7588 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307589 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307590 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307591 {
7592 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7593 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7594 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7595 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307596 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307597 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307598 {
7599 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7600 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7601 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7602 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307603 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307604 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307605 {
7606 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7607 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7608 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7609 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307610 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307611 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307612 {
7613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7616 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307617 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307618 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307619 {
7620 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307621 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7622 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7623 WIPHY_VENDOR_CMD_NEED_NETDEV |
7624 WIPHY_VENDOR_CMD_NEED_RUNNING,
7625 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7626 },
7627 {
7628 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307629 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7630 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7631 WIPHY_VENDOR_CMD_NEED_NETDEV |
7632 WIPHY_VENDOR_CMD_NEED_RUNNING,
7633 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307634 },
7635 {
7636 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7637 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7638 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7639 WIPHY_VENDOR_CMD_NEED_NETDEV,
7640 .doit = wlan_hdd_cfg80211_wifi_logger_start
7641 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307642 {
7643 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7644 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7645 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7646 WIPHY_VENDOR_CMD_NEED_NETDEV|
7647 WIPHY_VENDOR_CMD_NEED_RUNNING,
7648 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307649 },
7650 {
7651 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7652 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7653 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7654 WIPHY_VENDOR_CMD_NEED_NETDEV |
7655 WIPHY_VENDOR_CMD_NEED_RUNNING,
7656 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307657 },
7658 {
7659 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7660 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7661 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7662 WIPHY_VENDOR_CMD_NEED_NETDEV |
7663 WIPHY_VENDOR_CMD_NEED_RUNNING,
7664 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307665 },
7666#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7667 {
7668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7671 WIPHY_VENDOR_CMD_NEED_NETDEV |
7672 WIPHY_VENDOR_CMD_NEED_RUNNING,
7673 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307674 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307675#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307676 {
7677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7680 WIPHY_VENDOR_CMD_NEED_NETDEV |
7681 WIPHY_VENDOR_CMD_NEED_RUNNING,
7682 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307683 },
7684 {
7685 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7686 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7687 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7688 WIPHY_VENDOR_CMD_NEED_NETDEV |
7689 WIPHY_VENDOR_CMD_NEED_RUNNING,
7690 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307691 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307692};
7693
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007694/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307695static const
7696struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007697{
7698#ifdef FEATURE_WLAN_CH_AVOID
7699 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307700 .vendor_id = QCA_NL80211_VENDOR_ID,
7701 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007702 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307703#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7704#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7705 {
7706 /* Index = 1*/
7707 .vendor_id = QCA_NL80211_VENDOR_ID,
7708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7709 },
7710 {
7711 /* Index = 2*/
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7714 },
7715 {
7716 /* Index = 3*/
7717 .vendor_id = QCA_NL80211_VENDOR_ID,
7718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7719 },
7720 {
7721 /* Index = 4*/
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7724 },
7725 {
7726 /* Index = 5*/
7727 .vendor_id = QCA_NL80211_VENDOR_ID,
7728 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7729 },
7730 {
7731 /* Index = 6*/
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7734 },
7735#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307736#ifdef WLAN_FEATURE_EXTSCAN
7737 {
7738 .vendor_id = QCA_NL80211_VENDOR_ID,
7739 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7740 },
7741 {
7742 .vendor_id = QCA_NL80211_VENDOR_ID,
7743 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7744 },
7745 {
7746 .vendor_id = QCA_NL80211_VENDOR_ID,
7747 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7748 },
7749 {
7750 .vendor_id = QCA_NL80211_VENDOR_ID,
7751 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7752 },
7753 {
7754 .vendor_id = QCA_NL80211_VENDOR_ID,
7755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7756 },
7757 {
7758 .vendor_id = QCA_NL80211_VENDOR_ID,
7759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7760 },
7761 {
7762 .vendor_id = QCA_NL80211_VENDOR_ID,
7763 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7764 },
7765 {
7766 .vendor_id = QCA_NL80211_VENDOR_ID,
7767 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7768 },
7769 {
7770 .vendor_id = QCA_NL80211_VENDOR_ID,
7771 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7772 },
7773 {
7774 .vendor_id = QCA_NL80211_VENDOR_ID,
7775 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7776 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307777 {
7778 .vendor_id = QCA_NL80211_VENDOR_ID,
7779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7780 },
7781 {
7782 .vendor_id = QCA_NL80211_VENDOR_ID,
7783 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7784 },
7785 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7786 .vendor_id = QCA_NL80211_VENDOR_ID,
7787 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7788 },
7789 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7790 .vendor_id = QCA_NL80211_VENDOR_ID,
7791 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7792 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307793#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307794/*EXT TDLS*/
7795 {
7796 .vendor_id = QCA_NL80211_VENDOR_ID,
7797 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7798 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307799 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7800 .vendor_id = QCA_NL80211_VENDOR_ID,
7801 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7802 },
7803
Srinivas Dasari030bad32015-02-18 23:23:54 +05307804
7805 {
7806 .vendor_id = QCA_NL80211_VENDOR_ID,
7807 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7808 },
7809
Sushant Kaushik084f6592015-09-10 13:11:56 +05307810 {
7811 .vendor_id = QCA_NL80211_VENDOR_ID,
7812 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307813 },
7814 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7815 .vendor_id = QCA_NL80211_VENDOR_ID,
7816 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7817 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307818 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7819 .vendor_id = QCA_NL80211_VENDOR_ID,
7820 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7821 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307822
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007823};
7824
Jeff Johnson295189b2012-06-20 16:38:30 -07007825/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307826 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307827 * This function is called by hdd_wlan_startup()
7828 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307829 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307831struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007832{
7833 struct wiphy *wiphy;
7834 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307835 /*
7836 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 */
7838 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7839
7840 if (!wiphy)
7841 {
7842 /* Print error and jump into err label and free the memory */
7843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7844 return NULL;
7845 }
7846
Sunil Duttc69bccb2014-05-26 21:30:20 +05307847
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 return wiphy;
7849}
7850
7851/*
7852 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307853 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 * private ioctl to change the band value
7855 */
7856int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7857{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307858 int i, j;
7859 eNVChannelEnabledType channelEnabledState;
7860
Jeff Johnsone7245742012-09-05 17:12:55 -07007861 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307862
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307863 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307865
7866 if (NULL == wiphy->bands[i])
7867 {
7868 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7869 __func__, i);
7870 continue;
7871 }
7872
7873 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7874 {
7875 struct ieee80211_supported_band *band = wiphy->bands[i];
7876
7877 channelEnabledState = vos_nv_getChannelEnabledState(
7878 band->channels[j].hw_value);
7879
7880 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7881 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307882 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307883 continue;
7884 }
7885 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7886 {
7887 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7888 continue;
7889 }
7890
7891 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7892 NV_CHANNEL_INVALID == channelEnabledState)
7893 {
7894 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7895 }
7896 else if (NV_CHANNEL_DFS == channelEnabledState)
7897 {
7898 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7899 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7900 }
7901 else
7902 {
7903 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7904 |IEEE80211_CHAN_RADAR);
7905 }
7906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 }
7908 return 0;
7909}
7910/*
7911 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307912 * This function is called by hdd_wlan_startup()
7913 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 * This function is used to initialize and register wiphy structure.
7915 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307916int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 struct wiphy *wiphy,
7918 hdd_config_t *pCfg
7919 )
7920{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307921 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307922 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7923
Jeff Johnsone7245742012-09-05 17:12:55 -07007924 ENTER();
7925
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 /* Now bind the underlying wlan device with wiphy */
7927 set_wiphy_dev(wiphy, dev);
7928
7929 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007930
Kiet Lam6c583332013-10-14 05:37:09 +05307931#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007932 /* the flag for the other case would be initialzed in
7933 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7935 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7936#else
Amar Singhal0a402232013-10-11 20:57:16 -07007937 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307938#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307939#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007940
Amar Singhalfddc28c2013-09-05 13:03:40 -07007941 /* This will disable updating of NL channels from passive to
7942 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7944 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7945#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007946 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307947#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007948
Amar Singhala49cbc52013-10-08 18:37:44 -07007949
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007951 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7952 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7953 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007954 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307956 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307957#else
7958 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7959#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007960#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007961
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007962#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007963 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007964#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007965 || pCfg->isFastRoamIniFeatureEnabled
7966#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007967#ifdef FEATURE_WLAN_ESE
7968 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007969#endif
7970 )
7971 {
7972 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7973 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007974#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007975#ifdef FEATURE_WLAN_TDLS
7976 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7977 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7978#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307979#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307980 if (pCfg->configPNOScanSupport)
7981 {
7982 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7983 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7984 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7985 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7986 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307987#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007988
Abhishek Singh10d85972015-04-17 10:27:23 +05307989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7990 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7991#endif
7992
Amar Singhalfddc28c2013-09-05 13:03:40 -07007993#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007994 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7995 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007996 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007997 driver need to determine what to do with both
7998 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007999
8000 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008001#else
8002 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008003#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008004
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308005 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8006
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308007 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008008
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308009 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8010
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308012 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8013 | BIT(NL80211_IFTYPE_ADHOC)
8014 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8015 | BIT(NL80211_IFTYPE_P2P_GO)
8016 | BIT(NL80211_IFTYPE_AP);
8017
8018 if (VOS_MONITOR_MODE == hdd_get_conparam())
8019 {
8020 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008022
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308023 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008024 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8026 if( pCfg->enableMCC )
8027 {
8028 /* Currently, supports up to two channels */
8029 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008030
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308031 if( !pCfg->allowMCCGODiffBI )
8032 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008033
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308034 }
8035 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8036 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008037#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308038 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008039
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 /* Before registering we need to update the ht capabilitied based
8041 * on ini values*/
8042 if( !pCfg->ShortGI20MhzEnable )
8043 {
8044 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8045 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 }
8047
8048 if( !pCfg->ShortGI40MhzEnable )
8049 {
8050 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8051 }
8052
8053 if( !pCfg->nChannelBondingMode5GHz )
8054 {
8055 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8056 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308057 /*
8058 * In case of static linked driver at the time of driver unload,
8059 * module exit doesn't happens. Module cleanup helps in cleaning
8060 * of static memory.
8061 * If driver load happens statically, at the time of driver unload,
8062 * wiphy flags don't get reset because of static memory.
8063 * It's better not to store channel in static memory.
8064 */
8065 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8066 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8067 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8068 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8069 {
8070 hddLog(VOS_TRACE_LEVEL_ERROR,
8071 FL("Not enough memory to allocate channels"));
8072 return -ENOMEM;
8073 }
8074 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8075 &hdd_channels_2_4_GHZ[0],
8076 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008077
Agrawal Ashish97dec502015-11-26 20:20:58 +05308078 if (true == hdd_is_5g_supported(pHddCtx))
8079 {
8080 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8081 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8082 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8083 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8084 {
8085 hddLog(VOS_TRACE_LEVEL_ERROR,
8086 FL("Not enough memory to allocate channels"));
8087 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8088 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8089 return -ENOMEM;
8090 }
8091 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8092 &hdd_channels_5_GHZ[0],
8093 sizeof(hdd_channels_5_GHZ));
8094 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308095
8096 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8097 {
8098
8099 if (NULL == wiphy->bands[i])
8100 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308101 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308102 __func__, i);
8103 continue;
8104 }
8105
8106 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8107 {
8108 struct ieee80211_supported_band *band = wiphy->bands[i];
8109
8110 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8111 {
8112 // Enable social channels for P2P
8113 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8114 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8115 else
8116 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8117 continue;
8118 }
8119 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8120 {
8121 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8122 continue;
8123 }
8124 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 }
8126 /*Initialise the supported cipher suite details*/
8127 wiphy->cipher_suites = hdd_cipher_suites;
8128 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8129
8130 /*signal strength in mBm (100*dBm) */
8131 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8132
8133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308134 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008136
Sunil Duttc69bccb2014-05-26 21:30:20 +05308137 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8138 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008139 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8140 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8141
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308142 EXIT();
8143 return 0;
8144}
8145
8146/* In this function we are registering wiphy. */
8147int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8148{
8149 ENTER();
8150 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 if (0 > wiphy_register(wiphy))
8152 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308153 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008154 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8155 return -EIO;
8156 }
8157
8158 EXIT();
8159 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308160}
Jeff Johnson295189b2012-06-20 16:38:30 -07008161
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308162/* In this function we are updating channel list when,
8163 regulatory domain is FCC and country code is US.
8164 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8165 As per FCC smart phone is not a indoor device.
8166 GO should not opeate on indoor channels */
8167void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8168{
8169 int j;
8170 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8171 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8172 //Default counrtycode from NV at the time of wiphy initialization.
8173 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8174 &defaultCountryCode[0]))
8175 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008176 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308177 }
8178 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8179 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308180 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8181 {
8182 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8183 return;
8184 }
8185 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8186 {
8187 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8188 // Mark UNII -1 band channel as passive
8189 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8190 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8191 }
8192 }
8193}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308194/* This function registers for all frame which supplicant is interested in */
8195void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008196{
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8198 /* Register for all P2P action, public action etc frames */
8199 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008200 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308201 /* Register frame indication call back */
8202 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 /* Right now we are registering these frame when driver is getting
8204 initialized. Once we will move to 2.6.37 kernel, in which we have
8205 frame register ops, we will move this code as a part of that */
8206 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308207 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8209
8210 /* GAS Initial Response */
8211 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8212 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 /* GAS Comeback Request */
8215 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8216 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8217
8218 /* GAS Comeback Response */
8219 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8220 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8221
8222 /* P2P Public Action */
8223 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308224 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 P2P_PUBLIC_ACTION_FRAME_SIZE );
8226
8227 /* P2P Action */
8228 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8229 (v_U8_t*)P2P_ACTION_FRAME,
8230 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008231
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308232 /* WNM BSS Transition Request frame */
8233 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8234 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8235 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008236
8237 /* WNM-Notification */
8238 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8239 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8240 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008241}
8242
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308243void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008244{
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8246 /* Register for all P2P action, public action etc frames */
8247 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8248
Jeff Johnsone7245742012-09-05 17:12:55 -07008249 ENTER();
8250
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 /* Right now we are registering these frame when driver is getting
8252 initialized. Once we will move to 2.6.37 kernel, in which we have
8253 frame register ops, we will move this code as a part of that */
8254 /* GAS Initial Request */
8255
8256 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8257 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8258
8259 /* GAS Initial Response */
8260 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8261 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308262
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 /* GAS Comeback Request */
8264 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8265 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8266
8267 /* GAS Comeback Response */
8268 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8269 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8270
8271 /* P2P Public Action */
8272 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308273 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 P2P_PUBLIC_ACTION_FRAME_SIZE );
8275
8276 /* P2P Action */
8277 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8278 (v_U8_t*)P2P_ACTION_FRAME,
8279 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008280 /* WNM-Notification */
8281 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8282 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8283 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008284}
8285
8286#ifdef FEATURE_WLAN_WAPI
8287void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308288 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008289{
8290 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8291 tCsrRoamSetKey setKey;
8292 v_BOOL_t isConnected = TRUE;
8293 int status = 0;
8294 v_U32_t roamId= 0xFF;
8295 tANI_U8 *pKeyPtr = NULL;
8296 int n = 0;
8297
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8299 __func__, hdd_device_modetoString(pAdapter->device_mode),
8300 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008301
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308302 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 setKey.keyId = key_index; // Store Key ID
8304 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8305 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8306 setKey.paeRole = 0 ; // the PAE role
8307 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8308 {
8309 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8310 }
8311 else
8312 {
8313 isConnected = hdd_connIsConnected(pHddStaCtx);
8314 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8315 }
8316 setKey.keyLength = key_Len;
8317 pKeyPtr = setKey.Key;
8318 memcpy( pKeyPtr, key, key_Len);
8319
Arif Hussain6d2a3322013-11-17 19:50:10 -08008320 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 __func__, key_Len);
8322 for (n = 0 ; n < key_Len; n++)
8323 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8324 __func__,n,setKey.Key[n]);
8325
8326 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8327 if ( isConnected )
8328 {
8329 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8330 pAdapter->sessionId, &setKey, &roamId );
8331 }
8332 if ( status != 0 )
8333 {
8334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8335 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8336 __LINE__, status );
8337 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8338 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308339 /* Need to clear any trace of key value in the memory.
8340 * Thus zero out the memory even though it is local
8341 * variable.
8342 */
8343 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008344}
8345#endif /* FEATURE_WLAN_WAPI*/
8346
8347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308348int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 beacon_data_t **ppBeacon,
8350 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008351#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308352int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008353 beacon_data_t **ppBeacon,
8354 struct cfg80211_beacon_data *params,
8355 int dtim_period)
8356#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308357{
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 int size;
8359 beacon_data_t *beacon = NULL;
8360 beacon_data_t *old = NULL;
8361 int head_len,tail_len;
8362
Jeff Johnsone7245742012-09-05 17:12:55 -07008363 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308365 {
8366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8367 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008368 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008370
8371 old = pAdapter->sessionCtx.ap.beacon;
8372
8373 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 {
8375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8376 FL("session(%d) old and new heads points to NULL"),
8377 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308379 }
8380
8381 if (params->tail && !params->tail_len)
8382 {
8383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8384 FL("tail_len is zero but tail is not NULL"));
8385 return -EINVAL;
8386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8389 /* Kernel 3.0 is not updating dtim_period for set beacon */
8390 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308391 {
8392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8393 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008396#endif
8397
8398 if(params->head)
8399 head_len = params->head_len;
8400 else
8401 head_len = old->head_len;
8402
8403 if(params->tail || !old)
8404 tail_len = params->tail_len;
8405 else
8406 tail_len = old->tail_len;
8407
8408 size = sizeof(beacon_data_t) + head_len + tail_len;
8409
8410 beacon = kzalloc(size, GFP_KERNEL);
8411
8412 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308413 {
8414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8415 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308417 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008418
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008419#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 if(params->dtim_period || !old )
8421 beacon->dtim_period = params->dtim_period;
8422 else
8423 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008424#else
8425 if(dtim_period || !old )
8426 beacon->dtim_period = dtim_period;
8427 else
8428 beacon->dtim_period = old->dtim_period;
8429#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308430
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8432 beacon->tail = beacon->head + head_len;
8433 beacon->head_len = head_len;
8434 beacon->tail_len = tail_len;
8435
8436 if(params->head) {
8437 memcpy (beacon->head,params->head,beacon->head_len);
8438 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308439 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 if(old)
8441 memcpy (beacon->head,old->head,beacon->head_len);
8442 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 if(params->tail) {
8445 memcpy (beacon->tail,params->tail,beacon->tail_len);
8446 }
8447 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 memcpy (beacon->tail,old->tail,beacon->tail_len);
8450 }
8451
8452 *ppBeacon = beacon;
8453
8454 kfree(old);
8455
8456 return 0;
8457
8458}
Jeff Johnson295189b2012-06-20 16:38:30 -07008459
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308460v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8462 const v_U8_t *pIes,
8463#else
8464 v_U8_t *pIes,
8465#endif
8466 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008467{
8468 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308469 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308471
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308473 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 elem_id = ptr[0];
8475 elem_len = ptr[1];
8476 left -= 2;
8477 if(elem_len > left)
8478 {
8479 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008480 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 eid,elem_len,left);
8482 return NULL;
8483 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308484 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 {
8486 return ptr;
8487 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308488
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 left -= elem_len;
8490 ptr += (elem_len + 2);
8491 }
8492 return NULL;
8493}
8494
Jeff Johnson295189b2012-06-20 16:38:30 -07008495/* Check if rate is 11g rate or not */
8496static int wlan_hdd_rate_is_11g(u8 rate)
8497{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008498 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 u8 i;
8500 for (i = 0; i < 8; i++)
8501 {
8502 if(rate == gRateArray[i])
8503 return TRUE;
8504 }
8505 return FALSE;
8506}
8507
8508/* Check for 11g rate and set proper 11g only mode */
8509static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8510 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8511{
8512 u8 i, num_rates = pIe[0];
8513
8514 pIe += 1;
8515 for ( i = 0; i < num_rates; i++)
8516 {
8517 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8518 {
8519 /* If rate set have 11g rate than change the mode to 11G */
8520 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8521 if (pIe[i] & BASIC_RATE_MASK)
8522 {
8523 /* If we have 11g rate as basic rate, it means mode
8524 is 11g only mode.
8525 */
8526 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8527 *pCheckRatesfor11g = FALSE;
8528 }
8529 }
8530 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8531 {
8532 *require_ht = TRUE;
8533 }
8534 }
8535 return;
8536}
8537
8538static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8539{
8540 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8541 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8542 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8543 u8 checkRatesfor11g = TRUE;
8544 u8 require_ht = FALSE;
8545 u8 *pIe=NULL;
8546
8547 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8548
8549 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8550 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8551 if (pIe != NULL)
8552 {
8553 pIe += 1;
8554 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8555 &pConfig->SapHw_mode);
8556 }
8557
8558 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8559 WLAN_EID_EXT_SUPP_RATES);
8560 if (pIe != NULL)
8561 {
8562
8563 pIe += 1;
8564 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8565 &pConfig->SapHw_mode);
8566 }
8567
8568 if( pConfig->channel > 14 )
8569 {
8570 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8571 }
8572
8573 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8574 WLAN_EID_HT_CAPABILITY);
8575
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308576 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 {
8578 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8579 if(require_ht)
8580 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8581 }
8582}
8583
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308584static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8585 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8586{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008587 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308588 v_U8_t *pIe = NULL;
8589 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8590
8591 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8592 pBeacon->tail, pBeacon->tail_len);
8593
8594 if (pIe)
8595 {
8596 ielen = pIe[1] + 2;
8597 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8598 {
8599 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8600 }
8601 else
8602 {
8603 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8604 return -EINVAL;
8605 }
8606 *total_ielen += ielen;
8607 }
8608 return 0;
8609}
8610
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008611static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8612 v_U8_t *genie, v_U8_t *total_ielen)
8613{
8614 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8615 int left = pBeacon->tail_len;
8616 v_U8_t *ptr = pBeacon->tail;
8617 v_U8_t elem_id, elem_len;
8618 v_U16_t ielen = 0;
8619
8620 if ( NULL == ptr || 0 == left )
8621 return;
8622
8623 while (left >= 2)
8624 {
8625 elem_id = ptr[0];
8626 elem_len = ptr[1];
8627 left -= 2;
8628 if (elem_len > left)
8629 {
8630 hddLog( VOS_TRACE_LEVEL_ERROR,
8631 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8632 elem_id, elem_len, left);
8633 return;
8634 }
8635 if (IE_EID_VENDOR == elem_id)
8636 {
8637 /* skipping the VSIE's which we don't want to include or
8638 * it will be included by existing code
8639 */
8640 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8641#ifdef WLAN_FEATURE_WFD
8642 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8643#endif
8644 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8645 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8646 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8647 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8648 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8649 {
8650 ielen = ptr[1] + 2;
8651 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8652 {
8653 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8654 *total_ielen += ielen;
8655 }
8656 else
8657 {
8658 hddLog( VOS_TRACE_LEVEL_ERROR,
8659 "IE Length is too big "
8660 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8661 elem_id, elem_len, *total_ielen);
8662 }
8663 }
8664 }
8665
8666 left -= elem_len;
8667 ptr += (elem_len + 2);
8668 }
8669 return;
8670}
8671
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008672#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008673static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8674 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008675#else
8676static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8677 struct cfg80211_beacon_data *params)
8678#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008679{
8680 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308681 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008683 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008684
8685 genie = vos_mem_malloc(MAX_GENIE_LEN);
8686
8687 if(genie == NULL) {
8688
8689 return -ENOMEM;
8690 }
8691
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308692 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8693 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308695 hddLog(LOGE,
8696 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308697 ret = -EINVAL;
8698 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 }
8700
8701#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308702 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8703 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8704 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308705 hddLog(LOGE,
8706 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308707 ret = -EINVAL;
8708 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 }
8710#endif
8711
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308712 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8713 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308715 hddLog(LOGE,
8716 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308717 ret = -EINVAL;
8718 goto done;
8719 }
8720
8721 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8722 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008723 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008725
8726 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8727 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8728 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8729 {
8730 hddLog(LOGE,
8731 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008732 ret = -EINVAL;
8733 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 }
8735
8736 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8737 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8738 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8739 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8740 ==eHAL_STATUS_FAILURE)
8741 {
8742 hddLog(LOGE,
8743 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008744 ret = -EINVAL;
8745 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 }
8747
8748 // Added for ProResp IE
8749 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8750 {
8751 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8752 u8 probe_rsp_ie_len[3] = {0};
8753 u8 counter = 0;
8754 /* Check Probe Resp Length if it is greater then 255 then Store
8755 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8756 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8757 Store More then 255 bytes into One Variable.
8758 */
8759 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8760 {
8761 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8762 {
8763 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8764 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8765 }
8766 else
8767 {
8768 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8769 rem_probe_resp_ie_len = 0;
8770 }
8771 }
8772
8773 rem_probe_resp_ie_len = 0;
8774
8775 if (probe_rsp_ie_len[0] > 0)
8776 {
8777 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8778 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8779 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8780 probe_rsp_ie_len[0], NULL,
8781 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8782 {
8783 hddLog(LOGE,
8784 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008785 ret = -EINVAL;
8786 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 }
8788 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8789 }
8790
8791 if (probe_rsp_ie_len[1] > 0)
8792 {
8793 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8794 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8795 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8796 probe_rsp_ie_len[1], NULL,
8797 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8798 {
8799 hddLog(LOGE,
8800 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008801 ret = -EINVAL;
8802 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 }
8804 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8805 }
8806
8807 if (probe_rsp_ie_len[2] > 0)
8808 {
8809 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8810 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8811 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8812 probe_rsp_ie_len[2], NULL,
8813 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8814 {
8815 hddLog(LOGE,
8816 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008817 ret = -EINVAL;
8818 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 }
8820 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8821 }
8822
8823 if (probe_rsp_ie_len[1] == 0 )
8824 {
8825 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8826 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8827 eANI_BOOLEAN_FALSE) )
8828 {
8829 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008830 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 }
8832 }
8833
8834 if (probe_rsp_ie_len[2] == 0 )
8835 {
8836 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8837 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8838 eANI_BOOLEAN_FALSE) )
8839 {
8840 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008841 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 }
8843 }
8844
8845 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8846 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8847 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8848 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8849 == eHAL_STATUS_FAILURE)
8850 {
8851 hddLog(LOGE,
8852 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008853 ret = -EINVAL;
8854 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 }
8856 }
8857 else
8858 {
8859 // Reset WNI_CFG_PROBE_RSP Flags
8860 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8861
8862 hddLog(VOS_TRACE_LEVEL_INFO,
8863 "%s: No Probe Response IE received in set beacon",
8864 __func__);
8865 }
8866
8867 // Added for AssocResp IE
8868 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8869 {
8870 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8871 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8872 params->assocresp_ies_len, NULL,
8873 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8874 {
8875 hddLog(LOGE,
8876 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008877 ret = -EINVAL;
8878 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 }
8880
8881 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8882 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8883 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8884 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8885 == eHAL_STATUS_FAILURE)
8886 {
8887 hddLog(LOGE,
8888 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008889 ret = -EINVAL;
8890 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 }
8892 }
8893 else
8894 {
8895 hddLog(VOS_TRACE_LEVEL_INFO,
8896 "%s: No Assoc Response IE received in set beacon",
8897 __func__);
8898
8899 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8900 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8901 eANI_BOOLEAN_FALSE) )
8902 {
8903 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008904 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 }
8906 }
8907
Jeff Johnsone7245742012-09-05 17:12:55 -07008908done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308910 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008911}
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 * FUNCTION: wlan_hdd_validate_operation_channel
8915 * called by wlan_hdd_cfg80211_start_bss() and
8916 * wlan_hdd_cfg80211_set_channel()
8917 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308918 * channel list.
8919 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008920VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008921{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308922
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 v_U32_t num_ch = 0;
8924 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8925 u32 indx = 0;
8926 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308927 v_U8_t fValidChannel = FALSE, count = 0;
8928 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308929
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8931
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308932 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308934 /* Validate the channel */
8935 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308937 if ( channel == rfChannels[count].channelNum )
8938 {
8939 fValidChannel = TRUE;
8940 break;
8941 }
8942 }
8943 if (fValidChannel != TRUE)
8944 {
8945 hddLog(VOS_TRACE_LEVEL_ERROR,
8946 "%s: Invalid Channel [%d]", __func__, channel);
8947 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 }
8949 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308950 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308952 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8953 valid_ch, &num_ch))
8954 {
8955 hddLog(VOS_TRACE_LEVEL_ERROR,
8956 "%s: failed to get valid channel list", __func__);
8957 return VOS_STATUS_E_FAILURE;
8958 }
8959 for (indx = 0; indx < num_ch; indx++)
8960 {
8961 if (channel == valid_ch[indx])
8962 {
8963 break;
8964 }
8965 }
8966
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308967 if (indx >= num_ch)
8968 {
8969 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8970 {
8971 eCsrBand band;
8972 unsigned int freq;
8973
8974 sme_GetFreqBand(hHal, &band);
8975
8976 if (eCSR_BAND_5G == band)
8977 {
8978#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8979 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8980 {
8981 freq = ieee80211_channel_to_frequency(channel,
8982 IEEE80211_BAND_2GHZ);
8983 }
8984 else
8985 {
8986 freq = ieee80211_channel_to_frequency(channel,
8987 IEEE80211_BAND_5GHZ);
8988 }
8989#else
8990 freq = ieee80211_channel_to_frequency(channel);
8991#endif
8992 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8993 return VOS_STATUS_SUCCESS;
8994 }
8995 }
8996
8997 hddLog(VOS_TRACE_LEVEL_ERROR,
8998 "%s: Invalid Channel [%d]", __func__, channel);
8999 return VOS_STATUS_E_FAILURE;
9000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005}
9006
Viral Modi3a32cc52013-02-08 11:14:52 -08009007/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309008 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009009 * This function is used to set the channel number
9010 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309011static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009012 struct ieee80211_channel *chan,
9013 enum nl80211_channel_type channel_type
9014 )
9015{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309016 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009017 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009018 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009019 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309020 hdd_context_t *pHddCtx;
9021 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009022
9023 ENTER();
9024
9025 if( NULL == dev )
9026 {
9027 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009028 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009029 return -ENODEV;
9030 }
9031 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9034 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9035 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009036 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309037 "%s: device_mode = %s (%d) freq = %d", __func__,
9038 hdd_device_modetoString(pAdapter->device_mode),
9039 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309040
9041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9042 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309043 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309045 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009046 }
9047
9048 /*
9049 * Do freq to chan conversion
9050 * TODO: for 11a
9051 */
9052
9053 channel = ieee80211_frequency_to_channel(freq);
9054
9055 /* Check freq range */
9056 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9057 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9058 {
9059 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009060 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009061 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9062 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9063 return -EINVAL;
9064 }
9065
9066 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9067
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309068 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9069 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009070 {
9071 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9072 {
9073 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009074 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009075 return -EINVAL;
9076 }
9077 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9078 "%s: set channel to [%d] for device mode =%d",
9079 __func__, channel,pAdapter->device_mode);
9080 }
9081 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009082 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009083 )
9084 {
9085 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9086 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9087 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9088
9089 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9090 {
9091 /* Link is up then return cant set channel*/
9092 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009093 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009094 return -EINVAL;
9095 }
9096
9097 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9098 pHddStaCtx->conn_info.operationChannel = channel;
9099 pRoamProfile->ChannelInfo.ChannelList =
9100 &pHddStaCtx->conn_info.operationChannel;
9101 }
9102 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009103 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009104 )
9105 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309106 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9107 {
9108 if(VOS_STATUS_SUCCESS !=
9109 wlan_hdd_validate_operation_channel(pAdapter,channel))
9110 {
9111 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009112 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309113 return -EINVAL;
9114 }
9115 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9116 }
9117 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009118 {
9119 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9120
9121 /* If auto channel selection is configured as enable/ 1 then ignore
9122 channel set by supplicant
9123 */
9124 if ( cfg_param->apAutoChannelSelection )
9125 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309126 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9127 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009128 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309129 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9130 __func__, hdd_device_modetoString(pAdapter->device_mode),
9131 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009132 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309133 else
9134 {
9135 if(VOS_STATUS_SUCCESS !=
9136 wlan_hdd_validate_operation_channel(pAdapter,channel))
9137 {
9138 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009139 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309140 return -EINVAL;
9141 }
9142 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9143 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009144 }
9145 }
9146 else
9147 {
9148 hddLog(VOS_TRACE_LEVEL_FATAL,
9149 "%s: Invalid device mode failed to set valid channel", __func__);
9150 return -EINVAL;
9151 }
9152 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309153 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009154}
9155
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309156static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9157 struct net_device *dev,
9158 struct ieee80211_channel *chan,
9159 enum nl80211_channel_type channel_type
9160 )
9161{
9162 int ret;
9163
9164 vos_ssr_protect(__func__);
9165 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9166 vos_ssr_unprotect(__func__);
9167
9168 return ret;
9169}
9170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9172static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9173 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009174#else
9175static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9176 struct cfg80211_beacon_data *params,
9177 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309178 enum nl80211_hidden_ssid hidden_ssid,
9179 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009180#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009181{
9182 tsap_Config_t *pConfig;
9183 beacon_data_t *pBeacon = NULL;
9184 struct ieee80211_mgmt *pMgmt_frame;
9185 v_U8_t *pIe=NULL;
9186 v_U16_t capab_info;
9187 eCsrAuthType RSNAuthType;
9188 eCsrEncryptionType RSNEncryptType;
9189 eCsrEncryptionType mcRSNEncryptType;
9190 int status = VOS_STATUS_SUCCESS;
9191 tpWLAN_SAPEventCB pSapEventCallback;
9192 hdd_hostapd_state_t *pHostapdState;
9193 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9194 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309195 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309197 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309200 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009201 v_BOOL_t MFPCapable = VOS_FALSE;
9202 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309203 v_BOOL_t sapEnable11AC =
9204 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 ENTER();
9206
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309207 iniConfig = pHddCtx->cfg_ini;
9208
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9210
9211 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9212
9213 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9214
9215 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9216
9217 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9218
9219 //channel is already set in the set_channel Call back
9220 //pConfig->channel = pCommitConfig->channel;
9221
9222 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309223 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9225
9226 pConfig->dtim_period = pBeacon->dtim_period;
9227
Arif Hussain6d2a3322013-11-17 19:50:10 -08009228 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 pConfig->dtim_period);
9230
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009231 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009232 {
9233 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009234 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309235 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9236 {
9237 tANI_BOOLEAN restartNeeded;
9238 pConfig->ieee80211d = 1;
9239 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9240 sme_setRegInfo(hHal, pConfig->countryCode);
9241 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9242 }
9243 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009245 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009246 pConfig->ieee80211d = 1;
9247 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9248 sme_setRegInfo(hHal, pConfig->countryCode);
9249 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009251 else
9252 {
9253 pConfig->ieee80211d = 0;
9254 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309255 /*
9256 * If auto channel is configured i.e. channel is 0,
9257 * so skip channel validation.
9258 */
9259 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9260 {
9261 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9262 {
9263 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009264 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309265 return -EINVAL;
9266 }
9267 }
9268 else
9269 {
9270 if(1 != pHddCtx->is_dynamic_channel_range_set)
9271 {
9272 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9273 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9274 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9275 }
9276 pHddCtx->is_dynamic_channel_range_set = 0;
9277 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009279 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 {
9281 pConfig->ieee80211d = 0;
9282 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309283
9284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9285 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9286 pConfig->authType = eSAP_OPEN_SYSTEM;
9287 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9288 pConfig->authType = eSAP_SHARED_KEY;
9289 else
9290 pConfig->authType = eSAP_AUTO_SWITCH;
9291#else
9292 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9293 pConfig->authType = eSAP_OPEN_SYSTEM;
9294 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9295 pConfig->authType = eSAP_SHARED_KEY;
9296 else
9297 pConfig->authType = eSAP_AUTO_SWITCH;
9298#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009299
9300 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309301
9302 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9304
9305 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9306
9307 /*Set wps station to configured*/
9308 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9309
9310 if(pIe)
9311 {
9312 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9313 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009314 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 return -EINVAL;
9316 }
9317 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9318 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009319 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 /* Check 15 bit of WPS IE as it contain information for wps state
9321 * WPS state
9322 */
9323 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9324 {
9325 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9326 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9327 {
9328 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9329 }
9330 }
9331 }
9332 else
9333 {
9334 pConfig->wps_state = SAP_WPS_DISABLED;
9335 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309336 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009337
c_hpothufe599e92014-06-16 11:38:55 +05309338 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9339 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9340 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9341 eCSR_ENCRYPT_TYPE_NONE;
9342
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 pConfig->RSNWPAReqIELength = 0;
9344 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309345 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 WLAN_EID_RSN);
9347 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309348 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9350 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9351 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352 /* The actual processing may eventually be more extensive than
9353 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 * by the app.
9355 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309356 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9358 &RSNEncryptType,
9359 &mcRSNEncryptType,
9360 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009361 &MFPCapable,
9362 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 pConfig->pRSNWPAReqIE[1]+2,
9364 pConfig->pRSNWPAReqIE );
9365
9366 if( VOS_STATUS_SUCCESS == status )
9367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309368 /* Now copy over all the security attributes you have
9369 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 * */
9371 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9372 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9373 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9374 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309375 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009376 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9378 }
9379 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309380
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9382 pBeacon->tail, pBeacon->tail_len);
9383
9384 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9385 {
9386 if (pConfig->pRSNWPAReqIE)
9387 {
9388 /*Mixed mode WPA/WPA2*/
9389 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9390 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9391 }
9392 else
9393 {
9394 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9395 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9396 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309397 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9399 &RSNEncryptType,
9400 &mcRSNEncryptType,
9401 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009402 &MFPCapable,
9403 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 pConfig->pRSNWPAReqIE[1]+2,
9405 pConfig->pRSNWPAReqIE );
9406
9407 if( VOS_STATUS_SUCCESS == status )
9408 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309409 /* Now copy over all the security attributes you have
9410 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 * */
9412 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9413 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9414 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9415 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309416 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009417 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9419 }
9420 }
9421 }
9422
Jeff Johnson4416a782013-03-25 14:17:50 -07009423 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9424 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9425 return -EINVAL;
9426 }
9427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9429
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 if (params->ssid != NULL)
9432 {
9433 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9434 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9435 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9436 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9437 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009438#else
9439 if (ssid != NULL)
9440 {
9441 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9442 pConfig->SSIDinfo.ssid.length = ssid_len;
9443 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9444 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9445 }
9446#endif
9447
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309448 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 /* default value */
9452 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9453 pConfig->num_accept_mac = 0;
9454 pConfig->num_deny_mac = 0;
9455
9456 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9457 pBeacon->tail, pBeacon->tail_len);
9458
9459 /* pIe for black list is following form:
9460 type : 1 byte
9461 length : 1 byte
9462 OUI : 4 bytes
9463 acl type : 1 byte
9464 no of mac addr in black list: 1 byte
9465 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 */
9467 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 {
9469 pConfig->SapMacaddr_acl = pIe[6];
9470 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009471 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309473 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9474 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9476 for (i = 0; i < pConfig->num_deny_mac; i++)
9477 {
9478 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9479 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 }
9482 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9483 pBeacon->tail, pBeacon->tail_len);
9484
9485 /* pIe for white list is following form:
9486 type : 1 byte
9487 length : 1 byte
9488 OUI : 4 bytes
9489 acl type : 1 byte
9490 no of mac addr in white list: 1 byte
9491 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309492 */
9493 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 {
9495 pConfig->SapMacaddr_acl = pIe[6];
9496 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009497 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309499 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9500 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9502 for (i = 0; i < pConfig->num_accept_mac; i++)
9503 {
9504 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9505 acl_entry++;
9506 }
9507 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309508
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9510
Jeff Johnsone7245742012-09-05 17:12:55 -07009511#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009512 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309513 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9514 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309515 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9516 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009517 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9518 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309519 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9520 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009521 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309522 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009523 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309524 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009525
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309526 /* If ACS disable and selected channel <= 14
9527 * OR
9528 * ACS enabled and ACS operating band is choosen as 2.4
9529 * AND
9530 * VHT in 2.4G Disabled
9531 * THEN
9532 * Fallback to 11N mode
9533 */
9534 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9535 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309536 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309537 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009538 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309539 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9540 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009541 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9542 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009543 }
9544#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309545
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 // ht_capab is not what the name conveys,this is used for protection bitmap
9547 pConfig->ht_capab =
9548 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9549
9550 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9551 {
9552 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9553 return -EINVAL;
9554 }
9555
9556 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9559 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309560 pConfig->obssProtEnabled =
9561 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009562
Chet Lanctot8cecea22014-02-11 19:09:36 -08009563#ifdef WLAN_FEATURE_11W
9564 pConfig->mfpCapable = MFPCapable;
9565 pConfig->mfpRequired = MFPRequired;
9566 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9567 pConfig->mfpCapable, pConfig->mfpRequired);
9568#endif
9569
Arif Hussain6d2a3322013-11-17 19:50:10 -08009570 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009572 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9573 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9574 (int)pConfig->channel);
9575 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9576 pConfig->SapHw_mode, pConfig->privacy,
9577 pConfig->authType);
9578 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9579 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9580 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9581 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
9585 //Bss already started. just return.
9586 //TODO Probably it should update some beacon params.
9587 hddLog( LOGE, "Bss Already started...Ignore the request");
9588 EXIT();
9589 return 0;
9590 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591
Agarwal Ashish51325b52014-06-16 16:50:49 +05309592 if (vos_max_concurrent_connections_reached()) {
9593 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9594 return -EINVAL;
9595 }
9596
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 pConfig->persona = pHostapdAdapter->device_mode;
9598
Peng Xu2446a892014-09-05 17:21:18 +05309599 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9600 if ( NULL != psmeConfig)
9601 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309602 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309603 sme_GetConfigParam(hHal, psmeConfig);
9604 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309605#ifdef WLAN_FEATURE_AP_HT40_24G
9606 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9607 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9608 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9609 {
9610 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9611 sme_UpdateConfig (hHal, psmeConfig);
9612 }
9613#endif
Peng Xu2446a892014-09-05 17:21:18 +05309614 vos_mem_free(psmeConfig);
9615 }
Peng Xuafc34e32014-09-25 13:23:55 +05309616 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309617
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 pSapEventCallback = hdd_hostapd_SAPEventCB;
9619 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9620 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9621 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009622 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 return -EINVAL;
9624 }
9625
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9628
9629 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309632 {
9633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009634 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009635 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 VOS_ASSERT(0);
9637 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309640 /* Initialize WMM configuation */
9641 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309642 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009644#ifdef WLAN_FEATURE_P2P_DEBUG
9645 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9646 {
9647 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9648 {
9649 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9650 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009651 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009652 }
9653 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9654 {
9655 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9656 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009657 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009658 }
9659 }
9660#endif
9661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 pHostapdState->bCommit = TRUE;
9663 EXIT();
9664
9665 return 0;
9666}
9667
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009668#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309669static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309670 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 struct beacon_parameters *params)
9672{
9673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309674 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309675 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009676
9677 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309678
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309679 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9680 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9681 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309682 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9683 hdd_device_modetoString(pAdapter->device_mode),
9684 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009685
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309686 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9687 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309688 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009689 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309690 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009691 }
9692
Agarwal Ashish51325b52014-06-16 16:50:49 +05309693 if (vos_max_concurrent_connections_reached()) {
9694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9695 return -EINVAL;
9696 }
9697
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309698 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 )
9701 {
9702 beacon_data_t *old,*new;
9703
9704 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309705
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309707 {
9708 hddLog(VOS_TRACE_LEVEL_WARN,
9709 FL("already beacon info added to session(%d)"),
9710 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309712 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009713
9714 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9715
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309716 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 {
9718 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009719 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 return -EINVAL;
9721 }
9722
9723 pAdapter->sessionCtx.ap.beacon = new;
9724
9725 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9726 }
9727
9728 EXIT();
9729 return status;
9730}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309731
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309732static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9733 struct net_device *dev,
9734 struct beacon_parameters *params)
9735{
9736 int ret;
9737
9738 vos_ssr_protect(__func__);
9739 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9740 vos_ssr_unprotect(__func__);
9741
9742 return ret;
9743}
9744
9745static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 struct net_device *dev,
9747 struct beacon_parameters *params)
9748{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309749 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309750 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9751 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309752 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009753
9754 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309755
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309756 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9757 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9758 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9759 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9760 __func__, hdd_device_modetoString(pAdapter->device_mode),
9761 pAdapter->device_mode);
9762
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309763 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9764 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309765 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009766 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309767 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009768 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309769
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309772 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 {
9774 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309777
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309779 {
9780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9781 FL("session(%d) old and new heads points to NULL"),
9782 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009785
9786 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9787
9788 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009790 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 return -EINVAL;
9792 }
9793
9794 pAdapter->sessionCtx.ap.beacon = new;
9795
9796 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9797 }
9798
9799 EXIT();
9800 return status;
9801}
9802
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309803static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9804 struct net_device *dev,
9805 struct beacon_parameters *params)
9806{
9807 int ret;
9808
9809 vos_ssr_protect(__func__);
9810 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9811 vos_ssr_unprotect(__func__);
9812
9813 return ret;
9814}
9815
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009816#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9817
9818#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309819static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009821#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309822static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009823 struct net_device *dev)
9824#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009825{
9826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 hdd_context_t *pHddCtx = NULL;
9828 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309829 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309830 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009831
9832 ENTER();
9833
9834 if (NULL == pAdapter)
9835 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009837 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 return -ENODEV;
9839 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009840
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309841 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9842 TRACE_CODE_HDD_CFG80211_STOP_AP,
9843 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9845 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309846 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009847 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309848 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009849 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009850
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009851 pScanInfo = &pHddCtx->scan_info;
9852
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9854 __func__, hdd_device_modetoString(pAdapter->device_mode),
9855 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009856
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309857 ret = wlan_hdd_scan_abort(pAdapter);
9858
Girish Gowli4bf7a632014-06-12 13:42:11 +05309859 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009860 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9862 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309863
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309864 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009865 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9867 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009868
Jeff Johnsone7245742012-09-05 17:12:55 -07009869 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309870 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009871 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309872 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009873 }
9874
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309875 /* Delete all associated STAs before stopping AP/P2P GO */
9876 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309877 hdd_hostapd_stop(dev);
9878
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 )
9882 {
9883 beacon_data_t *old;
9884
9885 old = pAdapter->sessionCtx.ap.beacon;
9886
9887 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309888 {
9889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9890 FL("session(%d) beacon data points to NULL"),
9891 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009892 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009894
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009896
9897 mutex_lock(&pHddCtx->sap_lock);
9898 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9899 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009900 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 {
9902 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9903
9904 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9905
9906 if (!VOS_IS_STATUS_SUCCESS(status))
9907 {
9908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009909 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309911 }
9912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309914 /* BSS stopped, clear the active sessions for this device mode */
9915 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 }
9917 mutex_unlock(&pHddCtx->sap_lock);
9918
9919 if(status != VOS_STATUS_SUCCESS)
9920 {
9921 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009922 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 return -EINVAL;
9924 }
9925
Jeff Johnson4416a782013-03-25 14:17:50 -07009926 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9928 ==eHAL_STATUS_FAILURE)
9929 {
9930 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009931 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 }
9933
Jeff Johnson4416a782013-03-25 14:17:50 -07009934 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9936 eANI_BOOLEAN_FALSE) )
9937 {
9938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941
9942 // Reset WNI_CFG_PROBE_RSP Flags
9943 wlan_hdd_reset_prob_rspies(pAdapter);
9944
9945 pAdapter->sessionCtx.ap.beacon = NULL;
9946 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009947#ifdef WLAN_FEATURE_P2P_DEBUG
9948 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9949 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9950 {
9951 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9952 "GO got removed");
9953 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9954 }
9955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 }
9957 EXIT();
9958 return status;
9959}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009960
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9962static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9963 struct net_device *dev)
9964{
9965 int ret;
9966
9967 vos_ssr_protect(__func__);
9968 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9969 vos_ssr_unprotect(__func__);
9970
9971 return ret;
9972}
9973#else
9974static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9975 struct net_device *dev)
9976{
9977 int ret;
9978
9979 vos_ssr_protect(__func__);
9980 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9981 vos_ssr_unprotect(__func__);
9982
9983 return ret;
9984}
9985#endif
9986
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009987#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9988
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309989static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309990 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009991 struct cfg80211_ap_settings *params)
9992{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309993 hdd_adapter_t *pAdapter;
9994 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309995 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009996
9997 ENTER();
9998
Girish Gowlib143d7a2015-02-18 19:39:55 +05309999 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010000 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010002 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010003 return -ENODEV;
10004 }
10005
10006 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10007 if (NULL == pAdapter)
10008 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010010 "%s: HDD adapter is Null", __func__);
10011 return -ENODEV;
10012 }
10013
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10015 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10016 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010017 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10018 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010020 "%s: HDD adapter magic is invalid", __func__);
10021 return -ENODEV;
10022 }
10023
10024 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010026 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010027 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010028 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010029 }
10030
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010031 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10032 __func__, hdd_device_modetoString(pAdapter->device_mode),
10033 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010034
10035 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010036 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010037 )
10038 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010039 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010040
10041 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010042
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010043 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010044 {
10045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10046 FL("already beacon info added to session(%d)"),
10047 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010048 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010049 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010050
Girish Gowlib143d7a2015-02-18 19:39:55 +053010051#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10052 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10053 &new,
10054 &params->beacon);
10055#else
10056 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10057 &new,
10058 &params->beacon,
10059 params->dtim_period);
10060#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010062 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010063 {
10064 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010065 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010066 return -EINVAL;
10067 }
10068 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010070 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10071#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10072 params->channel, params->channel_type);
10073#else
10074 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10075#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010077 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010078 params->ssid_len, params->hidden_ssid,
10079 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010080 }
10081
10082 EXIT();
10083 return status;
10084}
10085
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010086static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10087 struct net_device *dev,
10088 struct cfg80211_ap_settings *params)
10089{
10090 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010091
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010092 vos_ssr_protect(__func__);
10093 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10094 vos_ssr_unprotect(__func__);
10095
10096 return ret;
10097}
10098
10099static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010100 struct net_device *dev,
10101 struct cfg80211_beacon_data *params)
10102{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010104 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010105 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010106
10107 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010108
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010109 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10110 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10111 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010113 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010114
10115 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 Koyyalamudib2c36892012-10-18 20:52:38 -070010118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010119 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010120 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010121
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010123 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010125 {
10126 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010128 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010129
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010130 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010131 {
10132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10133 FL("session(%d) beacon data points to NULL"),
10134 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010135 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010136 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010137
10138 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10139
10140 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010141 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010142 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010143 return -EINVAL;
10144 }
10145
10146 pAdapter->sessionCtx.ap.beacon = new;
10147
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010148 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10149 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010150 }
10151
10152 EXIT();
10153 return status;
10154}
10155
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010156static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10157 struct net_device *dev,
10158 struct cfg80211_beacon_data *params)
10159{
10160 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010161
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010162 vos_ssr_protect(__func__);
10163 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10164 vos_ssr_unprotect(__func__);
10165
10166 return ret;
10167}
10168
10169#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010170
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010171static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 struct net_device *dev,
10173 struct bss_parameters *params)
10174{
10175 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010176 hdd_context_t *pHddCtx;
10177 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178
10179 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010180
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010181 if (NULL == pAdapter)
10182 {
10183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10184 "%s: HDD adapter is Null", __func__);
10185 return -ENODEV;
10186 }
10187 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010188 ret = wlan_hdd_validate_context(pHddCtx);
10189 if (0 != ret)
10190 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010191 return ret;
10192 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010193 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10194 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10195 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10197 __func__, hdd_device_modetoString(pAdapter->device_mode),
10198 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010199
10200 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010202 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 {
10204 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10205 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010206 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 {
10208 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010209 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 }
10211
10212 EXIT();
10213 return 0;
10214}
10215
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010216static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10217 struct net_device *dev,
10218 struct bss_parameters *params)
10219{
10220 int ret;
10221
10222 vos_ssr_protect(__func__);
10223 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10224 vos_ssr_unprotect(__func__);
10225
10226 return ret;
10227}
Kiet Lam10841362013-11-01 11:36:50 +053010228/* FUNCTION: wlan_hdd_change_country_code_cd
10229* to wait for contry code completion
10230*/
10231void* wlan_hdd_change_country_code_cb(void *pAdapter)
10232{
10233 hdd_adapter_t *call_back_pAdapter = pAdapter;
10234 complete(&call_back_pAdapter->change_country_code);
10235 return NULL;
10236}
10237
Jeff Johnson295189b2012-06-20 16:38:30 -070010238/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010239 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010240 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10241 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010242int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 struct net_device *ndev,
10244 enum nl80211_iftype type,
10245 u32 *flags,
10246 struct vif_params *params
10247 )
10248{
10249 struct wireless_dev *wdev;
10250 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010251 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010252 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 tCsrRoamProfile *pRoamProfile = NULL;
10254 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010255 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 eMib_dot11DesiredBssType connectedBssType;
10257 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010258 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010259
10260 ENTER();
10261
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010262 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010263 {
10264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10265 "%s: Adapter context is null", __func__);
10266 return VOS_STATUS_E_FAILURE;
10267 }
10268
10269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10270 if (!pHddCtx)
10271 {
10272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10273 "%s: HDD context is null", __func__);
10274 return VOS_STATUS_E_FAILURE;
10275 }
10276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10278 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10279 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010280 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010281 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010283 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 }
10285
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10287 __func__, hdd_device_modetoString(pAdapter->device_mode),
10288 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010289
Agarwal Ashish51325b52014-06-16 16:50:49 +053010290 if (vos_max_concurrent_connections_reached()) {
10291 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10292 return -EINVAL;
10293 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 wdev = ndev->ieee80211_ptr;
10296
10297#ifdef WLAN_BTAMP_FEATURE
10298 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10299 (NL80211_IFTYPE_ADHOC == type)||
10300 (NL80211_IFTYPE_AP == type)||
10301 (NL80211_IFTYPE_P2P_GO == type))
10302 {
10303 pHddCtx->isAmpAllowed = VOS_FALSE;
10304 // stop AMP traffic
10305 status = WLANBAP_StopAmp();
10306 if(VOS_STATUS_SUCCESS != status )
10307 {
10308 pHddCtx->isAmpAllowed = VOS_TRUE;
10309 hddLog(VOS_TRACE_LEVEL_FATAL,
10310 "%s: Failed to stop AMP", __func__);
10311 return -EINVAL;
10312 }
10313 }
10314#endif //WLAN_BTAMP_FEATURE
10315 /* Reset the current device mode bit mask*/
10316 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10317
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010318 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10319 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10320 (type == NL80211_IFTYPE_P2P_GO)))
10321 {
10322 /* Notify Mode change in case of concurrency.
10323 * Below function invokes TDLS teardown Functionality Since TDLS is
10324 * not Supported in case of concurrency i.e Once P2P session
10325 * is detected disable offchannel and teardown TDLS links
10326 */
10327 hddLog(LOG1,
10328 FL("Device mode = %d Interface type = %d"),
10329 pAdapter->device_mode, type);
10330 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10331 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010332
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010335 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 )
10337 {
10338 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010339 if (!pWextState)
10340 {
10341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10342 "%s: pWextState is null", __func__);
10343 return VOS_STATUS_E_FAILURE;
10344 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 pRoamProfile = &pWextState->roamProfile;
10346 LastBSSType = pRoamProfile->BSSType;
10347
10348 switch (type)
10349 {
10350 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 hddLog(VOS_TRACE_LEVEL_INFO,
10353 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10354 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010355#ifdef WLAN_FEATURE_11AC
10356 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10357 {
10358 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10359 }
10360#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010361 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010362 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010364 //Check for sub-string p2p to confirm its a p2p interface
10365 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010366 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010367#ifdef FEATURE_WLAN_TDLS
10368 mutex_lock(&pHddCtx->tdls_lock);
10369 wlan_hdd_tdls_exit(pAdapter, TRUE);
10370 mutex_unlock(&pHddCtx->tdls_lock);
10371#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010372 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10373 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10374 }
10375 else
10376 {
10377 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010379 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 case NL80211_IFTYPE_ADHOC:
10383 hddLog(VOS_TRACE_LEVEL_INFO,
10384 "%s: setting interface Type to ADHOC", __func__);
10385 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10386 pRoamProfile->phyMode =
10387 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010388 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010390 hdd_set_ibss_ops( pAdapter );
10391 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010392
10393 status = hdd_sta_id_hash_attach(pAdapter);
10394 if (VOS_STATUS_SUCCESS != status) {
10395 hddLog(VOS_TRACE_LEVEL_ERROR,
10396 FL("Failed to initialize hash for IBSS"));
10397 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 break;
10399
10400 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 {
10403 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10404 "%s: setting interface Type to %s", __func__,
10405 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10406
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010407 //Cancel any remain on channel for GO mode
10408 if (NL80211_IFTYPE_P2P_GO == type)
10409 {
10410 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10411 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010412 if (NL80211_IFTYPE_AP == type)
10413 {
10414 /* As Loading WLAN Driver one interface being created for p2p device
10415 * address. This will take one HW STA and the max number of clients
10416 * that can connect to softAP will be reduced by one. so while changing
10417 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10418 * interface as it is not required in SoftAP mode.
10419 */
10420
10421 // Get P2P Adapter
10422 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10423
10424 if (pP2pAdapter)
10425 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010426 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010427 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010428 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10429 }
10430 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010431 //Disable IMPS & BMPS for SAP/GO
10432 if(VOS_STATUS_E_FAILURE ==
10433 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10434 {
10435 //Fail to Exit BMPS
10436 VOS_ASSERT(0);
10437 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010438
10439 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10440
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010441#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010442
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010443 /* A Mutex Lock is introduced while changing the mode to
10444 * protect the concurrent access for the Adapters by TDLS
10445 * module.
10446 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010447 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010448#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010450 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10453 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010454#ifdef FEATURE_WLAN_TDLS
10455 mutex_unlock(&pHddCtx->tdls_lock);
10456#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010457 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10458 (pConfig->apRandomBssidEnabled))
10459 {
10460 /* To meet Android requirements create a randomized
10461 MAC address of the form 02:1A:11:Fx:xx:xx */
10462 get_random_bytes(&ndev->dev_addr[3], 3);
10463 ndev->dev_addr[0] = 0x02;
10464 ndev->dev_addr[1] = 0x1A;
10465 ndev->dev_addr[2] = 0x11;
10466 ndev->dev_addr[3] |= 0xF0;
10467 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10468 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010469 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10470 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010471 }
10472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 hdd_set_ap_ops( pAdapter->dev );
10474
Kiet Lam10841362013-11-01 11:36:50 +053010475 /* This is for only SAP mode where users can
10476 * control country through ini.
10477 * P2P GO follows station country code
10478 * acquired during the STA scanning. */
10479 if((NL80211_IFTYPE_AP == type) &&
10480 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10481 {
10482 int status = 0;
10483 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10484 "%s: setting country code from INI ", __func__);
10485 init_completion(&pAdapter->change_country_code);
10486 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10487 (void *)(tSmeChangeCountryCallback)
10488 wlan_hdd_change_country_code_cb,
10489 pConfig->apCntryCode, pAdapter,
10490 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010491 eSIR_FALSE,
10492 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010493 if (eHAL_STATUS_SUCCESS == status)
10494 {
10495 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010496 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010497 &pAdapter->change_country_code,
10498 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010499 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010500 {
10501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010502 FL("SME Timed out while setting country code %ld"),
10503 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010504
10505 if (pHddCtx->isLogpInProgress)
10506 {
10507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10508 "%s: LOGP in Progress. Ignore!!!", __func__);
10509 return -EAGAIN;
10510 }
Kiet Lam10841362013-11-01 11:36:50 +053010511 }
10512 }
10513 else
10514 {
10515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010516 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010517 return -EINVAL;
10518 }
10519 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 status = hdd_init_ap_mode(pAdapter);
10521 if(status != VOS_STATUS_SUCCESS)
10522 {
10523 hddLog(VOS_TRACE_LEVEL_FATAL,
10524 "%s: Error initializing the ap mode", __func__);
10525 return -EINVAL;
10526 }
10527 hdd_set_conparam(1);
10528
Nirav Shah7e3c8132015-06-22 23:51:42 +053010529 status = hdd_sta_id_hash_attach(pAdapter);
10530 if (VOS_STATUS_SUCCESS != status)
10531 {
10532 hddLog(VOS_TRACE_LEVEL_ERROR,
10533 FL("Failed to initialize hash for AP"));
10534 return -EINVAL;
10535 }
10536
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 /*interface type changed update in wiphy structure*/
10538 if(wdev)
10539 {
10540 wdev->iftype = type;
10541 pHddCtx->change_iface = type;
10542 }
10543 else
10544 {
10545 hddLog(VOS_TRACE_LEVEL_ERROR,
10546 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10547 return -EINVAL;
10548 }
10549 goto done;
10550 }
10551
10552 default:
10553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10554 __func__);
10555 return -EOPNOTSUPP;
10556 }
10557 }
10558 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 )
10561 {
10562 switch(type)
10563 {
10564 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010567
10568 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010569#ifdef FEATURE_WLAN_TDLS
10570
10571 /* A Mutex Lock is introduced while changing the mode to
10572 * protect the concurrent access for the Adapters by TDLS
10573 * module.
10574 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010575 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010576#endif
c_hpothu002231a2015-02-05 14:58:51 +053010577 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010579 //Check for sub-string p2p to confirm its a p2p interface
10580 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010581 {
10582 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10583 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10584 }
10585 else
10586 {
10587 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010589 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010590
10591 /* set con_mode to STA only when no SAP concurrency mode */
10592 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10593 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10596 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010597#ifdef FEATURE_WLAN_TDLS
10598 mutex_unlock(&pHddCtx->tdls_lock);
10599#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010600 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 if( VOS_STATUS_SUCCESS != status )
10602 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010603 /* In case of JB, for P2P-GO, only change interface will be called,
10604 * This is the right place to enable back bmps_imps()
10605 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010606 if (pHddCtx->hdd_wlan_suspended)
10607 {
10608 hdd_set_pwrparams(pHddCtx);
10609 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010610 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 goto done;
10612 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010613 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10616 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 goto done;
10618 default:
10619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10620 __func__);
10621 return -EOPNOTSUPP;
10622
10623 }
10624
10625 }
10626 else
10627 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010628 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10629 __func__, hdd_device_modetoString(pAdapter->device_mode),
10630 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 return -EOPNOTSUPP;
10632 }
10633
10634
10635 if(pRoamProfile)
10636 {
10637 if ( LastBSSType != pRoamProfile->BSSType )
10638 {
10639 /*interface type changed update in wiphy structure*/
10640 wdev->iftype = type;
10641
10642 /*the BSS mode changed, We need to issue disconnect
10643 if connected or in IBSS disconnect state*/
10644 if ( hdd_connGetConnectedBssType(
10645 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10646 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10647 {
10648 /*need to issue a disconnect to CSR.*/
10649 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10650 if( eHAL_STATUS_SUCCESS ==
10651 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10652 pAdapter->sessionId,
10653 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10654 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010655 ret = wait_for_completion_interruptible_timeout(
10656 &pAdapter->disconnect_comp_var,
10657 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10658 if (ret <= 0)
10659 {
10660 hddLog(VOS_TRACE_LEVEL_ERROR,
10661 FL("wait on disconnect_comp_var failed %ld"), ret);
10662 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 }
10664 }
10665 }
10666 }
10667
10668done:
10669 /*set bitmask based on updated value*/
10670 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010671
10672 /* Only STA mode support TM now
10673 * all other mode, TM feature should be disabled */
10674 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10675 (~VOS_STA & pHddCtx->concurrency_mode) )
10676 {
10677 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10678 }
10679
Jeff Johnson295189b2012-06-20 16:38:30 -070010680#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010681 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010682 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 {
10684 //we are ok to do AMP
10685 pHddCtx->isAmpAllowed = VOS_TRUE;
10686 }
10687#endif //WLAN_BTAMP_FEATURE
10688 EXIT();
10689 return 0;
10690}
10691
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010692/*
10693 * FUNCTION: wlan_hdd_cfg80211_change_iface
10694 * wrapper function to protect the actual implementation from SSR.
10695 */
10696int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10697 struct net_device *ndev,
10698 enum nl80211_iftype type,
10699 u32 *flags,
10700 struct vif_params *params
10701 )
10702{
10703 int ret;
10704
10705 vos_ssr_protect(__func__);
10706 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10707 vos_ssr_unprotect(__func__);
10708
10709 return ret;
10710}
10711
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010712#ifdef FEATURE_WLAN_TDLS
10713static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010714 struct net_device *dev,
10715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10716 const u8 *mac,
10717#else
10718 u8 *mac,
10719#endif
10720 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010721{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010722 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010723 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010724 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010725 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010726 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010727 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010728
10729 ENTER();
10730
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010731 if (!dev) {
10732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10733 return -EINVAL;
10734 }
10735
10736 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10737 if (!pAdapter) {
10738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10739 return -EINVAL;
10740 }
10741
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010742 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010743 {
10744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10745 "Invalid arguments");
10746 return -EINVAL;
10747 }
Hoonki Lee27511902013-03-14 18:19:06 -070010748
10749 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10750 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10751 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010753 "%s: TDLS mode is disabled OR not enabled in FW."
10754 MAC_ADDRESS_STR " Request declined.",
10755 __func__, MAC_ADDR_ARRAY(mac));
10756 return -ENOTSUPP;
10757 }
10758
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010759 if (pHddCtx->isLogpInProgress)
10760 {
10761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10762 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010763 wlan_hdd_tdls_set_link_status(pAdapter,
10764 mac,
10765 eTDLS_LINK_IDLE,
10766 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010767 return -EBUSY;
10768 }
10769
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010770 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010771 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010772
10773 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010775 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10776 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010777 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010778 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010779 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010780
10781 /* in add station, we accept existing valid staId if there is */
10782 if ((0 == update) &&
10783 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10784 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010785 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010787 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010788 " link_status %d. staId %d. add station ignored.",
10789 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010790 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010791 return 0;
10792 }
10793 /* in change station, we accept only when staId is valid */
10794 if ((1 == update) &&
10795 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10796 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10797 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010798 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010800 "%s: " MAC_ADDRESS_STR
10801 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010802 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10803 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10804 mutex_unlock(&pHddCtx->tdls_lock);
10805 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010806 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010807 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010808
10809 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010810 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010811 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10813 "%s: " MAC_ADDRESS_STR
10814 " TDLS setup is ongoing. Request declined.",
10815 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010816 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010817 }
10818
10819 /* first to check if we reached to maximum supported TDLS peer.
10820 TODO: for now, return -EPERM looks working fine,
10821 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010822 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10823 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010824 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10826 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010827 " TDLS Max peer already connected. Request declined."
10828 " Num of peers (%d), Max allowed (%d).",
10829 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10830 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010831 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010832 }
10833 else
10834 {
10835 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010836 mutex_lock(&pHddCtx->tdls_lock);
10837 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010838 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010839 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010840 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10842 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10843 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010844 return -EPERM;
10845 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010846 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010847 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010848 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010849 wlan_hdd_tdls_set_link_status(pAdapter,
10850 mac,
10851 eTDLS_LINK_CONNECTING,
10852 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010853
Jeff Johnsond75fe012013-04-06 10:53:06 -070010854 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010855 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010856 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010858 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010859 if(StaParams->htcap_present)
10860 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010862 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010864 "ht_capa->extended_capabilities: %0x",
10865 StaParams->HTCap.extendedHtCapInfo);
10866 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010868 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010870 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010871 if(StaParams->vhtcap_present)
10872 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010874 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10875 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10876 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10877 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010878 {
10879 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010881 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010883 "[%d]: %x ", i, StaParams->supported_rates[i]);
10884 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010885 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010886 else if ((1 == update) && (NULL == StaParams))
10887 {
10888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10889 "%s : update is true, but staParams is NULL. Error!", __func__);
10890 return -EPERM;
10891 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010892
10893 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10894
10895 if (!update)
10896 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010897 /*Before adding sta make sure that device exited from BMPS*/
10898 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10899 {
10900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10901 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10902 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10903 if (status != VOS_STATUS_SUCCESS) {
10904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10905 }
10906 }
10907
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010908 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010909 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010910 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010911 hddLog(VOS_TRACE_LEVEL_ERROR,
10912 FL("Failed to add TDLS peer STA. Enable Bmps"));
10913 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010914 return -EPERM;
10915 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010916 }
10917 else
10918 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010919 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010920 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010921 if (ret != eHAL_STATUS_SUCCESS) {
10922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10923 return -EPERM;
10924 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010925 }
10926
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010927 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010928 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10929
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010930 mutex_lock(&pHddCtx->tdls_lock);
10931 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10932
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010933 if ((pTdlsPeer != NULL) &&
10934 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010935 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010936 hddLog(VOS_TRACE_LEVEL_ERROR,
10937 FL("peer link status %u"), pTdlsPeer->link_status);
10938 mutex_unlock(&pHddCtx->tdls_lock);
10939 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010940 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010941 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010942
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010943 if (ret <= 0)
10944 {
10945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10946 "%s: timeout waiting for tdls add station indication %ld",
10947 __func__, ret);
10948 goto error;
10949 }
10950
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010951 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10952 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010954 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010955 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010956 }
10957
10958 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010959
10960error:
Atul Mittal115287b2014-07-08 13:26:33 +053010961 wlan_hdd_tdls_set_link_status(pAdapter,
10962 mac,
10963 eTDLS_LINK_IDLE,
10964 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010965 return -EPERM;
10966
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010967}
10968#endif
10969
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010970static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10973 const u8 *mac,
10974#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010976#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 struct station_parameters *params)
10978{
10979 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010980 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010981 hdd_context_t *pHddCtx;
10982 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010984 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010985#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010986 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010987 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010988 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010989 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010990#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010991
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010992 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010993
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010994 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010995 if ((NULL == pAdapter))
10996 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010998 "invalid adapter ");
10999 return -EINVAL;
11000 }
11001
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011002 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11003 TRACE_CODE_HDD_CHANGE_STATION,
11004 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011005 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011006
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011007 ret = wlan_hdd_validate_context(pHddCtx);
11008 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011009 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011010 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011011 }
11012
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011013 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11014
11015 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011016 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11018 "invalid HDD station context");
11019 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11022
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011023 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11024 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011026 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011028 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 WLANTL_STA_AUTHENTICATED);
11030
Gopichand Nakkala29149562013-05-10 21:43:41 +053011031 if (status != VOS_STATUS_SUCCESS)
11032 {
11033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11034 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11035 return -EINVAL;
11036 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 }
11038 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011039 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11040 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011041#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011042 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11043 StaParams.capability = params->capability;
11044 StaParams.uapsd_queues = params->uapsd_queues;
11045 StaParams.max_sp = params->max_sp;
11046
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011047 /* Convert (first channel , number of channels) tuple to
11048 * the total list of channels. This goes with the assumption
11049 * that if the first channel is < 14, then the next channels
11050 * are an incremental of 1 else an incremental of 4 till the number
11051 * of channels.
11052 */
11053 if (0 != params->supported_channels_len) {
11054 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11055 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11056 {
11057 int wifi_chan_index;
11058 StaParams.supported_channels[j] = params->supported_channels[i];
11059 wifi_chan_index =
11060 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11061 no_of_channels = params->supported_channels[i+1];
11062 for(k=1; k <= no_of_channels; k++)
11063 {
11064 StaParams.supported_channels[j+1] =
11065 StaParams.supported_channels[j] + wifi_chan_index;
11066 j+=1;
11067 }
11068 }
11069 StaParams.supported_channels_len = j;
11070 }
11071 vos_mem_copy(StaParams.supported_oper_classes,
11072 params->supported_oper_classes,
11073 params->supported_oper_classes_len);
11074 StaParams.supported_oper_classes_len =
11075 params->supported_oper_classes_len;
11076
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011077 if (0 != params->ext_capab_len)
11078 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11079 sizeof(StaParams.extn_capability));
11080
11081 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011082 {
11083 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011084 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011085 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011086
11087 StaParams.supported_rates_len = params->supported_rates_len;
11088
11089 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11090 * The supported_rates array , for all the structures propogating till Add Sta
11091 * to the firmware has to be modified , if the supplicant (ieee80211) is
11092 * modified to send more rates.
11093 */
11094
11095 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11096 */
11097 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11098 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11099
11100 if (0 != StaParams.supported_rates_len) {
11101 int i = 0;
11102 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11103 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011105 "Supported Rates with Length %d", StaParams.supported_rates_len);
11106 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011108 "[%d]: %0x", i, StaParams.supported_rates[i]);
11109 }
11110
11111 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011112 {
11113 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011114 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011115 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011116
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011117 if (0 != params->ext_capab_len ) {
11118 /*Define A Macro : TODO Sunil*/
11119 if ((1<<4) & StaParams.extn_capability[3]) {
11120 isBufSta = 1;
11121 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011122 /* TDLS Channel Switching Support */
11123 if ((1<<6) & StaParams.extn_capability[3]) {
11124 isOffChannelSupported = 1;
11125 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011126 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011127
11128 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011129 (params->ht_capa || params->vht_capa ||
11130 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011131 /* TDLS Peer is WME/QoS capable */
11132 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011133
11134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11135 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11136 __func__, isQosWmmSta, StaParams.htcap_present);
11137
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011138 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11139 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011140 isOffChannelSupported,
11141 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011142
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011143 if (VOS_STATUS_SUCCESS != status) {
11144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11145 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11146 return -EINVAL;
11147 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011148 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11149
11150 if (VOS_STATUS_SUCCESS != status) {
11151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11152 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11153 return -EINVAL;
11154 }
11155 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011156#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011157 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011158 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 return status;
11160}
11161
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011162#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11163static int wlan_hdd_change_station(struct wiphy *wiphy,
11164 struct net_device *dev,
11165 const u8 *mac,
11166 struct station_parameters *params)
11167#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011168static int wlan_hdd_change_station(struct wiphy *wiphy,
11169 struct net_device *dev,
11170 u8 *mac,
11171 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011172#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011173{
11174 int ret;
11175
11176 vos_ssr_protect(__func__);
11177 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11178 vos_ssr_unprotect(__func__);
11179
11180 return ret;
11181}
11182
Jeff Johnson295189b2012-06-20 16:38:30 -070011183/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011184 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 * This function is used to initialize the key information
11186 */
11187#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011188static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 struct net_device *ndev,
11190 u8 key_index, bool pairwise,
11191 const u8 *mac_addr,
11192 struct key_params *params
11193 )
11194#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011195static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 struct net_device *ndev,
11197 u8 key_index, const u8 *mac_addr,
11198 struct key_params *params
11199 )
11200#endif
11201{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 tCsrRoamSetKey setKey;
11204 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011205 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011206 v_U32_t roamId= 0xFF;
11207 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 hdd_hostapd_state_t *pHostapdState;
11209 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011210 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011211 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011212
11213 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011214
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011215 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11216 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11217 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011218 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11219 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011220 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011221 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011222 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011223 }
11224
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11226 __func__, hdd_device_modetoString(pAdapter->device_mode),
11227 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011228
11229 if (CSR_MAX_NUM_KEY <= key_index)
11230 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 key_index);
11233
11234 return -EINVAL;
11235 }
11236
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011237 if (CSR_MAX_KEY_LEN < params->key_len)
11238 {
11239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11240 params->key_len);
11241
11242 return -EINVAL;
11243 }
11244
11245 hddLog(VOS_TRACE_LEVEL_INFO,
11246 "%s: called with key index = %d & key length %d",
11247 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 /*extract key idx, key len and key*/
11250 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11251 setKey.keyId = key_index;
11252 setKey.keyLength = params->key_len;
11253 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11254
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011255 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 {
11257 case WLAN_CIPHER_SUITE_WEP40:
11258 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11259 break;
11260
11261 case WLAN_CIPHER_SUITE_WEP104:
11262 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11263 break;
11264
11265 case WLAN_CIPHER_SUITE_TKIP:
11266 {
11267 u8 *pKey = &setKey.Key[0];
11268 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11269
11270 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11271
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011272 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011273
11274 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011275 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 |--------------|----------|----------|
11277 <---16bytes---><--8bytes--><--8bytes-->
11278
11279 */
11280 /*Sme expects the 32 bytes key to be in the below order
11281
11282 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011283 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 |--------------|----------|----------|
11285 <---16bytes---><--8bytes--><--8bytes-->
11286 */
11287 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011288 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011289
11290 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011291 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011292
11293 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011294 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011295
11296
11297 break;
11298 }
11299
11300 case WLAN_CIPHER_SUITE_CCMP:
11301 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11302 break;
11303
11304#ifdef FEATURE_WLAN_WAPI
11305 case WLAN_CIPHER_SUITE_SMS4:
11306 {
11307 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11308 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11309 params->key, params->key_len);
11310 return 0;
11311 }
11312#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011313
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011314#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 case WLAN_CIPHER_SUITE_KRK:
11316 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11317 break;
11318#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011319
11320#ifdef WLAN_FEATURE_11W
11321 case WLAN_CIPHER_SUITE_AES_CMAC:
11322 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011323 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011324#endif
11325
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011329 status = -EOPNOTSUPP;
11330 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 }
11332
11333 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11334 __func__, setKey.encType);
11335
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011336 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11338 (!pairwise)
11339#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011340 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011341#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011342 )
11343 {
11344 /* set group key*/
11345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11346 "%s- %d: setting Broadcast key",
11347 __func__, __LINE__);
11348 setKey.keyDirection = eSIR_RX_ONLY;
11349 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11350 }
11351 else
11352 {
11353 /* set pairwise key*/
11354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11355 "%s- %d: setting pairwise key",
11356 __func__, __LINE__);
11357 setKey.keyDirection = eSIR_TX_RX;
11358 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11359 }
11360 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11361 {
11362 setKey.keyDirection = eSIR_TX_RX;
11363 /*Set the group key*/
11364 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11365 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011366
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011367 if ( 0 != status )
11368 {
11369 hddLog(VOS_TRACE_LEVEL_ERROR,
11370 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011371 status = -EINVAL;
11372 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011373 }
11374 /*Save the keys here and call sme_RoamSetKey for setting
11375 the PTK after peer joins the IBSS network*/
11376 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11377 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011378 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011379 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011380 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11381 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11382 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011384 if( pHostapdState->bssState == BSS_START )
11385 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011386 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11387 vos_status = wlan_hdd_check_ula_done(pAdapter);
11388
11389 if ( vos_status != VOS_STATUS_SUCCESS )
11390 {
11391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11392 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11393 __LINE__, vos_status );
11394
11395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11396
11397 status = -EINVAL;
11398 goto end;
11399 }
11400
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11402
11403 if ( status != eHAL_STATUS_SUCCESS )
11404 {
11405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11406 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11407 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011408 status = -EINVAL;
11409 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 }
11411 }
11412
11413 /* Saving WEP keys */
11414 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11415 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11416 {
11417 //Save the wep key in ap context. Issue setkey after the BSS is started.
11418 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11419 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11420 }
11421 else
11422 {
11423 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011424 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11426 }
11427 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011428 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11429 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 {
11431 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11432 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11433
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11435 if (!pairwise)
11436#else
11437 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11438#endif
11439 {
11440 /* set group key*/
11441 if (pHddStaCtx->roam_info.deferKeyComplete)
11442 {
11443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11444 "%s- %d: Perform Set key Complete",
11445 __func__, __LINE__);
11446 hdd_PerformRoamSetKeyComplete(pAdapter);
11447 }
11448 }
11449
Jeff Johnson295189b2012-06-20 16:38:30 -070011450 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11451
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011452 pWextState->roamProfile.Keys.defaultIndex = key_index;
11453
11454
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011455 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 params->key, params->key_len);
11457
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011458
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11460
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 __func__, setKey.peerMac[0], setKey.peerMac[1],
11464 setKey.peerMac[2], setKey.peerMac[3],
11465 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 setKey.keyDirection);
11467
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011468 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011469
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011470 if ( vos_status != VOS_STATUS_SUCCESS )
11471 {
11472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11474 __LINE__, vos_status );
11475
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011476 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011477
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011478 status = -EINVAL;
11479 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011480
11481 }
11482
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011483#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011484 /* The supplicant may attempt to set the PTK once pre-authentication
11485 is done. Save the key in the UMAC and include it in the ADD BSS
11486 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011487 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011488 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011489 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011490 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11491 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011492 status = 0;
11493 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011494 }
11495 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11496 {
11497 hddLog(VOS_TRACE_LEVEL_ERROR,
11498 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011499 status = -EINVAL;
11500 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011501 }
11502#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011503
11504 /* issue set key request to SME*/
11505 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11506 pAdapter->sessionId, &setKey, &roamId );
11507
11508 if ( 0 != status )
11509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011510 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11512 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011513 status = -EINVAL;
11514 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 }
11516
11517
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011518 /* in case of IBSS as there was no information available about WEP keys during
11519 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011521 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11522 !( ( IW_AUTH_KEY_MGMT_802_1X
11523 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11525 )
11526 &&
11527 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11528 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11529 )
11530 )
11531 {
11532 setKey.keyDirection = eSIR_RX_ONLY;
11533 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11534
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011535 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537 __func__, setKey.peerMac[0], setKey.peerMac[1],
11538 setKey.peerMac[2], setKey.peerMac[3],
11539 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 setKey.keyDirection);
11541
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 pAdapter->sessionId, &setKey, &roamId );
11544
11545 if ( 0 != status )
11546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011547 hddLog(VOS_TRACE_LEVEL_ERROR,
11548 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 __func__, status);
11550 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011551 status = -EINVAL;
11552 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011553 }
11554 }
11555 }
11556
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011557end:
11558 /* Need to clear any trace of key value in the memory.
11559 * Thus zero out the memory even though it is local
11560 * variable.
11561 */
11562 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011563 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011564 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011565}
11566
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11568static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11569 struct net_device *ndev,
11570 u8 key_index, bool pairwise,
11571 const u8 *mac_addr,
11572 struct key_params *params
11573 )
11574#else
11575static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11576 struct net_device *ndev,
11577 u8 key_index, const u8 *mac_addr,
11578 struct key_params *params
11579 )
11580#endif
11581{
11582 int ret;
11583 vos_ssr_protect(__func__);
11584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11585 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11586 mac_addr, params);
11587#else
11588 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11589 params);
11590#endif
11591 vos_ssr_unprotect(__func__);
11592
11593 return ret;
11594}
11595
Jeff Johnson295189b2012-06-20 16:38:30 -070011596/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011597 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 * This function is used to get the key information
11599 */
11600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011601static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011602 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 const u8 *mac_addr, void *cookie,
11606 void (*callback)(void *cookie, struct key_params*)
11607 )
11608#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011609static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011610 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 struct net_device *ndev,
11612 u8 key_index, const u8 *mac_addr, void *cookie,
11613 void (*callback)(void *cookie, struct key_params*)
11614 )
11615#endif
11616{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011617 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011618 hdd_wext_state_t *pWextState = NULL;
11619 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011621 hdd_context_t *pHddCtx;
11622 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011623
11624 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011625
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011626 if (NULL == pAdapter)
11627 {
11628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11629 "%s: HDD adapter is Null", __func__);
11630 return -ENODEV;
11631 }
11632
11633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11634 ret = wlan_hdd_validate_context(pHddCtx);
11635 if (0 != ret)
11636 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011637 return ret;
11638 }
11639
11640 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11641 pRoamProfile = &(pWextState->roamProfile);
11642
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11644 __func__, hdd_device_modetoString(pAdapter->device_mode),
11645 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011646
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 memset(&params, 0, sizeof(params));
11648
11649 if (CSR_MAX_NUM_KEY <= key_index)
11650 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011653 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011654
11655 switch(pRoamProfile->EncryptionType.encryptionType[0])
11656 {
11657 case eCSR_ENCRYPT_TYPE_NONE:
11658 params.cipher = IW_AUTH_CIPHER_NONE;
11659 break;
11660
11661 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11662 case eCSR_ENCRYPT_TYPE_WEP40:
11663 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11664 break;
11665
11666 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11667 case eCSR_ENCRYPT_TYPE_WEP104:
11668 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11669 break;
11670
11671 case eCSR_ENCRYPT_TYPE_TKIP:
11672 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11673 break;
11674
11675 case eCSR_ENCRYPT_TYPE_AES:
11676 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11677 break;
11678
11679 default:
11680 params.cipher = IW_AUTH_CIPHER_NONE;
11681 break;
11682 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011683
c_hpothuaaf19692014-05-17 17:01:48 +053011684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11685 TRACE_CODE_HDD_CFG80211_GET_KEY,
11686 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011687
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11689 params.seq_len = 0;
11690 params.seq = NULL;
11691 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11692 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011693 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 return 0;
11695}
11696
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11698static int wlan_hdd_cfg80211_get_key(
11699 struct wiphy *wiphy,
11700 struct net_device *ndev,
11701 u8 key_index, bool pairwise,
11702 const u8 *mac_addr, void *cookie,
11703 void (*callback)(void *cookie, struct key_params*)
11704 )
11705#else
11706static int wlan_hdd_cfg80211_get_key(
11707 struct wiphy *wiphy,
11708 struct net_device *ndev,
11709 u8 key_index, const u8 *mac_addr, void *cookie,
11710 void (*callback)(void *cookie, struct key_params*)
11711 )
11712#endif
11713{
11714 int ret;
11715
11716 vos_ssr_protect(__func__);
11717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11718 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11719 mac_addr, cookie, callback);
11720#else
11721 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11722 callback);
11723#endif
11724 vos_ssr_unprotect(__func__);
11725
11726 return ret;
11727}
11728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011730 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 * This function is used to delete the key information
11732 */
11733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011734static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 u8 key_index,
11737 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 const u8 *mac_addr
11739 )
11740#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011741static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 struct net_device *ndev,
11743 u8 key_index,
11744 const u8 *mac_addr
11745 )
11746#endif
11747{
11748 int status = 0;
11749
11750 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011751 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 //it is observed that this is invalidating peer
11753 //key index whenever re-key is done. This is affecting data link.
11754 //It should be ok to ignore del_key.
11755#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11757 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11759 tCsrRoamSetKey setKey;
11760 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 ENTER();
11763
11764 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11765 __func__,pAdapter->device_mode);
11766
11767 if (CSR_MAX_NUM_KEY <= key_index)
11768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011770 key_index);
11771
11772 return -EINVAL;
11773 }
11774
11775 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11776 setKey.keyId = key_index;
11777
11778 if (mac_addr)
11779 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11780 else
11781 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11782
11783 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11784
11785 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787 )
11788 {
11789
11790 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11792 if( pHostapdState->bssState == BSS_START)
11793 {
11794 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011795
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 if ( status != eHAL_STATUS_SUCCESS )
11797 {
11798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11799 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11800 __LINE__, status );
11801 }
11802 }
11803 }
11804 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011805 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 )
11807 {
11808 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11809
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11811
11812 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011814 __func__, setKey.peerMac[0], setKey.peerMac[1],
11815 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 if(pAdapter->sessionCtx.station.conn_info.connState ==
11818 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011820 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 if ( 0 != status )
11824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011825 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 "%s: sme_RoamSetKey failure, returned %d",
11827 __func__, status);
11828 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11829 return -EINVAL;
11830 }
11831 }
11832 }
11833#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011834 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011835 return status;
11836}
11837
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11839static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11840 struct net_device *ndev,
11841 u8 key_index,
11842 bool pairwise,
11843 const u8 *mac_addr
11844 )
11845#else
11846static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11847 struct net_device *ndev,
11848 u8 key_index,
11849 const u8 *mac_addr
11850 )
11851#endif
11852{
11853 int ret;
11854
11855 vos_ssr_protect(__func__);
11856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11857 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11858 mac_addr);
11859#else
11860 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
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_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 * This function is used to set the default tx key index
11870 */
11871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011872static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 struct net_device *ndev,
11874 u8 key_index,
11875 bool unicast, bool multicast)
11876#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011877static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011878 struct net_device *ndev,
11879 u8 key_index)
11880#endif
11881{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011883 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011884 hdd_wext_state_t *pWextState;
11885 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011886 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011887
11888 ENTER();
11889
Gopichand Nakkala29149562013-05-10 21:43:41 +053011890 if ((NULL == pAdapter))
11891 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011893 "invalid adapter");
11894 return -EINVAL;
11895 }
11896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11898 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11899 pAdapter->sessionId, key_index));
11900
Gopichand Nakkala29149562013-05-10 21:43:41 +053011901 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11902 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11903
11904 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11905 {
11906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11907 "invalid Wext state or HDD context");
11908 return -EINVAL;
11909 }
11910
Arif Hussain6d2a3322013-11-17 19:50:10 -080011911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011913
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 if (CSR_MAX_NUM_KEY <= key_index)
11915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 key_index);
11918
11919 return -EINVAL;
11920 }
11921
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011922 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11923 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011924 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011925 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011926 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011927 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011928
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011933 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011934 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011935 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011936 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011938 {
11939 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 tCsrRoamSetKey setKey;
11943 v_U32_t roamId= 0xFF;
11944 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945
11946 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011947 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011948
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 Keys->defaultIndex = (u8)key_index;
11950 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11951 setKey.keyId = key_index;
11952 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011953
11954 vos_mem_copy(&setKey.Key[0],
11955 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011957
Gopichand Nakkala29149562013-05-10 21:43:41 +053011958 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959
11960 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 &pHddStaCtx->conn_info.bssId[0],
11962 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011963
Gopichand Nakkala29149562013-05-10 21:43:41 +053011964 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11965 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11966 eCSR_ENCRYPT_TYPE_WEP104)
11967 {
11968 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11969 even though ap is configured for WEP-40 encryption. In this canse the key length
11970 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11971 type(104) and switching encryption type to 40*/
11972 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11973 eCSR_ENCRYPT_TYPE_WEP40;
11974 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11975 eCSR_ENCRYPT_TYPE_WEP40;
11976 }
11977
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011980
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011982 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011984
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 if ( 0 != status )
11986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011987 hddLog(VOS_TRACE_LEVEL_ERROR,
11988 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011989 status);
11990 return -EINVAL;
11991 }
11992 }
11993 }
11994
11995 /* In SoftAp mode setting key direction for default mode */
11996 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11997 {
11998 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11999 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12000 (eCSR_ENCRYPT_TYPE_AES !=
12001 pWextState->roamProfile.EncryptionType.encryptionType[0])
12002 )
12003 {
12004 /* Saving key direction for default key index to TX default */
12005 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12006 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12007 }
12008 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012009 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012010 return status;
12011}
12012
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012013#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12014static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12015 struct net_device *ndev,
12016 u8 key_index,
12017 bool unicast, bool multicast)
12018#else
12019static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12020 struct net_device *ndev,
12021 u8 key_index)
12022#endif
12023{
12024 int ret;
12025 vos_ssr_protect(__func__);
12026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12027 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12028 multicast);
12029#else
12030 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12031#endif
12032 vos_ssr_unprotect(__func__);
12033
12034 return ret;
12035}
12036
Jeff Johnson295189b2012-06-20 16:38:30 -070012037/*
12038 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12039 * This function is used to inform the BSS details to nl80211 interface.
12040 */
12041static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12042 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12043{
12044 struct net_device *dev = pAdapter->dev;
12045 struct wireless_dev *wdev = dev->ieee80211_ptr;
12046 struct wiphy *wiphy = wdev->wiphy;
12047 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12048 int chan_no;
12049 int ie_length;
12050 const char *ie;
12051 unsigned int freq;
12052 struct ieee80211_channel *chan;
12053 int rssi = 0;
12054 struct cfg80211_bss *bss = NULL;
12055
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 if( NULL == pBssDesc )
12057 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012058 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 return bss;
12060 }
12061
12062 chan_no = pBssDesc->channelId;
12063 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12064 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12065
12066 if( NULL == ie )
12067 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012068 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012069 return bss;
12070 }
12071
12072#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12073 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12074 {
12075 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12076 }
12077 else
12078 {
12079 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12080 }
12081#else
12082 freq = ieee80211_channel_to_frequency(chan_no);
12083#endif
12084
12085 chan = __ieee80211_get_channel(wiphy, freq);
12086
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012087 if (!chan) {
12088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12089 return NULL;
12090 }
12091
Abhishek Singhaee43942014-06-16 18:55:47 +053012092 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012093
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012094 return cfg80211_inform_bss(wiphy, chan,
12095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12096 CFG80211_BSS_FTYPE_UNKNOWN,
12097#endif
12098 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012099 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 pBssDesc->capabilityInfo,
12101 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012102 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012103}
12104
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012105/*
12106 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12107 * interface that BSS might have been lost.
12108 * @pAdapter: adaptor
12109 * @bssid: bssid which might have been lost
12110 *
12111 * Return: bss which is unlinked from kernel cache
12112 */
12113struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12114 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12115{
12116 struct net_device *dev = pAdapter->dev;
12117 struct wireless_dev *wdev = dev->ieee80211_ptr;
12118 struct wiphy *wiphy = wdev->wiphy;
12119 struct cfg80211_bss *bss = NULL;
12120
12121 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12122 NULL,
12123 0,
12124#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12125 && !defined(IEEE80211_PRIVACY)
12126 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12127#else
12128 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12129#endif
12130 if (bss == NULL) {
12131 hddLog(LOGE, FL("BSS not present"));
12132 } else {
12133 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12134 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12135 cfg80211_unlink_bss(wiphy, bss);
12136 }
12137 return bss;
12138}
Jeff Johnson295189b2012-06-20 16:38:30 -070012139
12140
12141/*
12142 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12143 * This function is used to inform the BSS details to nl80211 interface.
12144 */
12145struct cfg80211_bss*
12146wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12147 tSirBssDescription *bss_desc
12148 )
12149{
12150 /*
12151 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12152 already exists in bss data base of cfg80211 for that particular BSS ID.
12153 Using cfg80211_inform_bss_frame to update the bss entry instead of
12154 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12155 now there is no possibility to get the mgmt(probe response) frame from PE,
12156 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12157 cfg80211_inform_bss_frame.
12158 */
12159 struct net_device *dev = pAdapter->dev;
12160 struct wireless_dev *wdev = dev->ieee80211_ptr;
12161 struct wiphy *wiphy = wdev->wiphy;
12162 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012163#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12164 qcom_ie_age *qie_age = NULL;
12165 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12166#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012168#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 const char *ie =
12170 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12171 unsigned int freq;
12172 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012173 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 struct cfg80211_bss *bss_status = NULL;
12175 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12176 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012177 hdd_context_t *pHddCtx;
12178 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012179#ifdef WLAN_OPEN_SOURCE
12180 struct timespec ts;
12181#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012182
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012183
Wilson Yangf80a0542013-10-07 13:02:37 -070012184 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12185 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012186 if (0 != status)
12187 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012188 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012189 }
12190
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012191 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012192 if (!mgmt)
12193 {
12194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12195 "%s: memory allocation failed ", __func__);
12196 return NULL;
12197 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012198
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012200
12201#ifdef WLAN_OPEN_SOURCE
12202 /* Android does not want the timestamp from the frame.
12203 Instead it wants a monotonic increasing value */
12204 get_monotonic_boottime(&ts);
12205 mgmt->u.probe_resp.timestamp =
12206 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12207#else
12208 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12210 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012211
12212#endif
12213
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12215 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012216
12217#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12218 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12219 /* Assuming this is the last IE, copy at the end */
12220 ie_length -=sizeof(qcom_ie_age);
12221 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12222 qie_age->element_id = QCOM_VENDOR_IE_ID;
12223 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12224 qie_age->oui_1 = QCOM_OUI1;
12225 qie_age->oui_2 = QCOM_OUI2;
12226 qie_age->oui_3 = QCOM_OUI3;
12227 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012228 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12229 * bss related timestamp is in units of ms. Due to this when scan results
12230 * are sent to lowi the scan age is high.To address this, send age in units
12231 * of 1/10 ms.
12232 */
12233 qie_age->age = (vos_timer_get_system_time() -
12234 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012235#endif
12236
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012238 if (bss_desc->fProbeRsp)
12239 {
12240 mgmt->frame_control |=
12241 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12242 }
12243 else
12244 {
12245 mgmt->frame_control |=
12246 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12247 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012248
12249#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012250 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12252 {
12253 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12257
12258 {
12259 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12260 }
12261 else
12262 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12264 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 kfree(mgmt);
12266 return NULL;
12267 }
12268#else
12269 freq = ieee80211_channel_to_frequency(chan_no);
12270#endif
12271 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012272 /*when the band is changed on the fly using the GUI, three things are done
12273 * 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)
12274 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12275 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12276 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12277 * and discards the channels correponding to previous band and calls back with zero bss results.
12278 * 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
12279 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12280 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12281 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12282 * So drop the bss and continue to next bss.
12283 */
12284 if(chan == NULL)
12285 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012286 hddLog(VOS_TRACE_LEVEL_ERROR,
12287 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12288 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012289 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012290 return NULL;
12291 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012292 /*To keep the rssi icon of the connected AP in the scan window
12293 *and the rssi icon of the wireless networks in sync
12294 * */
12295 if (( eConnectionState_Associated ==
12296 pAdapter->sessionCtx.station.conn_info.connState ) &&
12297 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12298 pAdapter->sessionCtx.station.conn_info.bssId,
12299 WNI_CFG_BSSID_LEN)) &&
12300 (pHddCtx->hdd_wlan_suspended == FALSE))
12301 {
12302 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12303 rssi = (pAdapter->rssi * 100);
12304 }
12305 else
12306 {
12307 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12308 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012309
Nirav Shah20ac06f2013-12-12 18:14:06 +053012310 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012311 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12312 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012313
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12315 frame_len, rssi, GFP_KERNEL);
12316 kfree(mgmt);
12317 return bss_status;
12318}
12319
12320/*
12321 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12322 * This function is used to update the BSS data base of CFG8011
12323 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012324struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 tCsrRoamInfo *pRoamInfo
12326 )
12327{
12328 tCsrRoamConnectedProfile roamProfile;
12329 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12330 struct cfg80211_bss *bss = NULL;
12331
12332 ENTER();
12333
12334 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12335 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12336
12337 if (NULL != roamProfile.pBssDesc)
12338 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012339 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12340 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012341
12342 if (NULL == bss)
12343 {
12344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12345 __func__);
12346 }
12347
12348 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12349 }
12350 else
12351 {
12352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12353 __func__);
12354 }
12355 return bss;
12356}
12357
12358/*
12359 * FUNCTION: wlan_hdd_cfg80211_update_bss
12360 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012361static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12362 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012364{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012365 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 tCsrScanResultInfo *pScanResult;
12367 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012368 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 tScanResultHandle pResult;
12370 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012371 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012372 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012374
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12376 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12377 NO_SESSION, pAdapter->sessionId));
12378
Wilson Yangf80a0542013-10-07 13:02:37 -070012379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012380 ret = wlan_hdd_validate_context(pHddCtx);
12381 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012382 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012383 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012384 }
12385
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012386 if (pAdapter->request != NULL)
12387 {
12388 if ((pAdapter->request->n_ssids == 1)
12389 && (pAdapter->request->ssids != NULL)
12390 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12391 is_p2p_scan = true;
12392 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 /*
12394 * start getting scan results and populate cgf80211 BSS database
12395 */
12396 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12397
12398 /* no scan results */
12399 if (NULL == pResult)
12400 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012401 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12402 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012403 wlan_hdd_get_frame_logs(pAdapter,
12404 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 return status;
12406 }
12407
12408 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12409
12410 while (pScanResult)
12411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012412 /*
12413 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12414 * entry already exists in bss data base of cfg80211 for that
12415 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12416 * bss entry instead of cfg80211_inform_bss, But this call expects
12417 * mgmt packet as input. As of now there is no possibility to get
12418 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 * ieee80211_mgmt(probe response) and passing to c
12420 * fg80211_inform_bss_frame.
12421 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012422 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12423 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12424 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012425 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12426 continue; //Skip the non p2p bss entries
12427 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12429 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012430
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
12432 if (NULL == bss_status)
12433 {
12434 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012435 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 }
12437 else
12438 {
Yue Maf49ba872013-08-19 12:04:25 -070012439 cfg80211_put_bss(
12440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12441 wiphy,
12442#endif
12443 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 }
12445
12446 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12447 }
12448
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012449 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012450 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012451 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012452}
12453
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012454void
12455hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12456{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012457 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012458 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012459} /****** end hddPrintMacAddr() ******/
12460
12461void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012462hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012463{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012464 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012465 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012466 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12467 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12468 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012469} /****** end hddPrintPmkId() ******/
12470
12471//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12472//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12473
12474//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12475//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12476
12477#define dump_bssid(bssid) \
12478 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012479 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12480 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012481 }
12482
12483#define dump_pmkid(pMac, pmkid) \
12484 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012485 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12486 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012487 }
12488
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012489#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012490/*
12491 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12492 * This function is used to notify the supplicant of a new PMKSA candidate.
12493 */
12494int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012495 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012496 int index, bool preauth )
12497{
Jeff Johnsone7245742012-09-05 17:12:55 -070012498#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012499 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012500 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012501
12502 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012503 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012504
12505 if( NULL == pRoamInfo )
12506 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012507 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012508 return -EINVAL;
12509 }
12510
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012511 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12512 {
12513 dump_bssid(pRoamInfo->bssid);
12514 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012515 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012516 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012517#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012519}
12520#endif //FEATURE_WLAN_LFR
12521
Yue Maef608272013-04-08 23:09:17 -070012522#ifdef FEATURE_WLAN_LFR_METRICS
12523/*
12524 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12525 * 802.11r/LFR metrics reporting function to report preauth initiation
12526 *
12527 */
12528#define MAX_LFR_METRICS_EVENT_LENGTH 100
12529VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12530 tCsrRoamInfo *pRoamInfo)
12531{
12532 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12533 union iwreq_data wrqu;
12534
12535 ENTER();
12536
12537 if (NULL == pAdapter)
12538 {
12539 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12540 return VOS_STATUS_E_FAILURE;
12541 }
12542
12543 /* create the event */
12544 memset(&wrqu, 0, sizeof(wrqu));
12545 memset(metrics_notification, 0, sizeof(metrics_notification));
12546
12547 wrqu.data.pointer = metrics_notification;
12548 wrqu.data.length = scnprintf(metrics_notification,
12549 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12550 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12551
12552 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12553
12554 EXIT();
12555
12556 return VOS_STATUS_SUCCESS;
12557}
12558
12559/*
12560 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12561 * 802.11r/LFR metrics reporting function to report preauth completion
12562 * or failure
12563 */
12564VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12565 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12566{
12567 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12568 union iwreq_data wrqu;
12569
12570 ENTER();
12571
12572 if (NULL == pAdapter)
12573 {
12574 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12575 return VOS_STATUS_E_FAILURE;
12576 }
12577
12578 /* create the event */
12579 memset(&wrqu, 0, sizeof(wrqu));
12580 memset(metrics_notification, 0, sizeof(metrics_notification));
12581
12582 scnprintf(metrics_notification, sizeof(metrics_notification),
12583 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12584 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12585
12586 if (1 == preauth_status)
12587 strncat(metrics_notification, " TRUE", 5);
12588 else
12589 strncat(metrics_notification, " FALSE", 6);
12590
12591 wrqu.data.pointer = metrics_notification;
12592 wrqu.data.length = strlen(metrics_notification);
12593
12594 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12595
12596 EXIT();
12597
12598 return VOS_STATUS_SUCCESS;
12599}
12600
12601/*
12602 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12603 * 802.11r/LFR metrics reporting function to report handover initiation
12604 *
12605 */
12606VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12607 tCsrRoamInfo *pRoamInfo)
12608{
12609 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12610 union iwreq_data wrqu;
12611
12612 ENTER();
12613
12614 if (NULL == pAdapter)
12615 {
12616 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12617 return VOS_STATUS_E_FAILURE;
12618 }
12619
12620 /* create the event */
12621 memset(&wrqu, 0, sizeof(wrqu));
12622 memset(metrics_notification, 0, sizeof(metrics_notification));
12623
12624 wrqu.data.pointer = metrics_notification;
12625 wrqu.data.length = scnprintf(metrics_notification,
12626 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12627 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12628
12629 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12630
12631 EXIT();
12632
12633 return VOS_STATUS_SUCCESS;
12634}
12635#endif
12636
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012637
12638/**
12639 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12640 * @scan_req: scan request to be checked
12641 *
12642 * Return: true or false
12643 */
12644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12645static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12646 cfg80211_scan_request
12647 *scan_req)
12648{
12649 if (!scan_req || !scan_req->wiphy) {
12650 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12651 return false;
12652 }
12653 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12654 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12655 return false;
12656 }
12657 return true;
12658}
12659#else
12660static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12661 cfg80211_scan_request
12662 *scan_req)
12663{
12664 if (!scan_req || !scan_req->wiphy) {
12665 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12666 return false;
12667 }
12668 return true;
12669}
12670#endif
12671
12672
Jeff Johnson295189b2012-06-20 16:38:30 -070012673/*
12674 * FUNCTION: hdd_cfg80211_scan_done_callback
12675 * scanning callback function, called after finishing scan
12676 *
12677 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012678static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12680{
12681 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012682 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012684 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 struct cfg80211_scan_request *req = NULL;
12686 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012687 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012688#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12689 bool iface_down = false;
12690#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012691 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012692 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012693 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012694
12695 ENTER();
12696
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012697 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012698 if (NULL == pHddCtx) {
12699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012700 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012701 }
12702
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12704 if (!(pAdapter->dev->flags & IFF_UP))
12705 {
12706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012707 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012708 }
12709#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012710 pScanInfo = &pHddCtx->scan_info;
12711
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 hddLog(VOS_TRACE_LEVEL_INFO,
12713 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012714 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 __func__, halHandle, pContext, (int) scanId, (int) status);
12716
Kiet Lamac06e2c2013-10-23 16:25:07 +053012717 pScanInfo->mScanPendingCounter = 0;
12718
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012720 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012721 &pScanInfo->scan_req_completion_event,
12722 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012723 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012725 hddLog(VOS_TRACE_LEVEL_ERROR,
12726 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012727 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012728 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 }
12730
Yue Maef608272013-04-08 23:09:17 -070012731 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 {
12733 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012734 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 }
12736
12737 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012738 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 {
12740 hddLog(VOS_TRACE_LEVEL_INFO,
12741 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012742 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 (int) scanId);
12744 }
12745
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012747 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012748#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012749 {
12750 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12751 pAdapter);
12752 if (0 > ret)
12753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012754 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012755
Jeff Johnson295189b2012-06-20 16:38:30 -070012756 /* If any client wait scan result through WEXT
12757 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012758 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 {
12760 /* The other scan request waiting for current scan finish
12761 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012762 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012763 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012764 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012765 }
12766 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012767 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012768 {
12769 struct net_device *dev = pAdapter->dev;
12770 union iwreq_data wrqu;
12771 int we_event;
12772 char *msg;
12773
12774 memset(&wrqu, '\0', sizeof(wrqu));
12775 we_event = SIOCGIWSCAN;
12776 msg = NULL;
12777 wireless_send_event(dev, we_event, &wrqu, msg);
12778 }
12779 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012780 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012781
12782 /* Get the Scan Req */
12783 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012784 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012785
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012786 /* Scan is no longer pending */
12787 pScanInfo->mScanPending = VOS_FALSE;
12788
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012789 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12793 iface_down ? "up" : "down");
12794#endif
12795
12796 if (pAdapter->dev) {
12797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12798 pAdapter->dev->name);
12799 }
mukul sharmae7041822015-12-03 15:09:21 +053012800 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012801 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 }
12803
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012804 /* last_scan_timestamp is used to decide if new scan
12805 * is needed or not on station interface. If last station
12806 * scan time and new station scan time is less then
12807 * last_scan_timestamp ; driver will return cached scan.
12808 */
12809 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12810 {
12811 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12812
12813 if ( req->n_channels )
12814 {
12815 for (i = 0; i < req->n_channels ; i++ )
12816 {
12817 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12818 }
12819 /* store no of channel scanned */
12820 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12821 }
12822
12823 }
12824
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012825 /*
12826 * cfg80211_scan_done informing NL80211 about completion
12827 * of scanning
12828 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012829 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12830 {
12831 aborted = true;
12832 }
mukul sharmae7041822015-12-03 15:09:21 +053012833
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12835 if (!iface_down)
12836#endif
12837 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012838
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012839 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012840
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012841allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012842 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12843 ) && (pHddCtx->spoofMacAddr.isEnabled
12844 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012845 /* Generate new random mac addr for next scan */
12846 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012847
12848 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12849 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012850 }
12851
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012852 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012853 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012854
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012855 /* Acquire wakelock to handle the case where APP's tries to suspend
12856 * immediatly after the driver gets connect request(i.e after scan)
12857 * from supplicant, this result in app's is suspending and not able
12858 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012859 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012860
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012861#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12862 if (!iface_down)
12863#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012864#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012865 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012866#endif
12867
Jeff Johnson295189b2012-06-20 16:38:30 -070012868 EXIT();
12869 return 0;
12870}
12871
12872/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012873 * FUNCTION: hdd_isConnectionInProgress
12874 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012875 *
12876 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012877v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012878{
12879 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12880 hdd_station_ctx_t *pHddStaCtx = NULL;
12881 hdd_adapter_t *pAdapter = NULL;
12882 VOS_STATUS status = 0;
12883 v_U8_t staId = 0;
12884 v_U8_t *staMac = NULL;
12885
12886 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12887
12888 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12889 {
12890 pAdapter = pAdapterNode->pAdapter;
12891
12892 if( pAdapter )
12893 {
12894 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012895 "%s: Adapter with device mode %s (%d) exists",
12896 __func__, hdd_device_modetoString(pAdapter->device_mode),
12897 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012898 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012899 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12900 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12901 (eConnectionState_Connecting ==
12902 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12903 {
12904 hddLog(VOS_TRACE_LEVEL_ERROR,
12905 "%s: %p(%d) Connection is in progress", __func__,
12906 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12907 return VOS_TRUE;
12908 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012909 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012910 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012911 {
12912 hddLog(VOS_TRACE_LEVEL_ERROR,
12913 "%s: %p(%d) Reassociation is in progress", __func__,
12914 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12915 return VOS_TRUE;
12916 }
12917 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012918 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12919 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012920 {
12921 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12922 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012923 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012924 {
12925 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12926 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012927 "%s: client " MAC_ADDRESS_STR
12928 " is in the middle of WPS/EAPOL exchange.", __func__,
12929 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012930 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012931 }
12932 }
12933 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12934 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12935 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012936 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12937 ptSapContext pSapCtx = NULL;
12938 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12939 if(pSapCtx == NULL){
12940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12941 FL("psapCtx is NULL"));
12942 return VOS_FALSE;
12943 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012944 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12945 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012946 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12947 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012948 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012949 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012950
12951 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012952 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12953 "middle of WPS/EAPOL exchange.", __func__,
12954 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012955 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012956 }
12957 }
12958 }
12959 }
12960 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12961 pAdapterNode = pNext;
12962 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012963 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012964}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012965
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012966/**
12967 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12968 * to the Scan request
12969 * @scanRequest: Pointer to the csr scan request
12970 * @request: Pointer to the scan request from supplicant
12971 *
12972 * Return: None
12973 */
12974#ifdef CFG80211_SCAN_BSSID
12975static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12976 struct cfg80211_scan_request *request)
12977{
12978 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12979}
12980#else
12981static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12982 struct cfg80211_scan_request *request)
12983{
12984}
12985#endif
12986
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012987/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012988 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 * this scan respond to scan trigger and update cfg80211 scan database
12990 * later, scan dump command can be used to recieve scan results
12991 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012992int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012993#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12994 struct net_device *dev,
12995#endif
12996 struct cfg80211_scan_request *request)
12997{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012998 hdd_adapter_t *pAdapter = NULL;
12999 hdd_context_t *pHddCtx = NULL;
13000 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013001 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 tCsrScanRequest scanRequest;
13003 tANI_U8 *channelList = NULL, i;
13004 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013005 int status;
13006 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013008 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013009 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013010 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013011
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13013 struct net_device *dev = NULL;
13014 if (NULL == request)
13015 {
13016 hddLog(VOS_TRACE_LEVEL_ERROR,
13017 "%s: scan req param null", __func__);
13018 return -EINVAL;
13019 }
13020 dev = request->wdev->netdev;
13021#endif
13022
13023 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13024 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13025 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13026
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 ENTER();
13028
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13030 __func__, hdd_device_modetoString(pAdapter->device_mode),
13031 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013032
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013033 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013034 if (0 != status)
13035 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013036 return status;
13037 }
13038
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013039 if (NULL == pwextBuf)
13040 {
13041 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13042 __func__);
13043 return -EIO;
13044 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013045 cfg_param = pHddCtx->cfg_ini;
13046 pScanInfo = &pHddCtx->scan_info;
13047
Jeff Johnson295189b2012-06-20 16:38:30 -070013048#ifdef WLAN_BTAMP_FEATURE
13049 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013050 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013052 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 "%s: No scanning when AMP is on", __func__);
13054 return -EOPNOTSUPP;
13055 }
13056#endif
13057 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013058 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013060 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013061 "%s: Not scanning on device_mode = %s (%d)",
13062 __func__, hdd_device_modetoString(pAdapter->device_mode),
13063 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 return -EOPNOTSUPP;
13065 }
13066
13067 if (TRUE == pScanInfo->mScanPending)
13068 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013069 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13070 {
13071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13072 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013073 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013074 }
13075
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013076 // Don't allow scan if PNO scan is going on.
13077 if (pHddCtx->isPnoEnable)
13078 {
13079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13080 FL("pno scan in progress"));
13081 return -EBUSY;
13082 }
13083
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013084 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013085 //Channel and action frame is pending
13086 //Otherwise Cancel Remain On Channel and allow Scan
13087 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013088 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013089 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013091 return -EBUSY;
13092 }
13093
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13095 {
13096 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013097 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013099 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13101 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013102 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 "%s: MAX TM Level Scan not allowed", __func__);
13104 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013105 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 }
13107 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13108
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013109 /* Check if scan is allowed at this point of time.
13110 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013111 if (TRUE == pHddCtx->btCoexModeSet)
13112 {
13113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13114 FL("BTCoex Mode operation in progress"));
13115 return -EBUSY;
13116 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013117 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013118 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13120 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13122 FL("Triggering SSR, SSR status = %d"), status);
13123 vos_wlanRestart();
13124 }
13125 else
13126 pHddCtx->con_scan_abort_cnt++;
13127
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013128 return -EBUSY;
13129 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013130 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013131
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13133
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013134 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13135 * Becasue of this, driver is assuming that this is not wildcard scan and so
13136 * is not aging out the scan results.
13137 */
13138 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013139 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013140 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013142
13143 if ((request->ssids) && (0 < request->n_ssids))
13144 {
13145 tCsrSSIDInfo *SsidInfo;
13146 int j;
13147 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13148 /* Allocate num_ssid tCsrSSIDInfo structure */
13149 SsidInfo = scanRequest.SSIDs.SSIDList =
13150 ( tCsrSSIDInfo *)vos_mem_malloc(
13151 request->n_ssids*sizeof(tCsrSSIDInfo));
13152
13153 if(NULL == scanRequest.SSIDs.SSIDList)
13154 {
13155 hddLog(VOS_TRACE_LEVEL_ERROR,
13156 "%s: memory alloc failed SSIDInfo buffer", __func__);
13157 return -ENOMEM;
13158 }
13159
13160 /* copy all the ssid's and their length */
13161 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13162 {
13163 /* get the ssid length */
13164 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13165 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13166 SsidInfo->SSID.length);
13167 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13168 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13169 j, SsidInfo->SSID.ssId);
13170 }
13171 /* set the scan type to active */
13172 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13173 }
13174 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013176 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13177 TRACE_CODE_HDD_CFG80211_SCAN,
13178 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013179 /* set the scan type to active */
13180 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013181 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013182 else
13183 {
13184 /*Set the scan type to default type, in this case it is ACTIVE*/
13185 scanRequest.scanType = pScanInfo->scan_mode;
13186 }
13187 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13188 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013189
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013190 csr_scan_request_assign_bssid(&scanRequest, request);
13191
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 /* set BSSType to default type */
13193 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13194
13195 /*TODO: scan the requested channels only*/
13196
13197 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013198 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013199 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013200 hddLog(VOS_TRACE_LEVEL_WARN,
13201 "No of Scan Channels exceeded limit: %d", request->n_channels);
13202 request->n_channels = MAX_CHANNEL;
13203 }
13204
13205 hddLog(VOS_TRACE_LEVEL_INFO,
13206 "No of Scan Channels: %d", request->n_channels);
13207
13208
13209 if( request->n_channels )
13210 {
13211 char chList [(request->n_channels*5)+1];
13212 int len;
13213 channelList = vos_mem_malloc( request->n_channels );
13214 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013215 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013216 hddLog(VOS_TRACE_LEVEL_ERROR,
13217 "%s: memory alloc failed channelList", __func__);
13218 status = -ENOMEM;
13219 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013220 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013221
13222 for( i = 0, len = 0; i < request->n_channels ; i++ )
13223 {
13224 channelList[i] = request->channels[i]->hw_value;
13225 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13226 }
13227
Nirav Shah20ac06f2013-12-12 18:14:06 +053013228 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013229 "Channel-List: %s ", chList);
13230 }
c_hpothu53512302014-04-15 18:49:53 +053013231
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013232 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13233 scanRequest.ChannelInfo.ChannelList = channelList;
13234
13235 /* set requestType to full scan */
13236 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13237
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013238 /* if there is back to back scan happening in driver with in
13239 * nDeferScanTimeInterval interval driver should defer new scan request
13240 * and should provide last cached scan results instead of new channel list.
13241 * This rule is not applicable if scan is p2p scan.
13242 * This condition will work only in case when last request no of channels
13243 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013244 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013245 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013246 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013247
Sushant Kaushik86592172015-04-27 16:35:03 +053013248 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13249 /* if wps ie is NULL , then only defer scan */
13250 if ( pWpsIe == NULL &&
13251 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013252 {
13253 if ( pScanInfo->last_scan_timestamp !=0 &&
13254 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13255 {
13256 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13257 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13258 vos_mem_compare(pScanInfo->last_scan_channelList,
13259 channelList, pScanInfo->last_scan_numChannels))
13260 {
13261 hddLog(VOS_TRACE_LEVEL_WARN,
13262 " New and old station scan time differ is less then %u",
13263 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13264
13265 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013266 pAdapter);
13267
Agarwal Ashish57e84372014-12-05 18:26:53 +053013268 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013269 "Return old cached scan as all channels and no of channels are same");
13270
Agarwal Ashish57e84372014-12-05 18:26:53 +053013271 if (0 > ret)
13272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013273
Agarwal Ashish57e84372014-12-05 18:26:53 +053013274 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013275
13276 status = eHAL_STATUS_SUCCESS;
13277 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013278 }
13279 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013280 }
13281
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013282 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13283 * search (Flush on both full scan and social scan but not on single
13284 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13285 */
13286
13287 /* Supplicant does single channel scan after 8-way handshake
13288 * and in that case driver shoudnt flush scan results. If
13289 * driver flushes the scan results here and unfortunately if
13290 * the AP doesnt respond to our probe req then association
13291 * fails which is not desired
13292 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013293 if ((request->n_ssids == 1)
13294 && (request->ssids != NULL)
13295 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13296 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013297
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013298 if( is_p2p_scan ||
13299 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013300 {
13301 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13302 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13303 pAdapter->sessionId );
13304 }
13305
13306 if( request->ie_len )
13307 {
13308 /* save this for future association (join requires this) */
13309 /*TODO: Array needs to be converted to dynamic allocation,
13310 * as multiple ie.s can be sent in cfg80211_scan_request structure
13311 * CR 597966
13312 */
13313 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13314 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13315 pScanInfo->scanAddIE.length = request->ie_len;
13316
13317 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13318 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13319 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013321 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013323 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13324 memcpy( pwextBuf->roamProfile.addIEScan,
13325 request->ie, request->ie_len);
13326 }
13327 else
13328 {
13329 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13330 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013331 }
13332
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013333 }
13334 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13335 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13336
13337 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13338 request->ie_len);
13339 if (pP2pIe != NULL)
13340 {
13341#ifdef WLAN_FEATURE_P2P_DEBUG
13342 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13343 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13344 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013345 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013346 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13347 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13348 "Go nego completed to Connection is started");
13349 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13350 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013351 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013352 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13353 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013355 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13356 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13357 "Disconnected state to Connection is started");
13358 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13359 "for 4way Handshake");
13360 }
13361#endif
13362
13363 /* no_cck will be set during p2p find to disable 11b rates */
13364 if(TRUE == request->no_cck)
13365 {
13366 hddLog(VOS_TRACE_LEVEL_INFO,
13367 "%s: This is a P2P Search", __func__);
13368 scanRequest.p2pSearch = 1;
13369
13370 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013371 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013372 /* set requestType to P2P Discovery */
13373 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13374 }
13375
13376 /*
13377 Skip Dfs Channel in case of P2P Search
13378 if it is set in ini file
13379 */
13380 if(cfg_param->skipDfsChnlInP2pSearch)
13381 {
13382 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013383 }
13384 else
13385 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013386 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013387 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013388
Agarwal Ashish4f616132013-12-30 23:32:50 +053013389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 }
13391 }
13392
13393 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13394
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013395#ifdef FEATURE_WLAN_TDLS
13396 /* if tdls disagree scan right now, return immediately.
13397 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13398 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13399 */
13400 status = wlan_hdd_tdls_scan_callback (pAdapter,
13401 wiphy,
13402#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13403 dev,
13404#endif
13405 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013406 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013407 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013408 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13410 "scan rejected %d", __func__, status);
13411 else
13412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13413 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013414 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013415 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013416 }
13417#endif
13418
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013419 /* acquire the wakelock to avoid the apps suspend during the scan. To
13420 * address the following issues.
13421 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13422 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13423 * for long time, this result in apps running at full power for long time.
13424 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13425 * be stuck in full power because of resume BMPS
13426 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013427 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013428
Nirav Shah20ac06f2013-12-12 18:14:06 +053013429 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13430 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013431 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13432 scanRequest.requestType, scanRequest.scanType,
13433 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013434 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13435
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013436 if (pHddCtx->spoofMacAddr.isEnabled &&
13437 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013438 {
13439 hddLog(VOS_TRACE_LEVEL_INFO,
13440 "%s: MAC Spoofing enabled for current scan", __func__);
13441 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13442 * to fill TxBds for probe request during current scan
13443 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013444 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013445 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013446
13447 if(status != VOS_STATUS_SUCCESS)
13448 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013449 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013450 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013451#ifdef FEATURE_WLAN_TDLS
13452 wlan_hdd_tdls_scan_done_callback(pAdapter);
13453#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013454 goto free_mem;
13455 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013456 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013457 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013458 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013459 pAdapter->sessionId, &scanRequest, &scanId,
13460 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013461
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 if (eHAL_STATUS_SUCCESS != status)
13463 {
13464 hddLog(VOS_TRACE_LEVEL_ERROR,
13465 "%s: sme_ScanRequest returned error %d", __func__, status);
13466 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013467 if(eHAL_STATUS_RESOURCES == status)
13468 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13470 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013471 status = -EBUSY;
13472 } else {
13473 status = -EIO;
13474 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013475 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013476
13477#ifdef FEATURE_WLAN_TDLS
13478 wlan_hdd_tdls_scan_done_callback(pAdapter);
13479#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 goto free_mem;
13481 }
13482
13483 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013484 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 pAdapter->request = request;
13486 pScanInfo->scanId = scanId;
13487
13488 complete(&pScanInfo->scan_req_completion_event);
13489
13490free_mem:
13491 if( scanRequest.SSIDs.SSIDList )
13492 {
13493 vos_mem_free(scanRequest.SSIDs.SSIDList);
13494 }
13495
13496 if( channelList )
13497 vos_mem_free( channelList );
13498
13499 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013500 return status;
13501}
13502
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013503int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13505 struct net_device *dev,
13506#endif
13507 struct cfg80211_scan_request *request)
13508{
13509 int ret;
13510
13511 vos_ssr_protect(__func__);
13512 ret = __wlan_hdd_cfg80211_scan(wiphy,
13513#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13514 dev,
13515#endif
13516 request);
13517 vos_ssr_unprotect(__func__);
13518
13519 return ret;
13520}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013521
13522void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13523{
13524 v_U8_t iniDot11Mode =
13525 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13526 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13527
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013528 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13529 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013530 switch ( iniDot11Mode )
13531 {
13532 case eHDD_DOT11_MODE_AUTO:
13533 case eHDD_DOT11_MODE_11ac:
13534 case eHDD_DOT11_MODE_11ac_ONLY:
13535#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013536 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13537 sme_IsFeatureSupportedByFW(DOT11AC) )
13538 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13539 else
13540 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013541#else
13542 hddDot11Mode = eHDD_DOT11_MODE_11n;
13543#endif
13544 break;
13545 case eHDD_DOT11_MODE_11n:
13546 case eHDD_DOT11_MODE_11n_ONLY:
13547 hddDot11Mode = eHDD_DOT11_MODE_11n;
13548 break;
13549 default:
13550 hddDot11Mode = iniDot11Mode;
13551 break;
13552 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013553#ifdef WLAN_FEATURE_AP_HT40_24G
13554 if (operationChannel > SIR_11B_CHANNEL_END)
13555#endif
13556 {
13557 /* This call decides required channel bonding mode */
13558 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013559 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13560 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013561 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013562}
13563
Jeff Johnson295189b2012-06-20 16:38:30 -070013564/*
13565 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013566 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013568int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013569 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13570 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013571{
13572 int status = 0;
13573 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013574 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013575 v_U32_t roamId;
13576 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013578 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013579
13580 ENTER();
13581
13582 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013583 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13584
13585 status = wlan_hdd_validate_context(pHddCtx);
13586 if (status)
13587 {
Yue Mae36e3552014-03-05 17:06:20 -080013588 return status;
13589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13592 {
13593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13594 return -EINVAL;
13595 }
13596
13597 pRoamProfile = &pWextState->roamProfile;
13598
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013599 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013601 hdd_station_ctx_t *pHddStaCtx;
13602 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013603
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013604 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13605
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13608 {
13609 /*QoS not enabled in cfg file*/
13610 pRoamProfile->uapsd_mask = 0;
13611 }
13612 else
13613 {
13614 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013615 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13617 }
13618
13619 pRoamProfile->SSIDs.numOfSSIDs = 1;
13620 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13621 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013622 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13624 ssid, ssid_len);
13625
13626 if (bssid)
13627 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013628 pValidBssid = bssid;
13629 }
13630 else if (bssid_hint)
13631 {
13632 pValidBssid = bssid_hint;
13633 }
13634 if (pValidBssid)
13635 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013637 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013639 /* Save BSSID in seperate variable as well, as RoamProfile
13640 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 case of join failure we should send valid BSSID to supplicant
13642 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013643 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 WNI_CFG_BSSID_LEN);
13645 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013646 else
13647 {
13648 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013650
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013651 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13652 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13654 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013655 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 /*set gen ie*/
13657 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13658 /*set auth*/
13659 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13660 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013661#ifdef FEATURE_WLAN_WAPI
13662 if (pAdapter->wapi_info.nWapiMode)
13663 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013664 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013665 switch (pAdapter->wapi_info.wapiAuthMode)
13666 {
13667 case WAPI_AUTH_MODE_PSK:
13668 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013669 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 pAdapter->wapi_info.wapiAuthMode);
13671 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13672 break;
13673 }
13674 case WAPI_AUTH_MODE_CERT:
13675 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013676 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 pAdapter->wapi_info.wapiAuthMode);
13678 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13679 break;
13680 }
13681 } // End of switch
13682 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13683 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13684 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013685 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 pRoamProfile->AuthType.numEntries = 1;
13687 pRoamProfile->EncryptionType.numEntries = 1;
13688 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13689 pRoamProfile->mcEncryptionType.numEntries = 1;
13690 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13691 }
13692 }
13693#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013694#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013695 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013696 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13697 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13698 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013699 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13700 sizeof (tSirGtkOffloadParams));
13701 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013702 }
13703#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013704 pRoamProfile->csrPersona = pAdapter->device_mode;
13705
Jeff Johnson32d95a32012-09-10 13:15:23 -070013706 if( operatingChannel )
13707 {
13708 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13709 pRoamProfile->ChannelInfo.numOfChannels = 1;
13710 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013711 else
13712 {
13713 pRoamProfile->ChannelInfo.ChannelList = NULL;
13714 pRoamProfile->ChannelInfo.numOfChannels = 0;
13715 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013716 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13717 {
13718 hdd_select_cbmode(pAdapter,operatingChannel);
13719 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013720
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013721 /*
13722 * Change conn_state to connecting before sme_RoamConnect(),
13723 * because sme_RoamConnect() has a direct path to call
13724 * hdd_smeRoamCallback(), which will change the conn_state
13725 * If direct path, conn_state will be accordingly changed
13726 * to NotConnected or Associated by either
13727 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13728 * in sme_RoamCallback()
13729 * if sme_RomConnect is to be queued,
13730 * Connecting state will remain until it is completed.
13731 * If connection state is not changed,
13732 * connection state will remain in eConnectionState_NotConnected state.
13733 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13734 * if conn state is eConnectionState_NotConnected.
13735 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13736 * informed of connect result indication which is an issue.
13737 */
13738
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013739 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13740 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013741 {
13742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013743 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013744 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13745 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013746 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 pAdapter->sessionId, pRoamProfile, &roamId);
13749
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013750 if ((eHAL_STATUS_SUCCESS != status) &&
13751 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13752 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013753
13754 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013755 hddLog(VOS_TRACE_LEVEL_ERROR,
13756 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13757 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013758 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013759 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013760 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013761 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013762
13763 pRoamProfile->ChannelInfo.ChannelList = NULL;
13764 pRoamProfile->ChannelInfo.numOfChannels = 0;
13765
Jeff Johnson295189b2012-06-20 16:38:30 -070013766 }
13767 else
13768 {
13769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13770 return -EINVAL;
13771 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013772 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 return status;
13774}
13775
13776/*
13777 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13778 * This function is used to set the authentication type (OPEN/SHARED).
13779 *
13780 */
13781static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13782 enum nl80211_auth_type auth_type)
13783{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13786
13787 ENTER();
13788
13789 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013790 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013792 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013793 hddLog(VOS_TRACE_LEVEL_INFO,
13794 "%s: set authentication type to AUTOSWITCH", __func__);
13795 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13796 break;
13797
13798 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013799#ifdef WLAN_FEATURE_VOWIFI_11R
13800 case NL80211_AUTHTYPE_FT:
13801#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013802 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 "%s: set authentication type to OPEN", __func__);
13804 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13805 break;
13806
13807 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013808 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 "%s: set authentication type to SHARED", __func__);
13810 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13811 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013812#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013814 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 "%s: set authentication type to CCKM WPA", __func__);
13816 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13817 break;
13818#endif
13819
13820
13821 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013822 hddLog(VOS_TRACE_LEVEL_ERROR,
13823 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 auth_type);
13825 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13826 return -EINVAL;
13827 }
13828
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013829 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 pHddStaCtx->conn_info.authType;
13831 return 0;
13832}
13833
13834/*
13835 * FUNCTION: wlan_hdd_set_akm_suite
13836 * This function is used to set the key mgmt type(PSK/8021x).
13837 *
13838 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013839static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 u32 key_mgmt
13841 )
13842{
13843 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13844 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013845 /* Should be in ieee802_11_defs.h */
13846#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13847#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 /*set key mgmt type*/
13849 switch(key_mgmt)
13850 {
13851 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013852 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013853#ifdef WLAN_FEATURE_VOWIFI_11R
13854 case WLAN_AKM_SUITE_FT_PSK:
13855#endif
13856 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 __func__);
13858 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13859 break;
13860
13861 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013862 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013863#ifdef WLAN_FEATURE_VOWIFI_11R
13864 case WLAN_AKM_SUITE_FT_8021X:
13865#endif
13866 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 __func__);
13868 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13869 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013870#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013871#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13872#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13873 case WLAN_AKM_SUITE_CCKM:
13874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13875 __func__);
13876 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13877 break;
13878#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013879#ifndef WLAN_AKM_SUITE_OSEN
13880#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13881 case WLAN_AKM_SUITE_OSEN:
13882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13883 __func__);
13884 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13885 break;
13886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013887
13888 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 __func__, key_mgmt);
13891 return -EINVAL;
13892
13893 }
13894 return 0;
13895}
13896
13897/*
13898 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013899 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 * (NONE/WEP40/WEP104/TKIP/CCMP).
13901 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013902static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13903 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013904 bool ucast
13905 )
13906{
13907 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013908 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13910
13911 ENTER();
13912
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013915 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 __func__, cipher);
13917 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13918 }
13919 else
13920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013921
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013923 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 {
13925 case IW_AUTH_CIPHER_NONE:
13926 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13927 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013930 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013932
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013934 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013936
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 case WLAN_CIPHER_SUITE_TKIP:
13938 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13939 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013940
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 case WLAN_CIPHER_SUITE_CCMP:
13942 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13943 break;
13944#ifdef FEATURE_WLAN_WAPI
13945 case WLAN_CIPHER_SUITE_SMS4:
13946 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13947 break;
13948#endif
13949
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013950#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 case WLAN_CIPHER_SUITE_KRK:
13952 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13953 break;
13954#endif
13955 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 __func__, cipher);
13958 return -EOPNOTSUPP;
13959 }
13960 }
13961
13962 if (ucast)
13963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 __func__, encryptionType);
13966 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13967 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 encryptionType;
13970 }
13971 else
13972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 __func__, encryptionType);
13975 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13976 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13977 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13978 }
13979
13980 return 0;
13981}
13982
13983
13984/*
13985 * FUNCTION: wlan_hdd_cfg80211_set_ie
13986 * This function is used to parse WPA/RSN IE's.
13987 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013988int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13990 const u8 *ie,
13991#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013992 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 size_t ie_len
13995 )
13996{
13997 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13999 const u8 *genie = ie;
14000#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014002#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014003 v_U16_t remLen = ie_len;
14004#ifdef FEATURE_WLAN_WAPI
14005 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14006 u16 *tmp;
14007 v_U16_t akmsuiteCount;
14008 int *akmlist;
14009#endif
14010 ENTER();
14011
14012 /* clear previous assocAddIE */
14013 pWextState->assocAddIE.length = 0;
14014 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014015 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014016
14017 while (remLen >= 2)
14018 {
14019 v_U16_t eLen = 0;
14020 v_U8_t elementId;
14021 elementId = *genie++;
14022 eLen = *genie++;
14023 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014024
Arif Hussain6d2a3322013-11-17 19:50:10 -080014025 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014026 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014027
14028 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014030 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014031 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 -070014032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 "%s: Invalid WPA IE", __func__);
14035 return -EINVAL;
14036 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014037 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 {
14039 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014040 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014042
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014043 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014045 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14046 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 VOS_ASSERT(0);
14048 return -ENOMEM;
14049 }
14050 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14051 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14052 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014053
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14055 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14056 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14057 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014058 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14059 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014060 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14061 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14062 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14063 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14064 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14065 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014066 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014067 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 {
14069 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014070 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014073 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014075 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14076 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 VOS_ASSERT(0);
14078 return -ENOMEM;
14079 }
14080 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14081 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14082 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14085 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14086 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014087#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014088 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14089 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 /*Consider WFD IE, only for P2P Client */
14091 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14092 {
14093 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014094 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014096
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014097 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014099 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14100 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 VOS_ASSERT(0);
14102 return -ENOMEM;
14103 }
14104 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14105 // WPS IE + P2P IE + WFD IE
14106 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14107 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14110 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14111 }
14112#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014113 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014114 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014115 HS20_OUI_TYPE_SIZE)) )
14116 {
14117 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014118 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014119 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014120
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014121 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014122 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014123 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14124 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014125 VOS_ASSERT(0);
14126 return -ENOMEM;
14127 }
14128 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14129 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014130
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014131 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14132 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14133 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014134 /* Appending OSEN Information Element in Assiciation Request */
14135 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14136 OSEN_OUI_TYPE_SIZE)) )
14137 {
14138 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14139 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14140 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014141
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014142 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014143 {
14144 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14145 "Need bigger buffer space");
14146 VOS_ASSERT(0);
14147 return -ENOMEM;
14148 }
14149 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14150 pWextState->assocAddIE.length += eLen + 2;
14151
14152 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14153 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14154 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14155 }
14156
Abhishek Singh4322e622015-06-10 15:42:54 +053014157 /* Update only for WPA IE */
14158 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14159 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014160
14161 /* populating as ADDIE in beacon frames */
14162 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014163 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014164 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14165 {
14166 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14167 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14168 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14169 {
14170 hddLog(LOGE,
14171 "Coldn't pass "
14172 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14173 }
14174 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14175 else
14176 hddLog(LOGE,
14177 "Could not pass on "
14178 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14179
14180 /* IBSS mode doesn't contain params->proberesp_ies still
14181 beaconIE's need to be populated in probe response frames */
14182 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14183 {
14184 u16 rem_probe_resp_ie_len = eLen + 2;
14185 u8 probe_rsp_ie_len[3] = {0};
14186 u8 counter = 0;
14187
14188 /* Check Probe Resp Length if it is greater then 255 then
14189 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14190 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14191 not able Store More then 255 bytes into One Variable */
14192
14193 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14194 {
14195 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14196 {
14197 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14198 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14199 }
14200 else
14201 {
14202 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14203 rem_probe_resp_ie_len = 0;
14204 }
14205 }
14206
14207 rem_probe_resp_ie_len = 0;
14208
14209 if (probe_rsp_ie_len[0] > 0)
14210 {
14211 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14212 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14213 (tANI_U8*)(genie - 2),
14214 probe_rsp_ie_len[0], NULL,
14215 eANI_BOOLEAN_FALSE)
14216 == eHAL_STATUS_FAILURE)
14217 {
14218 hddLog(LOGE,
14219 "Could not pass"
14220 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14221 }
14222 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14223 }
14224
14225 if (probe_rsp_ie_len[1] > 0)
14226 {
14227 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14228 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14229 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14230 probe_rsp_ie_len[1], NULL,
14231 eANI_BOOLEAN_FALSE)
14232 == eHAL_STATUS_FAILURE)
14233 {
14234 hddLog(LOGE,
14235 "Could not pass"
14236 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14237 }
14238 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14239 }
14240
14241 if (probe_rsp_ie_len[2] > 0)
14242 {
14243 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14244 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14245 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14246 probe_rsp_ie_len[2], NULL,
14247 eANI_BOOLEAN_FALSE)
14248 == eHAL_STATUS_FAILURE)
14249 {
14250 hddLog(LOGE,
14251 "Could not pass"
14252 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14253 }
14254 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14255 }
14256
14257 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14258 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14259 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14260 {
14261 hddLog(LOGE,
14262 "Could not pass"
14263 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14264 }
14265 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014266 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014267 break;
14268 case DOT11F_EID_RSN:
14269 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14270 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14271 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14272 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14273 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14274 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014275
Abhishek Singhb16f3562016-01-20 11:08:32 +053014276 /* Appending extended capabilities with Interworking or
14277 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014278 *
14279 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014280 * interworkingService or bsstransition bit is set to 1.
14281 * Driver is only interested in interworkingService and
14282 * bsstransition capability from supplicant.
14283 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014284 * required from supplicat, it needs to be handled while
14285 * sending Assoc Req in LIM.
14286 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014287 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014288 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014289 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014290 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014291 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014292
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014293 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014294 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014295 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14296 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014297 VOS_ASSERT(0);
14298 return -ENOMEM;
14299 }
14300 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14301 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014302
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014303 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14304 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14305 break;
14306 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014307#ifdef FEATURE_WLAN_WAPI
14308 case WLAN_EID_WAPI:
14309 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014310 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 pAdapter->wapi_info.nWapiMode);
14312 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014313 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 akmsuiteCount = WPA_GET_LE16(tmp);
14315 tmp = tmp + 1;
14316 akmlist = (int *)(tmp);
14317 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14318 {
14319 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14320 }
14321 else
14322 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014323 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 VOS_ASSERT(0);
14325 return -EINVAL;
14326 }
14327
14328 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14329 {
14330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014331 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014332 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014334 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014335 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014337 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014338 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14339 }
14340 break;
14341#endif
14342 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014343 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014344 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014345 /* when Unknown IE is received we should break and continue
14346 * to the next IE in the buffer instead we were returning
14347 * so changing this to break */
14348 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 }
14350 genie += eLen;
14351 remLen -= eLen;
14352 }
14353 EXIT();
14354 return 0;
14355}
14356
14357/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014358 * FUNCTION: hdd_isWPAIEPresent
14359 * Parse the received IE to find the WPA IE
14360 *
14361 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014362static bool hdd_isWPAIEPresent(
14363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14364 const u8 *ie,
14365#else
14366 u8 *ie,
14367#endif
14368 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014369{
14370 v_U8_t eLen = 0;
14371 v_U16_t remLen = ie_len;
14372 v_U8_t elementId = 0;
14373
14374 while (remLen >= 2)
14375 {
14376 elementId = *ie++;
14377 eLen = *ie++;
14378 remLen -= 2;
14379 if (eLen > remLen)
14380 {
14381 hddLog(VOS_TRACE_LEVEL_ERROR,
14382 "%s: IE length is wrong %d", __func__, eLen);
14383 return FALSE;
14384 }
14385 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14386 {
14387 /* OUI - 0x00 0X50 0XF2
14388 WPA Information Element - 0x01
14389 WPA version - 0x01*/
14390 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14391 return TRUE;
14392 }
14393 ie += eLen;
14394 remLen -= eLen;
14395 }
14396 return FALSE;
14397}
14398
14399/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014401 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014402 * parameters during connect operation.
14403 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014404int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014406 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014407{
14408 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 ENTER();
14411
14412 /*set wpa version*/
14413 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14414
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014417 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 {
14419 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14420 }
14421 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14422 {
14423 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14424 }
14425 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014426
14427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014428 pWextState->wpaVersion);
14429
14430 /*set authentication type*/
14431 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14432
14433 if (0 > status)
14434 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014435 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014436 "%s: failed to set authentication type ", __func__);
14437 return status;
14438 }
14439
14440 /*set key mgmt type*/
14441 if (req->crypto.n_akm_suites)
14442 {
14443 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14444 if (0 > status)
14445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014447 __func__);
14448 return status;
14449 }
14450 }
14451
14452 /*set pairwise cipher type*/
14453 if (req->crypto.n_ciphers_pairwise)
14454 {
14455 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14456 req->crypto.ciphers_pairwise[0], true);
14457 if (0 > status)
14458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014459 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 "%s: failed to set unicast cipher type", __func__);
14461 return status;
14462 }
14463 }
14464 else
14465 {
14466 /*Reset previous cipher suite to none*/
14467 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14468 if (0 > status)
14469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014470 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014471 "%s: failed to set unicast cipher type", __func__);
14472 return status;
14473 }
14474 }
14475
14476 /*set group cipher type*/
14477 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14478 false);
14479
14480 if (0 > status)
14481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 __func__);
14484 return status;
14485 }
14486
Chet Lanctot186b5732013-03-18 10:26:30 -070014487#ifdef WLAN_FEATURE_11W
14488 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14489#endif
14490
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14492 if (req->ie_len)
14493 {
14494 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14495 if ( 0 > status)
14496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 __func__);
14499 return status;
14500 }
14501 }
14502
14503 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014504 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 {
14506 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14507 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14508 )
14509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014510 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 __func__);
14515 return -EOPNOTSUPP;
14516 }
14517 else
14518 {
14519 u8 key_len = req->key_len;
14520 u8 key_idx = req->key_idx;
14521
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014522 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 && (CSR_MAX_NUM_KEY > key_idx)
14524 )
14525 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526 hddLog(VOS_TRACE_LEVEL_INFO,
14527 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 __func__, key_idx, key_len);
14529 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014530 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014532 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 (u8)key_len;
14534 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14535 }
14536 }
14537 }
14538 }
14539
14540 return status;
14541}
14542
14543/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014544 * FUNCTION: wlan_hdd_try_disconnect
14545 * This function is used to disconnect from previous
14546 * connection
14547 */
14548static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14549{
14550 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014551 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014552 hdd_station_ctx_t *pHddStaCtx;
14553 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014554 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014555
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014556 ret = wlan_hdd_validate_context(pHddCtx);
14557 if (0 != ret)
14558 {
14559 return ret;
14560 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014561 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14562
14563 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14564
14565 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14566 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014567 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014568 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14569 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014570 spin_lock_bh(&pAdapter->lock_for_active_session);
14571 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14572 {
14573 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14574 }
14575 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014576 hdd_connSetConnectionState(pHddStaCtx,
14577 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014578 /* Issue disconnect to CSR */
14579 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014580 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014581 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014582 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14583 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14584 hddLog(LOG1,
14585 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14586 } else if ( 0 != status ) {
14587 hddLog(LOGE,
14588 FL("csrRoamDisconnect failure, returned %d"),
14589 (int)status );
14590 result = -EINVAL;
14591 goto disconnected;
14592 }
14593 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014594 &pAdapter->disconnect_comp_var,
14595 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014596 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14597 hddLog(LOGE,
14598 "%s: Failed to disconnect, timed out", __func__);
14599 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014600 }
14601 }
14602 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14603 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014604 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014605 &pAdapter->disconnect_comp_var,
14606 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014607 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014608 {
14609 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014610 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014611 }
14612 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014613disconnected:
14614 hddLog(LOG1,
14615 FL("Set HDD connState to eConnectionState_NotConnected"));
14616 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14617 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014618}
14619
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014620/**
14621 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14622 * @adapter: Pointer to the HDD adapter
14623 * @req: Pointer to the structure cfg_connect_params receieved from user space
14624 *
14625 * This function will start reassociation if bssid hint, channel hint and
14626 * previous bssid parameters are present in the connect request
14627 *
14628 * Return: success if reassociation is happening
14629 * Error code if reassociation is not permitted or not happening
14630 */
14631#ifdef CFG80211_CONNECT_PREV_BSSID
14632static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14633 struct cfg80211_connect_params *req)
14634{
14635 int status = -EPERM;
14636 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14637 hddLog(VOS_TRACE_LEVEL_INFO,
14638 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14639 req->channel_hint->hw_value,
14640 MAC_ADDR_ARRAY(req->bssid_hint));
14641 status = hdd_reassoc(adapter, req->bssid_hint,
14642 req->channel_hint->hw_value,
14643 CONNECT_CMD_USERSPACE);
14644 }
14645 return status;
14646}
14647#else
14648static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14649 struct cfg80211_connect_params *req)
14650{
14651 return -EPERM;
14652}
14653#endif
14654
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014655/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014656 * FUNCTION: __wlan_hdd_cfg80211_connect
14657 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014658 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014659static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 struct net_device *ndev,
14661 struct cfg80211_connect_params *req
14662 )
14663{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014664 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014665 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14667 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014668 const u8 *bssid_hint = req->bssid_hint;
14669#else
14670 const u8 *bssid_hint = NULL;
14671#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014673 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014674 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014675
14676 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014677
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014678 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14679 TRACE_CODE_HDD_CFG80211_CONNECT,
14680 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014681 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014682 "%s: device_mode = %s (%d)", __func__,
14683 hdd_device_modetoString(pAdapter->device_mode),
14684 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014685
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014686 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014687 if (!pHddCtx)
14688 {
14689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14690 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014691 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014692 }
14693
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014694 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014695 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014697 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 }
14699
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014700 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14701 if (0 == status)
14702 return status;
14703
Agarwal Ashish51325b52014-06-16 16:50:49 +053014704
Jeff Johnson295189b2012-06-20 16:38:30 -070014705#ifdef WLAN_BTAMP_FEATURE
14706 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014707 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014709 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014710 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014711 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014712 }
14713#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014714
14715 //If Device Mode is Station Concurrent Sessions Exit BMps
14716 //P2P Mode will be taken care in Open/close adapter
14717 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014718 (vos_concurrent_open_sessions_running())) {
14719 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14720 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014721 }
14722
14723 /*Try disconnecting if already in connected state*/
14724 status = wlan_hdd_try_disconnect(pAdapter);
14725 if ( 0 > status)
14726 {
14727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14728 " connection"));
14729 return -EALREADY;
14730 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014731 /* Check for max concurrent connections after doing disconnect if any*/
14732 if (vos_max_concurrent_connections_reached()) {
14733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14734 return -ECONNREFUSED;
14735 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014736
Jeff Johnson295189b2012-06-20 16:38:30 -070014737 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014738 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014739
14740 if ( 0 > status)
14741 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014743 __func__);
14744 return status;
14745 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014746
14747 if (pHddCtx->spoofMacAddr.isEnabled)
14748 {
14749 hddLog(VOS_TRACE_LEVEL_INFO,
14750 "%s: MAC Spoofing enabled ", __func__);
14751 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14752 * to fill TxBds for probe request during SSID scan which may happen
14753 * as part of connect command
14754 */
14755 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14756 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14757 if (status != VOS_STATUS_SUCCESS)
14758 return -ECONNREFUSED;
14759 }
14760
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014761 if (req->channel)
14762 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014763 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014764 channel = 0;
14765 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14766 req->ssid_len, req->bssid,
14767 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014768
Sushant Kaushikd7083982015-03-18 14:33:24 +053014769 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014770 {
14771 //ReEnable BMPS if disabled
14772 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14773 (NULL != pHddCtx))
14774 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014775 if (pHddCtx->hdd_wlan_suspended)
14776 {
14777 hdd_set_pwrparams(pHddCtx);
14778 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 //ReEnable Bmps and Imps back
14780 hdd_enable_bmps_imps(pHddCtx);
14781 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014783 return status;
14784 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014785 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014786 EXIT();
14787 return status;
14788}
14789
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014790static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14791 struct net_device *ndev,
14792 struct cfg80211_connect_params *req)
14793{
14794 int ret;
14795 vos_ssr_protect(__func__);
14796 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14797 vos_ssr_unprotect(__func__);
14798
14799 return ret;
14800}
Jeff Johnson295189b2012-06-20 16:38:30 -070014801
14802/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014803 * FUNCTION: wlan_hdd_disconnect
14804 * This function is used to issue a disconnect request to SME
14805 */
14806int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14807{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014808 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014810 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014811 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014813 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014814
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014815 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014816 if (0 != status)
14817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014818 return status;
14819 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014820 /* Indicate sme of disconnect so that in progress connection or preauth
14821 * can be aborted
14822 */
14823 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014824 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014825 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014826
Agarwal Ashish47d18112014-08-04 19:55:07 +053014827 /* Need to apply spin lock before decreasing active sessions
14828 * as there can be chance for double decrement if context switch
14829 * Calls hdd_DisConnectHandler.
14830 */
14831
14832 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014833 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14834 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014835 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14836 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014837 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14838 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014839
Abhishek Singhf4669da2014-05-26 15:07:49 +053014840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014841 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14842
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014843 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014844
Mihir Shete182a0b22014-08-18 16:08:48 +053014845 /*
14846 * stop tx queues before deleting STA/BSS context from the firmware.
14847 * tx has to be disabled because the firmware can get busy dropping
14848 * the tx frames after BSS/STA has been deleted and will not send
14849 * back a response resulting in WDI timeout
14850 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014851 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014852 netif_tx_disable(pAdapter->dev);
14853 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014854
Mihir Shete182a0b22014-08-18 16:08:48 +053014855 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014856 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14857 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014858 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14859 {
14860 hddLog(LOG1,
14861 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014862 }
14863 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014864 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014865 hddLog(LOGE,
14866 FL("csrRoamDisconnect failure, returned %d"),
14867 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014868 result = -EINVAL;
14869 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014870 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014871 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014872 &pAdapter->disconnect_comp_var,
14873 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014874 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014875 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014876 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014877 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014878 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014879 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014880disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014881 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014882 FL("Set HDD connState to eConnectionState_NotConnected"));
14883 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014884#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14885 /* Sending disconnect event to userspace for kernel version < 3.11
14886 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14887 */
14888 hddLog(LOG1, FL("Send disconnected event to userspace"));
14889
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014890 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014891 WLAN_REASON_UNSPECIFIED);
14892#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014893
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014894 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014895 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014896}
14897
14898
14899/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014900 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014901 * This function is used to issue a disconnect request to SME
14902 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014903static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 struct net_device *dev,
14905 u16 reason
14906 )
14907{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014909 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014910 tCsrRoamProfile *pRoamProfile;
14911 hdd_station_ctx_t *pHddStaCtx;
14912 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014913#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014914 tANI_U8 staIdx;
14915#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014916
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014918
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014919 if (!pAdapter) {
14920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14921 return -EINVAL;
14922 }
14923
14924 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14925 if (!pHddStaCtx) {
14926 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14927 return -EINVAL;
14928 }
14929
14930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14931 status = wlan_hdd_validate_context(pHddCtx);
14932 if (0 != status)
14933 {
14934 return status;
14935 }
14936
14937 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14938
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14940 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14941 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14943 __func__, hdd_device_modetoString(pAdapter->device_mode),
14944 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014945
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014946 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14947 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014948
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 if (NULL != pRoamProfile)
14950 {
14951 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014952 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14953 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014955 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014957 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 switch(reason)
14959 {
14960 case WLAN_REASON_MIC_FAILURE:
14961 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14962 break;
14963
14964 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14965 case WLAN_REASON_DISASSOC_AP_BUSY:
14966 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14967 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14968 break;
14969
14970 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14971 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014972 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14974 break;
14975
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 default:
14977 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14978 break;
14979 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014980 pScanInfo = &pHddCtx->scan_info;
14981 if (pScanInfo->mScanPending)
14982 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014983 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014984 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014985 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014986 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014987 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014988 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014989#ifdef FEATURE_WLAN_TDLS
14990 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014991 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014992 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014993 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14994 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014995 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014996 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014997 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014999 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015000 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015001 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015002 status = sme_DeleteTdlsPeerSta(
15003 WLAN_HDD_GET_HAL_CTX(pAdapter),
15004 pAdapter->sessionId,
15005 mac);
15006 if (status != eHAL_STATUS_SUCCESS) {
15007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15008 return -EPERM;
15009 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015010 }
15011 }
15012#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015013 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015014 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15015 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 {
15017 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015018 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 __func__, (int)status );
15020 return -EINVAL;
15021 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015023 else
15024 {
15025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15026 "called while in %d state", __func__,
15027 pHddStaCtx->conn_info.connState);
15028 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 }
15030 else
15031 {
15032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15033 }
15034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015035 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015036 return status;
15037}
15038
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015039static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15040 struct net_device *dev,
15041 u16 reason
15042 )
15043{
15044 int ret;
15045 vos_ssr_protect(__func__);
15046 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15047 vos_ssr_unprotect(__func__);
15048
15049 return ret;
15050}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015051
Jeff Johnson295189b2012-06-20 16:38:30 -070015052/*
15053 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015054 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 * settings in IBSS mode.
15056 */
15057static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015058 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015059 struct cfg80211_ibss_params *params
15060 )
15061{
15062 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015063 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015064 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15065 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015066
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 ENTER();
15068
15069 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015070 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015071
15072 if (params->ie_len && ( NULL != params->ie) )
15073 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015074 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15075 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 {
15077 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15078 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15079 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015080 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015082 tDot11fIEWPA dot11WPAIE;
15083 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015084 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015085
Wilson Yang00256342013-10-10 23:13:38 -070015086 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015087 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15088 params->ie_len, DOT11F_EID_WPA);
15089 if ( NULL != ie )
15090 {
15091 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15092 // Unpack the WPA IE
15093 //Skip past the EID byte and length byte - and four byte WiFi OUI
15094 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15095 &ie[2+4],
15096 ie[1] - 4,
15097 &dot11WPAIE);
15098 /*Extract the multicast cipher, the encType for unicast
15099 cipher for wpa-none is none*/
15100 encryptionType =
15101 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015103 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015104
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15106
15107 if (0 > status)
15108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 __func__);
15111 return status;
15112 }
15113 }
15114
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015115 pWextState->roamProfile.AuthType.authType[0] =
15116 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15118
15119 if (params->privacy)
15120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015121 /* Security enabled IBSS, At this time there is no information available
15122 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015123 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015124 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015125 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015126 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015127 *enable privacy bit in beacons */
15128
15129 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15130 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015131 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15132 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015133 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15134 pWextState->roamProfile.EncryptionType.numEntries = 1;
15135 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 return status;
15137}
15138
15139/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015140 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015141 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015142 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015143static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015144 struct net_device *dev,
15145 struct cfg80211_ibss_params *params
15146 )
15147{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015149 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15150 tCsrRoamProfile *pRoamProfile;
15151 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15153 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015154 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015155
15156 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15159 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15160 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015162 "%s: device_mode = %s (%d)", __func__,
15163 hdd_device_modetoString(pAdapter->device_mode),
15164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015165
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015166 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015167 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015168 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015169 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015170 }
15171
15172 if (NULL == pWextState)
15173 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015174 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015175 __func__);
15176 return -EIO;
15177 }
15178
Agarwal Ashish51325b52014-06-16 16:50:49 +053015179 if (vos_max_concurrent_connections_reached()) {
15180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15181 return -ECONNREFUSED;
15182 }
15183
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015184 /*Try disconnecting if already in connected state*/
15185 status = wlan_hdd_try_disconnect(pAdapter);
15186 if ( 0 > status)
15187 {
15188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15189 " IBSS connection"));
15190 return -EALREADY;
15191 }
15192
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 pRoamProfile = &pWextState->roamProfile;
15194
15195 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015197 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015198 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015199 return -EINVAL;
15200 }
15201
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015202 /* BSSID is provided by upper layers hence no need to AUTO generate */
15203 if (NULL != params->bssid) {
15204 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15205 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15206 hddLog (VOS_TRACE_LEVEL_ERROR,
15207 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15208 return -EIO;
15209 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015210 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015211 }
krunal sonie9002db2013-11-25 14:24:17 -080015212 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15213 {
15214 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15215 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15216 {
15217 hddLog (VOS_TRACE_LEVEL_ERROR,
15218 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15219 return -EIO;
15220 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015221
15222 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015223 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015224 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015225 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015226
Jeff Johnson295189b2012-06-20 16:38:30 -070015227 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015228 if (NULL !=
15229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15230 params->chandef.chan)
15231#else
15232 params->channel)
15233#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 {
15235 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015236 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15237 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15238 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15239 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015240
15241 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015242 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015243 ieee80211_frequency_to_channel(
15244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15245 params->chandef.chan->center_freq);
15246#else
15247 params->channel->center_freq);
15248#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015249
15250 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15251 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015252 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15254 __func__);
15255 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015256 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015257
15258 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015260 if (channelNum == validChan[indx])
15261 {
15262 break;
15263 }
15264 }
15265 if (indx >= numChans)
15266 {
15267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 __func__, channelNum);
15269 return -EINVAL;
15270 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015271 /* Set the Operational Channel */
15272 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15273 channelNum);
15274 pRoamProfile->ChannelInfo.numOfChannels = 1;
15275 pHddStaCtx->conn_info.operationChannel = channelNum;
15276 pRoamProfile->ChannelInfo.ChannelList =
15277 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 }
15279
15280 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 if (status < 0)
15283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015284 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 __func__);
15286 return status;
15287 }
15288
15289 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015290 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015291 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015292 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015293
15294 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015297 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015298 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015299}
15300
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015301static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15302 struct net_device *dev,
15303 struct cfg80211_ibss_params *params
15304 )
15305{
15306 int ret = 0;
15307
15308 vos_ssr_protect(__func__);
15309 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15310 vos_ssr_unprotect(__func__);
15311
15312 return ret;
15313}
15314
Jeff Johnson295189b2012-06-20 16:38:30 -070015315/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015316 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015317 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015318 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015319static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015320 struct net_device *dev
15321 )
15322{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015323 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015324 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15325 tCsrRoamProfile *pRoamProfile;
15326 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015327 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015328#ifdef WLAN_FEATURE_RMC
15329 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15330#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015331
15332 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015333
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15335 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15336 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015337 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015338 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015339 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015340 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015341 }
15342
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15344 hdd_device_modetoString(pAdapter->device_mode),
15345 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 if (NULL == pWextState)
15347 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015348 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 __func__);
15350 return -EIO;
15351 }
15352
15353 pRoamProfile = &pWextState->roamProfile;
15354
15355 /* Issue disconnect only if interface type is set to IBSS */
15356 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15357 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015358 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015359 __func__);
15360 return -EINVAL;
15361 }
15362
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015363#ifdef WLAN_FEATURE_RMC
15364 /* Clearing add IE of beacon */
15365 if (ccmCfgSetStr(pHddCtx->hHal,
15366 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15367 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15368 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15369 {
15370 hddLog (VOS_TRACE_LEVEL_ERROR,
15371 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15372 return -EINVAL;
15373 }
15374 if (ccmCfgSetInt(pHddCtx->hHal,
15375 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15376 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15377 {
15378 hddLog (VOS_TRACE_LEVEL_ERROR,
15379 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15380 __func__);
15381 return -EINVAL;
15382 }
15383
15384 // Reset WNI_CFG_PROBE_RSP Flags
15385 wlan_hdd_reset_prob_rspies(pAdapter);
15386
15387 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15388 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15389 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15390 {
15391 hddLog (VOS_TRACE_LEVEL_ERROR,
15392 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15393 __func__);
15394 return -EINVAL;
15395 }
15396#endif
15397
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 /* Issue Disconnect request */
15399 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15400 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15401 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015403 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015404 return 0;
15405}
15406
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015407static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15408 struct net_device *dev
15409 )
15410{
15411 int ret = 0;
15412
15413 vos_ssr_protect(__func__);
15414 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15415 vos_ssr_unprotect(__func__);
15416
15417 return ret;
15418}
15419
Jeff Johnson295189b2012-06-20 16:38:30 -070015420/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015421 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 * This function is used to set the phy parameters
15423 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15424 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015425static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015426 u32 changed)
15427{
15428 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15429 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015430 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015431
15432 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015433
15434 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015435 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15436 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015437
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015438 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015439 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015440 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015441 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015442 }
15443
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15445 {
15446 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15447 WNI_CFG_RTS_THRESHOLD_STAMAX :
15448 wiphy->rts_threshold;
15449
15450 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015451 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453 hddLog(VOS_TRACE_LEVEL_ERROR,
15454 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 __func__, rts_threshold);
15456 return -EINVAL;
15457 }
15458
15459 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15460 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015461 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015463 hddLog(VOS_TRACE_LEVEL_ERROR,
15464 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015465 __func__, rts_threshold);
15466 return -EIO;
15467 }
15468
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015469 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015470 rts_threshold);
15471 }
15472
15473 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15474 {
15475 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15476 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15477 wiphy->frag_threshold;
15478
15479 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015482 hddLog(VOS_TRACE_LEVEL_ERROR,
15483 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 frag_threshold);
15485 return -EINVAL;
15486 }
15487
15488 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15489 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015490 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015492 hddLog(VOS_TRACE_LEVEL_ERROR,
15493 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015494 __func__, frag_threshold);
15495 return -EIO;
15496 }
15497
15498 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15499 frag_threshold);
15500 }
15501
15502 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15503 || (changed & WIPHY_PARAM_RETRY_LONG))
15504 {
15505 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15506 wiphy->retry_short :
15507 wiphy->retry_long;
15508
15509 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15510 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15511 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015513 __func__, retry_value);
15514 return -EINVAL;
15515 }
15516
15517 if (changed & WIPHY_PARAM_RETRY_SHORT)
15518 {
15519 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15520 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015521 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015523 hddLog(VOS_TRACE_LEVEL_ERROR,
15524 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 __func__, retry_value);
15526 return -EIO;
15527 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015528 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015529 __func__, retry_value);
15530 }
15531 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15532 {
15533 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15534 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015535 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015536 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015537 hddLog(VOS_TRACE_LEVEL_ERROR,
15538 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 __func__, retry_value);
15540 return -EIO;
15541 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015542 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015543 __func__, retry_value);
15544 }
15545 }
15546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015547 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015548 return 0;
15549}
15550
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015551static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15552 u32 changed)
15553{
15554 int ret;
15555
15556 vos_ssr_protect(__func__);
15557 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15558 vos_ssr_unprotect(__func__);
15559
15560 return ret;
15561}
15562
Jeff Johnson295189b2012-06-20 16:38:30 -070015563/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015564 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015565 * This function is used to set the txpower
15566 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015567static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015568#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15569 struct wireless_dev *wdev,
15570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015571#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015572 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015573#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015574 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015575#endif
15576 int dbm)
15577{
15578 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015579 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015580 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15581 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015582 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015583
15584 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015585
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015586 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15587 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15588 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015589 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015590 if (0 != status)
15591 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015592 return status;
15593 }
15594
15595 hHal = pHddCtx->hHal;
15596
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015597 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15598 dbm, ccmCfgSetCallback,
15599 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015601 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015602 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15603 return -EIO;
15604 }
15605
15606 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15607 dbm);
15608
15609 switch(type)
15610 {
15611 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15612 /* Fall through */
15613 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15614 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15615 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15617 __func__);
15618 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015619 }
15620 break;
15621 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015623 __func__);
15624 return -EOPNOTSUPP;
15625 break;
15626 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15628 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015629 return -EIO;
15630 }
15631
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015632 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015633 return 0;
15634}
15635
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015636static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15637#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15638 struct wireless_dev *wdev,
15639#endif
15640#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15641 enum tx_power_setting type,
15642#else
15643 enum nl80211_tx_power_setting type,
15644#endif
15645 int dbm)
15646{
15647 int ret;
15648 vos_ssr_protect(__func__);
15649 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15650#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15651 wdev,
15652#endif
15653#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15654 type,
15655#else
15656 type,
15657#endif
15658 dbm);
15659 vos_ssr_unprotect(__func__);
15660
15661 return ret;
15662}
15663
Jeff Johnson295189b2012-06-20 16:38:30 -070015664/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015665 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 * This function is used to read the txpower
15667 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015668static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015669#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15670 struct wireless_dev *wdev,
15671#endif
15672 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015673{
15674
15675 hdd_adapter_t *pAdapter;
15676 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015677 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015678
Jeff Johnsone7245742012-09-05 17:12:55 -070015679 ENTER();
15680
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015681 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015682 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015683 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015684 *dbm = 0;
15685 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015686 }
15687
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15689 if (NULL == pAdapter)
15690 {
15691 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15692 return -ENOENT;
15693 }
15694
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015695 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15696 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15697 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015698 wlan_hdd_get_classAstats(pAdapter);
15699 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15700
Jeff Johnsone7245742012-09-05 17:12:55 -070015701 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 return 0;
15703}
15704
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015705static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15706#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15707 struct wireless_dev *wdev,
15708#endif
15709 int *dbm)
15710{
15711 int ret;
15712
15713 vos_ssr_protect(__func__);
15714 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15715#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15716 wdev,
15717#endif
15718 dbm);
15719 vos_ssr_unprotect(__func__);
15720
15721 return ret;
15722}
15723
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015724static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15726 const u8* mac,
15727#else
15728 u8* mac,
15729#endif
15730 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015731{
15732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15733 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15734 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015735 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015736
15737 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15738 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015739
15740 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15741 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15742 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15743 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15744 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15745 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15746 tANI_U16 maxRate = 0;
15747 tANI_U16 myRate;
15748 tANI_U16 currentRate = 0;
15749 tANI_U8 maxSpeedMCS = 0;
15750 tANI_U8 maxMCSIdx = 0;
15751 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015752 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015753 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015754 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015755
Leo Chang6f8870f2013-03-26 18:11:36 -070015756#ifdef WLAN_FEATURE_11AC
15757 tANI_U32 vht_mcs_map;
15758 eDataRate11ACMaxMcs vhtMaxMcs;
15759#endif /* WLAN_FEATURE_11AC */
15760
Jeff Johnsone7245742012-09-05 17:12:55 -070015761 ENTER();
15762
Jeff Johnson295189b2012-06-20 16:38:30 -070015763 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15764 (0 == ssidlen))
15765 {
15766 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15767 " Invalid ssidlen, %d", __func__, ssidlen);
15768 /*To keep GUI happy*/
15769 return 0;
15770 }
15771
Mukul Sharma811205f2014-07-09 21:07:30 +053015772 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15773 {
15774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15775 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015776 /* return a cached value */
15777 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015778 return 0;
15779 }
15780
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015781 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015782 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015783 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015784 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015785 }
15786
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015787 wlan_hdd_get_station_stats(pAdapter);
15788 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015789
Kiet Lam3b17fc82013-09-27 05:24:08 +053015790 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15791 sinfo->filled |= STATION_INFO_SIGNAL;
15792
c_hpothu09f19542014-05-30 21:53:31 +053015793 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015794 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15795 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015796 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015797 {
15798 rate_flags = pAdapter->maxRateFlags;
15799 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015800
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 //convert to the UI units of 100kbps
15802 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15803
15804#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015805 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 -070015806 sinfo->signal,
15807 pCfg->reportMaxLinkSpeed,
15808 myRate,
15809 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015810 (int) pCfg->linkSpeedRssiMid,
15811 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015812 (int) rate_flags,
15813 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015814#endif //LINKSPEED_DEBUG_ENABLED
15815
15816 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15817 {
15818 // we do not want to necessarily report the current speed
15819 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15820 {
15821 // report the max possible speed
15822 rssidx = 0;
15823 }
15824 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15825 {
15826 // report the max possible speed with RSSI scaling
15827 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15828 {
15829 // report the max possible speed
15830 rssidx = 0;
15831 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015832 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015833 {
15834 // report middle speed
15835 rssidx = 1;
15836 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015837 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15838 {
15839 // report middle speed
15840 rssidx = 2;
15841 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 else
15843 {
15844 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015845 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015846 }
15847 }
15848 else
15849 {
15850 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15851 hddLog(VOS_TRACE_LEVEL_ERROR,
15852 "%s: Invalid value for reportMaxLinkSpeed: %u",
15853 __func__, pCfg->reportMaxLinkSpeed);
15854 rssidx = 0;
15855 }
15856
15857 maxRate = 0;
15858
15859 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015860 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15861 OperationalRates, &ORLeng))
15862 {
15863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15864 /*To keep GUI happy*/
15865 return 0;
15866 }
15867
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 for (i = 0; i < ORLeng; i++)
15869 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015870 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015871 {
15872 /* Validate Rate Set */
15873 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15874 {
15875 currentRate = supported_data_rate[j].supported_rate[rssidx];
15876 break;
15877 }
15878 }
15879 /* Update MAX rate */
15880 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15881 }
15882
15883 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015884 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15885 ExtendedRates, &ERLeng))
15886 {
15887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15888 /*To keep GUI happy*/
15889 return 0;
15890 }
15891
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 for (i = 0; i < ERLeng; i++)
15893 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015894 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 {
15896 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15897 {
15898 currentRate = supported_data_rate[j].supported_rate[rssidx];
15899 break;
15900 }
15901 }
15902 /* Update MAX rate */
15903 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15904 }
c_hpothu79aab322014-07-14 21:11:01 +053015905
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015906 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015907 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015908 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015909 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 {
c_hpothu79aab322014-07-14 21:11:01 +053015911 if (rate_flags & eHAL_TX_RATE_VHT80)
15912 mode = 2;
15913 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15914 mode = 1;
15915 else
15916 mode = 0;
15917
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015918 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15919 MCSRates, &MCSLeng))
15920 {
15921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15922 /*To keep GUI happy*/
15923 return 0;
15924 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015926#ifdef WLAN_FEATURE_11AC
15927 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015928 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015929 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015930 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015931 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015932 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015934 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015935 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015936 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015938 maxMCSIdx = 7;
15939 }
15940 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15941 {
15942 maxMCSIdx = 8;
15943 }
15944 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15945 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015946 //VHT20 is supporting 0~8
15947 if (rate_flags & eHAL_TX_RATE_VHT20)
15948 maxMCSIdx = 8;
15949 else
15950 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015951 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015952
c_hpothu79aab322014-07-14 21:11:01 +053015953 if (0 != rssidx)/*check for scaled */
15954 {
15955 //get middle rate MCS index if rssi=1/2
15956 for (i=0; i <= maxMCSIdx; i++)
15957 {
15958 if (sinfo->signal <= rssiMcsTbl[mode][i])
15959 {
15960 maxMCSIdx = i;
15961 break;
15962 }
15963 }
15964 }
15965
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015966 if (rate_flags & eHAL_TX_RATE_VHT80)
15967 {
15968 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15969 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15970 }
15971 else if (rate_flags & eHAL_TX_RATE_VHT40)
15972 {
15973 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15974 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15975 }
15976 else if (rate_flags & eHAL_TX_RATE_VHT20)
15977 {
15978 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15979 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15980 }
15981
Leo Chang6f8870f2013-03-26 18:11:36 -070015982 maxSpeedMCS = 1;
15983 if (currentRate > maxRate)
15984 {
15985 maxRate = currentRate;
15986 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015987
Leo Chang6f8870f2013-03-26 18:11:36 -070015988 }
15989 else
15990#endif /* WLAN_FEATURE_11AC */
15991 {
15992 if (rate_flags & eHAL_TX_RATE_HT40)
15993 {
15994 rateFlag |= 1;
15995 }
15996 if (rate_flags & eHAL_TX_RATE_SGI)
15997 {
15998 rateFlag |= 2;
15999 }
16000
Girish Gowli01abcee2014-07-31 20:18:55 +053016001 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016002 if (rssidx == 1 || rssidx == 2)
16003 {
16004 //get middle rate MCS index if rssi=1/2
16005 for (i=0; i <= 7; i++)
16006 {
16007 if (sinfo->signal <= rssiMcsTbl[mode][i])
16008 {
16009 temp = i+1;
16010 break;
16011 }
16012 }
16013 }
c_hpothu79aab322014-07-14 21:11:01 +053016014
16015 for (i = 0; i < MCSLeng; i++)
16016 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016017 for (j = 0; j < temp; j++)
16018 {
16019 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16020 {
16021 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016022 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016023 break;
16024 }
16025 }
16026 if ((j < temp) && (currentRate > maxRate))
16027 {
16028 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016029 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016031 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016032 }
16033 }
16034
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016035 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16036 {
16037 maxRate = myRate;
16038 maxSpeedMCS = 1;
16039 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16040 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016042 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 {
16044 maxRate = myRate;
16045 if (rate_flags & eHAL_TX_RATE_LEGACY)
16046 {
16047 maxSpeedMCS = 0;
16048 }
16049 else
16050 {
16051 maxSpeedMCS = 1;
16052 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16053 }
16054 }
16055
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016056 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016057 {
16058 sinfo->txrate.legacy = maxRate;
16059#ifdef LINKSPEED_DEBUG_ENABLED
16060 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16061#endif //LINKSPEED_DEBUG_ENABLED
16062 }
16063 else
16064 {
16065 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016066#ifdef WLAN_FEATURE_11AC
16067 sinfo->txrate.nss = 1;
16068 if (rate_flags & eHAL_TX_RATE_VHT80)
16069 {
16070 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016071 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016072 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016073 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016074 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016075 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16076 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16077 }
16078 else if (rate_flags & eHAL_TX_RATE_VHT20)
16079 {
16080 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16081 }
16082#endif /* WLAN_FEATURE_11AC */
16083 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16084 {
16085 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16086 if (rate_flags & eHAL_TX_RATE_HT40)
16087 {
16088 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16089 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016090 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 if (rate_flags & eHAL_TX_RATE_SGI)
16092 {
16093 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16094 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016095
Jeff Johnson295189b2012-06-20 16:38:30 -070016096#ifdef LINKSPEED_DEBUG_ENABLED
16097 pr_info("Reporting MCS rate %d flags %x\n",
16098 sinfo->txrate.mcs,
16099 sinfo->txrate.flags );
16100#endif //LINKSPEED_DEBUG_ENABLED
16101 }
16102 }
16103 else
16104 {
16105 // report current rate instead of max rate
16106
16107 if (rate_flags & eHAL_TX_RATE_LEGACY)
16108 {
16109 //provide to the UI in units of 100kbps
16110 sinfo->txrate.legacy = myRate;
16111#ifdef LINKSPEED_DEBUG_ENABLED
16112 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16113#endif //LINKSPEED_DEBUG_ENABLED
16114 }
16115 else
16116 {
16117 //must be MCS
16118 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016119#ifdef WLAN_FEATURE_11AC
16120 sinfo->txrate.nss = 1;
16121 if (rate_flags & eHAL_TX_RATE_VHT80)
16122 {
16123 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16124 }
16125 else
16126#endif /* WLAN_FEATURE_11AC */
16127 {
16128 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 if (rate_flags & eHAL_TX_RATE_SGI)
16131 {
16132 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16133 }
16134 if (rate_flags & eHAL_TX_RATE_HT40)
16135 {
16136 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16137 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016138#ifdef WLAN_FEATURE_11AC
16139 else if (rate_flags & eHAL_TX_RATE_VHT80)
16140 {
16141 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16142 }
16143#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016144#ifdef LINKSPEED_DEBUG_ENABLED
16145 pr_info("Reporting actual MCS rate %d flags %x\n",
16146 sinfo->txrate.mcs,
16147 sinfo->txrate.flags );
16148#endif //LINKSPEED_DEBUG_ENABLED
16149 }
16150 }
16151 sinfo->filled |= STATION_INFO_TX_BITRATE;
16152
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016153 sinfo->tx_packets =
16154 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16155 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16156 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16157 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16158
16159 sinfo->tx_retries =
16160 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16161 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16162 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16163 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16164
16165 sinfo->tx_failed =
16166 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16167 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16168 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16169 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16170
16171 sinfo->filled |=
16172 STATION_INFO_TX_PACKETS |
16173 STATION_INFO_TX_RETRIES |
16174 STATION_INFO_TX_FAILED;
16175
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016176 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16177 sinfo->filled |= STATION_INFO_RX_PACKETS;
16178
16179 if (rate_flags & eHAL_TX_RATE_LEGACY)
16180 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16181 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16182 sinfo->rx_packets);
16183 else
16184 hddLog(LOG1,
16185 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16186 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16187 sinfo->tx_packets, sinfo->rx_packets);
16188
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016189 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16190 TRACE_CODE_HDD_CFG80211_GET_STA,
16191 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016192 EXIT();
16193 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016194}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16196static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16197 const u8* mac, struct station_info *sinfo)
16198#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016199static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16200 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016201#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016202{
16203 int ret;
16204
16205 vos_ssr_protect(__func__);
16206 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16207 vos_ssr_unprotect(__func__);
16208
16209 return ret;
16210}
16211
16212static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016213 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016214{
16215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016216 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016218 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016219
Jeff Johnsone7245742012-09-05 17:12:55 -070016220 ENTER();
16221
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 if (NULL == pAdapter)
16223 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016225 return -ENODEV;
16226 }
16227
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16229 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16230 pAdapter->sessionId, timeout));
16231
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016233 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016234 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016235 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016236 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016237 }
16238
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016239 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16240 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16241 (pHddCtx->cfg_ini->fhostArpOffload) &&
16242 (eConnectionState_Associated ==
16243 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16244 {
Amar Singhald53568e2013-09-26 11:03:45 -070016245
16246 hddLog(VOS_TRACE_LEVEL_INFO,
16247 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016248 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016249 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16250 {
16251 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016252 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016253 __func__, vos_status);
16254 }
16255 }
16256
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 /**The get power cmd from the supplicant gets updated by the nl only
16258 *on successful execution of the function call
16259 *we are oppositely mapped w.r.t mode in the driver
16260 **/
16261 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16262
16263 if (VOS_STATUS_E_FAILURE == vos_status)
16264 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16266 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 return -EINVAL;
16268 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016269 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016270 return 0;
16271}
16272
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016273static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16274 struct net_device *dev, bool mode, int timeout)
16275{
16276 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016277
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016278 vos_ssr_protect(__func__);
16279 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16280 vos_ssr_unprotect(__func__);
16281
16282 return ret;
16283}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016284
Jeff Johnson295189b2012-06-20 16:38:30 -070016285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016286static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16287 struct net_device *netdev,
16288 u8 key_index)
16289{
16290 ENTER();
16291 return 0;
16292}
16293
Jeff Johnson295189b2012-06-20 16:38:30 -070016294static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016295 struct net_device *netdev,
16296 u8 key_index)
16297{
16298 int ret;
16299 vos_ssr_protect(__func__);
16300 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16301 vos_ssr_unprotect(__func__);
16302 return ret;
16303}
16304#endif //LINUX_VERSION_CODE
16305
16306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16307static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16308 struct net_device *dev,
16309 struct ieee80211_txq_params *params)
16310{
16311 ENTER();
16312 return 0;
16313}
16314#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16315static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16316 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016317{
Jeff Johnsone7245742012-09-05 17:12:55 -070016318 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016319 return 0;
16320}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016321#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016322
16323#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16324static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016325 struct net_device *dev,
16326 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016327{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016328 int ret;
16329
16330 vos_ssr_protect(__func__);
16331 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16332 vos_ssr_unprotect(__func__);
16333 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016334}
16335#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16336static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16337 struct ieee80211_txq_params *params)
16338{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016339 int ret;
16340
16341 vos_ssr_protect(__func__);
16342 ret = __wlan_hdd_set_txq_params(wiphy, params);
16343 vos_ssr_unprotect(__func__);
16344 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016345}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016347
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016348static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016349 struct net_device *dev,
16350 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016351{
16352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016353 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016354 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016355 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016356 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016357 v_CONTEXT_t pVosContext = NULL;
16358 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016359
Jeff Johnsone7245742012-09-05 17:12:55 -070016360 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016361
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016362 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016365 return -EINVAL;
16366 }
16367
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16369 TRACE_CODE_HDD_CFG80211_DEL_STA,
16370 pAdapter->sessionId, pAdapter->device_mode));
16371
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016372 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016377 }
16378
Jeff Johnson295189b2012-06-20 16:38:30 -070016379 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016380 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016381 )
16382 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016383 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16384 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16385 if(pSapCtx == NULL){
16386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16387 FL("psapCtx is NULL"));
16388 return -ENOENT;
16389 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016390 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016391 {
16392 v_U16_t i;
16393 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16394 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016395 if ((pSapCtx->aStaInfo[i].isUsed) &&
16396 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016397 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016398 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016399 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016400 ETHER_ADDR_LEN);
16401
Jeff Johnson295189b2012-06-20 16:38:30 -070016402 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016403 "%s: Delete STA with MAC::"
16404 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016405 __func__,
16406 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16407 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016408 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016409 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016410 }
16411 }
16412 }
16413 else
16414 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016415
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016416 vos_status = hdd_softap_GetStaId(pAdapter,
16417 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016418 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16419 {
16420 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016421 "%s: Skip this DEL STA as this is not used::"
16422 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016423 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016424 return -ENOENT;
16425 }
16426
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016427 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016428 {
16429 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016430 "%s: Skip this DEL STA as deauth is in progress::"
16431 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016432 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016433 return -ENOENT;
16434 }
16435
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016436 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016437
Jeff Johnson295189b2012-06-20 16:38:30 -070016438 hddLog(VOS_TRACE_LEVEL_INFO,
16439 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016440 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016442 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016443
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016444 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016445 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16446 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016447 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016448 hddLog(VOS_TRACE_LEVEL_INFO,
16449 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016450 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016451 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016452 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016453 return -ENOENT;
16454 }
16455
Jeff Johnson295189b2012-06-20 16:38:30 -070016456 }
16457 }
16458
16459 EXIT();
16460
16461 return 0;
16462}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016463
16464#ifdef CFG80211_DEL_STA_V2
16465static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16466 struct net_device *dev,
16467 struct station_del_parameters *param)
16468#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016469#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16470static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16471 struct net_device *dev, const u8 *mac)
16472#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016473static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16474 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016475#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016476#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016477{
16478 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016479 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016480
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016481 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016482
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016483#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016484 if (NULL == param) {
16485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016486 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016487 return -EINVAL;
16488 }
16489
16490 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16491 param->subtype, &delStaParams);
16492
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016493#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016494 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016495 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016496#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016497 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16498
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016499 vos_ssr_unprotect(__func__);
16500
16501 return ret;
16502}
16503
16504static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016505 struct net_device *dev,
16506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16507 const u8 *mac,
16508#else
16509 u8 *mac,
16510#endif
16511 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016512{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016513 hdd_adapter_t *pAdapter;
16514 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016515 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016516#ifdef FEATURE_WLAN_TDLS
16517 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016518
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016519 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016520
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016521 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16522 if (NULL == pAdapter)
16523 {
16524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16525 "%s: Adapter is NULL",__func__);
16526 return -EINVAL;
16527 }
16528 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16529 status = wlan_hdd_validate_context(pHddCtx);
16530 if (0 != status)
16531 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016532 return status;
16533 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16536 TRACE_CODE_HDD_CFG80211_ADD_STA,
16537 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016538 mask = params->sta_flags_mask;
16539
16540 set = params->sta_flags_set;
16541
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016543 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16544 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016545
16546 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16547 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016548 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016549 }
16550 }
16551#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016552 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016553 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016554}
16555
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16557static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16558 struct net_device *dev, const u8 *mac,
16559 struct station_parameters *params)
16560#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016561static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16562 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016563#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016564{
16565 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016566
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016567 vos_ssr_protect(__func__);
16568 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16569 vos_ssr_unprotect(__func__);
16570
16571 return ret;
16572}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016573#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016574
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016575static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016576 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016577{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016578 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16579 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016580 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016581 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016582 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016583 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016585 ENTER();
16586
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016588 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016589 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016591 return -EINVAL;
16592 }
16593
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016594 if (!pmksa) {
16595 hddLog(LOGE, FL("pmksa is NULL"));
16596 return -EINVAL;
16597 }
16598
16599 if (!pmksa->bssid || !pmksa->pmkid) {
16600 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16601 pmksa->bssid, pmksa->pmkid);
16602 return -EINVAL;
16603 }
16604
16605 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16606 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16607
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016608 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16609 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016610 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016611 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016612 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016613 }
16614
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016615 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016616 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16617
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016618 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16619 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016620
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016621 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016622 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016623 &pmk_id, 1, FALSE);
16624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16626 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16627 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016629 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016630 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016631}
16632
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016633static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16634 struct cfg80211_pmksa *pmksa)
16635{
16636 int ret;
16637
16638 vos_ssr_protect(__func__);
16639 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16640 vos_ssr_unprotect(__func__);
16641
16642 return ret;
16643}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016644
Wilson Yang6507c4e2013-10-01 20:11:19 -070016645
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016646static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016647 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016648{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16650 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016651 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016652 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016653
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016654 ENTER();
16655
Wilson Yang6507c4e2013-10-01 20:11:19 -070016656 /* Validate pAdapter */
16657 if (NULL == pAdapter)
16658 {
16659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16660 return -EINVAL;
16661 }
16662
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016663 if (!pmksa) {
16664 hddLog(LOGE, FL("pmksa is NULL"));
16665 return -EINVAL;
16666 }
16667
16668 if (!pmksa->bssid) {
16669 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16670 return -EINVAL;
16671 }
16672
Kiet Lam98c46a12014-10-31 15:34:57 -070016673 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16674 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16675
Wilson Yang6507c4e2013-10-01 20:11:19 -070016676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16677 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016678 if (0 != status)
16679 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016680 return status;
16681 }
16682
16683 /*Retrieve halHandle*/
16684 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16685
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16687 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16688 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016689 /* Delete the PMKID CSR cache */
16690 if (eHAL_STATUS_SUCCESS !=
16691 sme_RoamDelPMKIDfromCache(halHandle,
16692 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16693 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16694 MAC_ADDR_ARRAY(pmksa->bssid));
16695 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016696 }
16697
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016698 EXIT();
16699 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016700}
16701
Wilson Yang6507c4e2013-10-01 20:11:19 -070016702
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016703static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16704 struct cfg80211_pmksa *pmksa)
16705{
16706 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016707
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016708 vos_ssr_protect(__func__);
16709 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16710 vos_ssr_unprotect(__func__);
16711
16712 return ret;
16713
16714}
16715
16716static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016717{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16719 tHalHandle halHandle;
16720 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016721 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016722
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016723 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016724
16725 /* Validate pAdapter */
16726 if (NULL == pAdapter)
16727 {
16728 hddLog(VOS_TRACE_LEVEL_ERROR,
16729 "%s: Invalid Adapter" ,__func__);
16730 return -EINVAL;
16731 }
16732
16733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16734 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016735 if (0 != status)
16736 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016737 return status;
16738 }
16739
16740 /*Retrieve halHandle*/
16741 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16742
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016743 /* Flush the PMKID cache in CSR */
16744 if (eHAL_STATUS_SUCCESS !=
16745 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16747 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016748 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016749 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016750 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016751}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016752
16753static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16754{
16755 int ret;
16756
16757 vos_ssr_protect(__func__);
16758 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16759 vos_ssr_unprotect(__func__);
16760
16761 return ret;
16762}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016763#endif
16764
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016765#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016766static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16767 struct net_device *dev,
16768 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016769{
16770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16771 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016772 hdd_context_t *pHddCtx;
16773 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016775 ENTER();
16776
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016777 if (NULL == pAdapter)
16778 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016780 return -ENODEV;
16781 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16783 ret = wlan_hdd_validate_context(pHddCtx);
16784 if (0 != ret)
16785 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016786 return ret;
16787 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016788 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016789 if (NULL == pHddStaCtx)
16790 {
16791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16792 return -EINVAL;
16793 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016794
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16796 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16797 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016798 // Added for debug on reception of Re-assoc Req.
16799 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16800 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016801 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016802 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016803 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016804 }
16805
16806#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016807 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016808 ftie->ie_len);
16809#endif
16810
16811 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016812 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16813 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016814 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016815
16816 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016817 return 0;
16818}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016819
16820static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16821 struct net_device *dev,
16822 struct cfg80211_update_ft_ies_params *ftie)
16823{
16824 int ret;
16825
16826 vos_ssr_protect(__func__);
16827 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16828 vos_ssr_unprotect(__func__);
16829
16830 return ret;
16831}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016832#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016833
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016834#ifdef FEATURE_WLAN_SCAN_PNO
16835
16836void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16837 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16838{
16839 int ret;
16840 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16841 hdd_context_t *pHddCtx;
16842
Nirav Shah80830bf2013-12-31 16:35:12 +053016843 ENTER();
16844
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016845 if (NULL == pAdapter)
16846 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016848 "%s: HDD adapter is Null", __func__);
16849 return ;
16850 }
16851
16852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16853 if (NULL == pHddCtx)
16854 {
16855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16856 "%s: HDD context is Null!!!", __func__);
16857 return ;
16858 }
16859
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016860 spin_lock(&pHddCtx->schedScan_lock);
16861 if (TRUE == pHddCtx->isWiphySuspended)
16862 {
16863 pHddCtx->isSchedScanUpdatePending = TRUE;
16864 spin_unlock(&pHddCtx->schedScan_lock);
16865 hddLog(VOS_TRACE_LEVEL_INFO,
16866 "%s: Update cfg80211 scan database after it resume", __func__);
16867 return ;
16868 }
16869 spin_unlock(&pHddCtx->schedScan_lock);
16870
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016871 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16872
16873 if (0 > ret)
16874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016875 else
16876 {
16877 /* Acquire wakelock to handle the case where APP's tries to suspend
16878 * immediatly after the driver gets connect request(i.e after pno)
16879 * from supplicant, this result in app's is suspending and not able
16880 * to process the connect request to AP */
16881 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16882 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016883 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16885 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016886}
16887
16888/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016889 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016890 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016891 */
16892static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16893{
16894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16895 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016896 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16898 int status = 0;
16899 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16900
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016901 /* The current firmware design does not allow PNO during any
16902 * active sessions. Hence, determine the active sessions
16903 * and return a failure.
16904 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016905 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16906 {
16907 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016908 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016909
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016910 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16911 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16912 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16913 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16914 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016915 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016916 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016917 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016918 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016919 }
16920 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16921 pAdapterNode = pNext;
16922 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016923 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016924}
16925
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016926void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16927{
16928 hdd_adapter_t *pAdapter = callbackContext;
16929 hdd_context_t *pHddCtx;
16930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016931 ENTER();
16932
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016933 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16934 {
16935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16936 FL("Invalid adapter or adapter has invalid magic"));
16937 return;
16938 }
16939
16940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16941 if (0 != wlan_hdd_validate_context(pHddCtx))
16942 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016943 return;
16944 }
16945
c_hpothub53c45d2014-08-18 16:53:14 +053016946 if (VOS_STATUS_SUCCESS != status)
16947 {
16948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016949 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016950 pHddCtx->isPnoEnable = FALSE;
16951 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016952
16953 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16954 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016955 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016956}
16957
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016958/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016959 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16960 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016962static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016963 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16964{
16965 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016966 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016967 hdd_context_t *pHddCtx;
16968 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016969 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016970 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16971 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016972 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16973 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016974 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016975 hdd_config_t *pConfig = NULL;
16976 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016978 ENTER();
16979
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016980 if (NULL == pAdapter)
16981 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016983 "%s: HDD adapter is Null", __func__);
16984 return -ENODEV;
16985 }
16986
16987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016988 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016989
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016990 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016991 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016992 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016993 }
16994
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016995 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016996 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16997 if (NULL == hHal)
16998 {
16999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17000 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017001 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017002 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17004 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17005 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017006 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017007 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017008 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017009 {
17010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17011 "%s: aborting the existing scan is unsuccessfull", __func__);
17012 return -EBUSY;
17013 }
17014
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017015 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017016 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017018 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017019 return -EBUSY;
17020 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017021
c_hpothu37f21312014-04-09 21:49:54 +053017022 if (TRUE == pHddCtx->isPnoEnable)
17023 {
17024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17025 FL("already PNO is enabled"));
17026 return -EBUSY;
17027 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017028
17029 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17030 {
17031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17032 "%s: abort ROC failed ", __func__);
17033 return -EBUSY;
17034 }
17035
c_hpothu37f21312014-04-09 21:49:54 +053017036 pHddCtx->isPnoEnable = TRUE;
17037
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017038 pnoRequest.enable = 1; /*Enable PNO */
17039 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017040
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017041 if (( !pnoRequest.ucNetworksCount ) ||
17042 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017043 {
17044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017045 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017046 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017047 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017048 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017049 goto error;
17050 }
17051
17052 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17053 {
17054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017055 "%s: Incorrect number of channels %d",
17056 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017057 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017058 goto error;
17059 }
17060
17061 /* Framework provides one set of channels(all)
17062 * common for all saved profile */
17063 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17064 channels_allowed, &num_channels_allowed))
17065 {
17066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17067 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017068 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017069 goto error;
17070 }
17071 /* Checking each channel against allowed channel list */
17072 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017073 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017074 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017075 char chList [(request->n_channels*5)+1];
17076 int len;
17077 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017078 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017079 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017080 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017081 if (request->channels[i]->hw_value == channels_allowed[indx])
17082 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017083 if ((!pConfig->enableDFSPnoChnlScan) &&
17084 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17085 {
17086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17087 "%s : Dropping DFS channel : %d",
17088 __func__,channels_allowed[indx]);
17089 num_ignore_dfs_ch++;
17090 break;
17091 }
17092
Nirav Shah80830bf2013-12-31 16:35:12 +053017093 valid_ch[num_ch++] = request->channels[i]->hw_value;
17094 len += snprintf(chList+len, 5, "%d ",
17095 request->channels[i]->hw_value);
17096 break ;
17097 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017098 }
17099 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017100 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017101
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017102 /*If all channels are DFS and dropped, then ignore the PNO request*/
17103 if (num_ignore_dfs_ch == request->n_channels)
17104 {
17105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17106 "%s : All requested channels are DFS channels", __func__);
17107 ret = -EINVAL;
17108 goto error;
17109 }
17110 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017111
17112 pnoRequest.aNetworks =
17113 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17114 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017115 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017116 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17117 FL("failed to allocate memory aNetworks %u"),
17118 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17119 goto error;
17120 }
17121 vos_mem_zero(pnoRequest.aNetworks,
17122 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17123
17124 /* Filling per profile params */
17125 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17126 {
17127 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017128 request->match_sets[i].ssid.ssid_len;
17129
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017130 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17131 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017132 {
17133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017134 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017135 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017136 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017137 goto error;
17138 }
17139
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017140 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017141 request->match_sets[i].ssid.ssid,
17142 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17144 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017145 i, pnoRequest.aNetworks[i].ssId.ssId);
17146 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17147 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17148 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017149
17150 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017151 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17152 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017153
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017154 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017155 }
17156
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017157 for (i = 0; i < request->n_ssids; i++)
17158 {
17159 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017160 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017161 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017162 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017163 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017164 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017165 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017166 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017167 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017168 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017169 break;
17170 }
17171 j++;
17172 }
17173 }
17174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17175 "Number of hidden networks being Configured = %d",
17176 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017178 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017179
17180 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17181 if (pnoRequest.p24GProbeTemplate == NULL)
17182 {
17183 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17184 FL("failed to allocate memory p24GProbeTemplate %u"),
17185 SIR_PNO_MAX_PB_REQ_SIZE);
17186 goto error;
17187 }
17188
17189 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17190 if (pnoRequest.p5GProbeTemplate == NULL)
17191 {
17192 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17193 FL("failed to allocate memory p5GProbeTemplate %u"),
17194 SIR_PNO_MAX_PB_REQ_SIZE);
17195 goto error;
17196 }
17197
17198 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17199 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17200
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017201 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17202 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017203 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017204 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17205 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17206 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017207
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017208 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17209 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17210 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017211 }
17212
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017213 /* Driver gets only one time interval which is hardcoded in
17214 * supplicant for 10000ms. Taking power consumption into account 6 timers
17215 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17216 * 80,160,320 secs. And number of scan cycle for each timer
17217 * is configurable through INI param gPNOScanTimerRepeatValue.
17218 * If it is set to 0 only one timer will be used and PNO scan cycle
17219 * will be repeated after each interval specified by supplicant
17220 * till PNO is disabled.
17221 */
17222 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017223 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017224 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017225 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017226 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17227
17228 tempInterval = (request->interval)/1000;
17229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17230 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17231 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017232 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017233 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017234 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017235 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017236 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017237 tempInterval *= 2;
17238 }
17239 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017240 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017241
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017242 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017243
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017244 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017245 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17246 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017247 pAdapter->pno_req_status = 0;
17248
Nirav Shah80830bf2013-12-31 16:35:12 +053017249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17250 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017251 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17252 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017253
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017254 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017255 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017256 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17257 if (eHAL_STATUS_SUCCESS != status)
17258 {
17259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017260 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017261 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017262 goto error;
17263 }
17264
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017265 ret = wait_for_completion_timeout(
17266 &pAdapter->pno_comp_var,
17267 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17268 if (0 >= ret)
17269 {
17270 // Did not receive the response for PNO enable in time.
17271 // Assuming the PNO enable was success.
17272 // Returning error from here, because we timeout, results
17273 // in side effect of Wifi (Wifi Setting) not to work.
17274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17275 FL("Timed out waiting for PNO to be Enabled"));
17276 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017277 }
17278
17279 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017280 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017281
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017282error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17284 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017285 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017286 if (pnoRequest.aNetworks)
17287 vos_mem_free(pnoRequest.aNetworks);
17288 if (pnoRequest.p24GProbeTemplate)
17289 vos_mem_free(pnoRequest.p24GProbeTemplate);
17290 if (pnoRequest.p5GProbeTemplate)
17291 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017292
17293 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017294 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017295}
17296
17297/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017298 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17299 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017300 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017301static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17302 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17303{
17304 int ret;
17305
17306 vos_ssr_protect(__func__);
17307 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17308 vos_ssr_unprotect(__func__);
17309
17310 return ret;
17311}
17312
17313/*
17314 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17315 * Function to disable PNO
17316 */
17317static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017318 struct net_device *dev)
17319{
17320 eHalStatus status = eHAL_STATUS_FAILURE;
17321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17322 hdd_context_t *pHddCtx;
17323 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017324 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017325 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017326
17327 ENTER();
17328
17329 if (NULL == pAdapter)
17330 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017332 "%s: HDD adapter is Null", __func__);
17333 return -ENODEV;
17334 }
17335
17336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017337
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017338 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017339 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017341 "%s: HDD context is Null", __func__);
17342 return -ENODEV;
17343 }
17344
17345 /* The return 0 is intentional when isLogpInProgress and
17346 * isLoadUnloadInProgress. We did observe a crash due to a return of
17347 * failure in sched_scan_stop , especially for a case where the unload
17348 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17349 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17350 * success. If it returns a failure , then its next invocation due to the
17351 * clean up of the second interface will have the dev pointer corresponding
17352 * to the first one leading to a crash.
17353 */
17354 if (pHddCtx->isLogpInProgress)
17355 {
17356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17357 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017358 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017359 return ret;
17360 }
17361
Mihir Shete18156292014-03-11 15:38:30 +053017362 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017363 {
17364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17365 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17366 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017367 }
17368
17369 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17370 if (NULL == hHal)
17371 {
17372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17373 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017374 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017375 }
17376
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017377 pnoRequest.enable = 0; /* Disable PNO */
17378 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017379
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17381 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17382 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017383
17384 INIT_COMPLETION(pAdapter->pno_comp_var);
17385 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17386 pnoRequest.callbackContext = pAdapter;
17387 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017388 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017389 pAdapter->sessionId,
17390 NULL, pAdapter);
17391 if (eHAL_STATUS_SUCCESS != status)
17392 {
17393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17394 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017395 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017396 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017397 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017398 ret = wait_for_completion_timeout(
17399 &pAdapter->pno_comp_var,
17400 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17401 if (0 >= ret)
17402 {
17403 // Did not receive the response for PNO disable in time.
17404 // Assuming the PNO disable was success.
17405 // Returning error from here, because we timeout, results
17406 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017408 FL("Timed out waiting for PNO to be disabled"));
17409 ret = 0;
17410 }
17411
17412 ret = pAdapter->pno_req_status;
17413 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017414
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017415error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017417 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017418
17419 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017420 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017421}
17422
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017423/*
17424 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17425 * NL interface to disable PNO
17426 */
17427static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17428 struct net_device *dev)
17429{
17430 int ret;
17431
17432 vos_ssr_protect(__func__);
17433 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17434 vos_ssr_unprotect(__func__);
17435
17436 return ret;
17437}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017438#endif /*FEATURE_WLAN_SCAN_PNO*/
17439
17440
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017441#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017442#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017443static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17444 struct net_device *dev,
17445 u8 *peer, u8 action_code,
17446 u8 dialog_token,
17447 u16 status_code, u32 peer_capability,
17448 const u8 *buf, size_t len)
17449#else /* TDLS_MGMT_VERSION2 */
17450#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17451static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17452 struct net_device *dev,
17453 const u8 *peer, u8 action_code,
17454 u8 dialog_token, u16 status_code,
17455 u32 peer_capability, bool initiator,
17456 const u8 *buf, size_t len)
17457#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17458static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17459 struct net_device *dev,
17460 const u8 *peer, u8 action_code,
17461 u8 dialog_token, u16 status_code,
17462 u32 peer_capability, const u8 *buf,
17463 size_t len)
17464#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17465static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17466 struct net_device *dev,
17467 u8 *peer, u8 action_code,
17468 u8 dialog_token,
17469 u16 status_code, u32 peer_capability,
17470 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017471#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017472static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17473 struct net_device *dev,
17474 u8 *peer, u8 action_code,
17475 u8 dialog_token,
17476 u16 status_code, const u8 *buf,
17477 size_t len)
17478#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017479#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017480{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017481 hdd_adapter_t *pAdapter;
17482 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017483 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017484 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017485 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017486 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017487 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017488 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017489#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017490 u32 peer_capability = 0;
17491#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017492 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017493 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017494
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017495 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17496 if (NULL == pAdapter)
17497 {
17498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17499 "%s: Adapter is NULL",__func__);
17500 return -EINVAL;
17501 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17503 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17504 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017505
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017506 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017507 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017510 "Invalid arguments");
17511 return -EINVAL;
17512 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017513
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017514 if (pHddCtx->isLogpInProgress)
17515 {
17516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17517 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017518 wlan_hdd_tdls_set_link_status(pAdapter,
17519 peer,
17520 eTDLS_LINK_IDLE,
17521 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017522 return -EBUSY;
17523 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017524
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017525 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17526 {
17527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17528 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17529 return -EAGAIN;
17530 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017531
Hoonki Lee27511902013-03-14 18:19:06 -070017532 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017533 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017535 "%s: TDLS mode is disabled OR not enabled in FW."
17536 MAC_ADDRESS_STR " action %d declined.",
17537 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017538 return -ENOTSUPP;
17539 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017540
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017541 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17542
17543 if( NULL == pHddStaCtx )
17544 {
17545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17546 "%s: HDD station context NULL ",__func__);
17547 return -EINVAL;
17548 }
17549
17550 /* STA should be connected and authenticated
17551 * before sending any TDLS frames
17552 */
17553 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17554 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17555 {
17556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17557 "STA is not connected or unauthenticated. "
17558 "connState %u, uIsAuthenticated %u",
17559 pHddStaCtx->conn_info.connState,
17560 pHddStaCtx->conn_info.uIsAuthenticated);
17561 return -EAGAIN;
17562 }
17563
Hoonki Lee27511902013-03-14 18:19:06 -070017564 /* other than teardown frame, other mgmt frames are not sent if disabled */
17565 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17566 {
17567 /* if tdls_mode is disabled to respond to peer's request */
17568 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17569 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017571 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017572 " TDLS mode is disabled. action %d declined.",
17573 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017574
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017575 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017576 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017577
17578 if (vos_max_concurrent_connections_reached())
17579 {
17580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17581 return -EINVAL;
17582 }
Hoonki Lee27511902013-03-14 18:19:06 -070017583 }
17584
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017585 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17586 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017587 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017588 {
17589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017590 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017591 " TDLS setup is ongoing. action %d declined.",
17592 __func__, MAC_ADDR_ARRAY(peer), action_code);
17593 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017594 }
17595 }
17596
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017597 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17598 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017599 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017600 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17601 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017602 {
17603 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17604 we return error code at 'add_station()'. Hence we have this
17605 check again in addtion to add_station().
17606 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017607 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017608 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17610 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017611 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17612 __func__, MAC_ADDR_ARRAY(peer), action_code,
17613 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017614 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017615 }
17616 else
17617 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017618 /* maximum reached. tweak to send error code to peer and return
17619 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017620 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17622 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017623 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17624 __func__, MAC_ADDR_ARRAY(peer), status_code,
17625 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017626 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017627 /* fall through to send setup resp with failure status
17628 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017629 }
17630 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017631 else
17632 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017633 mutex_lock(&pHddCtx->tdls_lock);
17634 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017635 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017636 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017637 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017639 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17640 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017641 return -EPERM;
17642 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017643 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017644 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017645 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017646
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017648 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017649 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17650 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017651
Hoonki Leea34dd892013-02-05 22:56:02 -080017652 /*Except teardown responder will not be used so just make 0*/
17653 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017654 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017655 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017656
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017657 mutex_lock(&pHddCtx->tdls_lock);
17658 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017659
17660 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17661 responder = pTdlsPeer->is_responder;
17662 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017663 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017665 "%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 -070017666 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17667 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017668 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017669 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017670 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017671 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017672 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017673
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017674 /* Discard TDLS setup if peer is removed by user app */
17675 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17676 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17677 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17678 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17679
17680 mutex_lock(&pHddCtx->tdls_lock);
17681 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17682 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17683 mutex_unlock(&pHddCtx->tdls_lock);
17684 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17685 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17686 MAC_ADDR_ARRAY(peer), action_code);
17687 return -EINVAL;
17688 }
17689 mutex_unlock(&pHddCtx->tdls_lock);
17690 }
17691
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017692 /* For explicit trigger of DIS_REQ come out of BMPS for
17693 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017694 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017695 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017696 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17697 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017698 {
17699 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17700 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017702 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017703 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17704 if (status != VOS_STATUS_SUCCESS) {
17705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17706 }
Hoonki Lee14621352013-04-16 17:51:19 -070017707 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017708 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017709 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17711 }
17712 }
Hoonki Lee14621352013-04-16 17:51:19 -070017713 }
17714
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017715 /* make sure doesn't call send_mgmt() while it is pending */
17716 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17717 {
17718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017719 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017720 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017721 ret = -EBUSY;
17722 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017723 }
17724
17725 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017726 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17727
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017728 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17729 pAdapter->sessionId, peer, action_code, dialog_token,
17730 status_code, peer_capability, (tANI_U8 *)buf, len,
17731 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017732
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017733 if (VOS_STATUS_SUCCESS != status)
17734 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17736 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017737 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017738 ret = -EINVAL;
17739 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017740 }
17741
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17743 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17744 WAIT_TIME_TDLS_MGMT);
17745
Hoonki Leed37cbb32013-04-20 00:31:14 -070017746 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17747 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17748
17749 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017750 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017752 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017753 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017754 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017755
17756 if (pHddCtx->isLogpInProgress)
17757 {
17758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17759 "%s: LOGP in Progress. Ignore!!!", __func__);
17760 return -EAGAIN;
17761 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017762 if (rc <= 0)
17763 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17764 WLAN_LOG_INDICATOR_HOST_DRIVER,
17765 WLAN_LOG_REASON_HDD_TIME_OUT,
17766 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017767
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017768 ret = -EINVAL;
17769 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017770 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017771 else
17772 {
17773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17774 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17775 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17776 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017777
Gopichand Nakkala05922802013-03-14 12:23:19 -070017778 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017779 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017780 ret = max_sta_failed;
17781 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017782 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017783
Hoonki Leea34dd892013-02-05 22:56:02 -080017784 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17785 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017786 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17788 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017789 }
17790 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17791 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017792 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17794 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017795 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017796
17797 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017798
17799tx_failed:
17800 /* add_station will be called before sending TDLS_SETUP_REQ and
17801 * TDLS_SETUP_RSP and as part of add_station driver will enable
17802 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17803 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17804 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17805 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17806 */
17807
17808 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17809 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17810 wlan_hdd_tdls_check_bmps(pAdapter);
17811 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017812}
17813
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017814#if TDLS_MGMT_VERSION2
17815static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17816 u8 *peer, u8 action_code, u8 dialog_token,
17817 u16 status_code, u32 peer_capability,
17818 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017819#else /* TDLS_MGMT_VERSION2 */
17820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17821static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17822 struct net_device *dev,
17823 const u8 *peer, u8 action_code,
17824 u8 dialog_token, u16 status_code,
17825 u32 peer_capability, bool initiator,
17826 const u8 *buf, size_t len)
17827#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17828static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17829 struct net_device *dev,
17830 const u8 *peer, u8 action_code,
17831 u8 dialog_token, u16 status_code,
17832 u32 peer_capability, const u8 *buf,
17833 size_t len)
17834#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17835static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17836 struct net_device *dev,
17837 u8 *peer, u8 action_code,
17838 u8 dialog_token,
17839 u16 status_code, u32 peer_capability,
17840 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017841#else
17842static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17843 u8 *peer, u8 action_code, u8 dialog_token,
17844 u16 status_code, const u8 *buf, size_t len)
17845#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017846#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017847{
17848 int ret;
17849
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017850 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017851#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017852 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17853 dialog_token, status_code,
17854 peer_capability, buf, len);
17855#else /* TDLS_MGMT_VERSION2 */
17856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17857 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17858 dialog_token, status_code,
17859 peer_capability, initiator,
17860 buf, len);
17861#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17862 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17863 dialog_token, status_code,
17864 peer_capability, buf, len);
17865#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17866 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17867 dialog_token, status_code,
17868 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017869#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017870 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17871 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017872#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017873#endif
17874 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017875
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017876 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017877}
Atul Mittal115287b2014-07-08 13:26:33 +053017878
17879int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17881 const u8 *peer,
17882#else
Atul Mittal115287b2014-07-08 13:26:33 +053017883 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017884#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017885 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017886 cfg80211_exttdls_callback callback)
17887{
17888
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017889 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017891 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17893 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17894 __func__, MAC_ADDR_ARRAY(peer));
17895
17896 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17897 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17898
17899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017900 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17901 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17902 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017903 return -ENOTSUPP;
17904 }
17905
17906 /* To cater the requirement of establishing the TDLS link
17907 * irrespective of the data traffic , get an entry of TDLS peer.
17908 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017909 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017910 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17911 if (pTdlsPeer == NULL) {
17912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17913 "%s: peer " MAC_ADDRESS_STR " not existing",
17914 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017915 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017916 return -EINVAL;
17917 }
17918
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017919 /* check FW TDLS Off Channel capability */
17920 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017921 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017922 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017923 {
17924 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17925 pTdlsPeer->peerParams.global_operating_class =
17926 tdls_peer_params->global_operating_class;
17927 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17928 pTdlsPeer->peerParams.min_bandwidth_kbps =
17929 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017930 /* check configured channel is valid, non dfs and
17931 * not current operating channel */
17932 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17933 tdls_peer_params->channel)) &&
17934 (pHddStaCtx) &&
17935 (tdls_peer_params->channel !=
17936 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017937 {
17938 pTdlsPeer->isOffChannelConfigured = TRUE;
17939 }
17940 else
17941 {
17942 pTdlsPeer->isOffChannelConfigured = FALSE;
17943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17944 "%s: Configured Tdls Off Channel is not valid", __func__);
17945
17946 }
17947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017948 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17949 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017950 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017951 pTdlsPeer->isOffChannelConfigured,
17952 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017953 }
17954 else
17955 {
17956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017957 "%s: TDLS off channel FW capability %d, "
17958 "host capab %d or Invalid TDLS Peer Params", __func__,
17959 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17960 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017961 }
17962
Atul Mittal115287b2014-07-08 13:26:33 +053017963 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17964
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017965 mutex_unlock(&pHddCtx->tdls_lock);
17966
Atul Mittal115287b2014-07-08 13:26:33 +053017967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17968 " %s TDLS Add Force Peer Failed",
17969 __func__);
17970 return -EINVAL;
17971 }
17972 /*EXT TDLS*/
17973
17974 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017975 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17977 " %s TDLS set callback Failed",
17978 __func__);
17979 return -EINVAL;
17980 }
17981
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017982 mutex_unlock(&pHddCtx->tdls_lock);
17983
Atul Mittal115287b2014-07-08 13:26:33 +053017984 return(0);
17985
17986}
17987
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017988int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17990 const u8 *peer
17991#else
17992 u8 *peer
17993#endif
17994)
Atul Mittal115287b2014-07-08 13:26:33 +053017995{
17996
17997 hddTdlsPeer_t *pTdlsPeer;
17998 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017999
Atul Mittal115287b2014-07-08 13:26:33 +053018000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18001 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18002 __func__, MAC_ADDR_ARRAY(peer));
18003
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018004 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18006 return -EINVAL;
18007 }
18008
Atul Mittal115287b2014-07-08 13:26:33 +053018009 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18010 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18011
18012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018013 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18014 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18015 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018016 return -ENOTSUPP;
18017 }
18018
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018019 mutex_lock(&pHddCtx->tdls_lock);
18020 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018021
18022 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018023 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018024 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018025 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018026 __func__, MAC_ADDR_ARRAY(peer));
18027 return -EINVAL;
18028 }
18029 else {
18030 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18031 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018032 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18033 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018034 /* if channel switch is configured, reset
18035 the channel for this peer */
18036 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18037 {
18038 pTdlsPeer->peerParams.channel = 0;
18039 pTdlsPeer->isOffChannelConfigured = FALSE;
18040 }
Atul Mittal115287b2014-07-08 13:26:33 +053018041 }
18042
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018043 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018044 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018046 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018047 }
Atul Mittal115287b2014-07-08 13:26:33 +053018048
18049 /*EXT TDLS*/
18050
18051 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018052 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18054 " %s TDLS set callback Failed",
18055 __func__);
18056 return -EINVAL;
18057 }
Atul Mittal115287b2014-07-08 13:26:33 +053018058
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018059 mutex_unlock(&pHddCtx->tdls_lock);
18060
18061 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018062}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018063static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18065 const u8 *peer,
18066#else
18067 u8 *peer,
18068#endif
18069 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018070{
18071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18072 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018073 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018074 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018075
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018076 ENTER();
18077
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018078 if (!pAdapter) {
18079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18080 return -EINVAL;
18081 }
18082
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18084 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18085 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018086 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018087 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018089 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018090 return -EINVAL;
18091 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018092
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018093 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018094 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018095 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018096 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018097 }
18098
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018099
18100 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018101 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018102 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018104 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18105 "Cannot process TDLS commands",
18106 pHddCtx->cfg_ini->fEnableTDLSSupport,
18107 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018108 return -ENOTSUPP;
18109 }
18110
18111 switch (oper) {
18112 case NL80211_TDLS_ENABLE_LINK:
18113 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018114 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018115 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018116 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18117 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018118 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018119 tANI_U16 numCurrTdlsPeers = 0;
18120 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018121 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018122 tSirMacAddr peerMac;
18123 int channel;
18124 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018125
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18127 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18128 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018129
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018130 mutex_lock(&pHddCtx->tdls_lock);
18131 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018132 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018133 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018134 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18136 " (oper %d) not exsting. ignored",
18137 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18138 return -EINVAL;
18139 }
18140
18141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18142 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18143 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18144 "NL80211_TDLS_ENABLE_LINK");
18145
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018146 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18147 {
18148 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18149 MAC_ADDRESS_STR " failed",
18150 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018151 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018152 return -EINVAL;
18153 }
18154
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018155 /* before starting tdls connection, set tdls
18156 * off channel established status to default value */
18157 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018158
18159 mutex_unlock(&pHddCtx->tdls_lock);
18160
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018161 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018162 /* TDLS Off Channel, Disable tdls channel switch,
18163 when there are more than one tdls link */
18164 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018165 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018166 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018167 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018168 /* get connected peer and send disable tdls off chan */
18169 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018170 if ((connPeer) &&
18171 (connPeer->isOffChannelSupported == TRUE) &&
18172 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018173 {
18174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18175 "%s: More then one peer connected, Disable "
18176 "TDLS channel switch", __func__);
18177
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018178 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018179 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18180 channel = connPeer->peerParams.channel;
18181
18182 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018183
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018184 ret = sme_SendTdlsChanSwitchReq(
18185 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018186 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018187 peerMac,
18188 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018189 TDLS_OFF_CHANNEL_BW_OFFSET,
18190 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018191 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018192 hddLog(VOS_TRACE_LEVEL_ERROR,
18193 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018194 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018195 }
18196 else
18197 {
18198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18199 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018200 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018201 "isOffChannelConfigured %d",
18202 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018203 (connPeer ? (connPeer->isOffChannelSupported)
18204 : -1),
18205 (connPeer ? (connPeer->isOffChannelConfigured)
18206 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018207 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018208 }
18209 }
18210
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018211 mutex_lock(&pHddCtx->tdls_lock);
18212 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18213 if ( NULL == pTdlsPeer ) {
18214 mutex_unlock(&pHddCtx->tdls_lock);
18215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18216 "%s: " MAC_ADDRESS_STR
18217 " (oper %d) peer got freed in other context. ignored",
18218 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18219 return -EINVAL;
18220 }
18221 peer_status = pTdlsPeer->link_status;
18222 mutex_unlock(&pHddCtx->tdls_lock);
18223
18224 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018225 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018226 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018227
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018228 if (0 != wlan_hdd_tdls_get_link_establish_params(
18229 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018231 return -EINVAL;
18232 }
18233 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018234
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018235 ret = sme_SendTdlsLinkEstablishParams(
18236 WLAN_HDD_GET_HAL_CTX(pAdapter),
18237 pAdapter->sessionId, peer,
18238 &tdlsLinkEstablishParams);
18239 if (ret != VOS_STATUS_SUCCESS) {
18240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18241 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018242 /* Send TDLS peer UAPSD capabilities to the firmware and
18243 * register with the TL on after the response for this operation
18244 * is received .
18245 */
18246 ret = wait_for_completion_interruptible_timeout(
18247 &pAdapter->tdls_link_establish_req_comp,
18248 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018249
18250 mutex_lock(&pHddCtx->tdls_lock);
18251 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18252 if ( NULL == pTdlsPeer ) {
18253 mutex_unlock(&pHddCtx->tdls_lock);
18254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18255 "%s %d: " MAC_ADDRESS_STR
18256 " (oper %d) peer got freed in other context. ignored",
18257 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18258 (int)oper);
18259 return -EINVAL;
18260 }
18261 peer_status = pTdlsPeer->link_status;
18262 mutex_unlock(&pHddCtx->tdls_lock);
18263
18264 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018265 {
18266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018267 FL("Link Establish Request Failed Status %ld"),
18268 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018269 return -EINVAL;
18270 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018271 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018272
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018273 mutex_lock(&pHddCtx->tdls_lock);
18274 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18275 if ( NULL == pTdlsPeer ) {
18276 mutex_unlock(&pHddCtx->tdls_lock);
18277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18278 "%s: " MAC_ADDRESS_STR
18279 " (oper %d) peer got freed in other context. ignored",
18280 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18281 return -EINVAL;
18282 }
18283
Atul Mittal115287b2014-07-08 13:26:33 +053018284 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18285 eTDLS_LINK_CONNECTED,
18286 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018287 staDesc.ucSTAId = pTdlsPeer->staId;
18288 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018289
18290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18291 "%s: tdlsLinkEstablishParams of peer "
18292 MAC_ADDRESS_STR "uapsdQueues: %d"
18293 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18294 "isResponder: %d peerstaId: %d",
18295 __func__,
18296 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18297 tdlsLinkEstablishParams.uapsdQueues,
18298 tdlsLinkEstablishParams.qos,
18299 tdlsLinkEstablishParams.maxSp,
18300 tdlsLinkEstablishParams.isBufSta,
18301 tdlsLinkEstablishParams.isOffChannelSupported,
18302 tdlsLinkEstablishParams.isResponder,
18303 pTdlsPeer->staId);
18304
18305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18306 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18307 __func__,
18308 staDesc.ucSTAId,
18309 staDesc.ucQosEnabled);
18310
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018311 ret = WLANTL_UpdateTdlsSTAClient(
18312 pHddCtx->pvosContext,
18313 &staDesc);
18314 if (ret != VOS_STATUS_SUCCESS) {
18315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18316 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018317
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018318 /* Mark TDLS client Authenticated .*/
18319 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18320 pTdlsPeer->staId,
18321 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018322 if (VOS_STATUS_SUCCESS == status)
18323 {
Hoonki Lee14621352013-04-16 17:51:19 -070018324 if (pTdlsPeer->is_responder == 0)
18325 {
18326 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018327 tdlsConnInfo_t *tdlsInfo;
18328
18329 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18330
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018331 if (!vos_timer_is_initialized(
18332 &pTdlsPeer->initiatorWaitTimeoutTimer))
18333 {
18334 /* Initialize initiator wait callback */
18335 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018336 &pTdlsPeer->initiatorWaitTimeoutTimer,
18337 VOS_TIMER_TYPE_SW,
18338 wlan_hdd_tdls_initiator_wait_cb,
18339 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018340 }
Hoonki Lee14621352013-04-16 17:51:19 -070018341 wlan_hdd_tdls_timer_restart(pAdapter,
18342 &pTdlsPeer->initiatorWaitTimeoutTimer,
18343 WAIT_TIME_TDLS_INITIATOR);
18344 /* suspend initiator TX until it receives direct packet from the
18345 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018346 ret = WLANTL_SuspendDataTx(
18347 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18348 &staId, NULL);
18349 if (ret != VOS_STATUS_SUCCESS) {
18350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18351 }
Hoonki Lee14621352013-04-16 17:51:19 -070018352 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018353
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018354 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018355 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018356 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018357 suppChannelLen =
18358 tdlsLinkEstablishParams.supportedChannelsLen;
18359
18360 if ((suppChannelLen > 0) &&
18361 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18362 {
18363 tANI_U8 suppPeerChannel = 0;
18364 int i = 0;
18365 for (i = 0U; i < suppChannelLen; i++)
18366 {
18367 suppPeerChannel =
18368 tdlsLinkEstablishParams.supportedChannels[i];
18369
18370 pTdlsPeer->isOffChannelSupported = FALSE;
18371 if (suppPeerChannel ==
18372 pTdlsPeer->peerParams.channel)
18373 {
18374 pTdlsPeer->isOffChannelSupported = TRUE;
18375 break;
18376 }
18377 }
18378 }
18379 else
18380 {
18381 pTdlsPeer->isOffChannelSupported = FALSE;
18382 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018383 }
18384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18385 "%s: TDLS channel switch request for channel "
18386 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018387 "%d isOffChannelSupported %d", __func__,
18388 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018389 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018390 suppChannelLen,
18391 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018392
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018393 /* TDLS Off Channel, Enable tdls channel switch,
18394 when their is only one tdls link and it supports */
18395 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18396 if ((numCurrTdlsPeers == 1) &&
18397 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18398 (TRUE == pTdlsPeer->isOffChannelConfigured))
18399 {
18400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18401 "%s: Send TDLS channel switch request for channel %d",
18402 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018403
18404 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018405 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18406 channel = pTdlsPeer->peerParams.channel;
18407
18408 mutex_unlock(&pHddCtx->tdls_lock);
18409
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018410 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18411 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018412 peerMac,
18413 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018414 TDLS_OFF_CHANNEL_BW_OFFSET,
18415 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018416 if (ret != VOS_STATUS_SUCCESS) {
18417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18418 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018419 }
18420 else
18421 {
18422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18423 "%s: TDLS channel switch request not sent"
18424 " numCurrTdlsPeers %d "
18425 "isOffChannelSupported %d "
18426 "isOffChannelConfigured %d",
18427 __func__, numCurrTdlsPeers,
18428 pTdlsPeer->isOffChannelSupported,
18429 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018430 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018431 }
18432
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018433 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018434 else
18435 mutex_unlock(&pHddCtx->tdls_lock);
18436
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018437 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018438
18439 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018440 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18441 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018442 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018443 int ac;
18444 uint8 ucAc[4] = { WLANTL_AC_VO,
18445 WLANTL_AC_VI,
18446 WLANTL_AC_BK,
18447 WLANTL_AC_BE };
18448 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18449 for(ac=0; ac < 4; ac++)
18450 {
18451 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18452 pTdlsPeer->staId, ucAc[ac],
18453 tlTid[ac], tlTid[ac], 0, 0,
18454 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018455 if (status != VOS_STATUS_SUCCESS) {
18456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18457 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018458 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018459 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018460 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018461
Bhargav Shah66896792015-10-01 18:17:37 +053018462 /* stop TCP delack timer if TDLS is enable */
18463 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18464 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018465 hdd_wlan_tdls_enable_link_event(peer,
18466 pTdlsPeer->isOffChannelSupported,
18467 pTdlsPeer->isOffChannelConfigured,
18468 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018469 }
18470 break;
18471 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018472 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018473 tANI_U16 numCurrTdlsPeers = 0;
18474 hddTdlsPeer_t *connPeer = NULL;
18475
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18477 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18478 __func__, MAC_ADDR_ARRAY(peer));
18479
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018480 mutex_lock(&pHddCtx->tdls_lock);
18481 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018482
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018483
Sunil Dutt41de4e22013-11-14 18:09:02 +053018484 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018485 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18487 " (oper %d) not exsting. ignored",
18488 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18489 return -EINVAL;
18490 }
18491
18492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18493 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18494 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18495 "NL80211_TDLS_DISABLE_LINK");
18496
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018497 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018498 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018499 long status;
18500
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018501 /* set tdls off channel status to false for this peer */
18502 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018503 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18504 eTDLS_LINK_TEARING,
18505 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18506 eTDLS_LINK_UNSPECIFIED:
18507 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018508 mutex_unlock(&pHddCtx->tdls_lock);
18509
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018510 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18511
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018512 status = sme_DeleteTdlsPeerSta(
18513 WLAN_HDD_GET_HAL_CTX(pAdapter),
18514 pAdapter->sessionId, peer );
18515 if (status != VOS_STATUS_SUCCESS) {
18516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18517 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018518
18519 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18520 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018521
18522 mutex_lock(&pHddCtx->tdls_lock);
18523 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18524 if ( NULL == pTdlsPeer ) {
18525 mutex_unlock(&pHddCtx->tdls_lock);
18526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18527 " peer was freed in other context",
18528 __func__, MAC_ADDR_ARRAY(peer));
18529 return -EINVAL;
18530 }
18531
Atul Mittal271a7652014-09-12 13:18:22 +053018532 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018533 eTDLS_LINK_IDLE,
18534 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018535 mutex_unlock(&pHddCtx->tdls_lock);
18536
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018537 if (status <= 0)
18538 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18540 "%s: Del station failed status %ld",
18541 __func__, status);
18542 return -EPERM;
18543 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018544
18545 /* TDLS Off Channel, Enable tdls channel switch,
18546 when their is only one tdls link and it supports */
18547 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18548 if (numCurrTdlsPeers == 1)
18549 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018550 tSirMacAddr peerMac;
18551 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018552
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018553 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018554 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018555
18556 if (connPeer == NULL) {
18557 mutex_unlock(&pHddCtx->tdls_lock);
18558 hddLog(VOS_TRACE_LEVEL_ERROR,
18559 "%s connPeer is NULL", __func__);
18560 return -EINVAL;
18561 }
18562
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018563 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18564 channel = connPeer->peerParams.channel;
18565
18566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18567 "%s: TDLS channel switch "
18568 "isOffChannelSupported %d "
18569 "isOffChannelConfigured %d "
18570 "isOffChannelEstablished %d",
18571 __func__,
18572 (connPeer ? connPeer->isOffChannelSupported : -1),
18573 (connPeer ? connPeer->isOffChannelConfigured : -1),
18574 (connPeer ? connPeer->isOffChannelEstablished : -1));
18575
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018576 if ((connPeer) &&
18577 (connPeer->isOffChannelSupported == TRUE) &&
18578 (connPeer->isOffChannelConfigured == TRUE))
18579 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018580 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018581 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018582 status = sme_SendTdlsChanSwitchReq(
18583 WLAN_HDD_GET_HAL_CTX(pAdapter),
18584 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018585 peerMac,
18586 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018587 TDLS_OFF_CHANNEL_BW_OFFSET,
18588 TDLS_CHANNEL_SWITCH_ENABLE);
18589 if (status != VOS_STATUS_SUCCESS) {
18590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18591 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018592 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018593 else
18594 mutex_unlock(&pHddCtx->tdls_lock);
18595 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018596 else
18597 {
18598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18599 "%s: TDLS channel switch request not sent "
18600 "numCurrTdlsPeers %d ",
18601 __func__, numCurrTdlsPeers);
18602 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018603 }
18604 else
18605 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018606 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18608 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018609 }
Bhargav Shah66896792015-10-01 18:17:37 +053018610 if (numCurrTdlsPeers == 0) {
18611 /* start TCP delack timer if TDLS is disable */
18612 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18613 hdd_manage_delack_timer(pHddCtx);
18614 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018615 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018616 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018617 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018618 {
Atul Mittal115287b2014-07-08 13:26:33 +053018619 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018620
Atul Mittal115287b2014-07-08 13:26:33 +053018621 if (0 != status)
18622 {
18623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018624 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018625 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018626 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018627 break;
18628 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018629 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018630 {
Atul Mittal115287b2014-07-08 13:26:33 +053018631 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18632 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018633 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018634 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018635
Atul Mittal115287b2014-07-08 13:26:33 +053018636 if (0 != status)
18637 {
18638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018639 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018640 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018641 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018642 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018643 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018644 case NL80211_TDLS_DISCOVERY_REQ:
18645 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018647 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018648 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018649 return -ENOTSUPP;
18650 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18652 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018653 return -ENOTSUPP;
18654 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018655
18656 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018657 return 0;
18658}
Chilam NG571c65a2013-01-19 12:27:36 +053018659
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018660static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18662 const u8 *peer,
18663#else
18664 u8 *peer,
18665#endif
18666 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018667{
18668 int ret;
18669
18670 vos_ssr_protect(__func__);
18671 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18672 vos_ssr_unprotect(__func__);
18673
18674 return ret;
18675}
18676
Chilam NG571c65a2013-01-19 12:27:36 +053018677int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18678 struct net_device *dev, u8 *peer)
18679{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018680 hddLog(VOS_TRACE_LEVEL_INFO,
18681 "tdls send discover req: "MAC_ADDRESS_STR,
18682 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018683#if TDLS_MGMT_VERSION2
18684 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18685 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18686#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18688 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18689 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18690#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18691 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18692 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18693#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18694 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18695 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18696#else
Chilam NG571c65a2013-01-19 12:27:36 +053018697 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18698 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018699#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018700#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018701}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018702#endif
18703
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018704#ifdef WLAN_FEATURE_GTK_OFFLOAD
18705/*
18706 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18707 * Callback rountine called upon receiving response for
18708 * get offload info
18709 */
18710void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18711 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18712{
18713
18714 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018715 tANI_U8 tempReplayCounter[8];
18716 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018717
18718 ENTER();
18719
18720 if (NULL == pAdapter)
18721 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018723 "%s: HDD adapter is Null", __func__);
18724 return ;
18725 }
18726
18727 if (NULL == pGtkOffloadGetInfoRsp)
18728 {
18729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18730 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18731 return ;
18732 }
18733
18734 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18735 {
18736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18737 "%s: wlan Failed to get replay counter value",
18738 __func__);
18739 return ;
18740 }
18741
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018742 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18743 /* Update replay counter */
18744 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18745 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18746
18747 {
18748 /* changing from little to big endian since supplicant
18749 * works on big endian format
18750 */
18751 int i;
18752 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18753
18754 for (i = 0; i < 8; i++)
18755 {
18756 tempReplayCounter[7-i] = (tANI_U8)p[i];
18757 }
18758 }
18759
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018760 /* Update replay counter to NL */
18761 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018762 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018763}
18764
18765/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018766 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018767 * This function is used to offload GTK rekeying job to the firmware.
18768 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018769int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018770 struct cfg80211_gtk_rekey_data *data)
18771{
18772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18773 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18774 hdd_station_ctx_t *pHddStaCtx;
18775 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018776 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018777 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018778 eHalStatus status = eHAL_STATUS_FAILURE;
18779
18780 ENTER();
18781
18782 if (NULL == pAdapter)
18783 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018785 "%s: HDD adapter is Null", __func__);
18786 return -ENODEV;
18787 }
18788
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18790 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18791 pAdapter->sessionId, pAdapter->device_mode));
18792
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018793 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018794 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018796 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018797 }
18798
18799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18800 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18801 if (NULL == hHal)
18802 {
18803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18804 "%s: HAL context is Null!!!", __func__);
18805 return -EAGAIN;
18806 }
18807
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018808 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18809 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18810 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18811 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018812 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018813 {
18814 /* changing from big to little endian since driver
18815 * works on little endian format
18816 */
18817 tANI_U8 *p =
18818 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18819 int i;
18820
18821 for (i = 0; i < 8; i++)
18822 {
18823 p[7-i] = data->replay_ctr[i];
18824 }
18825 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018826
18827 if (TRUE == pHddCtx->hdd_wlan_suspended)
18828 {
18829 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018830 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18831 sizeof (tSirGtkOffloadParams));
18832 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018833 pAdapter->sessionId);
18834
18835 if (eHAL_STATUS_SUCCESS != status)
18836 {
18837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18838 "%s: sme_SetGTKOffload failed, returned %d",
18839 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018840
18841 /* Need to clear any trace of key value in the memory.
18842 * Thus zero out the memory even though it is local
18843 * variable.
18844 */
18845 vos_mem_zero(&hddGtkOffloadReqParams,
18846 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018847 return status;
18848 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18850 "%s: sme_SetGTKOffload successfull", __func__);
18851 }
18852 else
18853 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18855 "%s: wlan not suspended GTKOffload request is stored",
18856 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018857 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018858
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018859 /* Need to clear any trace of key value in the memory.
18860 * Thus zero out the memory even though it is local
18861 * variable.
18862 */
18863 vos_mem_zero(&hddGtkOffloadReqParams,
18864 sizeof(hddGtkOffloadReqParams));
18865
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018866 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018867 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018868}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018869
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018870int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18871 struct cfg80211_gtk_rekey_data *data)
18872{
18873 int ret;
18874
18875 vos_ssr_protect(__func__);
18876 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18877 vos_ssr_unprotect(__func__);
18878
18879 return ret;
18880}
18881#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018882/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018883 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018884 * This function is used to set access control policy
18885 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018886static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18887 struct net_device *dev,
18888 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018889{
18890 int i;
18891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18892 hdd_hostapd_state_t *pHostapdState;
18893 tsap_Config_t *pConfig;
18894 v_CONTEXT_t pVosContext = NULL;
18895 hdd_context_t *pHddCtx;
18896 int status;
18897
18898 ENTER();
18899
18900 if (NULL == pAdapter)
18901 {
18902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18903 "%s: HDD adapter is Null", __func__);
18904 return -ENODEV;
18905 }
18906
18907 if (NULL == params)
18908 {
18909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18910 "%s: params is Null", __func__);
18911 return -EINVAL;
18912 }
18913
18914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18915 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018916 if (0 != status)
18917 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018918 return status;
18919 }
18920
18921 pVosContext = pHddCtx->pvosContext;
18922 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18923
18924 if (NULL == pHostapdState)
18925 {
18926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18927 "%s: pHostapdState is Null", __func__);
18928 return -EINVAL;
18929 }
18930
18931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18932 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18934 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18935 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018936
18937 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18938 {
18939 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18940
18941 /* default value */
18942 pConfig->num_accept_mac = 0;
18943 pConfig->num_deny_mac = 0;
18944
18945 /**
18946 * access control policy
18947 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18948 * listed in hostapd.deny file.
18949 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18950 * listed in hostapd.accept file.
18951 */
18952 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18953 {
18954 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18955 }
18956 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18957 {
18958 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18959 }
18960 else
18961 {
18962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18963 "%s:Acl Policy : %d is not supported",
18964 __func__, params->acl_policy);
18965 return -ENOTSUPP;
18966 }
18967
18968 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18969 {
18970 pConfig->num_accept_mac = params->n_acl_entries;
18971 for (i = 0; i < params->n_acl_entries; i++)
18972 {
18973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18974 "** Add ACL MAC entry %i in WhiletList :"
18975 MAC_ADDRESS_STR, i,
18976 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18977
18978 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18979 sizeof(qcmacaddr));
18980 }
18981 }
18982 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18983 {
18984 pConfig->num_deny_mac = params->n_acl_entries;
18985 for (i = 0; i < params->n_acl_entries; i++)
18986 {
18987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18988 "** Add ACL MAC entry %i in BlackList :"
18989 MAC_ADDRESS_STR, i,
18990 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18991
18992 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18993 sizeof(qcmacaddr));
18994 }
18995 }
18996
18997 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18998 {
18999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19000 "%s: SAP Set Mac Acl fail", __func__);
19001 return -EINVAL;
19002 }
19003 }
19004 else
19005 {
19006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019007 "%s: Invalid device_mode = %s (%d)",
19008 __func__, hdd_device_modetoString(pAdapter->device_mode),
19009 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019010 return -EINVAL;
19011 }
19012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019013 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019014 return 0;
19015}
19016
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019017static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19018 struct net_device *dev,
19019 const struct cfg80211_acl_data *params)
19020{
19021 int ret;
19022 vos_ssr_protect(__func__);
19023 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19024 vos_ssr_unprotect(__func__);
19025
19026 return ret;
19027}
19028
Leo Chang9056f462013-08-01 19:21:11 -070019029#ifdef WLAN_NL80211_TESTMODE
19030#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019031void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019032(
19033 void *pAdapter,
19034 void *indCont
19035)
19036{
Leo Changd9df8aa2013-09-26 13:32:26 -070019037 tSirLPHBInd *lphbInd;
19038 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019039 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019040
19041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019042 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019043
c_hpothu73f35e62014-04-18 13:40:08 +053019044 if (pAdapter == NULL)
19045 {
19046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19047 "%s: pAdapter is NULL\n",__func__);
19048 return;
19049 }
19050
Leo Chang9056f462013-08-01 19:21:11 -070019051 if (NULL == indCont)
19052 {
19053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019054 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019055 return;
19056 }
19057
c_hpothu73f35e62014-04-18 13:40:08 +053019058 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019059 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019060 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019061 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019062 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019063 GFP_ATOMIC);
19064 if (!skb)
19065 {
19066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19067 "LPHB timeout, NL buffer alloc fail");
19068 return;
19069 }
19070
Leo Changac3ba772013-10-07 09:47:04 -070019071 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019072 {
19073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19074 "WLAN_HDD_TM_ATTR_CMD put fail");
19075 goto nla_put_failure;
19076 }
Leo Changac3ba772013-10-07 09:47:04 -070019077 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019078 {
19079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19080 "WLAN_HDD_TM_ATTR_TYPE put fail");
19081 goto nla_put_failure;
19082 }
Leo Changac3ba772013-10-07 09:47:04 -070019083 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019084 sizeof(tSirLPHBInd), lphbInd))
19085 {
19086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19087 "WLAN_HDD_TM_ATTR_DATA put fail");
19088 goto nla_put_failure;
19089 }
Leo Chang9056f462013-08-01 19:21:11 -070019090 cfg80211_testmode_event(skb, GFP_ATOMIC);
19091 return;
19092
19093nla_put_failure:
19094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19095 "NLA Put fail");
19096 kfree_skb(skb);
19097
19098 return;
19099}
19100#endif /* FEATURE_WLAN_LPHB */
19101
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019102static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019103{
19104 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19105 int err = 0;
19106#ifdef FEATURE_WLAN_LPHB
19107 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019108 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019109
19110 ENTER();
19111
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019112 err = wlan_hdd_validate_context(pHddCtx);
19113 if (0 != err)
19114 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019115 return err;
19116 }
Leo Chang9056f462013-08-01 19:21:11 -070019117#endif /* FEATURE_WLAN_LPHB */
19118
19119 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19120 if (err)
19121 {
19122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19123 "%s Testmode INV ATTR", __func__);
19124 return err;
19125 }
19126
19127 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19128 {
19129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19130 "%s Testmode INV CMD", __func__);
19131 return -EINVAL;
19132 }
19133
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19135 TRACE_CODE_HDD_CFG80211_TESTMODE,
19136 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019137 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19138 {
19139#ifdef FEATURE_WLAN_LPHB
19140 /* Low Power Heartbeat configuration request */
19141 case WLAN_HDD_TM_CMD_WLAN_HB:
19142 {
19143 int buf_len;
19144 void *buf;
19145 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019146 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019147
19148 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19149 {
19150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19151 "%s Testmode INV DATA", __func__);
19152 return -EINVAL;
19153 }
19154
19155 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19156 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019157
19158 hb_params_temp =(tSirLPHBReq *)buf;
19159 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19160 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19161 return -EINVAL;
19162
Leo Chang9056f462013-08-01 19:21:11 -070019163 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19164 if (NULL == hb_params)
19165 {
19166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19167 "%s Request Buffer Alloc Fail", __func__);
19168 return -EINVAL;
19169 }
19170
19171 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019172 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19173 hb_params,
19174 wlan_hdd_cfg80211_lphb_ind_handler);
19175 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019176 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19178 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019179 vos_mem_free(hb_params);
19180 }
Leo Chang9056f462013-08-01 19:21:11 -070019181 return 0;
19182 }
19183#endif /* FEATURE_WLAN_LPHB */
19184 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19186 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019187 return -EOPNOTSUPP;
19188 }
19189
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019190 EXIT();
19191 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019192}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019193
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019194static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19196 struct wireless_dev *wdev,
19197#endif
19198 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019199{
19200 int ret;
19201
19202 vos_ssr_protect(__func__);
19203 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19204 vos_ssr_unprotect(__func__);
19205
19206 return ret;
19207}
Leo Chang9056f462013-08-01 19:21:11 -070019208#endif /* CONFIG_NL80211_TESTMODE */
19209
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019210static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019211 struct net_device *dev,
19212 int idx, struct survey_info *survey)
19213{
19214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19215 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019216 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019217 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019218 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019219 v_S7_t snr,rssi;
19220 int status, i, j, filled = 0;
19221
19222 ENTER();
19223
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019224 if (NULL == pAdapter)
19225 {
19226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19227 "%s: HDD adapter is Null", __func__);
19228 return -ENODEV;
19229 }
19230
19231 if (NULL == wiphy)
19232 {
19233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19234 "%s: wiphy is Null", __func__);
19235 return -ENODEV;
19236 }
19237
19238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19239 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019240 if (0 != status)
19241 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019242 return status;
19243 }
19244
Mihir Sheted9072e02013-08-21 17:02:29 +053019245 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19246
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019247 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019248 0 != pAdapter->survey_idx ||
19249 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019250 {
19251 /* The survey dump ops when implemented completely is expected to
19252 * return a survey of all channels and the ops is called by the
19253 * kernel with incremental values of the argument 'idx' till it
19254 * returns -ENONET. But we can only support the survey for the
19255 * operating channel for now. survey_idx is used to track
19256 * that the ops is called only once and then return -ENONET for
19257 * the next iteration
19258 */
19259 pAdapter->survey_idx = 0;
19260 return -ENONET;
19261 }
19262
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019263 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19264 {
19265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19266 "%s: Roaming in progress, hence return ", __func__);
19267 return -ENONET;
19268 }
19269
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019270 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19271
19272 wlan_hdd_get_snr(pAdapter, &snr);
19273 wlan_hdd_get_rssi(pAdapter, &rssi);
19274
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19276 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19277 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019278 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19279 hdd_wlan_get_freq(channel, &freq);
19280
19281
19282 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19283 {
19284 if (NULL == wiphy->bands[i])
19285 {
19286 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19287 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19288 continue;
19289 }
19290
19291 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19292 {
19293 struct ieee80211_supported_band *band = wiphy->bands[i];
19294
19295 if (band->channels[j].center_freq == (v_U16_t)freq)
19296 {
19297 survey->channel = &band->channels[j];
19298 /* The Rx BDs contain SNR values in dB for the received frames
19299 * while the supplicant expects noise. So we calculate and
19300 * return the value of noise (dBm)
19301 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19302 */
19303 survey->noise = rssi - snr;
19304 survey->filled = SURVEY_INFO_NOISE_DBM;
19305 filled = 1;
19306 }
19307 }
19308 }
19309
19310 if (filled)
19311 pAdapter->survey_idx = 1;
19312 else
19313 {
19314 pAdapter->survey_idx = 0;
19315 return -ENONET;
19316 }
19317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019318 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019319 return 0;
19320}
19321
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019322static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19323 struct net_device *dev,
19324 int idx, struct survey_info *survey)
19325{
19326 int ret;
19327
19328 vos_ssr_protect(__func__);
19329 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19330 vos_ssr_unprotect(__func__);
19331
19332 return ret;
19333}
19334
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019335/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019336 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019337 * this is called when cfg80211 driver resume
19338 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19339 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019340int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019341{
19342 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19343 hdd_adapter_t *pAdapter;
19344 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19345 VOS_STATUS status = VOS_STATUS_SUCCESS;
19346
19347 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019348
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019349 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019350 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019351 return 0;
19352 }
19353
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019354 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19355 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019356 spin_lock(&pHddCtx->schedScan_lock);
19357 pHddCtx->isWiphySuspended = FALSE;
19358 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19359 {
19360 spin_unlock(&pHddCtx->schedScan_lock);
19361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19362 "%s: Return resume is not due to PNO indication", __func__);
19363 return 0;
19364 }
19365 // Reset flag to avoid updatating cfg80211 data old results again
19366 pHddCtx->isSchedScanUpdatePending = FALSE;
19367 spin_unlock(&pHddCtx->schedScan_lock);
19368
19369 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19370
19371 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19372 {
19373 pAdapter = pAdapterNode->pAdapter;
19374 if ( (NULL != pAdapter) &&
19375 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19376 {
19377 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019378 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19380 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019381 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019382 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019383 {
19384 /* Acquire wakelock to handle the case where APP's tries to
19385 * suspend immediately after updating the scan results. Whis
19386 * results in app's is in suspended state and not able to
19387 * process the connect request to AP
19388 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019389 hdd_prevent_suspend_timeout(2000,
19390 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019391 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019392 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019393
19394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19395 "%s : cfg80211 scan result database updated", __func__);
19396
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019397 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019398 return 0;
19399
19400 }
19401 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19402 pAdapterNode = pNext;
19403 }
19404
19405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19406 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019407 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019408 return 0;
19409}
19410
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019411int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19412{
19413 int ret;
19414
19415 vos_ssr_protect(__func__);
19416 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19417 vos_ssr_unprotect(__func__);
19418
19419 return ret;
19420}
19421
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019422/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019423 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019424 * this is called when cfg80211 driver suspends
19425 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019426int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019427 struct cfg80211_wowlan *wow)
19428{
19429 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019430 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019431
19432 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019433
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019434 ret = wlan_hdd_validate_context(pHddCtx);
19435 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019436 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019437 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019438 }
19439
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019440
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19442 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19443 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019444 pHddCtx->isWiphySuspended = TRUE;
19445
19446 EXIT();
19447
19448 return 0;
19449}
19450
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019451int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19452 struct cfg80211_wowlan *wow)
19453{
19454 int ret;
19455
19456 vos_ssr_protect(__func__);
19457 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19458 vos_ssr_unprotect(__func__);
19459
19460 return ret;
19461}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019462
19463#ifdef FEATURE_OEM_DATA_SUPPORT
19464static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019465 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019466{
19467 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19468
19469 ENTER();
19470
19471 if (wlan_hdd_validate_context(pHddCtx)) {
19472 return;
19473 }
19474 if (!pMsg)
19475 {
19476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19477 return;
19478 }
19479
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019480 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019481
19482 EXIT();
19483 return;
19484
19485}
19486
19487void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019488 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019489{
19490 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19491
19492 ENTER();
19493
19494 if (wlan_hdd_validate_context(pHddCtx)) {
19495 return;
19496 }
19497
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019499
19500 switch(evType) {
19501 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019502 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019503 break;
19504 default:
19505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19506 break;
19507 }
19508 EXIT();
19509}
19510#endif
19511
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19513 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019514/**
19515 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19516 * @wiphy: Pointer to wiphy
19517 * @wdev: Pointer to wireless device structure
19518 *
19519 * This function is used to abort an ongoing scan
19520 *
19521 * Return: None
19522 */
19523static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19524 struct wireless_dev *wdev)
19525{
19526 struct net_device *dev = wdev->netdev;
19527 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19528 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19529 int ret;
19530
19531 ENTER();
19532
19533 if (NULL == adapter) {
19534 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19535 return;
19536 }
19537
19538 ret = wlan_hdd_validate_context(hdd_ctx);
19539 if (0 != ret)
19540 return;
19541
19542 wlan_hdd_scan_abort(adapter);
19543
19544 return;
19545}
19546
19547/**
19548 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19549 * @wiphy: Pointer to wiphy
19550 * @wdev: Pointer to wireless device structure
19551 *
19552 * Return: None
19553 */
19554void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19555 struct wireless_dev *wdev)
19556{
19557 vos_ssr_protect(__func__);
19558 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19559 vos_ssr_unprotect(__func__);
19560
19561 return;
19562}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019563#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019564
Jeff Johnson295189b2012-06-20 16:38:30 -070019565/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019566static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019567{
19568 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19569 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19570 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19571 .change_station = wlan_hdd_change_station,
19572#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19573 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19574 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19575 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019576#else
19577 .start_ap = wlan_hdd_cfg80211_start_ap,
19578 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19579 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019580#endif
19581 .change_bss = wlan_hdd_cfg80211_change_bss,
19582 .add_key = wlan_hdd_cfg80211_add_key,
19583 .get_key = wlan_hdd_cfg80211_get_key,
19584 .del_key = wlan_hdd_cfg80211_del_key,
19585 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019586#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019587 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019588#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019589 .scan = wlan_hdd_cfg80211_scan,
19590 .connect = wlan_hdd_cfg80211_connect,
19591 .disconnect = wlan_hdd_cfg80211_disconnect,
19592 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19593 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19594 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19595 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19596 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019597 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19598 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019599 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19601 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19602 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19603 .set_txq_params = wlan_hdd_set_txq_params,
19604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019605 .get_station = wlan_hdd_cfg80211_get_station,
19606 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19607 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019608 .add_station = wlan_hdd_cfg80211_add_station,
19609#ifdef FEATURE_WLAN_LFR
19610 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19611 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19612 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19613#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019614#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19615 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19616#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019617#ifdef FEATURE_WLAN_TDLS
19618 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19619 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19620#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019621#ifdef WLAN_FEATURE_GTK_OFFLOAD
19622 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19623#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019624#ifdef FEATURE_WLAN_SCAN_PNO
19625 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19626 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19627#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019628 .resume = wlan_hdd_cfg80211_resume_wlan,
19629 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019630 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019631#ifdef WLAN_NL80211_TESTMODE
19632 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19633#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019634 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19636 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019637 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019638#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019639};
19640