blob: 0a53e43caebce0076fe21c50f83858f9bdc6e8a1 [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 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301731 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 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
c_manjee1b4ab9a2016-10-26 11:36:55 +053012697 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12698 !pAdapter->dev) {
12699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12700 return 0;
12701 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012702 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012703 if (NULL == pHddCtx) {
12704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012705 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012706 }
12707
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12709 if (!(pAdapter->dev->flags & IFF_UP))
12710 {
12711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012712 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012713 }
12714#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012715 pScanInfo = &pHddCtx->scan_info;
12716
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 hddLog(VOS_TRACE_LEVEL_INFO,
12718 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012719 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012720 __func__, halHandle, pContext, (int) scanId, (int) status);
12721
Kiet Lamac06e2c2013-10-23 16:25:07 +053012722 pScanInfo->mScanPendingCounter = 0;
12723
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012725 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 &pScanInfo->scan_req_completion_event,
12727 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012728 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012730 hddLog(VOS_TRACE_LEVEL_ERROR,
12731 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012733 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 }
12735
Yue Maef608272013-04-08 23:09:17 -070012736 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012737 {
12738 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012739 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 }
12741
12742 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 {
12745 hddLog(VOS_TRACE_LEVEL_INFO,
12746 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012747 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012748 (int) scanId);
12749 }
12750
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012752 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012753#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012754 {
12755 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12756 pAdapter);
12757 if (0 > ret)
12758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012759 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012760
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 /* If any client wait scan result through WEXT
12762 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012763 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012764 {
12765 /* The other scan request waiting for current scan finish
12766 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012767 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012768 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012769 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012770 }
12771 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012772 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012773 {
12774 struct net_device *dev = pAdapter->dev;
12775 union iwreq_data wrqu;
12776 int we_event;
12777 char *msg;
12778
12779 memset(&wrqu, '\0', sizeof(wrqu));
12780 we_event = SIOCGIWSCAN;
12781 msg = NULL;
12782 wireless_send_event(dev, we_event, &wrqu, msg);
12783 }
12784 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012785 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012786
12787 /* Get the Scan Req */
12788 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012789 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012790
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012791 /* Scan is no longer pending */
12792 pScanInfo->mScanPending = VOS_FALSE;
12793
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012794 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12798 iface_down ? "up" : "down");
12799#endif
12800
12801 if (pAdapter->dev) {
12802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12803 pAdapter->dev->name);
12804 }
mukul sharmae7041822015-12-03 15:09:21 +053012805 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012806 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 }
12808
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012809 /* last_scan_timestamp is used to decide if new scan
12810 * is needed or not on station interface. If last station
12811 * scan time and new station scan time is less then
12812 * last_scan_timestamp ; driver will return cached scan.
12813 */
12814 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12815 {
12816 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12817
12818 if ( req->n_channels )
12819 {
12820 for (i = 0; i < req->n_channels ; i++ )
12821 {
12822 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12823 }
12824 /* store no of channel scanned */
12825 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12826 }
12827
12828 }
12829
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012830 /*
12831 * cfg80211_scan_done informing NL80211 about completion
12832 * of scanning
12833 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012834 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12835 {
12836 aborted = true;
12837 }
mukul sharmae7041822015-12-03 15:09:21 +053012838
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12840 if (!iface_down)
12841#endif
12842 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012843
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012844 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012845
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012846allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012847 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12848 ) && (pHddCtx->spoofMacAddr.isEnabled
12849 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012850 /* Generate new random mac addr for next scan */
12851 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012852
12853 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12854 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012855 }
12856
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012857 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012858 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012859
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012860 /* Acquire wakelock to handle the case where APP's tries to suspend
12861 * immediatly after the driver gets connect request(i.e after scan)
12862 * from supplicant, this result in app's is suspending and not able
12863 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012864 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012865
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12867 if (!iface_down)
12868#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012869#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012870 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012871#endif
12872
Jeff Johnson295189b2012-06-20 16:38:30 -070012873 EXIT();
12874 return 0;
12875}
12876
12877/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012878 * FUNCTION: hdd_isConnectionInProgress
12879 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012880 *
12881 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012882v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012883{
12884 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12885 hdd_station_ctx_t *pHddStaCtx = NULL;
12886 hdd_adapter_t *pAdapter = NULL;
12887 VOS_STATUS status = 0;
12888 v_U8_t staId = 0;
12889 v_U8_t *staMac = NULL;
12890
12891 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12892
12893 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12894 {
12895 pAdapter = pAdapterNode->pAdapter;
12896
12897 if( pAdapter )
12898 {
12899 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012900 "%s: Adapter with device mode %s (%d) exists",
12901 __func__, hdd_device_modetoString(pAdapter->device_mode),
12902 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012903 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012904 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12905 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12906 (eConnectionState_Connecting ==
12907 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12908 {
12909 hddLog(VOS_TRACE_LEVEL_ERROR,
12910 "%s: %p(%d) Connection is in progress", __func__,
12911 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12912 return VOS_TRUE;
12913 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012914 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012915 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012916 {
12917 hddLog(VOS_TRACE_LEVEL_ERROR,
12918 "%s: %p(%d) Reassociation is in progress", __func__,
12919 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12920 return VOS_TRUE;
12921 }
12922 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012923 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12924 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012925 {
12926 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12927 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012928 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012929 {
12930 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12931 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012932 "%s: client " MAC_ADDRESS_STR
12933 " is in the middle of WPS/EAPOL exchange.", __func__,
12934 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012935 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012936 }
12937 }
12938 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12939 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12940 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012941 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12942 ptSapContext pSapCtx = NULL;
12943 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12944 if(pSapCtx == NULL){
12945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12946 FL("psapCtx is NULL"));
12947 return VOS_FALSE;
12948 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012949 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12950 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012951 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12952 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012953 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012954 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012955
12956 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012957 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12958 "middle of WPS/EAPOL exchange.", __func__,
12959 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012960 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012961 }
12962 }
12963 }
12964 }
12965 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12966 pAdapterNode = pNext;
12967 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012968 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012969}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012970
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012971/**
12972 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12973 * to the Scan request
12974 * @scanRequest: Pointer to the csr scan request
12975 * @request: Pointer to the scan request from supplicant
12976 *
12977 * Return: None
12978 */
12979#ifdef CFG80211_SCAN_BSSID
12980static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12981 struct cfg80211_scan_request *request)
12982{
12983 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12984}
12985#else
12986static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12987 struct cfg80211_scan_request *request)
12988{
12989}
12990#endif
12991
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012992/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012993 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 * this scan respond to scan trigger and update cfg80211 scan database
12995 * later, scan dump command can be used to recieve scan results
12996 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012997int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012998#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12999 struct net_device *dev,
13000#endif
13001 struct cfg80211_scan_request *request)
13002{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013003 hdd_adapter_t *pAdapter = NULL;
13004 hdd_context_t *pHddCtx = NULL;
13005 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013006 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 tCsrScanRequest scanRequest;
13008 tANI_U8 *channelList = NULL, i;
13009 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013010 int status;
13011 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013013 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013014 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013015 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013016
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13018 struct net_device *dev = NULL;
13019 if (NULL == request)
13020 {
13021 hddLog(VOS_TRACE_LEVEL_ERROR,
13022 "%s: scan req param null", __func__);
13023 return -EINVAL;
13024 }
13025 dev = request->wdev->netdev;
13026#endif
13027
13028 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13029 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13030 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13031
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 ENTER();
13033
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13035 __func__, hdd_device_modetoString(pAdapter->device_mode),
13036 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013038 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013039 if (0 != status)
13040 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013041 return status;
13042 }
13043
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013044 if (NULL == pwextBuf)
13045 {
13046 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13047 __func__);
13048 return -EIO;
13049 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013050 cfg_param = pHddCtx->cfg_ini;
13051 pScanInfo = &pHddCtx->scan_info;
13052
Jeff Johnson295189b2012-06-20 16:38:30 -070013053#ifdef WLAN_BTAMP_FEATURE
13054 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013055 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013057 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 "%s: No scanning when AMP is on", __func__);
13059 return -EOPNOTSUPP;
13060 }
13061#endif
13062 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013063 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013065 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013066 "%s: Not scanning on device_mode = %s (%d)",
13067 __func__, hdd_device_modetoString(pAdapter->device_mode),
13068 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 return -EOPNOTSUPP;
13070 }
13071
13072 if (TRUE == pScanInfo->mScanPending)
13073 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013074 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13075 {
13076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13077 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013078 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 }
13080
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013081 // Don't allow scan if PNO scan is going on.
13082 if (pHddCtx->isPnoEnable)
13083 {
13084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13085 FL("pno scan in progress"));
13086 return -EBUSY;
13087 }
13088
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013089 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013090 //Channel and action frame is pending
13091 //Otherwise Cancel Remain On Channel and allow Scan
13092 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013093 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013094 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013096 return -EBUSY;
13097 }
13098
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13100 {
13101 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013102 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13106 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013107 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013108 "%s: MAX TM Level Scan not allowed", __func__);
13109 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013110 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013111 }
13112 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13113
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013114 /* Check if scan is allowed at this point of time.
13115 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013116 if (TRUE == pHddCtx->btCoexModeSet)
13117 {
13118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13119 FL("BTCoex Mode operation in progress"));
13120 return -EBUSY;
13121 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013122 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013123 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13125 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13127 FL("Triggering SSR, SSR status = %d"), status);
13128 vos_wlanRestart();
13129 }
13130 else
13131 pHddCtx->con_scan_abort_cnt++;
13132
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013133 return -EBUSY;
13134 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013135 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013136
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13138
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013139 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13140 * Becasue of this, driver is assuming that this is not wildcard scan and so
13141 * is not aging out the scan results.
13142 */
13143 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013145 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013146 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013147
13148 if ((request->ssids) && (0 < request->n_ssids))
13149 {
13150 tCsrSSIDInfo *SsidInfo;
13151 int j;
13152 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13153 /* Allocate num_ssid tCsrSSIDInfo structure */
13154 SsidInfo = scanRequest.SSIDs.SSIDList =
13155 ( tCsrSSIDInfo *)vos_mem_malloc(
13156 request->n_ssids*sizeof(tCsrSSIDInfo));
13157
13158 if(NULL == scanRequest.SSIDs.SSIDList)
13159 {
13160 hddLog(VOS_TRACE_LEVEL_ERROR,
13161 "%s: memory alloc failed SSIDInfo buffer", __func__);
13162 return -ENOMEM;
13163 }
13164
13165 /* copy all the ssid's and their length */
13166 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13167 {
13168 /* get the ssid length */
13169 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13170 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13171 SsidInfo->SSID.length);
13172 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13173 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13174 j, SsidInfo->SSID.ssId);
13175 }
13176 /* set the scan type to active */
13177 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13178 }
13179 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13182 TRACE_CODE_HDD_CFG80211_SCAN,
13183 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 /* set the scan type to active */
13185 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013186 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013187 else
13188 {
13189 /*Set the scan type to default type, in this case it is ACTIVE*/
13190 scanRequest.scanType = pScanInfo->scan_mode;
13191 }
13192 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13193 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013194
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013195 csr_scan_request_assign_bssid(&scanRequest, request);
13196
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 /* set BSSType to default type */
13198 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13199
13200 /*TODO: scan the requested channels only*/
13201
13202 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013203 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013204 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013205 hddLog(VOS_TRACE_LEVEL_WARN,
13206 "No of Scan Channels exceeded limit: %d", request->n_channels);
13207 request->n_channels = MAX_CHANNEL;
13208 }
13209
13210 hddLog(VOS_TRACE_LEVEL_INFO,
13211 "No of Scan Channels: %d", request->n_channels);
13212
13213
13214 if( request->n_channels )
13215 {
13216 char chList [(request->n_channels*5)+1];
13217 int len;
13218 channelList = vos_mem_malloc( request->n_channels );
13219 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013220 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013221 hddLog(VOS_TRACE_LEVEL_ERROR,
13222 "%s: memory alloc failed channelList", __func__);
13223 status = -ENOMEM;
13224 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013225 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013226
13227 for( i = 0, len = 0; i < request->n_channels ; i++ )
13228 {
13229 channelList[i] = request->channels[i]->hw_value;
13230 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13231 }
13232
Nirav Shah20ac06f2013-12-12 18:14:06 +053013233 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013234 "Channel-List: %s ", chList);
13235 }
c_hpothu53512302014-04-15 18:49:53 +053013236
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013237 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13238 scanRequest.ChannelInfo.ChannelList = channelList;
13239
13240 /* set requestType to full scan */
13241 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13242
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013243 /* if there is back to back scan happening in driver with in
13244 * nDeferScanTimeInterval interval driver should defer new scan request
13245 * and should provide last cached scan results instead of new channel list.
13246 * This rule is not applicable if scan is p2p scan.
13247 * This condition will work only in case when last request no of channels
13248 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013249 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013250 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013251 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013252
Sushant Kaushik86592172015-04-27 16:35:03 +053013253 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13254 /* if wps ie is NULL , then only defer scan */
13255 if ( pWpsIe == NULL &&
13256 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013257 {
13258 if ( pScanInfo->last_scan_timestamp !=0 &&
13259 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13260 {
13261 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13262 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13263 vos_mem_compare(pScanInfo->last_scan_channelList,
13264 channelList, pScanInfo->last_scan_numChannels))
13265 {
13266 hddLog(VOS_TRACE_LEVEL_WARN,
13267 " New and old station scan time differ is less then %u",
13268 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13269
13270 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013271 pAdapter);
13272
Agarwal Ashish57e84372014-12-05 18:26:53 +053013273 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013274 "Return old cached scan as all channels and no of channels are same");
13275
Agarwal Ashish57e84372014-12-05 18:26:53 +053013276 if (0 > ret)
13277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013278
Agarwal Ashish57e84372014-12-05 18:26:53 +053013279 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013280
13281 status = eHAL_STATUS_SUCCESS;
13282 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013283 }
13284 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013285 }
13286
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013287 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13288 * search (Flush on both full scan and social scan but not on single
13289 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13290 */
13291
13292 /* Supplicant does single channel scan after 8-way handshake
13293 * and in that case driver shoudnt flush scan results. If
13294 * driver flushes the scan results here and unfortunately if
13295 * the AP doesnt respond to our probe req then association
13296 * fails which is not desired
13297 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013298 if ((request->n_ssids == 1)
13299 && (request->ssids != NULL)
13300 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13301 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013302
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013303 if( is_p2p_scan ||
13304 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013305 {
13306 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13307 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13308 pAdapter->sessionId );
13309 }
13310
13311 if( request->ie_len )
13312 {
13313 /* save this for future association (join requires this) */
13314 /*TODO: Array needs to be converted to dynamic allocation,
13315 * as multiple ie.s can be sent in cfg80211_scan_request structure
13316 * CR 597966
13317 */
13318 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13319 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13320 pScanInfo->scanAddIE.length = request->ie_len;
13321
13322 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13323 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13324 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013325 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013326 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013328 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13329 memcpy( pwextBuf->roamProfile.addIEScan,
13330 request->ie, request->ie_len);
13331 }
13332 else
13333 {
13334 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13335 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013336 }
13337
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013338 }
13339 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13340 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13341
13342 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13343 request->ie_len);
13344 if (pP2pIe != NULL)
13345 {
13346#ifdef WLAN_FEATURE_P2P_DEBUG
13347 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13348 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13349 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013350 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013351 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13352 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13353 "Go nego completed to Connection is started");
13354 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13355 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013356 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013357 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13358 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013360 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13361 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13362 "Disconnected state to Connection is started");
13363 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13364 "for 4way Handshake");
13365 }
13366#endif
13367
13368 /* no_cck will be set during p2p find to disable 11b rates */
13369 if(TRUE == request->no_cck)
13370 {
13371 hddLog(VOS_TRACE_LEVEL_INFO,
13372 "%s: This is a P2P Search", __func__);
13373 scanRequest.p2pSearch = 1;
13374
13375 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013376 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013377 /* set requestType to P2P Discovery */
13378 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13379 }
13380
13381 /*
13382 Skip Dfs Channel in case of P2P Search
13383 if it is set in ini file
13384 */
13385 if(cfg_param->skipDfsChnlInP2pSearch)
13386 {
13387 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013388 }
13389 else
13390 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013391 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013392 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013393
Agarwal Ashish4f616132013-12-30 23:32:50 +053013394 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 }
13396 }
13397
13398 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13399
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013400#ifdef FEATURE_WLAN_TDLS
13401 /* if tdls disagree scan right now, return immediately.
13402 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13403 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13404 */
13405 status = wlan_hdd_tdls_scan_callback (pAdapter,
13406 wiphy,
13407#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13408 dev,
13409#endif
13410 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013411 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013412 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013413 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13415 "scan rejected %d", __func__, status);
13416 else
13417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13418 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013419 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013420 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013421 }
13422#endif
13423
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013424 /* acquire the wakelock to avoid the apps suspend during the scan. To
13425 * address the following issues.
13426 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13427 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13428 * for long time, this result in apps running at full power for long time.
13429 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13430 * be stuck in full power because of resume BMPS
13431 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013432 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013433
Nirav Shah20ac06f2013-12-12 18:14:06 +053013434 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13435 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013436 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13437 scanRequest.requestType, scanRequest.scanType,
13438 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013439 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13440
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013441 if (pHddCtx->spoofMacAddr.isEnabled &&
13442 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013443 {
13444 hddLog(VOS_TRACE_LEVEL_INFO,
13445 "%s: MAC Spoofing enabled for current scan", __func__);
13446 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13447 * to fill TxBds for probe request during current scan
13448 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013449 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013450 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013451
13452 if(status != VOS_STATUS_SUCCESS)
13453 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013454 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013455 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013456#ifdef FEATURE_WLAN_TDLS
13457 wlan_hdd_tdls_scan_done_callback(pAdapter);
13458#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013459 goto free_mem;
13460 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013461 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013462 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013463 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 pAdapter->sessionId, &scanRequest, &scanId,
13465 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013466
Jeff Johnson295189b2012-06-20 16:38:30 -070013467 if (eHAL_STATUS_SUCCESS != status)
13468 {
13469 hddLog(VOS_TRACE_LEVEL_ERROR,
13470 "%s: sme_ScanRequest returned error %d", __func__, status);
13471 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013472 if(eHAL_STATUS_RESOURCES == status)
13473 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13475 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013476 status = -EBUSY;
13477 } else {
13478 status = -EIO;
13479 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013480 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013481
13482#ifdef FEATURE_WLAN_TDLS
13483 wlan_hdd_tdls_scan_done_callback(pAdapter);
13484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 goto free_mem;
13486 }
13487
13488 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013489 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 pAdapter->request = request;
13491 pScanInfo->scanId = scanId;
13492
13493 complete(&pScanInfo->scan_req_completion_event);
13494
13495free_mem:
13496 if( scanRequest.SSIDs.SSIDList )
13497 {
13498 vos_mem_free(scanRequest.SSIDs.SSIDList);
13499 }
13500
13501 if( channelList )
13502 vos_mem_free( channelList );
13503
13504 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 return status;
13506}
13507
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013508int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13509#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13510 struct net_device *dev,
13511#endif
13512 struct cfg80211_scan_request *request)
13513{
13514 int ret;
13515
13516 vos_ssr_protect(__func__);
13517 ret = __wlan_hdd_cfg80211_scan(wiphy,
13518#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13519 dev,
13520#endif
13521 request);
13522 vos_ssr_unprotect(__func__);
13523
13524 return ret;
13525}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013526
13527void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13528{
13529 v_U8_t iniDot11Mode =
13530 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13531 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13532
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013533 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13534 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013535 switch ( iniDot11Mode )
13536 {
13537 case eHDD_DOT11_MODE_AUTO:
13538 case eHDD_DOT11_MODE_11ac:
13539 case eHDD_DOT11_MODE_11ac_ONLY:
13540#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013541 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13542 sme_IsFeatureSupportedByFW(DOT11AC) )
13543 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13544 else
13545 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013546#else
13547 hddDot11Mode = eHDD_DOT11_MODE_11n;
13548#endif
13549 break;
13550 case eHDD_DOT11_MODE_11n:
13551 case eHDD_DOT11_MODE_11n_ONLY:
13552 hddDot11Mode = eHDD_DOT11_MODE_11n;
13553 break;
13554 default:
13555 hddDot11Mode = iniDot11Mode;
13556 break;
13557 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013558#ifdef WLAN_FEATURE_AP_HT40_24G
13559 if (operationChannel > SIR_11B_CHANNEL_END)
13560#endif
13561 {
13562 /* This call decides required channel bonding mode */
13563 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013564 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13565 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013566 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013567}
13568
Jeff Johnson295189b2012-06-20 16:38:30 -070013569/*
13570 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013571 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013572 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013574 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13575 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013576{
13577 int status = 0;
13578 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013579 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 v_U32_t roamId;
13581 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013583 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013584
13585 ENTER();
13586
13587 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013588 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13589
13590 status = wlan_hdd_validate_context(pHddCtx);
13591 if (status)
13592 {
Yue Mae36e3552014-03-05 17:06:20 -080013593 return status;
13594 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013595
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13597 {
13598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13599 return -EINVAL;
13600 }
13601
13602 pRoamProfile = &pWextState->roamProfile;
13603
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013606 hdd_station_ctx_t *pHddStaCtx;
13607 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013608
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013609 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13610
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013611 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013612 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13613 {
13614 /*QoS not enabled in cfg file*/
13615 pRoamProfile->uapsd_mask = 0;
13616 }
13617 else
13618 {
13619 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013620 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013621 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13622 }
13623
13624 pRoamProfile->SSIDs.numOfSSIDs = 1;
13625 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13626 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013627 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13629 ssid, ssid_len);
13630
13631 if (bssid)
13632 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013633 pValidBssid = bssid;
13634 }
13635 else if (bssid_hint)
13636 {
13637 pValidBssid = bssid_hint;
13638 }
13639 if (pValidBssid)
13640 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013642 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013643 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013644 /* Save BSSID in seperate variable as well, as RoamProfile
13645 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 case of join failure we should send valid BSSID to supplicant
13647 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013648 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 WNI_CFG_BSSID_LEN);
13650 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013651 else
13652 {
13653 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13654 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013655
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013656 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13657 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13659 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013660 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 /*set gen ie*/
13662 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13663 /*set auth*/
13664 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013666#ifdef FEATURE_WLAN_WAPI
13667 if (pAdapter->wapi_info.nWapiMode)
13668 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013669 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 switch (pAdapter->wapi_info.wapiAuthMode)
13671 {
13672 case WAPI_AUTH_MODE_PSK:
13673 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013674 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 pAdapter->wapi_info.wapiAuthMode);
13676 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13677 break;
13678 }
13679 case WAPI_AUTH_MODE_CERT:
13680 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013681 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 pAdapter->wapi_info.wapiAuthMode);
13683 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13684 break;
13685 }
13686 } // End of switch
13687 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13688 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13689 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013690 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 pRoamProfile->AuthType.numEntries = 1;
13692 pRoamProfile->EncryptionType.numEntries = 1;
13693 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13694 pRoamProfile->mcEncryptionType.numEntries = 1;
13695 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13696 }
13697 }
13698#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013699#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013700 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013701 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13702 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13703 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013704 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13705 sizeof (tSirGtkOffloadParams));
13706 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013707 }
13708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 pRoamProfile->csrPersona = pAdapter->device_mode;
13710
Jeff Johnson32d95a32012-09-10 13:15:23 -070013711 if( operatingChannel )
13712 {
13713 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13714 pRoamProfile->ChannelInfo.numOfChannels = 1;
13715 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013716 else
13717 {
13718 pRoamProfile->ChannelInfo.ChannelList = NULL;
13719 pRoamProfile->ChannelInfo.numOfChannels = 0;
13720 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013721 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13722 {
13723 hdd_select_cbmode(pAdapter,operatingChannel);
13724 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013725
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013726 /*
13727 * Change conn_state to connecting before sme_RoamConnect(),
13728 * because sme_RoamConnect() has a direct path to call
13729 * hdd_smeRoamCallback(), which will change the conn_state
13730 * If direct path, conn_state will be accordingly changed
13731 * to NotConnected or Associated by either
13732 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13733 * in sme_RoamCallback()
13734 * if sme_RomConnect is to be queued,
13735 * Connecting state will remain until it is completed.
13736 * If connection state is not changed,
13737 * connection state will remain in eConnectionState_NotConnected state.
13738 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13739 * if conn state is eConnectionState_NotConnected.
13740 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13741 * informed of connect result indication which is an issue.
13742 */
13743
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013744 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13745 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013746 {
13747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013748 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013749 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13750 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013752 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013753 pAdapter->sessionId, pRoamProfile, &roamId);
13754
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013755 if ((eHAL_STATUS_SUCCESS != status) &&
13756 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13757 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013758
13759 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013760 hddLog(VOS_TRACE_LEVEL_ERROR,
13761 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13762 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013763 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013764 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013765 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013766 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013767
13768 pRoamProfile->ChannelInfo.ChannelList = NULL;
13769 pRoamProfile->ChannelInfo.numOfChannels = 0;
13770
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 }
13772 else
13773 {
13774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13775 return -EINVAL;
13776 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013777 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 return status;
13779}
13780
13781/*
13782 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13783 * This function is used to set the authentication type (OPEN/SHARED).
13784 *
13785 */
13786static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13787 enum nl80211_auth_type auth_type)
13788{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013789 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13791
13792 ENTER();
13793
13794 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013795 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013798 hddLog(VOS_TRACE_LEVEL_INFO,
13799 "%s: set authentication type to AUTOSWITCH", __func__);
13800 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13801 break;
13802
13803 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013804#ifdef WLAN_FEATURE_VOWIFI_11R
13805 case NL80211_AUTHTYPE_FT:
13806#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013808 "%s: set authentication type to OPEN", __func__);
13809 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13810 break;
13811
13812 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 "%s: set authentication type to SHARED", __func__);
13815 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13816 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013817#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013818 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013819 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 "%s: set authentication type to CCKM WPA", __func__);
13821 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13822 break;
13823#endif
13824
13825
13826 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013827 hddLog(VOS_TRACE_LEVEL_ERROR,
13828 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 auth_type);
13830 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13831 return -EINVAL;
13832 }
13833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013834 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 pHddStaCtx->conn_info.authType;
13836 return 0;
13837}
13838
13839/*
13840 * FUNCTION: wlan_hdd_set_akm_suite
13841 * This function is used to set the key mgmt type(PSK/8021x).
13842 *
13843 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013844static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 u32 key_mgmt
13846 )
13847{
13848 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13849 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013850 /* Should be in ieee802_11_defs.h */
13851#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13852#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 /*set key mgmt type*/
13854 switch(key_mgmt)
13855 {
13856 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013857 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013858#ifdef WLAN_FEATURE_VOWIFI_11R
13859 case WLAN_AKM_SUITE_FT_PSK:
13860#endif
13861 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 __func__);
13863 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13864 break;
13865
13866 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013867 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013868#ifdef WLAN_FEATURE_VOWIFI_11R
13869 case WLAN_AKM_SUITE_FT_8021X:
13870#endif
13871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 __func__);
13873 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13874 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013875#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013876#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13877#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13878 case WLAN_AKM_SUITE_CCKM:
13879 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13880 __func__);
13881 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13882 break;
13883#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013884#ifndef WLAN_AKM_SUITE_OSEN
13885#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13886 case WLAN_AKM_SUITE_OSEN:
13887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13888 __func__);
13889 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13890 break;
13891#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013892
13893 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 __func__, key_mgmt);
13896 return -EINVAL;
13897
13898 }
13899 return 0;
13900}
13901
13902/*
13903 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 * (NONE/WEP40/WEP104/TKIP/CCMP).
13906 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013907static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13908 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 bool ucast
13910 )
13911{
13912 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13915
13916 ENTER();
13917
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013918 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 __func__, cipher);
13922 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13923 }
13924 else
13925 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013926
Jeff Johnson295189b2012-06-20 16:38:30 -070013927 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 {
13930 case IW_AUTH_CIPHER_NONE:
13931 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13932 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013933
Jeff Johnson295189b2012-06-20 16:38:30 -070013934 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013935 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013939 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013941
Jeff Johnson295189b2012-06-20 16:38:30 -070013942 case WLAN_CIPHER_SUITE_TKIP:
13943 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13944 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013945
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 case WLAN_CIPHER_SUITE_CCMP:
13947 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13948 break;
13949#ifdef FEATURE_WLAN_WAPI
13950 case WLAN_CIPHER_SUITE_SMS4:
13951 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13952 break;
13953#endif
13954
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013955#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 case WLAN_CIPHER_SUITE_KRK:
13957 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13958 break;
13959#endif
13960 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 __func__, cipher);
13963 return -EOPNOTSUPP;
13964 }
13965 }
13966
13967 if (ucast)
13968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 __func__, encryptionType);
13971 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13972 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013973 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 encryptionType;
13975 }
13976 else
13977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013979 __func__, encryptionType);
13980 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13981 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13982 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13983 }
13984
13985 return 0;
13986}
13987
13988
13989/*
13990 * FUNCTION: wlan_hdd_cfg80211_set_ie
13991 * This function is used to parse WPA/RSN IE's.
13992 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013993int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13995 const u8 *ie,
13996#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013997 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 size_t ie_len
14000 )
14001{
14002 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14004 const u8 *genie = ie;
14005#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 v_U16_t remLen = ie_len;
14009#ifdef FEATURE_WLAN_WAPI
14010 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14011 u16 *tmp;
14012 v_U16_t akmsuiteCount;
14013 int *akmlist;
14014#endif
14015 ENTER();
14016
14017 /* clear previous assocAddIE */
14018 pWextState->assocAddIE.length = 0;
14019 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014020 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014021
14022 while (remLen >= 2)
14023 {
14024 v_U16_t eLen = 0;
14025 v_U8_t elementId;
14026 elementId = *genie++;
14027 eLen = *genie++;
14028 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014029
Arif Hussain6d2a3322013-11-17 19:50:10 -080014030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032
14033 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014035 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014036 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 -070014037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014038 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014039 "%s: Invalid WPA IE", __func__);
14040 return -EINVAL;
14041 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014042 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 {
14044 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014047
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014048 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014050 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14051 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 VOS_ASSERT(0);
14053 return -ENOMEM;
14054 }
14055 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14056 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14057 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014058
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14060 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14061 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14062 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014063 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14064 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014065 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14066 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14067 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14068 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14069 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14070 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014072 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 {
14074 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014075 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014077
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014078 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014079 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014080 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14081 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 VOS_ASSERT(0);
14083 return -ENOMEM;
14084 }
14085 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14086 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14087 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014088
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14090 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014092#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014093 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14094 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 /*Consider WFD IE, only for P2P Client */
14096 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14097 {
14098 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014102 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014104 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14105 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 VOS_ASSERT(0);
14107 return -ENOMEM;
14108 }
14109 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14110 // WPS IE + P2P IE + WFD IE
14111 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14112 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14115 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14116 }
14117#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014118 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014119 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014120 HS20_OUI_TYPE_SIZE)) )
14121 {
14122 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014123 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014124 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014125
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014126 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014127 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014128 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14129 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014130 VOS_ASSERT(0);
14131 return -ENOMEM;
14132 }
14133 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14134 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014135
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014136 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14137 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14138 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014139 /* Appending OSEN Information Element in Assiciation Request */
14140 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14141 OSEN_OUI_TYPE_SIZE)) )
14142 {
14143 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14144 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14145 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014146
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014147 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014148 {
14149 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14150 "Need bigger buffer space");
14151 VOS_ASSERT(0);
14152 return -ENOMEM;
14153 }
14154 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14155 pWextState->assocAddIE.length += eLen + 2;
14156
14157 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14158 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14159 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14160 }
14161
Abhishek Singh4322e622015-06-10 15:42:54 +053014162 /* Update only for WPA IE */
14163 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14164 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014165
14166 /* populating as ADDIE in beacon frames */
14167 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014168 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014169 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14170 {
14171 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14172 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14173 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14174 {
14175 hddLog(LOGE,
14176 "Coldn't pass "
14177 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14178 }
14179 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14180 else
14181 hddLog(LOGE,
14182 "Could not pass on "
14183 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14184
14185 /* IBSS mode doesn't contain params->proberesp_ies still
14186 beaconIE's need to be populated in probe response frames */
14187 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14188 {
14189 u16 rem_probe_resp_ie_len = eLen + 2;
14190 u8 probe_rsp_ie_len[3] = {0};
14191 u8 counter = 0;
14192
14193 /* Check Probe Resp Length if it is greater then 255 then
14194 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14195 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14196 not able Store More then 255 bytes into One Variable */
14197
14198 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14199 {
14200 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14201 {
14202 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14203 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14204 }
14205 else
14206 {
14207 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14208 rem_probe_resp_ie_len = 0;
14209 }
14210 }
14211
14212 rem_probe_resp_ie_len = 0;
14213
14214 if (probe_rsp_ie_len[0] > 0)
14215 {
14216 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14217 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14218 (tANI_U8*)(genie - 2),
14219 probe_rsp_ie_len[0], NULL,
14220 eANI_BOOLEAN_FALSE)
14221 == eHAL_STATUS_FAILURE)
14222 {
14223 hddLog(LOGE,
14224 "Could not pass"
14225 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14226 }
14227 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14228 }
14229
14230 if (probe_rsp_ie_len[1] > 0)
14231 {
14232 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14233 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14234 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14235 probe_rsp_ie_len[1], NULL,
14236 eANI_BOOLEAN_FALSE)
14237 == eHAL_STATUS_FAILURE)
14238 {
14239 hddLog(LOGE,
14240 "Could not pass"
14241 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14242 }
14243 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14244 }
14245
14246 if (probe_rsp_ie_len[2] > 0)
14247 {
14248 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14249 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14250 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14251 probe_rsp_ie_len[2], NULL,
14252 eANI_BOOLEAN_FALSE)
14253 == eHAL_STATUS_FAILURE)
14254 {
14255 hddLog(LOGE,
14256 "Could not pass"
14257 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14258 }
14259 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14260 }
14261
14262 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14263 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14264 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14265 {
14266 hddLog(LOGE,
14267 "Could not pass"
14268 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14269 }
14270 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014271 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014272 break;
14273 case DOT11F_EID_RSN:
14274 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14275 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14276 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14277 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14278 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14279 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014280
Abhishek Singhb16f3562016-01-20 11:08:32 +053014281 /* Appending extended capabilities with Interworking or
14282 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014283 *
14284 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014285 * interworkingService or bsstransition bit is set to 1.
14286 * Driver is only interested in interworkingService and
14287 * bsstransition capability from supplicant.
14288 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014289 * required from supplicat, it needs to be handled while
14290 * sending Assoc Req in LIM.
14291 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014292 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014293 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014294 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014295 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014296 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014297
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014298 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014299 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014300 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14301 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014302 VOS_ASSERT(0);
14303 return -ENOMEM;
14304 }
14305 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14306 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014307
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014308 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14309 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14310 break;
14311 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014312#ifdef FEATURE_WLAN_WAPI
14313 case WLAN_EID_WAPI:
14314 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014315 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 pAdapter->wapi_info.nWapiMode);
14317 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014318 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 akmsuiteCount = WPA_GET_LE16(tmp);
14320 tmp = tmp + 1;
14321 akmlist = (int *)(tmp);
14322 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14323 {
14324 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14325 }
14326 else
14327 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014328 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 VOS_ASSERT(0);
14330 return -EINVAL;
14331 }
14332
14333 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14334 {
14335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014336 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014340 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014342 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14344 }
14345 break;
14346#endif
14347 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014348 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014350 /* when Unknown IE is received we should break and continue
14351 * to the next IE in the buffer instead we were returning
14352 * so changing this to break */
14353 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 }
14355 genie += eLen;
14356 remLen -= eLen;
14357 }
14358 EXIT();
14359 return 0;
14360}
14361
14362/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014363 * FUNCTION: hdd_isWPAIEPresent
14364 * Parse the received IE to find the WPA IE
14365 *
14366 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014367static bool hdd_isWPAIEPresent(
14368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14369 const u8 *ie,
14370#else
14371 u8 *ie,
14372#endif
14373 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014374{
14375 v_U8_t eLen = 0;
14376 v_U16_t remLen = ie_len;
14377 v_U8_t elementId = 0;
14378
14379 while (remLen >= 2)
14380 {
14381 elementId = *ie++;
14382 eLen = *ie++;
14383 remLen -= 2;
14384 if (eLen > remLen)
14385 {
14386 hddLog(VOS_TRACE_LEVEL_ERROR,
14387 "%s: IE length is wrong %d", __func__, eLen);
14388 return FALSE;
14389 }
14390 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14391 {
14392 /* OUI - 0x00 0X50 0XF2
14393 WPA Information Element - 0x01
14394 WPA version - 0x01*/
14395 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14396 return TRUE;
14397 }
14398 ie += eLen;
14399 remLen -= eLen;
14400 }
14401 return FALSE;
14402}
14403
14404/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014406 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 * parameters during connect operation.
14408 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014409int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014411 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014412{
14413 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014414 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 ENTER();
14416
14417 /*set wpa version*/
14418 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14419
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014420 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014422 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014423 {
14424 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14425 }
14426 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14427 {
14428 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14429 }
14430 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014431
14432 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 pWextState->wpaVersion);
14434
14435 /*set authentication type*/
14436 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14437
14438 if (0 > status)
14439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014440 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 "%s: failed to set authentication type ", __func__);
14442 return status;
14443 }
14444
14445 /*set key mgmt type*/
14446 if (req->crypto.n_akm_suites)
14447 {
14448 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14449 if (0 > status)
14450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014452 __func__);
14453 return status;
14454 }
14455 }
14456
14457 /*set pairwise cipher type*/
14458 if (req->crypto.n_ciphers_pairwise)
14459 {
14460 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14461 req->crypto.ciphers_pairwise[0], true);
14462 if (0 > status)
14463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014464 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 "%s: failed to set unicast cipher type", __func__);
14466 return status;
14467 }
14468 }
14469 else
14470 {
14471 /*Reset previous cipher suite to none*/
14472 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14473 if (0 > status)
14474 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014475 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 "%s: failed to set unicast cipher type", __func__);
14477 return status;
14478 }
14479 }
14480
14481 /*set group cipher type*/
14482 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14483 false);
14484
14485 if (0 > status)
14486 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014488 __func__);
14489 return status;
14490 }
14491
Chet Lanctot186b5732013-03-18 10:26:30 -070014492#ifdef WLAN_FEATURE_11W
14493 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14494#endif
14495
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14497 if (req->ie_len)
14498 {
14499 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14500 if ( 0 > status)
14501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 __func__);
14504 return status;
14505 }
14506 }
14507
14508 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014509 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014510 {
14511 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14512 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14513 )
14514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014515 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 __func__);
14520 return -EOPNOTSUPP;
14521 }
14522 else
14523 {
14524 u8 key_len = req->key_len;
14525 u8 key_idx = req->key_idx;
14526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014527 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 && (CSR_MAX_NUM_KEY > key_idx)
14529 )
14530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014531 hddLog(VOS_TRACE_LEVEL_INFO,
14532 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 __func__, key_idx, key_len);
14534 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014535 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014536 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014537 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 (u8)key_len;
14539 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14540 }
14541 }
14542 }
14543 }
14544
14545 return status;
14546}
14547
14548/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014549 * FUNCTION: wlan_hdd_try_disconnect
14550 * This function is used to disconnect from previous
14551 * connection
14552 */
14553static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14554{
14555 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014556 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014557 hdd_station_ctx_t *pHddStaCtx;
14558 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014559 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014560
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014561 ret = wlan_hdd_validate_context(pHddCtx);
14562 if (0 != ret)
14563 {
14564 return ret;
14565 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014566 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14567
14568 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14569
14570 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14571 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014572 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014573 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14574 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014575 spin_lock_bh(&pAdapter->lock_for_active_session);
14576 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14577 {
14578 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14579 }
14580 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014581 hdd_connSetConnectionState(pHddStaCtx,
14582 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014583 /* Issue disconnect to CSR */
14584 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014585 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014586 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014587 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14588 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14589 hddLog(LOG1,
14590 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14591 } else if ( 0 != status ) {
14592 hddLog(LOGE,
14593 FL("csrRoamDisconnect failure, returned %d"),
14594 (int)status );
14595 result = -EINVAL;
14596 goto disconnected;
14597 }
14598 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014599 &pAdapter->disconnect_comp_var,
14600 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014601 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14602 hddLog(LOGE,
14603 "%s: Failed to disconnect, timed out", __func__);
14604 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014605 }
14606 }
14607 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14608 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014609 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014610 &pAdapter->disconnect_comp_var,
14611 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014612 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014613 {
14614 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014615 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014616 }
14617 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014618disconnected:
14619 hddLog(LOG1,
14620 FL("Set HDD connState to eConnectionState_NotConnected"));
14621 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14622 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014623}
14624
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014625/**
14626 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14627 * @adapter: Pointer to the HDD adapter
14628 * @req: Pointer to the structure cfg_connect_params receieved from user space
14629 *
14630 * This function will start reassociation if bssid hint, channel hint and
14631 * previous bssid parameters are present in the connect request
14632 *
14633 * Return: success if reassociation is happening
14634 * Error code if reassociation is not permitted or not happening
14635 */
14636#ifdef CFG80211_CONNECT_PREV_BSSID
14637static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14638 struct cfg80211_connect_params *req)
14639{
14640 int status = -EPERM;
14641 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14642 hddLog(VOS_TRACE_LEVEL_INFO,
14643 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14644 req->channel_hint->hw_value,
14645 MAC_ADDR_ARRAY(req->bssid_hint));
14646 status = hdd_reassoc(adapter, req->bssid_hint,
14647 req->channel_hint->hw_value,
14648 CONNECT_CMD_USERSPACE);
14649 }
14650 return status;
14651}
14652#else
14653static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14654 struct cfg80211_connect_params *req)
14655{
14656 return -EPERM;
14657}
14658#endif
14659
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014660/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014661 * FUNCTION: __wlan_hdd_cfg80211_connect
14662 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014663 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014664static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014665 struct net_device *ndev,
14666 struct cfg80211_connect_params *req
14667 )
14668{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014669 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014670 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14672 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014673 const u8 *bssid_hint = req->bssid_hint;
14674#else
14675 const u8 *bssid_hint = NULL;
14676#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014679 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014680
14681 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014682
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014683 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14684 TRACE_CODE_HDD_CFG80211_CONNECT,
14685 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014686 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014687 "%s: device_mode = %s (%d)", __func__,
14688 hdd_device_modetoString(pAdapter->device_mode),
14689 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014690
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014691 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014692 if (!pHddCtx)
14693 {
14694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14695 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014696 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014697 }
14698
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014699 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014700 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014702 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 }
14704
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014705 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14706 if (0 == status)
14707 return status;
14708
Agarwal Ashish51325b52014-06-16 16:50:49 +053014709
Jeff Johnson295189b2012-06-20 16:38:30 -070014710#ifdef WLAN_BTAMP_FEATURE
14711 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014712 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014714 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014716 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 }
14718#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014719
14720 //If Device Mode is Station Concurrent Sessions Exit BMps
14721 //P2P Mode will be taken care in Open/close adapter
14722 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014723 (vos_concurrent_open_sessions_running())) {
14724 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14725 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014726 }
14727
14728 /*Try disconnecting if already in connected state*/
14729 status = wlan_hdd_try_disconnect(pAdapter);
14730 if ( 0 > status)
14731 {
14732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14733 " connection"));
14734 return -EALREADY;
14735 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014736 /* Check for max concurrent connections after doing disconnect if any*/
14737 if (vos_max_concurrent_connections_reached()) {
14738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14739 return -ECONNREFUSED;
14740 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014741
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014743 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014744
14745 if ( 0 > status)
14746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014748 __func__);
14749 return status;
14750 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014751
14752 if (pHddCtx->spoofMacAddr.isEnabled)
14753 {
14754 hddLog(VOS_TRACE_LEVEL_INFO,
14755 "%s: MAC Spoofing enabled ", __func__);
14756 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14757 * to fill TxBds for probe request during SSID scan which may happen
14758 * as part of connect command
14759 */
14760 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14761 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14762 if (status != VOS_STATUS_SUCCESS)
14763 return -ECONNREFUSED;
14764 }
14765
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014766 if (req->channel)
14767 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014768 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014769 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053014770
14771 /* Abort if any scan is going on */
14772 status = wlan_hdd_scan_abort(pAdapter);
14773 if (0 != status)
14774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
14775
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014776 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14777 req->ssid_len, req->bssid,
14778 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014779
Sushant Kaushikd7083982015-03-18 14:33:24 +053014780 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014781 {
14782 //ReEnable BMPS if disabled
14783 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14784 (NULL != pHddCtx))
14785 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014786 if (pHddCtx->hdd_wlan_suspended)
14787 {
14788 hdd_set_pwrparams(pHddCtx);
14789 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014790 //ReEnable Bmps and Imps back
14791 hdd_enable_bmps_imps(pHddCtx);
14792 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014794 return status;
14795 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014796 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014797 EXIT();
14798 return status;
14799}
14800
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014801static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14802 struct net_device *ndev,
14803 struct cfg80211_connect_params *req)
14804{
14805 int ret;
14806 vos_ssr_protect(__func__);
14807 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14808 vos_ssr_unprotect(__func__);
14809
14810 return ret;
14811}
Jeff Johnson295189b2012-06-20 16:38:30 -070014812
14813/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014814 * FUNCTION: wlan_hdd_disconnect
14815 * This function is used to issue a disconnect request to SME
14816 */
14817int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14818{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014819 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014820 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014821 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014822 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014823
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014824 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014827 if (0 != status)
14828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014829 return status;
14830 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014831 /* Indicate sme of disconnect so that in progress connection or preauth
14832 * can be aborted
14833 */
14834 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014835 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014836 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014837
Agarwal Ashish47d18112014-08-04 19:55:07 +053014838 /* Need to apply spin lock before decreasing active sessions
14839 * as there can be chance for double decrement if context switch
14840 * Calls hdd_DisConnectHandler.
14841 */
14842
14843 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014844 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14845 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014846 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14847 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014848 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14849 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014850
Abhishek Singhf4669da2014-05-26 15:07:49 +053014851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014852 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14853
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014854 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014855
Mihir Shete182a0b22014-08-18 16:08:48 +053014856 /*
14857 * stop tx queues before deleting STA/BSS context from the firmware.
14858 * tx has to be disabled because the firmware can get busy dropping
14859 * the tx frames after BSS/STA has been deleted and will not send
14860 * back a response resulting in WDI timeout
14861 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014863 netif_tx_disable(pAdapter->dev);
14864 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014865
Mihir Shete182a0b22014-08-18 16:08:48 +053014866 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014867 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14868 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014869 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14870 {
14871 hddLog(LOG1,
14872 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014873 }
14874 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014875 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014876 hddLog(LOGE,
14877 FL("csrRoamDisconnect failure, returned %d"),
14878 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014879 result = -EINVAL;
14880 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014881 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014882 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014883 &pAdapter->disconnect_comp_var,
14884 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014885 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014886 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014887 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014888 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014889 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014890 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014891disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014892 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014893 FL("Set HDD connState to eConnectionState_NotConnected"));
14894 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014895#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14896 /* Sending disconnect event to userspace for kernel version < 3.11
14897 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14898 */
14899 hddLog(LOG1, FL("Send disconnected event to userspace"));
14900
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014901 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014902 WLAN_REASON_UNSPECIFIED);
14903#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014904
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014905 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014906 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014907}
14908
14909
14910/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014911 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 * This function is used to issue a disconnect request to SME
14913 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014914static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 struct net_device *dev,
14916 u16 reason
14917 )
14918{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014920 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014921 tCsrRoamProfile *pRoamProfile;
14922 hdd_station_ctx_t *pHddStaCtx;
14923 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014924#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014925 tANI_U8 staIdx;
14926#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014927
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014929
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014930 if (!pAdapter) {
14931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14932 return -EINVAL;
14933 }
14934
14935 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14936 if (!pHddStaCtx) {
14937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14938 return -EINVAL;
14939 }
14940
14941 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14942 status = wlan_hdd_validate_context(pHddCtx);
14943 if (0 != status)
14944 {
14945 return status;
14946 }
14947
14948 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14949
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14951 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14952 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14954 __func__, hdd_device_modetoString(pAdapter->device_mode),
14955 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014956
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14958 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014959
Jeff Johnson295189b2012-06-20 16:38:30 -070014960 if (NULL != pRoamProfile)
14961 {
14962 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014963 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14964 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014966 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014968 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014969 switch(reason)
14970 {
14971 case WLAN_REASON_MIC_FAILURE:
14972 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14973 break;
14974
14975 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14976 case WLAN_REASON_DISASSOC_AP_BUSY:
14977 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14978 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14979 break;
14980
14981 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14982 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014983 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014984 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14985 break;
14986
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 default:
14988 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14989 break;
14990 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014991 pScanInfo = &pHddCtx->scan_info;
14992 if (pScanInfo->mScanPending)
14993 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014994 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014995 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014996 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014997 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014998 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014999 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015000#ifdef FEATURE_WLAN_TDLS
15001 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015002 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015003 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015004 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15005 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015006 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015007 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015008 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015010 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015011 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015012 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015013 status = sme_DeleteTdlsPeerSta(
15014 WLAN_HDD_GET_HAL_CTX(pAdapter),
15015 pAdapter->sessionId,
15016 mac);
15017 if (status != eHAL_STATUS_SUCCESS) {
15018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15019 return -EPERM;
15020 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015021 }
15022 }
15023#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015024 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015025 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15026 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 {
15028 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015029 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015030 __func__, (int)status );
15031 return -EINVAL;
15032 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015034 else
15035 {
15036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15037 "called while in %d state", __func__,
15038 pHddStaCtx->conn_info.connState);
15039 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 }
15041 else
15042 {
15043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15044 }
15045
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015046 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015047 return status;
15048}
15049
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015050static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15051 struct net_device *dev,
15052 u16 reason
15053 )
15054{
15055 int ret;
15056 vos_ssr_protect(__func__);
15057 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15058 vos_ssr_unprotect(__func__);
15059
15060 return ret;
15061}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015062
Jeff Johnson295189b2012-06-20 16:38:30 -070015063/*
15064 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015065 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 * settings in IBSS mode.
15067 */
15068static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015069 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015070 struct cfg80211_ibss_params *params
15071 )
15072{
15073 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015074 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015075 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15076 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015077
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 ENTER();
15079
15080 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015081 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015082
15083 if (params->ie_len && ( NULL != params->ie) )
15084 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015085 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15086 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015087 {
15088 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15089 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15090 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015091 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015092 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015093 tDot11fIEWPA dot11WPAIE;
15094 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015095 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015096
Wilson Yang00256342013-10-10 23:13:38 -070015097 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015098 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15099 params->ie_len, DOT11F_EID_WPA);
15100 if ( NULL != ie )
15101 {
15102 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15103 // Unpack the WPA IE
15104 //Skip past the EID byte and length byte - and four byte WiFi OUI
15105 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15106 &ie[2+4],
15107 ie[1] - 4,
15108 &dot11WPAIE);
15109 /*Extract the multicast cipher, the encType for unicast
15110 cipher for wpa-none is none*/
15111 encryptionType =
15112 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15113 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015115
Jeff Johnson295189b2012-06-20 16:38:30 -070015116 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15117
15118 if (0 > status)
15119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015121 __func__);
15122 return status;
15123 }
15124 }
15125
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015126 pWextState->roamProfile.AuthType.authType[0] =
15127 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15129
15130 if (params->privacy)
15131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015132 /* Security enabled IBSS, At this time there is no information available
15133 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015134 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015135 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015137 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015138 *enable privacy bit in beacons */
15139
15140 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15141 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015142 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15143 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015144 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15145 pWextState->roamProfile.EncryptionType.numEntries = 1;
15146 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015147 return status;
15148}
15149
15150/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015151 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015152 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015153 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015154static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015155 struct net_device *dev,
15156 struct cfg80211_ibss_params *params
15157 )
15158{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015159 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015160 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15161 tCsrRoamProfile *pRoamProfile;
15162 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015163 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015165 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015166
15167 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015168
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15170 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15171 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015172 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015173 "%s: device_mode = %s (%d)", __func__,
15174 hdd_device_modetoString(pAdapter->device_mode),
15175 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015177 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015178 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015179 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015180 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015181 }
15182
15183 if (NULL == pWextState)
15184 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015185 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 __func__);
15187 return -EIO;
15188 }
15189
Agarwal Ashish51325b52014-06-16 16:50:49 +053015190 if (vos_max_concurrent_connections_reached()) {
15191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15192 return -ECONNREFUSED;
15193 }
15194
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015195 /*Try disconnecting if already in connected state*/
15196 status = wlan_hdd_try_disconnect(pAdapter);
15197 if ( 0 > status)
15198 {
15199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15200 " IBSS connection"));
15201 return -EALREADY;
15202 }
15203
Jeff Johnson295189b2012-06-20 16:38:30 -070015204 pRoamProfile = &pWextState->roamProfile;
15205
15206 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015208 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015209 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015210 return -EINVAL;
15211 }
15212
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015213 /* BSSID is provided by upper layers hence no need to AUTO generate */
15214 if (NULL != params->bssid) {
15215 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15216 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
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 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015222 }
krunal sonie9002db2013-11-25 14:24:17 -080015223 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15224 {
15225 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15226 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15227 {
15228 hddLog (VOS_TRACE_LEVEL_ERROR,
15229 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15230 return -EIO;
15231 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015232
15233 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015234 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015235 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015236 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015237
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015239 if (NULL !=
15240#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15241 params->chandef.chan)
15242#else
15243 params->channel)
15244#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015245 {
15246 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015247 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15248 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15249 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15250 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015251
15252 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015253 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015254 ieee80211_frequency_to_channel(
15255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15256 params->chandef.chan->center_freq);
15257#else
15258 params->channel->center_freq);
15259#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015260
15261 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15262 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015263 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15265 __func__);
15266 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015268
15269 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015270 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015271 if (channelNum == validChan[indx])
15272 {
15273 break;
15274 }
15275 }
15276 if (indx >= numChans)
15277 {
15278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 __func__, channelNum);
15280 return -EINVAL;
15281 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015282 /* Set the Operational Channel */
15283 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15284 channelNum);
15285 pRoamProfile->ChannelInfo.numOfChannels = 1;
15286 pHddStaCtx->conn_info.operationChannel = channelNum;
15287 pRoamProfile->ChannelInfo.ChannelList =
15288 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015289 }
15290
15291 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015292 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 if (status < 0)
15294 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 __func__);
15297 return status;
15298 }
15299
15300 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015301 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015302 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015303 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015304
15305 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015308 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015309 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015310}
15311
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015312static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15313 struct net_device *dev,
15314 struct cfg80211_ibss_params *params
15315 )
15316{
15317 int ret = 0;
15318
15319 vos_ssr_protect(__func__);
15320 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15321 vos_ssr_unprotect(__func__);
15322
15323 return ret;
15324}
15325
Jeff Johnson295189b2012-06-20 16:38:30 -070015326/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015327 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015328 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015330static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015331 struct net_device *dev
15332 )
15333{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015334 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015335 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15336 tCsrRoamProfile *pRoamProfile;
15337 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015338 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015339#ifdef WLAN_FEATURE_RMC
15340 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15341#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015342
15343 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015344
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15346 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15347 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015348 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015349 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015350 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015351 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015352 }
15353
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015354 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15355 hdd_device_modetoString(pAdapter->device_mode),
15356 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015357 if (NULL == pWextState)
15358 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015359 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 __func__);
15361 return -EIO;
15362 }
15363
15364 pRoamProfile = &pWextState->roamProfile;
15365
15366 /* Issue disconnect only if interface type is set to IBSS */
15367 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15368 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 __func__);
15371 return -EINVAL;
15372 }
15373
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015374#ifdef WLAN_FEATURE_RMC
15375 /* Clearing add IE of beacon */
15376 if (ccmCfgSetStr(pHddCtx->hHal,
15377 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15378 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15379 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15380 {
15381 hddLog (VOS_TRACE_LEVEL_ERROR,
15382 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15383 return -EINVAL;
15384 }
15385 if (ccmCfgSetInt(pHddCtx->hHal,
15386 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15387 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15388 {
15389 hddLog (VOS_TRACE_LEVEL_ERROR,
15390 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15391 __func__);
15392 return -EINVAL;
15393 }
15394
15395 // Reset WNI_CFG_PROBE_RSP Flags
15396 wlan_hdd_reset_prob_rspies(pAdapter);
15397
15398 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15399 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15400 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15401 {
15402 hddLog (VOS_TRACE_LEVEL_ERROR,
15403 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15404 __func__);
15405 return -EINVAL;
15406 }
15407#endif
15408
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 /* Issue Disconnect request */
15410 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15411 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15412 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015414 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 return 0;
15416}
15417
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015418static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15419 struct net_device *dev
15420 )
15421{
15422 int ret = 0;
15423
15424 vos_ssr_protect(__func__);
15425 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15426 vos_ssr_unprotect(__func__);
15427
15428 return ret;
15429}
15430
Jeff Johnson295189b2012-06-20 16:38:30 -070015431/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015432 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015433 * This function is used to set the phy parameters
15434 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15435 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015436static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015437 u32 changed)
15438{
15439 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15440 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015441 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015442
15443 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015444
15445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015446 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15447 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015449 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015450 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015451 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015452 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015453 }
15454
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15456 {
15457 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15458 WNI_CFG_RTS_THRESHOLD_STAMAX :
15459 wiphy->rts_threshold;
15460
15461 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015462 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464 hddLog(VOS_TRACE_LEVEL_ERROR,
15465 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 __func__, rts_threshold);
15467 return -EINVAL;
15468 }
15469
15470 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15471 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015472 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015474 hddLog(VOS_TRACE_LEVEL_ERROR,
15475 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 __func__, rts_threshold);
15477 return -EIO;
15478 }
15479
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 rts_threshold);
15482 }
15483
15484 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15485 {
15486 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15487 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15488 wiphy->frag_threshold;
15489
15490 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015491 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015492 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015493 hddLog(VOS_TRACE_LEVEL_ERROR,
15494 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015495 frag_threshold);
15496 return -EINVAL;
15497 }
15498
15499 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15500 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015501 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015503 hddLog(VOS_TRACE_LEVEL_ERROR,
15504 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 __func__, frag_threshold);
15506 return -EIO;
15507 }
15508
15509 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15510 frag_threshold);
15511 }
15512
15513 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15514 || (changed & WIPHY_PARAM_RETRY_LONG))
15515 {
15516 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15517 wiphy->retry_short :
15518 wiphy->retry_long;
15519
15520 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15521 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015524 __func__, retry_value);
15525 return -EINVAL;
15526 }
15527
15528 if (changed & WIPHY_PARAM_RETRY_SHORT)
15529 {
15530 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15531 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015532 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015534 hddLog(VOS_TRACE_LEVEL_ERROR,
15535 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015536 __func__, retry_value);
15537 return -EIO;
15538 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015539 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015540 __func__, retry_value);
15541 }
15542 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15543 {
15544 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15545 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015546 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015548 hddLog(VOS_TRACE_LEVEL_ERROR,
15549 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015550 __func__, retry_value);
15551 return -EIO;
15552 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015553 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015554 __func__, retry_value);
15555 }
15556 }
15557
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015558 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015559 return 0;
15560}
15561
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015562static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15563 u32 changed)
15564{
15565 int ret;
15566
15567 vos_ssr_protect(__func__);
15568 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15569 vos_ssr_unprotect(__func__);
15570
15571 return ret;
15572}
15573
Jeff Johnson295189b2012-06-20 16:38:30 -070015574/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015575 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 * This function is used to set the txpower
15577 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015578static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015579#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15580 struct wireless_dev *wdev,
15581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015582#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015583 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015584#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015585 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015586#endif
15587 int dbm)
15588{
15589 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015590 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015591 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15592 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015593 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015594
15595 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015596
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015597 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15598 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15599 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015600 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015601 if (0 != status)
15602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015603 return status;
15604 }
15605
15606 hHal = pHddCtx->hHal;
15607
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015608 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15609 dbm, ccmCfgSetCallback,
15610 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015611 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015612 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15614 return -EIO;
15615 }
15616
15617 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15618 dbm);
15619
15620 switch(type)
15621 {
15622 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15623 /* Fall through */
15624 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15625 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15628 __func__);
15629 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015630 }
15631 break;
15632 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 __func__);
15635 return -EOPNOTSUPP;
15636 break;
15637 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15639 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015640 return -EIO;
15641 }
15642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015643 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015644 return 0;
15645}
15646
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015647static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15648#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15649 struct wireless_dev *wdev,
15650#endif
15651#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15652 enum tx_power_setting type,
15653#else
15654 enum nl80211_tx_power_setting type,
15655#endif
15656 int dbm)
15657{
15658 int ret;
15659 vos_ssr_protect(__func__);
15660 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15661#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15662 wdev,
15663#endif
15664#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15665 type,
15666#else
15667 type,
15668#endif
15669 dbm);
15670 vos_ssr_unprotect(__func__);
15671
15672 return ret;
15673}
15674
Jeff Johnson295189b2012-06-20 16:38:30 -070015675/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015676 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 * This function is used to read the txpower
15678 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015679static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015680#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15681 struct wireless_dev *wdev,
15682#endif
15683 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015684{
15685
15686 hdd_adapter_t *pAdapter;
15687 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015688 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015689
Jeff Johnsone7245742012-09-05 17:12:55 -070015690 ENTER();
15691
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015692 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015693 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015694 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015695 *dbm = 0;
15696 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015697 }
15698
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15700 if (NULL == pAdapter)
15701 {
15702 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15703 return -ENOENT;
15704 }
15705
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15707 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15708 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015709 wlan_hdd_get_classAstats(pAdapter);
15710 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15711
Jeff Johnsone7245742012-09-05 17:12:55 -070015712 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 return 0;
15714}
15715
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015716static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15717#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15718 struct wireless_dev *wdev,
15719#endif
15720 int *dbm)
15721{
15722 int ret;
15723
15724 vos_ssr_protect(__func__);
15725 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15726#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15727 wdev,
15728#endif
15729 dbm);
15730 vos_ssr_unprotect(__func__);
15731
15732 return ret;
15733}
15734
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015735static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15737 const u8* mac,
15738#else
15739 u8* mac,
15740#endif
15741 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015742{
15743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15744 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15745 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015746 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015747
15748 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15749 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015750
15751 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15752 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15753 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15754 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15755 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15756 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15757 tANI_U16 maxRate = 0;
15758 tANI_U16 myRate;
15759 tANI_U16 currentRate = 0;
15760 tANI_U8 maxSpeedMCS = 0;
15761 tANI_U8 maxMCSIdx = 0;
15762 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015763 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015764 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015765 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015766
Leo Chang6f8870f2013-03-26 18:11:36 -070015767#ifdef WLAN_FEATURE_11AC
15768 tANI_U32 vht_mcs_map;
15769 eDataRate11ACMaxMcs vhtMaxMcs;
15770#endif /* WLAN_FEATURE_11AC */
15771
Jeff Johnsone7245742012-09-05 17:12:55 -070015772 ENTER();
15773
Jeff Johnson295189b2012-06-20 16:38:30 -070015774 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15775 (0 == ssidlen))
15776 {
15777 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15778 " Invalid ssidlen, %d", __func__, ssidlen);
15779 /*To keep GUI happy*/
15780 return 0;
15781 }
15782
Mukul Sharma811205f2014-07-09 21:07:30 +053015783 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15784 {
15785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15786 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015787 /* return a cached value */
15788 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015789 return 0;
15790 }
15791
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015792 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015793 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015794 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015795 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015796 }
15797
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015798 wlan_hdd_get_station_stats(pAdapter);
15799 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015800
Kiet Lam3b17fc82013-09-27 05:24:08 +053015801 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15802 sinfo->filled |= STATION_INFO_SIGNAL;
15803
c_hpothu09f19542014-05-30 21:53:31 +053015804 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015805 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15806 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015807 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015808 {
15809 rate_flags = pAdapter->maxRateFlags;
15810 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015811
Jeff Johnson295189b2012-06-20 16:38:30 -070015812 //convert to the UI units of 100kbps
15813 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15814
15815#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015816 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 -070015817 sinfo->signal,
15818 pCfg->reportMaxLinkSpeed,
15819 myRate,
15820 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015821 (int) pCfg->linkSpeedRssiMid,
15822 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015823 (int) rate_flags,
15824 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015825#endif //LINKSPEED_DEBUG_ENABLED
15826
15827 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15828 {
15829 // we do not want to necessarily report the current speed
15830 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15831 {
15832 // report the max possible speed
15833 rssidx = 0;
15834 }
15835 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15836 {
15837 // report the max possible speed with RSSI scaling
15838 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15839 {
15840 // report the max possible speed
15841 rssidx = 0;
15842 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015843 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 {
15845 // report middle speed
15846 rssidx = 1;
15847 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015848 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15849 {
15850 // report middle speed
15851 rssidx = 2;
15852 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 else
15854 {
15855 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015856 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 }
15858 }
15859 else
15860 {
15861 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15862 hddLog(VOS_TRACE_LEVEL_ERROR,
15863 "%s: Invalid value for reportMaxLinkSpeed: %u",
15864 __func__, pCfg->reportMaxLinkSpeed);
15865 rssidx = 0;
15866 }
15867
15868 maxRate = 0;
15869
15870 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015871 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15872 OperationalRates, &ORLeng))
15873 {
15874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15875 /*To keep GUI happy*/
15876 return 0;
15877 }
15878
Jeff Johnson295189b2012-06-20 16:38:30 -070015879 for (i = 0; i < ORLeng; i++)
15880 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015881 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 {
15883 /* Validate Rate Set */
15884 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15885 {
15886 currentRate = supported_data_rate[j].supported_rate[rssidx];
15887 break;
15888 }
15889 }
15890 /* Update MAX rate */
15891 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15892 }
15893
15894 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015895 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15896 ExtendedRates, &ERLeng))
15897 {
15898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15899 /*To keep GUI happy*/
15900 return 0;
15901 }
15902
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 for (i = 0; i < ERLeng; i++)
15904 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015905 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 {
15907 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15908 {
15909 currentRate = supported_data_rate[j].supported_rate[rssidx];
15910 break;
15911 }
15912 }
15913 /* Update MAX rate */
15914 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15915 }
c_hpothu79aab322014-07-14 21:11:01 +053015916
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015917 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015918 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015919 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015920 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 {
c_hpothu79aab322014-07-14 21:11:01 +053015922 if (rate_flags & eHAL_TX_RATE_VHT80)
15923 mode = 2;
15924 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15925 mode = 1;
15926 else
15927 mode = 0;
15928
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015929 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15930 MCSRates, &MCSLeng))
15931 {
15932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15933 /*To keep GUI happy*/
15934 return 0;
15935 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015936 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015937#ifdef WLAN_FEATURE_11AC
15938 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015939 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015941 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015942 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015943 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015945 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015946 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015947 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015948 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015949 maxMCSIdx = 7;
15950 }
15951 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15952 {
15953 maxMCSIdx = 8;
15954 }
15955 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15956 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015957 //VHT20 is supporting 0~8
15958 if (rate_flags & eHAL_TX_RATE_VHT20)
15959 maxMCSIdx = 8;
15960 else
15961 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015962 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015963
c_hpothu79aab322014-07-14 21:11:01 +053015964 if (0 != rssidx)/*check for scaled */
15965 {
15966 //get middle rate MCS index if rssi=1/2
15967 for (i=0; i <= maxMCSIdx; i++)
15968 {
15969 if (sinfo->signal <= rssiMcsTbl[mode][i])
15970 {
15971 maxMCSIdx = i;
15972 break;
15973 }
15974 }
15975 }
15976
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015977 if (rate_flags & eHAL_TX_RATE_VHT80)
15978 {
15979 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15980 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15981 }
15982 else if (rate_flags & eHAL_TX_RATE_VHT40)
15983 {
15984 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15985 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15986 }
15987 else if (rate_flags & eHAL_TX_RATE_VHT20)
15988 {
15989 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15990 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15991 }
15992
Leo Chang6f8870f2013-03-26 18:11:36 -070015993 maxSpeedMCS = 1;
15994 if (currentRate > maxRate)
15995 {
15996 maxRate = currentRate;
15997 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015998
Leo Chang6f8870f2013-03-26 18:11:36 -070015999 }
16000 else
16001#endif /* WLAN_FEATURE_11AC */
16002 {
16003 if (rate_flags & eHAL_TX_RATE_HT40)
16004 {
16005 rateFlag |= 1;
16006 }
16007 if (rate_flags & eHAL_TX_RATE_SGI)
16008 {
16009 rateFlag |= 2;
16010 }
16011
Girish Gowli01abcee2014-07-31 20:18:55 +053016012 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016013 if (rssidx == 1 || rssidx == 2)
16014 {
16015 //get middle rate MCS index if rssi=1/2
16016 for (i=0; i <= 7; i++)
16017 {
16018 if (sinfo->signal <= rssiMcsTbl[mode][i])
16019 {
16020 temp = i+1;
16021 break;
16022 }
16023 }
16024 }
c_hpothu79aab322014-07-14 21:11:01 +053016025
16026 for (i = 0; i < MCSLeng; i++)
16027 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016028 for (j = 0; j < temp; j++)
16029 {
16030 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16031 {
16032 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016033 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016034 break;
16035 }
16036 }
16037 if ((j < temp) && (currentRate > maxRate))
16038 {
16039 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016040 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016042 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 }
16044 }
16045
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016046 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16047 {
16048 maxRate = myRate;
16049 maxSpeedMCS = 1;
16050 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16051 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016052 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016053 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 {
16055 maxRate = myRate;
16056 if (rate_flags & eHAL_TX_RATE_LEGACY)
16057 {
16058 maxSpeedMCS = 0;
16059 }
16060 else
16061 {
16062 maxSpeedMCS = 1;
16063 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16064 }
16065 }
16066
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016067 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016068 {
16069 sinfo->txrate.legacy = maxRate;
16070#ifdef LINKSPEED_DEBUG_ENABLED
16071 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16072#endif //LINKSPEED_DEBUG_ENABLED
16073 }
16074 else
16075 {
16076 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016077#ifdef WLAN_FEATURE_11AC
16078 sinfo->txrate.nss = 1;
16079 if (rate_flags & eHAL_TX_RATE_VHT80)
16080 {
16081 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016082 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016083 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016084 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016085 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016086 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16087 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16088 }
16089 else if (rate_flags & eHAL_TX_RATE_VHT20)
16090 {
16091 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16092 }
16093#endif /* WLAN_FEATURE_11AC */
16094 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16095 {
16096 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16097 if (rate_flags & eHAL_TX_RATE_HT40)
16098 {
16099 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16100 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016101 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016102 if (rate_flags & eHAL_TX_RATE_SGI)
16103 {
16104 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16105 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016106
Jeff Johnson295189b2012-06-20 16:38:30 -070016107#ifdef LINKSPEED_DEBUG_ENABLED
16108 pr_info("Reporting MCS rate %d flags %x\n",
16109 sinfo->txrate.mcs,
16110 sinfo->txrate.flags );
16111#endif //LINKSPEED_DEBUG_ENABLED
16112 }
16113 }
16114 else
16115 {
16116 // report current rate instead of max rate
16117
16118 if (rate_flags & eHAL_TX_RATE_LEGACY)
16119 {
16120 //provide to the UI in units of 100kbps
16121 sinfo->txrate.legacy = myRate;
16122#ifdef LINKSPEED_DEBUG_ENABLED
16123 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16124#endif //LINKSPEED_DEBUG_ENABLED
16125 }
16126 else
16127 {
16128 //must be MCS
16129 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016130#ifdef WLAN_FEATURE_11AC
16131 sinfo->txrate.nss = 1;
16132 if (rate_flags & eHAL_TX_RATE_VHT80)
16133 {
16134 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16135 }
16136 else
16137#endif /* WLAN_FEATURE_11AC */
16138 {
16139 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16140 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 if (rate_flags & eHAL_TX_RATE_SGI)
16142 {
16143 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16144 }
16145 if (rate_flags & eHAL_TX_RATE_HT40)
16146 {
16147 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16148 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016149#ifdef WLAN_FEATURE_11AC
16150 else if (rate_flags & eHAL_TX_RATE_VHT80)
16151 {
16152 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16153 }
16154#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016155#ifdef LINKSPEED_DEBUG_ENABLED
16156 pr_info("Reporting actual MCS rate %d flags %x\n",
16157 sinfo->txrate.mcs,
16158 sinfo->txrate.flags );
16159#endif //LINKSPEED_DEBUG_ENABLED
16160 }
16161 }
16162 sinfo->filled |= STATION_INFO_TX_BITRATE;
16163
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016164 sinfo->tx_packets =
16165 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16166 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16167 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16168 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16169
16170 sinfo->tx_retries =
16171 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16172 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16173 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16174 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16175
16176 sinfo->tx_failed =
16177 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16178 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16179 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16180 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16181
16182 sinfo->filled |=
16183 STATION_INFO_TX_PACKETS |
16184 STATION_INFO_TX_RETRIES |
16185 STATION_INFO_TX_FAILED;
16186
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016187 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16188 sinfo->filled |= STATION_INFO_RX_PACKETS;
16189
16190 if (rate_flags & eHAL_TX_RATE_LEGACY)
16191 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16192 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16193 sinfo->rx_packets);
16194 else
16195 hddLog(LOG1,
16196 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16197 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16198 sinfo->tx_packets, sinfo->rx_packets);
16199
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016200 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16201 TRACE_CODE_HDD_CFG80211_GET_STA,
16202 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016203 EXIT();
16204 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016205}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16207static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16208 const u8* mac, struct station_info *sinfo)
16209#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016210static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16211 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016212#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016213{
16214 int ret;
16215
16216 vos_ssr_protect(__func__);
16217 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16218 vos_ssr_unprotect(__func__);
16219
16220 return ret;
16221}
16222
16223static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016224 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016225{
16226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016227 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016228 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016229 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016230
Jeff Johnsone7245742012-09-05 17:12:55 -070016231 ENTER();
16232
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 if (NULL == pAdapter)
16234 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016236 return -ENODEV;
16237 }
16238
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016239 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16240 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16241 pAdapter->sessionId, timeout));
16242
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016244 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016245 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016246 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016247 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016248 }
16249
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016250 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16251 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16252 (pHddCtx->cfg_ini->fhostArpOffload) &&
16253 (eConnectionState_Associated ==
16254 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16255 {
Amar Singhald53568e2013-09-26 11:03:45 -070016256
16257 hddLog(VOS_TRACE_LEVEL_INFO,
16258 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016259 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016260 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16261 {
16262 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016263 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016264 __func__, vos_status);
16265 }
16266 }
16267
Jeff Johnson295189b2012-06-20 16:38:30 -070016268 /**The get power cmd from the supplicant gets updated by the nl only
16269 *on successful execution of the function call
16270 *we are oppositely mapped w.r.t mode in the driver
16271 **/
16272 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16273
16274 if (VOS_STATUS_E_FAILURE == vos_status)
16275 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16277 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016278 return -EINVAL;
16279 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016280 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016281 return 0;
16282}
16283
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016284static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16285 struct net_device *dev, bool mode, int timeout)
16286{
16287 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016289 vos_ssr_protect(__func__);
16290 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16291 vos_ssr_unprotect(__func__);
16292
16293 return ret;
16294}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016295
Jeff Johnson295189b2012-06-20 16:38:30 -070016296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016297static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16298 struct net_device *netdev,
16299 u8 key_index)
16300{
16301 ENTER();
16302 return 0;
16303}
16304
Jeff Johnson295189b2012-06-20 16:38:30 -070016305static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016306 struct net_device *netdev,
16307 u8 key_index)
16308{
16309 int ret;
16310 vos_ssr_protect(__func__);
16311 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16312 vos_ssr_unprotect(__func__);
16313 return ret;
16314}
16315#endif //LINUX_VERSION_CODE
16316
16317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16318static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16319 struct net_device *dev,
16320 struct ieee80211_txq_params *params)
16321{
16322 ENTER();
16323 return 0;
16324}
16325#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16326static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16327 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016328{
Jeff Johnsone7245742012-09-05 17:12:55 -070016329 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016330 return 0;
16331}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016332#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016333
16334#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16335static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016336 struct net_device *dev,
16337 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016338{
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, dev, params);
16343 vos_ssr_unprotect(__func__);
16344 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016345}
16346#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16347static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16348 struct ieee80211_txq_params *params)
16349{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016350 int ret;
16351
16352 vos_ssr_protect(__func__);
16353 ret = __wlan_hdd_set_txq_params(wiphy, params);
16354 vos_ssr_unprotect(__func__);
16355 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016356}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016357#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016358
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016359static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016360 struct net_device *dev,
16361 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016362{
16363 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016364 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016365 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016366 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016367 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016368 v_CONTEXT_t pVosContext = NULL;
16369 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016370
Jeff Johnsone7245742012-09-05 17:12:55 -070016371 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016372
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016373 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016374 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 return -EINVAL;
16377 }
16378
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016379 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16380 TRACE_CODE_HDD_CFG80211_DEL_STA,
16381 pAdapter->sessionId, pAdapter->device_mode));
16382
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016383 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16384 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016385 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016386 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016387 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016388 }
16389
Jeff Johnson295189b2012-06-20 16:38:30 -070016390 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016391 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 )
16393 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016394 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16395 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16396 if(pSapCtx == NULL){
16397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16398 FL("psapCtx is NULL"));
16399 return -ENOENT;
16400 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016401 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016402 {
16403 v_U16_t i;
16404 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16405 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016406 if ((pSapCtx->aStaInfo[i].isUsed) &&
16407 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016408 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016409 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016410 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016411 ETHER_ADDR_LEN);
16412
Jeff Johnson295189b2012-06-20 16:38:30 -070016413 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016414 "%s: Delete STA with MAC::"
16415 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016416 __func__,
16417 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16418 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016419 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016420 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 }
16422 }
16423 }
16424 else
16425 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016426
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016427 vos_status = hdd_softap_GetStaId(pAdapter,
16428 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016429 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16430 {
16431 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016432 "%s: Skip this DEL STA as this is not used::"
16433 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016434 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016435 return -ENOENT;
16436 }
16437
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016438 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016439 {
16440 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016441 "%s: Skip this DEL STA as deauth is in progress::"
16442 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016443 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016444 return -ENOENT;
16445 }
16446
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016447 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016448
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 hddLog(VOS_TRACE_LEVEL_INFO,
16450 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016451 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016453 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016454
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016455 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016456 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16457 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016458 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016459 hddLog(VOS_TRACE_LEVEL_INFO,
16460 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016461 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016462 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016463 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016464 return -ENOENT;
16465 }
16466
Jeff Johnson295189b2012-06-20 16:38:30 -070016467 }
16468 }
16469
16470 EXIT();
16471
16472 return 0;
16473}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016474
16475#ifdef CFG80211_DEL_STA_V2
16476static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16477 struct net_device *dev,
16478 struct station_del_parameters *param)
16479#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16481static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16482 struct net_device *dev, const u8 *mac)
16483#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016484static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16485 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016486#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016487#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016488{
16489 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016490 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016491
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016492 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016493
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016494#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016495 if (NULL == param) {
16496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016497 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016498 return -EINVAL;
16499 }
16500
16501 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16502 param->subtype, &delStaParams);
16503
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016504#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016505 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016506 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016507#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016508 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16509
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016510 vos_ssr_unprotect(__func__);
16511
16512 return ret;
16513}
16514
16515static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016516 struct net_device *dev,
16517#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16518 const u8 *mac,
16519#else
16520 u8 *mac,
16521#endif
16522 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016523{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016524 hdd_adapter_t *pAdapter;
16525 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016526 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016527#ifdef FEATURE_WLAN_TDLS
16528 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016529
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016530 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016531
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016532 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16533 if (NULL == pAdapter)
16534 {
16535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16536 "%s: Adapter is NULL",__func__);
16537 return -EINVAL;
16538 }
16539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16540 status = wlan_hdd_validate_context(pHddCtx);
16541 if (0 != status)
16542 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016543 return status;
16544 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016545
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016546 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16547 TRACE_CODE_HDD_CFG80211_ADD_STA,
16548 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016549 mask = params->sta_flags_mask;
16550
16551 set = params->sta_flags_set;
16552
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016554 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16555 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016556
16557 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16558 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016559 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016560 }
16561 }
16562#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016563 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016564 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016565}
16566
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16568static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16569 struct net_device *dev, const u8 *mac,
16570 struct station_parameters *params)
16571#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016572static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16573 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016574#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016575{
16576 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016577
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016578 vos_ssr_protect(__func__);
16579 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16580 vos_ssr_unprotect(__func__);
16581
16582 return ret;
16583}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016584#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016585
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016586static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016587 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016588{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16590 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016592 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016593 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016594 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016596 ENTER();
16597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016598 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016599 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016600 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016602 return -EINVAL;
16603 }
16604
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016605 if (!pmksa) {
16606 hddLog(LOGE, FL("pmksa is NULL"));
16607 return -EINVAL;
16608 }
16609
16610 if (!pmksa->bssid || !pmksa->pmkid) {
16611 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16612 pmksa->bssid, pmksa->pmkid);
16613 return -EINVAL;
16614 }
16615
16616 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16617 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16618
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16620 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016621 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016622 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016623 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016624 }
16625
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016626 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016627 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16628
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016629 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16630 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016631
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016632 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016633 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016634 &pmk_id, 1, FALSE);
16635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16637 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16638 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016639
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016640 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016641 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016642}
16643
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016644static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16645 struct cfg80211_pmksa *pmksa)
16646{
16647 int ret;
16648
16649 vos_ssr_protect(__func__);
16650 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16651 vos_ssr_unprotect(__func__);
16652
16653 return ret;
16654}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016655
Wilson Yang6507c4e2013-10-01 20:11:19 -070016656
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016657static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016658 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016659{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16661 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016662 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016663 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016664
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016665 ENTER();
16666
Wilson Yang6507c4e2013-10-01 20:11:19 -070016667 /* Validate pAdapter */
16668 if (NULL == pAdapter)
16669 {
16670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16671 return -EINVAL;
16672 }
16673
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016674 if (!pmksa) {
16675 hddLog(LOGE, FL("pmksa is NULL"));
16676 return -EINVAL;
16677 }
16678
16679 if (!pmksa->bssid) {
16680 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16681 return -EINVAL;
16682 }
16683
Kiet Lam98c46a12014-10-31 15:34:57 -070016684 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16685 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16686
Wilson Yang6507c4e2013-10-01 20:11:19 -070016687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16688 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016689 if (0 != status)
16690 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016691 return status;
16692 }
16693
16694 /*Retrieve halHandle*/
16695 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16696
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016697 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16698 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16699 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016700 /* Delete the PMKID CSR cache */
16701 if (eHAL_STATUS_SUCCESS !=
16702 sme_RoamDelPMKIDfromCache(halHandle,
16703 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16704 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16705 MAC_ADDR_ARRAY(pmksa->bssid));
16706 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016707 }
16708
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016709 EXIT();
16710 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016711}
16712
Wilson Yang6507c4e2013-10-01 20:11:19 -070016713
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016714static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16715 struct cfg80211_pmksa *pmksa)
16716{
16717 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016718
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016719 vos_ssr_protect(__func__);
16720 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16721 vos_ssr_unprotect(__func__);
16722
16723 return ret;
16724
16725}
16726
16727static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016728{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016729 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16730 tHalHandle halHandle;
16731 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016732 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016733
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016734 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016735
16736 /* Validate pAdapter */
16737 if (NULL == pAdapter)
16738 {
16739 hddLog(VOS_TRACE_LEVEL_ERROR,
16740 "%s: Invalid Adapter" ,__func__);
16741 return -EINVAL;
16742 }
16743
16744 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16745 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016746 if (0 != status)
16747 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016748 return status;
16749 }
16750
16751 /*Retrieve halHandle*/
16752 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16753
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016754 /* Flush the PMKID cache in CSR */
16755 if (eHAL_STATUS_SUCCESS !=
16756 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16758 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016759 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016760 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016761 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016762}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016763
16764static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16765{
16766 int ret;
16767
16768 vos_ssr_protect(__func__);
16769 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16770 vos_ssr_unprotect(__func__);
16771
16772 return ret;
16773}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016774#endif
16775
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016776#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016777static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16778 struct net_device *dev,
16779 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016780{
16781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16782 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016783 hdd_context_t *pHddCtx;
16784 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016786 ENTER();
16787
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016788 if (NULL == pAdapter)
16789 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016791 return -ENODEV;
16792 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016793 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16794 ret = wlan_hdd_validate_context(pHddCtx);
16795 if (0 != ret)
16796 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016797 return ret;
16798 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016800 if (NULL == pHddStaCtx)
16801 {
16802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16803 return -EINVAL;
16804 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16807 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16808 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016809 // Added for debug on reception of Re-assoc Req.
16810 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16811 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016812 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016813 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016814 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016815 }
16816
16817#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016818 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016819 ftie->ie_len);
16820#endif
16821
16822 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016823 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16824 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016825 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016826
16827 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016828 return 0;
16829}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016830
16831static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16832 struct net_device *dev,
16833 struct cfg80211_update_ft_ies_params *ftie)
16834{
16835 int ret;
16836
16837 vos_ssr_protect(__func__);
16838 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16839 vos_ssr_unprotect(__func__);
16840
16841 return ret;
16842}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016843#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016844
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016845#ifdef FEATURE_WLAN_SCAN_PNO
16846
16847void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16848 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16849{
16850 int ret;
16851 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16852 hdd_context_t *pHddCtx;
16853
Nirav Shah80830bf2013-12-31 16:35:12 +053016854 ENTER();
16855
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016856 if (NULL == pAdapter)
16857 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016859 "%s: HDD adapter is Null", __func__);
16860 return ;
16861 }
16862
16863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16864 if (NULL == pHddCtx)
16865 {
16866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16867 "%s: HDD context is Null!!!", __func__);
16868 return ;
16869 }
16870
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016871 spin_lock(&pHddCtx->schedScan_lock);
16872 if (TRUE == pHddCtx->isWiphySuspended)
16873 {
16874 pHddCtx->isSchedScanUpdatePending = TRUE;
16875 spin_unlock(&pHddCtx->schedScan_lock);
16876 hddLog(VOS_TRACE_LEVEL_INFO,
16877 "%s: Update cfg80211 scan database after it resume", __func__);
16878 return ;
16879 }
16880 spin_unlock(&pHddCtx->schedScan_lock);
16881
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016882 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16883
16884 if (0 > ret)
16885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016886 else
16887 {
16888 /* Acquire wakelock to handle the case where APP's tries to suspend
16889 * immediatly after the driver gets connect request(i.e after pno)
16890 * from supplicant, this result in app's is suspending and not able
16891 * to process the connect request to AP */
16892 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16893 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016894 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16896 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016897}
16898
16899/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016900 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016901 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016902 */
16903static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16904{
16905 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16906 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016907 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016908 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16909 int status = 0;
16910 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16911
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016912 /* The current firmware design does not allow PNO during any
16913 * active sessions. Hence, determine the active sessions
16914 * and return a failure.
16915 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016916 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16917 {
16918 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016919 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016920
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016921 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16922 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16923 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16924 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16925 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016926 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016927 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016928 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016929 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016930 }
16931 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16932 pAdapterNode = pNext;
16933 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016934 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016935}
16936
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016937void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16938{
16939 hdd_adapter_t *pAdapter = callbackContext;
16940 hdd_context_t *pHddCtx;
16941
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016942 ENTER();
16943
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016944 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16945 {
16946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16947 FL("Invalid adapter or adapter has invalid magic"));
16948 return;
16949 }
16950
16951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16952 if (0 != wlan_hdd_validate_context(pHddCtx))
16953 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016954 return;
16955 }
16956
c_hpothub53c45d2014-08-18 16:53:14 +053016957 if (VOS_STATUS_SUCCESS != status)
16958 {
16959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016960 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016961 pHddCtx->isPnoEnable = FALSE;
16962 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016963
16964 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16965 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016966 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016967}
16968
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016969/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016970 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16971 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016972 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016973static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016974 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16975{
16976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016977 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016978 hdd_context_t *pHddCtx;
16979 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016980 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016981 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16982 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016983 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16984 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016985 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016986 hdd_config_t *pConfig = NULL;
16987 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016989 ENTER();
16990
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016991 if (NULL == pAdapter)
16992 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016994 "%s: HDD adapter is Null", __func__);
16995 return -ENODEV;
16996 }
16997
16998 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016999 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017000
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017001 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017002 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017003 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017004 }
17005
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017006 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017007 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17008 if (NULL == hHal)
17009 {
17010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17011 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017012 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017013 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17015 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17016 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017017 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017018 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017019 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017020 {
17021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17022 "%s: aborting the existing scan is unsuccessfull", __func__);
17023 return -EBUSY;
17024 }
17025
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017026 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017027 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017029 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017030 return -EBUSY;
17031 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017032
c_hpothu37f21312014-04-09 21:49:54 +053017033 if (TRUE == pHddCtx->isPnoEnable)
17034 {
17035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17036 FL("already PNO is enabled"));
17037 return -EBUSY;
17038 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017039
17040 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17041 {
17042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17043 "%s: abort ROC failed ", __func__);
17044 return -EBUSY;
17045 }
17046
c_hpothu37f21312014-04-09 21:49:54 +053017047 pHddCtx->isPnoEnable = TRUE;
17048
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017049 pnoRequest.enable = 1; /*Enable PNO */
17050 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017051
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017052 if (( !pnoRequest.ucNetworksCount ) ||
17053 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017054 {
17055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017056 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017057 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017058 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017059 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017060 goto error;
17061 }
17062
17063 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17064 {
17065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017066 "%s: Incorrect number of channels %d",
17067 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017068 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017069 goto error;
17070 }
17071
17072 /* Framework provides one set of channels(all)
17073 * common for all saved profile */
17074 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17075 channels_allowed, &num_channels_allowed))
17076 {
17077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17078 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017079 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017080 goto error;
17081 }
17082 /* Checking each channel against allowed channel list */
17083 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017084 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017085 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017086 char chList [(request->n_channels*5)+1];
17087 int len;
17088 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017089 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017090 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017091 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017092 if (request->channels[i]->hw_value == channels_allowed[indx])
17093 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017094 if ((!pConfig->enableDFSPnoChnlScan) &&
17095 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17096 {
17097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17098 "%s : Dropping DFS channel : %d",
17099 __func__,channels_allowed[indx]);
17100 num_ignore_dfs_ch++;
17101 break;
17102 }
17103
Nirav Shah80830bf2013-12-31 16:35:12 +053017104 valid_ch[num_ch++] = request->channels[i]->hw_value;
17105 len += snprintf(chList+len, 5, "%d ",
17106 request->channels[i]->hw_value);
17107 break ;
17108 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017109 }
17110 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017111 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017112
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017113 /*If all channels are DFS and dropped, then ignore the PNO request*/
17114 if (num_ignore_dfs_ch == request->n_channels)
17115 {
17116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17117 "%s : All requested channels are DFS channels", __func__);
17118 ret = -EINVAL;
17119 goto error;
17120 }
17121 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017122
17123 pnoRequest.aNetworks =
17124 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17125 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017126 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017127 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17128 FL("failed to allocate memory aNetworks %u"),
17129 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17130 goto error;
17131 }
17132 vos_mem_zero(pnoRequest.aNetworks,
17133 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17134
17135 /* Filling per profile params */
17136 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17137 {
17138 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017139 request->match_sets[i].ssid.ssid_len;
17140
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017141 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17142 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017143 {
17144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017145 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017146 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017147 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017148 goto error;
17149 }
17150
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017151 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017152 request->match_sets[i].ssid.ssid,
17153 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17155 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017156 i, pnoRequest.aNetworks[i].ssId.ssId);
17157 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17158 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17159 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017160
17161 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017162 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17163 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017164
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017165 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017166 }
17167
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017168 for (i = 0; i < request->n_ssids; i++)
17169 {
17170 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017171 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017172 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017173 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017174 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017175 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017176 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017177 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017178 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017179 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017180 break;
17181 }
17182 j++;
17183 }
17184 }
17185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17186 "Number of hidden networks being Configured = %d",
17187 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017189 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017190
17191 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17192 if (pnoRequest.p24GProbeTemplate == NULL)
17193 {
17194 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17195 FL("failed to allocate memory p24GProbeTemplate %u"),
17196 SIR_PNO_MAX_PB_REQ_SIZE);
17197 goto error;
17198 }
17199
17200 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17201 if (pnoRequest.p5GProbeTemplate == NULL)
17202 {
17203 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17204 FL("failed to allocate memory p5GProbeTemplate %u"),
17205 SIR_PNO_MAX_PB_REQ_SIZE);
17206 goto error;
17207 }
17208
17209 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17210 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17211
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017212 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17213 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017214 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017215 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17216 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17217 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017218
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017219 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17220 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17221 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017222 }
17223
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017224 /* Driver gets only one time interval which is hardcoded in
17225 * supplicant for 10000ms. Taking power consumption into account 6 timers
17226 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17227 * 80,160,320 secs. And number of scan cycle for each timer
17228 * is configurable through INI param gPNOScanTimerRepeatValue.
17229 * If it is set to 0 only one timer will be used and PNO scan cycle
17230 * will be repeated after each interval specified by supplicant
17231 * till PNO is disabled.
17232 */
17233 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017234 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017235 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017236 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017237 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17238
17239 tempInterval = (request->interval)/1000;
17240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17241 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17242 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017243 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017244 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017245 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017246 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017247 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017248 tempInterval *= 2;
17249 }
17250 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017251 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017252
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017253 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017254
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017255 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017256 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17257 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017258 pAdapter->pno_req_status = 0;
17259
Nirav Shah80830bf2013-12-31 16:35:12 +053017260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17261 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017262 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17263 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017264
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017265 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017266 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017267 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17268 if (eHAL_STATUS_SUCCESS != status)
17269 {
17270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017271 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017272 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017273 goto error;
17274 }
17275
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017276 ret = wait_for_completion_timeout(
17277 &pAdapter->pno_comp_var,
17278 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17279 if (0 >= ret)
17280 {
17281 // Did not receive the response for PNO enable in time.
17282 // Assuming the PNO enable was success.
17283 // Returning error from here, because we timeout, results
17284 // in side effect of Wifi (Wifi Setting) not to work.
17285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17286 FL("Timed out waiting for PNO to be Enabled"));
17287 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017288 }
17289
17290 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017291 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017292
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017293error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17295 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017296 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017297 if (pnoRequest.aNetworks)
17298 vos_mem_free(pnoRequest.aNetworks);
17299 if (pnoRequest.p24GProbeTemplate)
17300 vos_mem_free(pnoRequest.p24GProbeTemplate);
17301 if (pnoRequest.p5GProbeTemplate)
17302 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017303
17304 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017305 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017306}
17307
17308/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017309 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17310 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017311 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017312static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17313 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17314{
17315 int ret;
17316
17317 vos_ssr_protect(__func__);
17318 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17319 vos_ssr_unprotect(__func__);
17320
17321 return ret;
17322}
17323
17324/*
17325 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17326 * Function to disable PNO
17327 */
17328static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017329 struct net_device *dev)
17330{
17331 eHalStatus status = eHAL_STATUS_FAILURE;
17332 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17333 hdd_context_t *pHddCtx;
17334 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017335 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017336 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017337
17338 ENTER();
17339
17340 if (NULL == pAdapter)
17341 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017343 "%s: HDD adapter is Null", __func__);
17344 return -ENODEV;
17345 }
17346
17347 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017348
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017349 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017350 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017352 "%s: HDD context is Null", __func__);
17353 return -ENODEV;
17354 }
17355
17356 /* The return 0 is intentional when isLogpInProgress and
17357 * isLoadUnloadInProgress. We did observe a crash due to a return of
17358 * failure in sched_scan_stop , especially for a case where the unload
17359 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17360 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17361 * success. If it returns a failure , then its next invocation due to the
17362 * clean up of the second interface will have the dev pointer corresponding
17363 * to the first one leading to a crash.
17364 */
17365 if (pHddCtx->isLogpInProgress)
17366 {
17367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17368 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017369 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017370 return ret;
17371 }
17372
Mihir Shete18156292014-03-11 15:38:30 +053017373 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017374 {
17375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17376 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17377 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017378 }
17379
17380 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17381 if (NULL == hHal)
17382 {
17383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17384 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017385 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017386 }
17387
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017388 pnoRequest.enable = 0; /* Disable PNO */
17389 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017390
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017391 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17392 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17393 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017394
17395 INIT_COMPLETION(pAdapter->pno_comp_var);
17396 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17397 pnoRequest.callbackContext = pAdapter;
17398 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017399 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017400 pAdapter->sessionId,
17401 NULL, pAdapter);
17402 if (eHAL_STATUS_SUCCESS != status)
17403 {
17404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17405 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017406 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017407 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017408 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017409 ret = wait_for_completion_timeout(
17410 &pAdapter->pno_comp_var,
17411 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17412 if (0 >= ret)
17413 {
17414 // Did not receive the response for PNO disable in time.
17415 // Assuming the PNO disable was success.
17416 // Returning error from here, because we timeout, results
17417 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017419 FL("Timed out waiting for PNO to be disabled"));
17420 ret = 0;
17421 }
17422
17423 ret = pAdapter->pno_req_status;
17424 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017425
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017426error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017428 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017429
17430 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017431 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017432}
17433
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017434/*
17435 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17436 * NL interface to disable PNO
17437 */
17438static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17439 struct net_device *dev)
17440{
17441 int ret;
17442
17443 vos_ssr_protect(__func__);
17444 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17445 vos_ssr_unprotect(__func__);
17446
17447 return ret;
17448}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017449#endif /*FEATURE_WLAN_SCAN_PNO*/
17450
17451
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017452#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017453#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017454static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17455 struct net_device *dev,
17456 u8 *peer, u8 action_code,
17457 u8 dialog_token,
17458 u16 status_code, u32 peer_capability,
17459 const u8 *buf, size_t len)
17460#else /* TDLS_MGMT_VERSION2 */
17461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17462static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17463 struct net_device *dev,
17464 const u8 *peer, u8 action_code,
17465 u8 dialog_token, u16 status_code,
17466 u32 peer_capability, bool initiator,
17467 const u8 *buf, size_t len)
17468#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17469static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17470 struct net_device *dev,
17471 const u8 *peer, u8 action_code,
17472 u8 dialog_token, u16 status_code,
17473 u32 peer_capability, const u8 *buf,
17474 size_t len)
17475#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17476static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17477 struct net_device *dev,
17478 u8 *peer, u8 action_code,
17479 u8 dialog_token,
17480 u16 status_code, u32 peer_capability,
17481 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017482#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017483static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17484 struct net_device *dev,
17485 u8 *peer, u8 action_code,
17486 u8 dialog_token,
17487 u16 status_code, const u8 *buf,
17488 size_t len)
17489#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017490#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017491{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017492 hdd_adapter_t *pAdapter;
17493 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017494 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017495 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017496 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017497 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017498 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017499 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017500#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017501 u32 peer_capability = 0;
17502#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017503 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017504 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017505
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017506 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17507 if (NULL == pAdapter)
17508 {
17509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17510 "%s: Adapter is NULL",__func__);
17511 return -EINVAL;
17512 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017513 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17514 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17515 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017516
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017517 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017518 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017521 "Invalid arguments");
17522 return -EINVAL;
17523 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017524
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017525 if (pHddCtx->isLogpInProgress)
17526 {
17527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17528 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017529 wlan_hdd_tdls_set_link_status(pAdapter,
17530 peer,
17531 eTDLS_LINK_IDLE,
17532 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017533 return -EBUSY;
17534 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017535
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017536 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17537 {
17538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17539 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17540 return -EAGAIN;
17541 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017542
Hoonki Lee27511902013-03-14 18:19:06 -070017543 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017544 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017546 "%s: TDLS mode is disabled OR not enabled in FW."
17547 MAC_ADDRESS_STR " action %d declined.",
17548 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017549 return -ENOTSUPP;
17550 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017551
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017552 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17553
17554 if( NULL == pHddStaCtx )
17555 {
17556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17557 "%s: HDD station context NULL ",__func__);
17558 return -EINVAL;
17559 }
17560
17561 /* STA should be connected and authenticated
17562 * before sending any TDLS frames
17563 */
17564 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17565 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17566 {
17567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17568 "STA is not connected or unauthenticated. "
17569 "connState %u, uIsAuthenticated %u",
17570 pHddStaCtx->conn_info.connState,
17571 pHddStaCtx->conn_info.uIsAuthenticated);
17572 return -EAGAIN;
17573 }
17574
Hoonki Lee27511902013-03-14 18:19:06 -070017575 /* other than teardown frame, other mgmt frames are not sent if disabled */
17576 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17577 {
17578 /* if tdls_mode is disabled to respond to peer's request */
17579 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17580 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017582 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017583 " TDLS mode is disabled. action %d declined.",
17584 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017585
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017586 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017587 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017588
17589 if (vos_max_concurrent_connections_reached())
17590 {
17591 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17592 return -EINVAL;
17593 }
Hoonki Lee27511902013-03-14 18:19:06 -070017594 }
17595
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017596 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17597 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017598 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017599 {
17600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017601 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017602 " TDLS setup is ongoing. action %d declined.",
17603 __func__, MAC_ADDR_ARRAY(peer), action_code);
17604 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017605 }
17606 }
17607
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017608 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17609 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017610 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017611 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17612 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017613 {
17614 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17615 we return error code at 'add_station()'. Hence we have this
17616 check again in addtion to add_station().
17617 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017618 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017619 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17621 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017622 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17623 __func__, MAC_ADDR_ARRAY(peer), action_code,
17624 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017625 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017626 }
17627 else
17628 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017629 /* maximum reached. tweak to send error code to peer and return
17630 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017631 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17633 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017634 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17635 __func__, MAC_ADDR_ARRAY(peer), status_code,
17636 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017637 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017638 /* fall through to send setup resp with failure status
17639 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017640 }
17641 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017642 else
17643 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017644 mutex_lock(&pHddCtx->tdls_lock);
17645 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017646 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017647 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017648 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017650 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17651 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017652 return -EPERM;
17653 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017654 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017655 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017656 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017657
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017659 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017660 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17661 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017662
Hoonki Leea34dd892013-02-05 22:56:02 -080017663 /*Except teardown responder will not be used so just make 0*/
17664 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017665 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017666 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017667
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017668 mutex_lock(&pHddCtx->tdls_lock);
17669 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017670
17671 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17672 responder = pTdlsPeer->is_responder;
17673 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017674 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017676 "%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 -070017677 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17678 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017679 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017680 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017681 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017682 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017683 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017684
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017685 /* Discard TDLS setup if peer is removed by user app */
17686 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17687 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17688 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17689 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17690
17691 mutex_lock(&pHddCtx->tdls_lock);
17692 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17693 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17694 mutex_unlock(&pHddCtx->tdls_lock);
17695 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17696 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17697 MAC_ADDR_ARRAY(peer), action_code);
17698 return -EINVAL;
17699 }
17700 mutex_unlock(&pHddCtx->tdls_lock);
17701 }
17702
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017703 /* For explicit trigger of DIS_REQ come out of BMPS for
17704 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017705 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017706 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017707 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17708 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017709 {
17710 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17711 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017713 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017714 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17715 if (status != VOS_STATUS_SUCCESS) {
17716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17717 }
Hoonki Lee14621352013-04-16 17:51:19 -070017718 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017719 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017720 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17722 }
17723 }
Hoonki Lee14621352013-04-16 17:51:19 -070017724 }
17725
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017726 /* make sure doesn't call send_mgmt() while it is pending */
17727 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17728 {
17729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017730 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017731 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017732 ret = -EBUSY;
17733 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017734 }
17735
17736 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017737 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17738
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017739 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17740 pAdapter->sessionId, peer, action_code, dialog_token,
17741 status_code, peer_capability, (tANI_U8 *)buf, len,
17742 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017743
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017744 if (VOS_STATUS_SUCCESS != status)
17745 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17747 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017748 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017749 ret = -EINVAL;
17750 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017751 }
17752
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17754 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17755 WAIT_TIME_TDLS_MGMT);
17756
Hoonki Leed37cbb32013-04-20 00:31:14 -070017757 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17758 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17759
17760 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017761 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017763 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017764 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017765 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017766
17767 if (pHddCtx->isLogpInProgress)
17768 {
17769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17770 "%s: LOGP in Progress. Ignore!!!", __func__);
17771 return -EAGAIN;
17772 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017773 if (rc <= 0)
17774 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17775 WLAN_LOG_INDICATOR_HOST_DRIVER,
17776 WLAN_LOG_REASON_HDD_TIME_OUT,
17777 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017778
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017779 ret = -EINVAL;
17780 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017781 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017782 else
17783 {
17784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17785 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17786 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17787 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017788
Gopichand Nakkala05922802013-03-14 12:23:19 -070017789 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017790 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017791 ret = max_sta_failed;
17792 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017793 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017794
Hoonki Leea34dd892013-02-05 22:56:02 -080017795 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17796 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017797 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17799 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017800 }
17801 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17802 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017803 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17805 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017806 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017807
17808 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017809
17810tx_failed:
17811 /* add_station will be called before sending TDLS_SETUP_REQ and
17812 * TDLS_SETUP_RSP and as part of add_station driver will enable
17813 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17814 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17815 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17816 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17817 */
17818
17819 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17820 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17821 wlan_hdd_tdls_check_bmps(pAdapter);
17822 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017823}
17824
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017825#if TDLS_MGMT_VERSION2
17826static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17827 u8 *peer, u8 action_code, u8 dialog_token,
17828 u16 status_code, u32 peer_capability,
17829 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017830#else /* TDLS_MGMT_VERSION2 */
17831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17832static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17833 struct net_device *dev,
17834 const u8 *peer, u8 action_code,
17835 u8 dialog_token, u16 status_code,
17836 u32 peer_capability, bool initiator,
17837 const u8 *buf, size_t len)
17838#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17839static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17840 struct net_device *dev,
17841 const u8 *peer, u8 action_code,
17842 u8 dialog_token, u16 status_code,
17843 u32 peer_capability, const u8 *buf,
17844 size_t len)
17845#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17846static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17847 struct net_device *dev,
17848 u8 *peer, u8 action_code,
17849 u8 dialog_token,
17850 u16 status_code, u32 peer_capability,
17851 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017852#else
17853static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17854 u8 *peer, u8 action_code, u8 dialog_token,
17855 u16 status_code, const u8 *buf, size_t len)
17856#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017857#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017858{
17859 int ret;
17860
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017861 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017862#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017863 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17864 dialog_token, status_code,
17865 peer_capability, buf, len);
17866#else /* TDLS_MGMT_VERSION2 */
17867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17868 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17869 dialog_token, status_code,
17870 peer_capability, initiator,
17871 buf, len);
17872#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17873 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17874 dialog_token, status_code,
17875 peer_capability, buf, len);
17876#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17877 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17878 dialog_token, status_code,
17879 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017880#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017881 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17882 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017883#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017884#endif
17885 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017886
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017887 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017888}
Atul Mittal115287b2014-07-08 13:26:33 +053017889
17890int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17892 const u8 *peer,
17893#else
Atul Mittal115287b2014-07-08 13:26:33 +053017894 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017895#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017896 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017897 cfg80211_exttdls_callback callback)
17898{
17899
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017900 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017901 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017902 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17904 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17905 __func__, MAC_ADDR_ARRAY(peer));
17906
17907 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17908 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17909
17910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017911 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17912 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17913 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017914 return -ENOTSUPP;
17915 }
17916
17917 /* To cater the requirement of establishing the TDLS link
17918 * irrespective of the data traffic , get an entry of TDLS peer.
17919 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017920 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017921 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17922 if (pTdlsPeer == NULL) {
17923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17924 "%s: peer " MAC_ADDRESS_STR " not existing",
17925 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017926 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017927 return -EINVAL;
17928 }
17929
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017930 /* check FW TDLS Off Channel capability */
17931 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017932 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017933 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017934 {
17935 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17936 pTdlsPeer->peerParams.global_operating_class =
17937 tdls_peer_params->global_operating_class;
17938 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17939 pTdlsPeer->peerParams.min_bandwidth_kbps =
17940 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017941 /* check configured channel is valid, non dfs and
17942 * not current operating channel */
17943 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17944 tdls_peer_params->channel)) &&
17945 (pHddStaCtx) &&
17946 (tdls_peer_params->channel !=
17947 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017948 {
17949 pTdlsPeer->isOffChannelConfigured = TRUE;
17950 }
17951 else
17952 {
17953 pTdlsPeer->isOffChannelConfigured = FALSE;
17954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17955 "%s: Configured Tdls Off Channel is not valid", __func__);
17956
17957 }
17958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017959 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17960 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017961 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017962 pTdlsPeer->isOffChannelConfigured,
17963 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017964 }
17965 else
17966 {
17967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017968 "%s: TDLS off channel FW capability %d, "
17969 "host capab %d or Invalid TDLS Peer Params", __func__,
17970 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17971 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017972 }
17973
Atul Mittal115287b2014-07-08 13:26:33 +053017974 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17975
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017976 mutex_unlock(&pHddCtx->tdls_lock);
17977
Atul Mittal115287b2014-07-08 13:26:33 +053017978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17979 " %s TDLS Add Force Peer Failed",
17980 __func__);
17981 return -EINVAL;
17982 }
17983 /*EXT TDLS*/
17984
17985 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017986 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17988 " %s TDLS set callback Failed",
17989 __func__);
17990 return -EINVAL;
17991 }
17992
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017993 mutex_unlock(&pHddCtx->tdls_lock);
17994
Atul Mittal115287b2014-07-08 13:26:33 +053017995 return(0);
17996
17997}
17998
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017999int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18001 const u8 *peer
18002#else
18003 u8 *peer
18004#endif
18005)
Atul Mittal115287b2014-07-08 13:26:33 +053018006{
18007
18008 hddTdlsPeer_t *pTdlsPeer;
18009 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018010
Atul Mittal115287b2014-07-08 13:26:33 +053018011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18012 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18013 __func__, MAC_ADDR_ARRAY(peer));
18014
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018015 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18017 return -EINVAL;
18018 }
18019
Atul Mittal115287b2014-07-08 13:26:33 +053018020 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18021 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18022
18023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018024 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18025 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18026 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018027 return -ENOTSUPP;
18028 }
18029
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018030 mutex_lock(&pHddCtx->tdls_lock);
18031 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018032
18033 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018034 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018036 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018037 __func__, MAC_ADDR_ARRAY(peer));
18038 return -EINVAL;
18039 }
18040 else {
18041 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18042 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018043 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18044 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018045 /* if channel switch is configured, reset
18046 the channel for this peer */
18047 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18048 {
18049 pTdlsPeer->peerParams.channel = 0;
18050 pTdlsPeer->isOffChannelConfigured = FALSE;
18051 }
Atul Mittal115287b2014-07-08 13:26:33 +053018052 }
18053
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018054 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018055 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018057 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018058 }
Atul Mittal115287b2014-07-08 13:26:33 +053018059
18060 /*EXT TDLS*/
18061
18062 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018063 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18065 " %s TDLS set callback Failed",
18066 __func__);
18067 return -EINVAL;
18068 }
Atul Mittal115287b2014-07-08 13:26:33 +053018069
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018070 mutex_unlock(&pHddCtx->tdls_lock);
18071
18072 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018073}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018074static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18076 const u8 *peer,
18077#else
18078 u8 *peer,
18079#endif
18080 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018081{
18082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018084 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018085 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018086
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018087 ENTER();
18088
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018089 if (!pAdapter) {
18090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18091 return -EINVAL;
18092 }
18093
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018094 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18095 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18096 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018097 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018098 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018100 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018101 return -EINVAL;
18102 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018104 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018105 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018106 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018107 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018108 }
18109
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018110
18111 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018112 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018113 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018115 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18116 "Cannot process TDLS commands",
18117 pHddCtx->cfg_ini->fEnableTDLSSupport,
18118 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018119 return -ENOTSUPP;
18120 }
18121
18122 switch (oper) {
18123 case NL80211_TDLS_ENABLE_LINK:
18124 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018125 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018126 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018127 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18128 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018129 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018130 tANI_U16 numCurrTdlsPeers = 0;
18131 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018132 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018133 tSirMacAddr peerMac;
18134 int channel;
18135 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018136
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18138 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18139 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018140
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018141 mutex_lock(&pHddCtx->tdls_lock);
18142 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018143 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018144 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018145 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18147 " (oper %d) not exsting. ignored",
18148 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18149 return -EINVAL;
18150 }
18151
18152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18153 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18154 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18155 "NL80211_TDLS_ENABLE_LINK");
18156
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018157 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18158 {
18159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18160 MAC_ADDRESS_STR " failed",
18161 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018162 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018163 return -EINVAL;
18164 }
18165
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018166 /* before starting tdls connection, set tdls
18167 * off channel established status to default value */
18168 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018169
18170 mutex_unlock(&pHddCtx->tdls_lock);
18171
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018172 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018173 /* TDLS Off Channel, Disable tdls channel switch,
18174 when there are more than one tdls link */
18175 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018176 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018177 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018178 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018179 /* get connected peer and send disable tdls off chan */
18180 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018181 if ((connPeer) &&
18182 (connPeer->isOffChannelSupported == TRUE) &&
18183 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018184 {
18185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18186 "%s: More then one peer connected, Disable "
18187 "TDLS channel switch", __func__);
18188
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018189 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018190 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18191 channel = connPeer->peerParams.channel;
18192
18193 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018194
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018195 ret = sme_SendTdlsChanSwitchReq(
18196 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018197 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018198 peerMac,
18199 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018200 TDLS_OFF_CHANNEL_BW_OFFSET,
18201 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018202 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018203 hddLog(VOS_TRACE_LEVEL_ERROR,
18204 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018205 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018206 }
18207 else
18208 {
18209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18210 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018211 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018212 "isOffChannelConfigured %d",
18213 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018214 (connPeer ? (connPeer->isOffChannelSupported)
18215 : -1),
18216 (connPeer ? (connPeer->isOffChannelConfigured)
18217 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018218 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018219 }
18220 }
18221
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018222 mutex_lock(&pHddCtx->tdls_lock);
18223 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18224 if ( NULL == pTdlsPeer ) {
18225 mutex_unlock(&pHddCtx->tdls_lock);
18226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18227 "%s: " MAC_ADDRESS_STR
18228 " (oper %d) peer got freed in other context. ignored",
18229 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18230 return -EINVAL;
18231 }
18232 peer_status = pTdlsPeer->link_status;
18233 mutex_unlock(&pHddCtx->tdls_lock);
18234
18235 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018236 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018237 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018238
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018239 if (0 != wlan_hdd_tdls_get_link_establish_params(
18240 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018242 return -EINVAL;
18243 }
18244 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018245
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018246 ret = sme_SendTdlsLinkEstablishParams(
18247 WLAN_HDD_GET_HAL_CTX(pAdapter),
18248 pAdapter->sessionId, peer,
18249 &tdlsLinkEstablishParams);
18250 if (ret != VOS_STATUS_SUCCESS) {
18251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18252 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018253 /* Send TDLS peer UAPSD capabilities to the firmware and
18254 * register with the TL on after the response for this operation
18255 * is received .
18256 */
18257 ret = wait_for_completion_interruptible_timeout(
18258 &pAdapter->tdls_link_establish_req_comp,
18259 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018260
18261 mutex_lock(&pHddCtx->tdls_lock);
18262 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18263 if ( NULL == pTdlsPeer ) {
18264 mutex_unlock(&pHddCtx->tdls_lock);
18265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18266 "%s %d: " MAC_ADDRESS_STR
18267 " (oper %d) peer got freed in other context. ignored",
18268 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18269 (int)oper);
18270 return -EINVAL;
18271 }
18272 peer_status = pTdlsPeer->link_status;
18273 mutex_unlock(&pHddCtx->tdls_lock);
18274
18275 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018276 {
18277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018278 FL("Link Establish Request Failed Status %ld"),
18279 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018280 return -EINVAL;
18281 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018282 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018283
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018284 mutex_lock(&pHddCtx->tdls_lock);
18285 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18286 if ( NULL == pTdlsPeer ) {
18287 mutex_unlock(&pHddCtx->tdls_lock);
18288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18289 "%s: " MAC_ADDRESS_STR
18290 " (oper %d) peer got freed in other context. ignored",
18291 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18292 return -EINVAL;
18293 }
18294
Atul Mittal115287b2014-07-08 13:26:33 +053018295 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18296 eTDLS_LINK_CONNECTED,
18297 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018298 staDesc.ucSTAId = pTdlsPeer->staId;
18299 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018300
18301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18302 "%s: tdlsLinkEstablishParams of peer "
18303 MAC_ADDRESS_STR "uapsdQueues: %d"
18304 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18305 "isResponder: %d peerstaId: %d",
18306 __func__,
18307 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18308 tdlsLinkEstablishParams.uapsdQueues,
18309 tdlsLinkEstablishParams.qos,
18310 tdlsLinkEstablishParams.maxSp,
18311 tdlsLinkEstablishParams.isBufSta,
18312 tdlsLinkEstablishParams.isOffChannelSupported,
18313 tdlsLinkEstablishParams.isResponder,
18314 pTdlsPeer->staId);
18315
18316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18317 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18318 __func__,
18319 staDesc.ucSTAId,
18320 staDesc.ucQosEnabled);
18321
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018322 ret = WLANTL_UpdateTdlsSTAClient(
18323 pHddCtx->pvosContext,
18324 &staDesc);
18325 if (ret != VOS_STATUS_SUCCESS) {
18326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18327 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018328
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018329 /* Mark TDLS client Authenticated .*/
18330 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18331 pTdlsPeer->staId,
18332 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018333 if (VOS_STATUS_SUCCESS == status)
18334 {
Hoonki Lee14621352013-04-16 17:51:19 -070018335 if (pTdlsPeer->is_responder == 0)
18336 {
18337 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018338 tdlsConnInfo_t *tdlsInfo;
18339
18340 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18341
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018342 if (!vos_timer_is_initialized(
18343 &pTdlsPeer->initiatorWaitTimeoutTimer))
18344 {
18345 /* Initialize initiator wait callback */
18346 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018347 &pTdlsPeer->initiatorWaitTimeoutTimer,
18348 VOS_TIMER_TYPE_SW,
18349 wlan_hdd_tdls_initiator_wait_cb,
18350 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018351 }
Hoonki Lee14621352013-04-16 17:51:19 -070018352 wlan_hdd_tdls_timer_restart(pAdapter,
18353 &pTdlsPeer->initiatorWaitTimeoutTimer,
18354 WAIT_TIME_TDLS_INITIATOR);
18355 /* suspend initiator TX until it receives direct packet from the
18356 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018357 ret = WLANTL_SuspendDataTx(
18358 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18359 &staId, NULL);
18360 if (ret != VOS_STATUS_SUCCESS) {
18361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18362 }
Hoonki Lee14621352013-04-16 17:51:19 -070018363 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018364
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018365 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018366 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018367 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018368 suppChannelLen =
18369 tdlsLinkEstablishParams.supportedChannelsLen;
18370
18371 if ((suppChannelLen > 0) &&
18372 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18373 {
18374 tANI_U8 suppPeerChannel = 0;
18375 int i = 0;
18376 for (i = 0U; i < suppChannelLen; i++)
18377 {
18378 suppPeerChannel =
18379 tdlsLinkEstablishParams.supportedChannels[i];
18380
18381 pTdlsPeer->isOffChannelSupported = FALSE;
18382 if (suppPeerChannel ==
18383 pTdlsPeer->peerParams.channel)
18384 {
18385 pTdlsPeer->isOffChannelSupported = TRUE;
18386 break;
18387 }
18388 }
18389 }
18390 else
18391 {
18392 pTdlsPeer->isOffChannelSupported = FALSE;
18393 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018394 }
18395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18396 "%s: TDLS channel switch request for channel "
18397 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018398 "%d isOffChannelSupported %d", __func__,
18399 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018400 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018401 suppChannelLen,
18402 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018403
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018404 /* TDLS Off Channel, Enable tdls channel switch,
18405 when their is only one tdls link and it supports */
18406 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18407 if ((numCurrTdlsPeers == 1) &&
18408 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18409 (TRUE == pTdlsPeer->isOffChannelConfigured))
18410 {
18411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18412 "%s: Send TDLS channel switch request for channel %d",
18413 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018414
18415 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018416 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18417 channel = pTdlsPeer->peerParams.channel;
18418
18419 mutex_unlock(&pHddCtx->tdls_lock);
18420
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018421 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18422 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018423 peerMac,
18424 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018425 TDLS_OFF_CHANNEL_BW_OFFSET,
18426 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018427 if (ret != VOS_STATUS_SUCCESS) {
18428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18429 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018430 }
18431 else
18432 {
18433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18434 "%s: TDLS channel switch request not sent"
18435 " numCurrTdlsPeers %d "
18436 "isOffChannelSupported %d "
18437 "isOffChannelConfigured %d",
18438 __func__, numCurrTdlsPeers,
18439 pTdlsPeer->isOffChannelSupported,
18440 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018441 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018442 }
18443
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018444 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018445 else
18446 mutex_unlock(&pHddCtx->tdls_lock);
18447
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018448 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018449
18450 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018451 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18452 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018453 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018454 int ac;
18455 uint8 ucAc[4] = { WLANTL_AC_VO,
18456 WLANTL_AC_VI,
18457 WLANTL_AC_BK,
18458 WLANTL_AC_BE };
18459 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18460 for(ac=0; ac < 4; ac++)
18461 {
18462 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18463 pTdlsPeer->staId, ucAc[ac],
18464 tlTid[ac], tlTid[ac], 0, 0,
18465 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018466 if (status != VOS_STATUS_SUCCESS) {
18467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18468 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018469 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018470 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018471 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018472
Bhargav Shah66896792015-10-01 18:17:37 +053018473 /* stop TCP delack timer if TDLS is enable */
18474 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18475 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018476 hdd_wlan_tdls_enable_link_event(peer,
18477 pTdlsPeer->isOffChannelSupported,
18478 pTdlsPeer->isOffChannelConfigured,
18479 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018480 }
18481 break;
18482 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018483 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018484 tANI_U16 numCurrTdlsPeers = 0;
18485 hddTdlsPeer_t *connPeer = NULL;
18486
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18488 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18489 __func__, MAC_ADDR_ARRAY(peer));
18490
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018491 mutex_lock(&pHddCtx->tdls_lock);
18492 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018493
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018494
Sunil Dutt41de4e22013-11-14 18:09:02 +053018495 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018496 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18498 " (oper %d) not exsting. ignored",
18499 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18500 return -EINVAL;
18501 }
18502
18503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18504 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18505 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18506 "NL80211_TDLS_DISABLE_LINK");
18507
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018508 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018509 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018510 long status;
18511
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018512 /* set tdls off channel status to false for this peer */
18513 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018514 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18515 eTDLS_LINK_TEARING,
18516 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18517 eTDLS_LINK_UNSPECIFIED:
18518 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018519 mutex_unlock(&pHddCtx->tdls_lock);
18520
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018521 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18522
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018523 status = sme_DeleteTdlsPeerSta(
18524 WLAN_HDD_GET_HAL_CTX(pAdapter),
18525 pAdapter->sessionId, peer );
18526 if (status != VOS_STATUS_SUCCESS) {
18527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18528 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018529
18530 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18531 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018532
18533 mutex_lock(&pHddCtx->tdls_lock);
18534 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18535 if ( NULL == pTdlsPeer ) {
18536 mutex_unlock(&pHddCtx->tdls_lock);
18537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18538 " peer was freed in other context",
18539 __func__, MAC_ADDR_ARRAY(peer));
18540 return -EINVAL;
18541 }
18542
Atul Mittal271a7652014-09-12 13:18:22 +053018543 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018544 eTDLS_LINK_IDLE,
18545 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018546 mutex_unlock(&pHddCtx->tdls_lock);
18547
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018548 if (status <= 0)
18549 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18551 "%s: Del station failed status %ld",
18552 __func__, status);
18553 return -EPERM;
18554 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018555
18556 /* TDLS Off Channel, Enable tdls channel switch,
18557 when their is only one tdls link and it supports */
18558 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18559 if (numCurrTdlsPeers == 1)
18560 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018561 tSirMacAddr peerMac;
18562 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018563
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018564 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018565 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018566
18567 if (connPeer == NULL) {
18568 mutex_unlock(&pHddCtx->tdls_lock);
18569 hddLog(VOS_TRACE_LEVEL_ERROR,
18570 "%s connPeer is NULL", __func__);
18571 return -EINVAL;
18572 }
18573
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018574 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18575 channel = connPeer->peerParams.channel;
18576
18577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18578 "%s: TDLS channel switch "
18579 "isOffChannelSupported %d "
18580 "isOffChannelConfigured %d "
18581 "isOffChannelEstablished %d",
18582 __func__,
18583 (connPeer ? connPeer->isOffChannelSupported : -1),
18584 (connPeer ? connPeer->isOffChannelConfigured : -1),
18585 (connPeer ? connPeer->isOffChannelEstablished : -1));
18586
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018587 if ((connPeer) &&
18588 (connPeer->isOffChannelSupported == TRUE) &&
18589 (connPeer->isOffChannelConfigured == TRUE))
18590 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018591 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018592 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018593 status = sme_SendTdlsChanSwitchReq(
18594 WLAN_HDD_GET_HAL_CTX(pAdapter),
18595 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018596 peerMac,
18597 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018598 TDLS_OFF_CHANNEL_BW_OFFSET,
18599 TDLS_CHANNEL_SWITCH_ENABLE);
18600 if (status != VOS_STATUS_SUCCESS) {
18601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18602 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018603 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018604 else
18605 mutex_unlock(&pHddCtx->tdls_lock);
18606 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018607 else
18608 {
18609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18610 "%s: TDLS channel switch request not sent "
18611 "numCurrTdlsPeers %d ",
18612 __func__, numCurrTdlsPeers);
18613 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018614 }
18615 else
18616 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018617 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18619 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018620 }
Bhargav Shah66896792015-10-01 18:17:37 +053018621 if (numCurrTdlsPeers == 0) {
18622 /* start TCP delack timer if TDLS is disable */
18623 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18624 hdd_manage_delack_timer(pHddCtx);
18625 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018626 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018627 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018628 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018629 {
Atul Mittal115287b2014-07-08 13:26:33 +053018630 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018631
Atul Mittal115287b2014-07-08 13:26:33 +053018632 if (0 != status)
18633 {
18634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018635 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018636 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018637 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018638 break;
18639 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018640 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018641 {
Atul Mittal115287b2014-07-08 13:26:33 +053018642 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18643 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018644 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018645 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018646
Atul Mittal115287b2014-07-08 13:26:33 +053018647 if (0 != status)
18648 {
18649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018650 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018651 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018652 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018653 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018654 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018655 case NL80211_TDLS_DISCOVERY_REQ:
18656 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018658 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018659 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018660 return -ENOTSUPP;
18661 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18663 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018664 return -ENOTSUPP;
18665 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018666
18667 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018668 return 0;
18669}
Chilam NG571c65a2013-01-19 12:27:36 +053018670
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018671static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18673 const u8 *peer,
18674#else
18675 u8 *peer,
18676#endif
18677 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018678{
18679 int ret;
18680
18681 vos_ssr_protect(__func__);
18682 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18683 vos_ssr_unprotect(__func__);
18684
18685 return ret;
18686}
18687
Chilam NG571c65a2013-01-19 12:27:36 +053018688int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18689 struct net_device *dev, u8 *peer)
18690{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018691 hddLog(VOS_TRACE_LEVEL_INFO,
18692 "tdls send discover req: "MAC_ADDRESS_STR,
18693 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018694#if TDLS_MGMT_VERSION2
18695 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18696 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18697#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18699 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18700 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18701#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18702 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18703 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18704#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18705 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18706 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18707#else
Chilam NG571c65a2013-01-19 12:27:36 +053018708 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18709 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018710#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018711#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018712}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018713#endif
18714
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018715#ifdef WLAN_FEATURE_GTK_OFFLOAD
18716/*
18717 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18718 * Callback rountine called upon receiving response for
18719 * get offload info
18720 */
18721void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18722 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18723{
18724
18725 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018726 tANI_U8 tempReplayCounter[8];
18727 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018728
18729 ENTER();
18730
18731 if (NULL == pAdapter)
18732 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018734 "%s: HDD adapter is Null", __func__);
18735 return ;
18736 }
18737
18738 if (NULL == pGtkOffloadGetInfoRsp)
18739 {
18740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18741 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18742 return ;
18743 }
18744
18745 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18746 {
18747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18748 "%s: wlan Failed to get replay counter value",
18749 __func__);
18750 return ;
18751 }
18752
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018753 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18754 /* Update replay counter */
18755 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18756 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18757
18758 {
18759 /* changing from little to big endian since supplicant
18760 * works on big endian format
18761 */
18762 int i;
18763 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18764
18765 for (i = 0; i < 8; i++)
18766 {
18767 tempReplayCounter[7-i] = (tANI_U8)p[i];
18768 }
18769 }
18770
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018771 /* Update replay counter to NL */
18772 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018773 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018774}
18775
18776/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018777 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018778 * This function is used to offload GTK rekeying job to the firmware.
18779 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018780int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018781 struct cfg80211_gtk_rekey_data *data)
18782{
18783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18784 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18785 hdd_station_ctx_t *pHddStaCtx;
18786 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018787 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018788 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018789 eHalStatus status = eHAL_STATUS_FAILURE;
18790
18791 ENTER();
18792
18793 if (NULL == pAdapter)
18794 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018796 "%s: HDD adapter is Null", __func__);
18797 return -ENODEV;
18798 }
18799
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018800 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18801 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18802 pAdapter->sessionId, pAdapter->device_mode));
18803
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018804 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018805 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018806 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018807 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018808 }
18809
18810 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18811 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18812 if (NULL == hHal)
18813 {
18814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18815 "%s: HAL context is Null!!!", __func__);
18816 return -EAGAIN;
18817 }
18818
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018819 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18820 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18821 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18822 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018823 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018824 {
18825 /* changing from big to little endian since driver
18826 * works on little endian format
18827 */
18828 tANI_U8 *p =
18829 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18830 int i;
18831
18832 for (i = 0; i < 8; i++)
18833 {
18834 p[7-i] = data->replay_ctr[i];
18835 }
18836 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018837
18838 if (TRUE == pHddCtx->hdd_wlan_suspended)
18839 {
18840 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018841 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18842 sizeof (tSirGtkOffloadParams));
18843 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018844 pAdapter->sessionId);
18845
18846 if (eHAL_STATUS_SUCCESS != status)
18847 {
18848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18849 "%s: sme_SetGTKOffload failed, returned %d",
18850 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018851
18852 /* Need to clear any trace of key value in the memory.
18853 * Thus zero out the memory even though it is local
18854 * variable.
18855 */
18856 vos_mem_zero(&hddGtkOffloadReqParams,
18857 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018858 return status;
18859 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18861 "%s: sme_SetGTKOffload successfull", __func__);
18862 }
18863 else
18864 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18866 "%s: wlan not suspended GTKOffload request is stored",
18867 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018868 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018869
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018870 /* Need to clear any trace of key value in the memory.
18871 * Thus zero out the memory even though it is local
18872 * variable.
18873 */
18874 vos_mem_zero(&hddGtkOffloadReqParams,
18875 sizeof(hddGtkOffloadReqParams));
18876
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018877 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018878 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018879}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018880
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018881int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18882 struct cfg80211_gtk_rekey_data *data)
18883{
18884 int ret;
18885
18886 vos_ssr_protect(__func__);
18887 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18888 vos_ssr_unprotect(__func__);
18889
18890 return ret;
18891}
18892#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018893/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018894 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018895 * This function is used to set access control policy
18896 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018897static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18898 struct net_device *dev,
18899 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018900{
18901 int i;
18902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18903 hdd_hostapd_state_t *pHostapdState;
18904 tsap_Config_t *pConfig;
18905 v_CONTEXT_t pVosContext = NULL;
18906 hdd_context_t *pHddCtx;
18907 int status;
18908
18909 ENTER();
18910
18911 if (NULL == pAdapter)
18912 {
18913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18914 "%s: HDD adapter is Null", __func__);
18915 return -ENODEV;
18916 }
18917
18918 if (NULL == params)
18919 {
18920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18921 "%s: params is Null", __func__);
18922 return -EINVAL;
18923 }
18924
18925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18926 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018927 if (0 != status)
18928 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018929 return status;
18930 }
18931
18932 pVosContext = pHddCtx->pvosContext;
18933 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18934
18935 if (NULL == pHostapdState)
18936 {
18937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18938 "%s: pHostapdState is Null", __func__);
18939 return -EINVAL;
18940 }
18941
18942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18943 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018944 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18945 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18946 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018947
18948 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18949 {
18950 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18951
18952 /* default value */
18953 pConfig->num_accept_mac = 0;
18954 pConfig->num_deny_mac = 0;
18955
18956 /**
18957 * access control policy
18958 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18959 * listed in hostapd.deny file.
18960 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18961 * listed in hostapd.accept file.
18962 */
18963 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18964 {
18965 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18966 }
18967 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18968 {
18969 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18970 }
18971 else
18972 {
18973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18974 "%s:Acl Policy : %d is not supported",
18975 __func__, params->acl_policy);
18976 return -ENOTSUPP;
18977 }
18978
18979 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18980 {
18981 pConfig->num_accept_mac = params->n_acl_entries;
18982 for (i = 0; i < params->n_acl_entries; i++)
18983 {
18984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18985 "** Add ACL MAC entry %i in WhiletList :"
18986 MAC_ADDRESS_STR, i,
18987 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18988
18989 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18990 sizeof(qcmacaddr));
18991 }
18992 }
18993 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18994 {
18995 pConfig->num_deny_mac = params->n_acl_entries;
18996 for (i = 0; i < params->n_acl_entries; i++)
18997 {
18998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18999 "** Add ACL MAC entry %i in BlackList :"
19000 MAC_ADDRESS_STR, i,
19001 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19002
19003 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19004 sizeof(qcmacaddr));
19005 }
19006 }
19007
19008 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19009 {
19010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19011 "%s: SAP Set Mac Acl fail", __func__);
19012 return -EINVAL;
19013 }
19014 }
19015 else
19016 {
19017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019018 "%s: Invalid device_mode = %s (%d)",
19019 __func__, hdd_device_modetoString(pAdapter->device_mode),
19020 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019021 return -EINVAL;
19022 }
19023
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019024 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019025 return 0;
19026}
19027
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019028static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19029 struct net_device *dev,
19030 const struct cfg80211_acl_data *params)
19031{
19032 int ret;
19033 vos_ssr_protect(__func__);
19034 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19035 vos_ssr_unprotect(__func__);
19036
19037 return ret;
19038}
19039
Leo Chang9056f462013-08-01 19:21:11 -070019040#ifdef WLAN_NL80211_TESTMODE
19041#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019042void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019043(
19044 void *pAdapter,
19045 void *indCont
19046)
19047{
Leo Changd9df8aa2013-09-26 13:32:26 -070019048 tSirLPHBInd *lphbInd;
19049 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019050 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019051
19052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019053 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019054
c_hpothu73f35e62014-04-18 13:40:08 +053019055 if (pAdapter == NULL)
19056 {
19057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19058 "%s: pAdapter is NULL\n",__func__);
19059 return;
19060 }
19061
Leo Chang9056f462013-08-01 19:21:11 -070019062 if (NULL == indCont)
19063 {
19064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019065 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019066 return;
19067 }
19068
c_hpothu73f35e62014-04-18 13:40:08 +053019069 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019070 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019071 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019072 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019073 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019074 GFP_ATOMIC);
19075 if (!skb)
19076 {
19077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19078 "LPHB timeout, NL buffer alloc fail");
19079 return;
19080 }
19081
Leo Changac3ba772013-10-07 09:47:04 -070019082 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019083 {
19084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19085 "WLAN_HDD_TM_ATTR_CMD put fail");
19086 goto nla_put_failure;
19087 }
Leo Changac3ba772013-10-07 09:47:04 -070019088 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019089 {
19090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19091 "WLAN_HDD_TM_ATTR_TYPE put fail");
19092 goto nla_put_failure;
19093 }
Leo Changac3ba772013-10-07 09:47:04 -070019094 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019095 sizeof(tSirLPHBInd), lphbInd))
19096 {
19097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19098 "WLAN_HDD_TM_ATTR_DATA put fail");
19099 goto nla_put_failure;
19100 }
Leo Chang9056f462013-08-01 19:21:11 -070019101 cfg80211_testmode_event(skb, GFP_ATOMIC);
19102 return;
19103
19104nla_put_failure:
19105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19106 "NLA Put fail");
19107 kfree_skb(skb);
19108
19109 return;
19110}
19111#endif /* FEATURE_WLAN_LPHB */
19112
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019113static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019114{
19115 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19116 int err = 0;
19117#ifdef FEATURE_WLAN_LPHB
19118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019119 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019120
19121 ENTER();
19122
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019123 err = wlan_hdd_validate_context(pHddCtx);
19124 if (0 != err)
19125 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019126 return err;
19127 }
Leo Chang9056f462013-08-01 19:21:11 -070019128#endif /* FEATURE_WLAN_LPHB */
19129
19130 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19131 if (err)
19132 {
19133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19134 "%s Testmode INV ATTR", __func__);
19135 return err;
19136 }
19137
19138 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19139 {
19140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19141 "%s Testmode INV CMD", __func__);
19142 return -EINVAL;
19143 }
19144
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19146 TRACE_CODE_HDD_CFG80211_TESTMODE,
19147 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019148 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19149 {
19150#ifdef FEATURE_WLAN_LPHB
19151 /* Low Power Heartbeat configuration request */
19152 case WLAN_HDD_TM_CMD_WLAN_HB:
19153 {
19154 int buf_len;
19155 void *buf;
19156 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019157 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019158
19159 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19160 {
19161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19162 "%s Testmode INV DATA", __func__);
19163 return -EINVAL;
19164 }
19165
19166 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19167 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019168
19169 hb_params_temp =(tSirLPHBReq *)buf;
19170 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19171 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19172 return -EINVAL;
19173
Leo Chang9056f462013-08-01 19:21:11 -070019174 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19175 if (NULL == hb_params)
19176 {
19177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19178 "%s Request Buffer Alloc Fail", __func__);
19179 return -EINVAL;
19180 }
19181
19182 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019183 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19184 hb_params,
19185 wlan_hdd_cfg80211_lphb_ind_handler);
19186 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019187 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19189 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019190 vos_mem_free(hb_params);
19191 }
Leo Chang9056f462013-08-01 19:21:11 -070019192 return 0;
19193 }
19194#endif /* FEATURE_WLAN_LPHB */
19195 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19197 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019198 return -EOPNOTSUPP;
19199 }
19200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019201 EXIT();
19202 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019203}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019204
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019205static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19207 struct wireless_dev *wdev,
19208#endif
19209 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019210{
19211 int ret;
19212
19213 vos_ssr_protect(__func__);
19214 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19215 vos_ssr_unprotect(__func__);
19216
19217 return ret;
19218}
Leo Chang9056f462013-08-01 19:21:11 -070019219#endif /* CONFIG_NL80211_TESTMODE */
19220
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019221static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019222 struct net_device *dev,
19223 int idx, struct survey_info *survey)
19224{
19225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19226 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019227 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019228 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019229 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019230 v_S7_t snr,rssi;
19231 int status, i, j, filled = 0;
19232
19233 ENTER();
19234
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019235 if (NULL == pAdapter)
19236 {
19237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19238 "%s: HDD adapter is Null", __func__);
19239 return -ENODEV;
19240 }
19241
19242 if (NULL == wiphy)
19243 {
19244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19245 "%s: wiphy is Null", __func__);
19246 return -ENODEV;
19247 }
19248
19249 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19250 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019251 if (0 != status)
19252 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019253 return status;
19254 }
19255
Mihir Sheted9072e02013-08-21 17:02:29 +053019256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19257
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019258 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019259 0 != pAdapter->survey_idx ||
19260 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019261 {
19262 /* The survey dump ops when implemented completely is expected to
19263 * return a survey of all channels and the ops is called by the
19264 * kernel with incremental values of the argument 'idx' till it
19265 * returns -ENONET. But we can only support the survey for the
19266 * operating channel for now. survey_idx is used to track
19267 * that the ops is called only once and then return -ENONET for
19268 * the next iteration
19269 */
19270 pAdapter->survey_idx = 0;
19271 return -ENONET;
19272 }
19273
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019274 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19275 {
19276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19277 "%s: Roaming in progress, hence return ", __func__);
19278 return -ENONET;
19279 }
19280
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019281 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19282
19283 wlan_hdd_get_snr(pAdapter, &snr);
19284 wlan_hdd_get_rssi(pAdapter, &rssi);
19285
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019286 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19287 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19288 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019289 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19290 hdd_wlan_get_freq(channel, &freq);
19291
19292
19293 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19294 {
19295 if (NULL == wiphy->bands[i])
19296 {
19297 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19298 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19299 continue;
19300 }
19301
19302 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19303 {
19304 struct ieee80211_supported_band *band = wiphy->bands[i];
19305
19306 if (band->channels[j].center_freq == (v_U16_t)freq)
19307 {
19308 survey->channel = &band->channels[j];
19309 /* The Rx BDs contain SNR values in dB for the received frames
19310 * while the supplicant expects noise. So we calculate and
19311 * return the value of noise (dBm)
19312 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19313 */
19314 survey->noise = rssi - snr;
19315 survey->filled = SURVEY_INFO_NOISE_DBM;
19316 filled = 1;
19317 }
19318 }
19319 }
19320
19321 if (filled)
19322 pAdapter->survey_idx = 1;
19323 else
19324 {
19325 pAdapter->survey_idx = 0;
19326 return -ENONET;
19327 }
19328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019329 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019330 return 0;
19331}
19332
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019333static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19334 struct net_device *dev,
19335 int idx, struct survey_info *survey)
19336{
19337 int ret;
19338
19339 vos_ssr_protect(__func__);
19340 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19341 vos_ssr_unprotect(__func__);
19342
19343 return ret;
19344}
19345
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019346/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019347 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019348 * this is called when cfg80211 driver resume
19349 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19350 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019351int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019352{
19353 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19354 hdd_adapter_t *pAdapter;
19355 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19356 VOS_STATUS status = VOS_STATUS_SUCCESS;
19357
19358 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019359
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019360 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019361 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019362 return 0;
19363 }
19364
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019365 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19366 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019367 spin_lock(&pHddCtx->schedScan_lock);
19368 pHddCtx->isWiphySuspended = FALSE;
19369 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19370 {
19371 spin_unlock(&pHddCtx->schedScan_lock);
19372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19373 "%s: Return resume is not due to PNO indication", __func__);
19374 return 0;
19375 }
19376 // Reset flag to avoid updatating cfg80211 data old results again
19377 pHddCtx->isSchedScanUpdatePending = FALSE;
19378 spin_unlock(&pHddCtx->schedScan_lock);
19379
19380 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19381
19382 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19383 {
19384 pAdapter = pAdapterNode->pAdapter;
19385 if ( (NULL != pAdapter) &&
19386 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19387 {
19388 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019389 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19391 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019392 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019393 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019394 {
19395 /* Acquire wakelock to handle the case where APP's tries to
19396 * suspend immediately after updating the scan results. Whis
19397 * results in app's is in suspended state and not able to
19398 * process the connect request to AP
19399 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019400 hdd_prevent_suspend_timeout(2000,
19401 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019402 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019403 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019404
19405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19406 "%s : cfg80211 scan result database updated", __func__);
19407
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019408 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019409 return 0;
19410
19411 }
19412 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19413 pAdapterNode = pNext;
19414 }
19415
19416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19417 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019418 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019419 return 0;
19420}
19421
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019422int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19423{
19424 int ret;
19425
19426 vos_ssr_protect(__func__);
19427 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19428 vos_ssr_unprotect(__func__);
19429
19430 return ret;
19431}
19432
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019433/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019434 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019435 * this is called when cfg80211 driver suspends
19436 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019437int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019438 struct cfg80211_wowlan *wow)
19439{
19440 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019441 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019442
19443 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019444
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019445 ret = wlan_hdd_validate_context(pHddCtx);
19446 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019447 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019448 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019449 }
19450
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019451
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019452 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19453 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19454 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019455 pHddCtx->isWiphySuspended = TRUE;
19456
19457 EXIT();
19458
19459 return 0;
19460}
19461
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019462int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19463 struct cfg80211_wowlan *wow)
19464{
19465 int ret;
19466
19467 vos_ssr_protect(__func__);
19468 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19469 vos_ssr_unprotect(__func__);
19470
19471 return ret;
19472}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019473
19474#ifdef FEATURE_OEM_DATA_SUPPORT
19475static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019476 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019477{
19478 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19479
19480 ENTER();
19481
19482 if (wlan_hdd_validate_context(pHddCtx)) {
19483 return;
19484 }
19485 if (!pMsg)
19486 {
19487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19488 return;
19489 }
19490
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019491 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019492
19493 EXIT();
19494 return;
19495
19496}
19497
19498void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019499 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019500{
19501 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19502
19503 ENTER();
19504
19505 if (wlan_hdd_validate_context(pHddCtx)) {
19506 return;
19507 }
19508
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019510
19511 switch(evType) {
19512 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019513 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019514 break;
19515 default:
19516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19517 break;
19518 }
19519 EXIT();
19520}
19521#endif
19522
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19524 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019525/**
19526 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19527 * @wiphy: Pointer to wiphy
19528 * @wdev: Pointer to wireless device structure
19529 *
19530 * This function is used to abort an ongoing scan
19531 *
19532 * Return: None
19533 */
19534static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19535 struct wireless_dev *wdev)
19536{
19537 struct net_device *dev = wdev->netdev;
19538 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19539 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19540 int ret;
19541
19542 ENTER();
19543
19544 if (NULL == adapter) {
19545 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19546 return;
19547 }
19548
19549 ret = wlan_hdd_validate_context(hdd_ctx);
19550 if (0 != ret)
19551 return;
19552
19553 wlan_hdd_scan_abort(adapter);
19554
19555 return;
19556}
19557
19558/**
19559 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19560 * @wiphy: Pointer to wiphy
19561 * @wdev: Pointer to wireless device structure
19562 *
19563 * Return: None
19564 */
19565void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19566 struct wireless_dev *wdev)
19567{
19568 vos_ssr_protect(__func__);
19569 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19570 vos_ssr_unprotect(__func__);
19571
19572 return;
19573}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019574#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019575
Jeff Johnson295189b2012-06-20 16:38:30 -070019576/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019577static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019578{
19579 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19580 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19581 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19582 .change_station = wlan_hdd_change_station,
19583#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19584 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19585 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19586 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019587#else
19588 .start_ap = wlan_hdd_cfg80211_start_ap,
19589 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19590 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019591#endif
19592 .change_bss = wlan_hdd_cfg80211_change_bss,
19593 .add_key = wlan_hdd_cfg80211_add_key,
19594 .get_key = wlan_hdd_cfg80211_get_key,
19595 .del_key = wlan_hdd_cfg80211_del_key,
19596 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019597#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019598 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019599#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019600 .scan = wlan_hdd_cfg80211_scan,
19601 .connect = wlan_hdd_cfg80211_connect,
19602 .disconnect = wlan_hdd_cfg80211_disconnect,
19603 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19604 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19605 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19606 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19607 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019608 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19609 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019610 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19612 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19613 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19614 .set_txq_params = wlan_hdd_set_txq_params,
19615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019616 .get_station = wlan_hdd_cfg80211_get_station,
19617 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19618 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019619 .add_station = wlan_hdd_cfg80211_add_station,
19620#ifdef FEATURE_WLAN_LFR
19621 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19622 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19623 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19624#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019625#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19626 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19627#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019628#ifdef FEATURE_WLAN_TDLS
19629 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19630 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19631#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019632#ifdef WLAN_FEATURE_GTK_OFFLOAD
19633 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19634#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019635#ifdef FEATURE_WLAN_SCAN_PNO
19636 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19637 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19638#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019639 .resume = wlan_hdd_cfg80211_resume_wlan,
19640 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019641 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019642#ifdef WLAN_NL80211_TESTMODE
19643 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19644#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019645 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19647 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019648 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019649#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019650};
19651