blob: 3834989459766f71d3bfb0f2172ab3ee7e17203f [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"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301443 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301444 " radio is %d onTime is %u "
1445 " txTime is %u rxTime is %u "
1446 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301447 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " onTimePnoScan is %u onTimeHs20 is %u "
1449 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301450 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1452 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1453 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301454 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->onTimeRoamScan,
1456 pWifiRadioStat->onTimePnoScan,
1457 pWifiRadioStat->onTimeHs20,
1458 pWifiRadioStat->numChannels);
1459 /*
1460 * Allocate a size of 4096 for the Radio stats comprising
1461 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1462 * (tSirWifiChannelStats).Each channel data is put with an
1463 * NL attribute.The size of 4096 is considered assuming that
1464 * number of channels shall not exceed beyond 60 with the
1465 * sizeof (tSirWifiChannelStats) being 24 bytes.
1466 */
1467
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301468 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1469 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301470 if (!vendor_event)
1471 {
1472 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301473 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 return;
1475 }
1476
1477 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1480 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1482 pWifiRadioStat->radio) ||
1483 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301484 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1485 NUM_RADIOS) ||
1486 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1488 pWifiRadioStat->onTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1491 pWifiRadioStat->txTime) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1494 pWifiRadioStat->rxTime) ||
1495 nla_put_u32(vendor_event,
1496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1497 pWifiRadioStat->onTimeScan) ||
1498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1500 pWifiRadioStat->onTimeNbd) ||
1501 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1503 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1506 pWifiRadioStat->onTimeRoamScan) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1509 pWifiRadioStat->onTimePnoScan) ||
1510 nla_put_u32(vendor_event,
1511 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1512 pWifiRadioStat->onTimeHs20) ||
1513 nla_put_u32(vendor_event,
1514 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1515 pWifiRadioStat->numChannels))
1516 {
1517 hddLog(VOS_TRACE_LEVEL_ERROR,
1518 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1519 kfree_skb(vendor_event);
1520 return ;
1521 }
1522
1523 chList = nla_nest_start(vendor_event,
1524 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301525 if(!chList)
1526 {
1527 hddLog(VOS_TRACE_LEVEL_ERROR,
1528 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1529 __func__);
1530 kfree_skb(vendor_event);
1531 return;
1532 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301533 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1534 {
1535 struct nlattr *chInfo;
1536
1537 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1538 pWifiRadioStat->channels +
1539 (i * sizeof(tSirWifiChannelStats)));
1540
Sunil Duttc69bccb2014-05-26 21:30:20 +05301541 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301542 if(!chInfo)
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 "%s: failed to put chInfo",
1546 __func__);
1547 kfree_skb(vendor_event);
1548 return;
1549 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550
1551 if (nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1553 pWifiChannelStats->channel.width) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1556 pWifiChannelStats->channel.centerFreq) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1559 pWifiChannelStats->channel.centerFreq0) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1562 pWifiChannelStats->channel.centerFreq1) ||
1563 nla_put_u32(vendor_event,
1564 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1565 pWifiChannelStats->onTime) ||
1566 nla_put_u32(vendor_event,
1567 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1568 pWifiChannelStats->ccaBusyTime))
1569 {
1570 hddLog(VOS_TRACE_LEVEL_ERROR,
1571 FL("cfg80211_vendor_event_alloc failed") );
1572 kfree_skb(vendor_event);
1573 return ;
1574 }
1575 nla_nest_end(vendor_event, chInfo);
1576 }
1577 nla_nest_end(vendor_event, chList);
1578
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301579 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301580
1581 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301582 return;
1583}
1584
1585/*
1586 * hdd_link_layer_stats_ind_callback () - This function is called after
1587 * receiving Link Layer indications from FW.This callback converts the firmware
1588 * data to the NL data and send the same to the kernel/upper layers.
1589 */
1590static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1591 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593{
Dino Mycled3d50022014-07-07 12:58:25 +05301594 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1595 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301596 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301597 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301598 int status;
1599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301600 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301601
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301602 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 if (0 != status)
1604 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605 return;
1606 }
1607
Dino Mycled3d50022014-07-07 12:58:25 +05301608 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1609 if (NULL == pAdapter)
1610 {
1611 hddLog(VOS_TRACE_LEVEL_ERROR,
1612 FL(" MAC address %pM does not exist with host"),
1613 macAddr);
1614 return;
1615 }
1616
Sunil Duttc69bccb2014-05-26 21:30:20 +05301617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301618 "%s: Interface: %s LLStats indType: %d", __func__,
1619 pAdapter->dev->name, indType);
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 switch (indType)
1622 {
1623 case SIR_HAL_LL_STATS_RESULTS_RSP:
1624 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301626 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1627 "respId = %u, moreResultToFollow = %u",
1628 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1629 macAddr, linkLayerStatsResults->respId,
1630 linkLayerStatsResults->moreResultToFollow);
1631
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301632 spin_lock(&hdd_context_lock);
1633 context = &pHddCtx->ll_stats_context;
1634 /* validate response received from target */
1635 if ((context->request_id != linkLayerStatsResults->respId) ||
1636 !(context->request_bitmap & linkLayerStatsResults->paramId))
1637 {
1638 spin_unlock(&hdd_context_lock);
1639 hddLog(LOGE,
1640 FL("Error : Request id %d response id %d request bitmap 0x%x"
1641 "response bitmap 0x%x"),
1642 context->request_id, linkLayerStatsResults->respId,
1643 context->request_bitmap, linkLayerStatsResults->paramId);
1644 return;
1645 }
1646 spin_unlock(&hdd_context_lock);
1647
Sunil Duttc69bccb2014-05-26 21:30:20 +05301648 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1649 {
1650 hdd_link_layer_process_radio_stats(pAdapter,
1651 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301652 spin_lock(&hdd_context_lock);
1653 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1654 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301655 }
1656 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1657 {
1658 hdd_link_layer_process_iface_stats(pAdapter,
1659 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301660 spin_lock(&hdd_context_lock);
1661 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1662 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301663 }
1664 else if ( linkLayerStatsResults->paramId &
1665 WMI_LINK_STATS_ALL_PEER )
1666 {
1667 hdd_link_layer_process_peer_stats(pAdapter,
1668 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301669 spin_lock(&hdd_context_lock);
1670 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1671 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301672 } /* WMI_LINK_STATS_ALL_PEER */
1673 else
1674 {
1675 hddLog(VOS_TRACE_LEVEL_ERROR,
1676 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1677 }
1678
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301679 spin_lock(&hdd_context_lock);
1680 /* complete response event if all requests are completed */
1681 if (0 == context->request_bitmap)
1682 complete(&context->response_event);
1683 spin_unlock(&hdd_context_lock);
1684
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 break;
1686 }
1687 default:
1688 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1689 break;
1690 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301691
1692 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 return;
1694}
1695
1696const struct
1697nla_policy
1698qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1699{
1700 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1701 { .type = NLA_U32 },
1702 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1703 { .type = NLA_U32 },
1704};
1705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301706static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1707 struct wireless_dev *wdev,
1708 const void *data,
1709 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710{
1711 int status;
1712 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301713 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 struct net_device *dev = wdev->netdev;
1715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1716 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1717
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301718 ENTER();
1719
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720 status = wlan_hdd_validate_context(pHddCtx);
1721 if (0 != status)
1722 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301723 return -EINVAL;
1724 }
1725
1726 if (NULL == pAdapter)
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR,
1729 FL("HDD adapter is Null"));
1730 return -ENODEV;
1731 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 /* check the LLStats Capability */
1733 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1734 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1735 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301736 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 FL("Link Layer Statistics not supported by Firmware"));
1738 return -EINVAL;
1739 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301740
1741 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1742 (struct nlattr *)data,
1743 data_len, qca_wlan_vendor_ll_set_policy))
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor
1749 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1752 return -EINVAL;
1753 }
1754 if (!tb_vendor[
1755 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1758 return -EINVAL;
1759 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301760 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762
Dino Mycledf0a5d92014-07-04 09:41:55 +05301763 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 nla_get_u32(
1765 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1770
Dino Mycled3d50022014-07-07 12:58:25 +05301771 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1772 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773
1774
1775 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301776 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1777 "Statistics Gathering = %d ",
1778 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1779 linkLayerStatsSetReq.mpduSizeThreshold,
1780 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301781
1782 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1783 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301784 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785 {
1786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1787 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 return -EINVAL;
1789
1790 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301791
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301793 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301794 {
1795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1796 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return -EINVAL;
1798 }
1799
1800 pAdapter->isLinkLayerStatsSet = 1;
1801
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301802 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301803 return 0;
1804}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301805static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1806 struct wireless_dev *wdev,
1807 const void *data,
1808 int data_len)
1809{
1810 int ret = 0;
1811
1812 vos_ssr_protect(__func__);
1813 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1814 vos_ssr_unprotect(__func__);
1815
1816 return ret;
1817}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818
1819const struct
1820nla_policy
1821qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1822{
1823 /* Unsigned 32bit value provided by the caller issuing the GET stats
1824 * command. When reporting
1825 * the stats results, the driver uses the same value to indicate
1826 * which GET request the results
1827 * correspond to.
1828 */
1829 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1830
1831 /* Unsigned 32bit value . bit mask to identify what statistics are
1832 requested for retrieval */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1834};
1835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301836static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1837 struct wireless_dev *wdev,
1838 const void *data,
1839 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301841 unsigned long rc;
1842 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1844 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301845 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 struct net_device *dev = wdev->netdev;
1847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301848 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849 int status;
1850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301851 ENTER();
1852
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 status = wlan_hdd_validate_context(pHddCtx);
1854 if (0 != status)
1855 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856 return -EINVAL ;
1857 }
1858
1859 if (NULL == pAdapter)
1860 {
1861 hddLog(VOS_TRACE_LEVEL_FATAL,
1862 "%s: HDD adapter is Null", __func__);
1863 return -ENODEV;
1864 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865
1866 if (pHddStaCtx == NULL)
1867 {
1868 hddLog(VOS_TRACE_LEVEL_FATAL,
1869 "%s: HddStaCtx is Null", __func__);
1870 return -ENODEV;
1871 }
1872
Dino Mycledf0a5d92014-07-04 09:41:55 +05301873 /* check the LLStats Capability */
1874 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1875 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1876 {
1877 hddLog(VOS_TRACE_LEVEL_ERROR,
1878 FL("Link Layer Statistics not supported by Firmware"));
1879 return -EINVAL;
1880 }
1881
Sunil Duttc69bccb2014-05-26 21:30:20 +05301882
1883 if (!pAdapter->isLinkLayerStatsSet)
1884 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301885 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886 "%s: isLinkLayerStatsSet : %d",
1887 __func__, pAdapter->isLinkLayerStatsSet);
1888 return -EINVAL;
1889 }
1890
Mukul Sharma10313ba2015-07-29 19:14:39 +05301891 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1892 {
1893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1894 "%s: Roaming in progress, so unable to proceed this request", __func__);
1895 return -EBUSY;
1896 }
1897
Sunil Duttc69bccb2014-05-26 21:30:20 +05301898 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1899 (struct nlattr *)data,
1900 data_len, qca_wlan_vendor_ll_get_policy))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1903 return -EINVAL;
1904 }
1905
1906 if (!tb_vendor
1907 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1908 {
1909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1910 return -EINVAL;
1911 }
1912
1913 if (!tb_vendor
1914 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1915 {
1916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1917 return -EINVAL;
1918 }
1919
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920
Dino Mycledf0a5d92014-07-04 09:41:55 +05301921 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 nla_get_u32( tb_vendor[
1923 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 nla_get_u32( tb_vendor[
1926 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1927
Dino Mycled3d50022014-07-07 12:58:25 +05301928 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1929 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930
1931 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301932 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1933 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301936 spin_lock(&hdd_context_lock);
1937 context = &pHddCtx->ll_stats_context;
1938 context->request_id = linkLayerStatsGetReq.reqId;
1939 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1940 INIT_COMPLETION(context->response_event);
1941 spin_unlock(&hdd_context_lock);
1942
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301944 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301945 {
1946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1947 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948 return -EINVAL;
1949 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301950
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301951 rc = wait_for_completion_timeout(&context->response_event,
1952 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1953 if (!rc)
1954 {
1955 hddLog(LOGE,
1956 FL("Target response timed out request id %d request bitmap 0x%x"),
1957 context->request_id, context->request_bitmap);
1958 return -ETIMEDOUT;
1959 }
1960
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301961 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301962 return 0;
1963}
1964
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301965static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1966 struct wireless_dev *wdev,
1967 const void *data,
1968 int data_len)
1969{
1970 int ret = 0;
1971
1972 vos_ssr_protect(__func__);
1973 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1974 vos_ssr_unprotect(__func__);
1975
1976 return ret;
1977}
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979const struct
1980nla_policy
1981qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1982{
1983 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1984 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1985 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1986 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1987};
1988
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301989static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1990 struct wireless_dev *wdev,
1991 const void *data,
1992 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301993{
1994 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1995 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301996 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 struct net_device *dev = wdev->netdev;
1998 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1999 u32 statsClearReqMask;
2000 u8 stopReq;
2001 int status;
2002
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302003 ENTER();
2004
Sunil Duttc69bccb2014-05-26 21:30:20 +05302005 status = wlan_hdd_validate_context(pHddCtx);
2006 if (0 != status)
2007 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302008 return -EINVAL;
2009 }
2010
2011 if (NULL == pAdapter)
2012 {
2013 hddLog(VOS_TRACE_LEVEL_FATAL,
2014 "%s: HDD adapter is Null", __func__);
2015 return -ENODEV;
2016 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302017 /* check the LLStats Capability */
2018 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2019 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2020 {
2021 hddLog(VOS_TRACE_LEVEL_ERROR,
2022 FL("Enable LLStats Capability"));
2023 return -EINVAL;
2024 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
2026 if (!pAdapter->isLinkLayerStatsSet)
2027 {
2028 hddLog(VOS_TRACE_LEVEL_FATAL,
2029 "%s: isLinkLayerStatsSet : %d",
2030 __func__, pAdapter->isLinkLayerStatsSet);
2031 return -EINVAL;
2032 }
2033
2034 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2035 (struct nlattr *)data,
2036 data_len, qca_wlan_vendor_ll_clr_policy))
2037 {
2038 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2039 return -EINVAL;
2040 }
2041
2042 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2043
2044 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2045 {
2046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2047 return -EINVAL;
2048
2049 }
2050
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051
Dino Mycledf0a5d92014-07-04 09:41:55 +05302052 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302053 nla_get_u32(
2054 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u8(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2059
2060 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302061 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302062
Dino Mycled3d50022014-07-07 12:58:25 +05302063 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2064 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302065
2066 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302067 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2068 "statsClearReqMask = 0x%X, stopReq = %d",
2069 linkLayerStatsClearReq.reqId,
2070 linkLayerStatsClearReq.macAddr,
2071 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302072 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302073
2074 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302075 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302076 {
2077 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302078 hdd_station_ctx_t *pHddStaCtx;
2079
2080 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2081 if (VOS_STATUS_SUCCESS !=
2082 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2083 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2086 "WLANTL_ClearInterfaceStats Failed", __func__);
2087 return -EINVAL;
2088 }
2089 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2090 (statsClearReqMask & WIFI_STATS_IFACE)) {
2091 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2092 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2093 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2094 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2095 }
2096
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2098 2 * sizeof(u32) +
2099 NLMSG_HDRLEN);
2100
2101 if (temp_skbuff != NULL)
2102 {
2103
2104 if (nla_put_u32(temp_skbuff,
2105 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2106 statsClearReqMask) ||
2107 nla_put_u32(temp_skbuff,
2108 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2109 stopReq))
2110 {
2111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2112 kfree_skb(temp_skbuff);
2113 return -EINVAL;
2114 }
2115 /* If the ask is to stop the stats collection as part of clear
2116 * (stopReq = 1) , ensure that no further requests of get
2117 * go to the firmware by having isLinkLayerStatsSet set to 0.
2118 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302119 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302120 * case the firmware is just asked to clear the statistics.
2121 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302122 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 pAdapter->isLinkLayerStatsSet = 0;
2124 return cfg80211_vendor_cmd_reply(temp_skbuff);
2125 }
2126 return -ENOMEM;
2127 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302128
2129 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130 return -EINVAL;
2131}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302132static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2133 struct wireless_dev *wdev,
2134 const void *data,
2135 int data_len)
2136{
2137 int ret = 0;
2138
2139 vos_ssr_protect(__func__);
2140 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2141 vos_ssr_unprotect(__func__);
2142
2143 return ret;
2144
2145
2146}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2148
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149#ifdef WLAN_FEATURE_EXTSCAN
2150static const struct nla_policy
2151wlan_hdd_extscan_config_policy
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2153{
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2155 { .type = NLA_U32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2157 { .type = NLA_U32 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2160 { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2168 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2174 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2178 { .type = NLA_U32 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2180 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2182 { .type = NLA_U8 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302184 { .type = NLA_U8 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2188 { .type = NLA_U8 },
2189
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2191 { .type = NLA_U32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2193 { .type = NLA_UNSPEC },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2195 { .type = NLA_S32 },
2196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2197 { .type = NLA_S32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2199 { .type = NLA_U32 },
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2201 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2203 { .type = NLA_U32 },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2205 { .type = NLA_BINARY,
2206 .len = IEEE80211_MAX_SSID_LEN + 1 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302208 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2210 { .type = NLA_U32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2212 { .type = NLA_U8 },
2213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2214 { .type = NLA_S32 },
2215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2216 { .type = NLA_S32 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2218 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302219};
2220
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302221/**
2222 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2223 * @ctx: hdd global context
2224 * @data: capabilities data
2225 *
2226 * Return: none
2227 */
2228static void
2229wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302230{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302231 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302232 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302233 tSirEXTScanCapabilitiesEvent *data =
2234 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302236 ENTER();
2237
2238 if (wlan_hdd_validate_context(pHddCtx))
2239 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240 return;
2241 }
2242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302243 if (!pMsg)
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2246 return;
2247 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302248
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302249 vos_spin_lock_acquire(&hdd_context_lock);
2250
2251 context = &pHddCtx->ext_scan_context;
2252 /* validate response received from target*/
2253 if (context->request_id != data->requestId)
2254 {
2255 vos_spin_lock_release(&hdd_context_lock);
2256 hddLog(LOGE,
2257 FL("Target response id did not match: request_id %d resposne_id %d"),
2258 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 return;
2260 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 else
2262 {
2263 context->capability_response = *data;
2264 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302265 }
2266
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302267 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302268
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 return;
2270}
2271
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272/*
2273 * define short names for the global vendor params
2274 * used by wlan_hdd_send_ext_scan_capability()
2275 */
2276#define PARAM_REQUEST_ID \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2278#define PARAM_STATUS \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2280#define MAX_SCAN_CACHE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2282#define MAX_SCAN_BUCKETS \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2284#define MAX_AP_CACHE_PER_SCAN \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2286#define MAX_RSSI_SAMPLE_SIZE \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2288#define MAX_SCAN_RPT_THRHOLD \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2290#define MAX_HOTLIST_BSSIDS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2292#define MAX_BSSID_HISTORY_ENTRIES \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2294#define MAX_HOTLIST_SSIDS \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302296#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302298
2299static int wlan_hdd_send_ext_scan_capability(void *ctx)
2300{
2301 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2302 struct sk_buff *skb = NULL;
2303 int ret;
2304 tSirEXTScanCapabilitiesEvent *data;
2305 tANI_U32 nl_buf_len;
2306
2307 ret = wlan_hdd_validate_context(pHddCtx);
2308 if (0 != ret)
2309 {
2310 return ret;
2311 }
2312
2313 data = &(pHddCtx->ext_scan_context.capability_response);
2314
2315 nl_buf_len = NLMSG_HDRLEN;
2316 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2317 (sizeof(data->status) + NLA_HDRLEN) +
2318 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2319 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2320 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2321 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2322 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2323 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2324 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2325 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2326
2327 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2328
2329 if (!skb)
2330 {
2331 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2332 return -ENOMEM;
2333 }
2334
2335 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2336 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2337 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2338 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2339 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2340 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2341 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2342 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2343
2344 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2345 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2346 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2347 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2348 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2349 data->maxApPerScan) ||
2350 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2351 data->maxRssiSampleSize) ||
2352 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2353 data->maxScanReportingThreshold) ||
2354 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2355 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2356 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302357 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2358 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302359 {
2360 hddLog(LOGE, FL("nla put fail"));
2361 goto nla_put_failure;
2362 }
2363
2364 cfg80211_vendor_cmd_reply(skb);
2365 return 0;
2366
2367nla_put_failure:
2368 kfree_skb(skb);
2369 return -EINVAL;;
2370}
2371
2372/*
2373 * done with short names for the global vendor params
2374 * used by wlan_hdd_send_ext_scan_capability()
2375 */
2376#undef PARAM_REQUEST_ID
2377#undef PARAM_STATUS
2378#undef MAX_SCAN_CACHE_SIZE
2379#undef MAX_SCAN_BUCKETS
2380#undef MAX_AP_CACHE_PER_SCAN
2381#undef MAX_RSSI_SAMPLE_SIZE
2382#undef MAX_SCAN_RPT_THRHOLD
2383#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302384#undef MAX_BSSID_HISTORY_ENTRIES
2385#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386
2387static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2388{
2389 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2390 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302391 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302394 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302396 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302397 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302399 if (!pMsg)
2400 {
2401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302402 return;
2403 }
2404
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2406 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2407
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 context = &pHddCtx->ext_scan_context;
2409 spin_lock(&hdd_context_lock);
2410 if (context->request_id == pData->requestId) {
2411 context->response_status = pData->status ? -EINVAL : 0;
2412 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302414 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302415
2416 /*
2417 * Store the Request ID for comparing with the requestID obtained
2418 * in other requests.HDD shall return a failure is the extscan_stop
2419 * request is issued with a different requestId as that of the
2420 * extscan_start request. Also, This requestId shall be used while
2421 * indicating the full scan results to the upper layers.
2422 * The requestId is stored with the assumption that the firmware
2423 * shall return the ext scan start request's requestId in ext scan
2424 * start response.
2425 */
2426 if (pData->status == 0)
2427 pMac->sme.extScanStartReqId = pData->requestId;
2428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302429 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302430 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302431}
2432
2433
2434static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2435{
2436 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2437 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302438 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 ENTER();
2441
2442 if (wlan_hdd_validate_context(pHddCtx)){
2443 return;
2444 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302445
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302446 if (!pMsg)
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449 return;
2450 }
2451
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302452 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2453 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 context = &pHddCtx->ext_scan_context;
2456 spin_lock(&hdd_context_lock);
2457 if (context->request_id == pData->requestId) {
2458 context->response_status = pData->status ? -EINVAL : 0;
2459 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302460 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302461 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302463 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465}
2466
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2468 void *pMsg)
2469{
2470 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471 tpSirEXTScanSetBssidHotListRspParams pData =
2472 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302473 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 ENTER();
2476
2477 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478 return;
2479 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302481 if (!pMsg)
2482 {
2483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2484 return;
2485 }
2486
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302487 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2488 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 context = &pHddCtx->ext_scan_context;
2491 spin_lock(&hdd_context_lock);
2492 if (context->request_id == pData->requestId) {
2493 context->response_status = pData->status ? -EINVAL : 0;
2494 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302495 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302496 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302498 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500}
2501
2502static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2503 void *pMsg)
2504{
2505 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302506 tpSirEXTScanResetBssidHotlistRspParams pData =
2507 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302508 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302510 ENTER();
2511
2512 if (wlan_hdd_validate_context(pHddCtx)) {
2513 return;
2514 }
2515 if (!pMsg)
2516 {
2517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518 return;
2519 }
2520
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302521 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2522 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 context = &pHddCtx->ext_scan_context;
2525 spin_lock(&hdd_context_lock);
2526 if (context->request_id == pData->requestId) {
2527 context->response_status = pData->status ? -EINVAL : 0;
2528 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302529 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302530 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302532 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302534}
2535
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302536static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2537 void *pMsg)
2538{
2539 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2540 tpSirEXTScanSetSsidHotListRspParams pData =
2541 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2542 struct hdd_ext_scan_context *context;
2543
2544 if (wlan_hdd_validate_context(pHddCtx)){
2545 return;
2546 }
2547
2548 if (!pMsg)
2549 {
2550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2551 return;
2552 }
2553
2554 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2555 pData->status);
2556
2557 context = &pHddCtx->ext_scan_context;
2558 spin_lock(&hdd_context_lock);
2559 if (context->request_id == pData->requestId) {
2560 context->response_status = pData->status ? -EINVAL : 0;
2561 complete(&context->response_event);
2562 }
2563 spin_unlock(&hdd_context_lock);
2564
2565 return;
2566}
2567
2568static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2569 void *pMsg)
2570{
2571 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2572 tpSirEXTScanResetSsidHotlistRspParams pData =
2573 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2574 struct hdd_ext_scan_context *context;
2575
2576 if (wlan_hdd_validate_context(pHddCtx)) {
2577 return;
2578 }
2579 if (!pMsg)
2580 {
2581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2582 return;
2583 }
2584
2585 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2586 pData->status);
2587
2588 context = &pHddCtx->ext_scan_context;
2589 spin_lock(&hdd_context_lock);
2590 if (context->request_id == pData->requestId) {
2591 context->response_status = pData->status ? -EINVAL : 0;
2592 complete(&context->response_event);
2593 }
2594 spin_unlock(&hdd_context_lock);
2595
2596 return;
2597}
2598
2599
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2601 void *pMsg)
2602{
2603 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2604 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302605 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302606 tANI_S32 totalResults;
2607 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302608 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2609 struct hdd_ext_scan_context *context;
2610 bool ignore_cached_results = false;
2611 tExtscanCachedScanResult *result;
2612 struct nlattr *nla_results;
2613 tANI_U16 ieLength= 0;
2614 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302616 ENTER();
2617
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302618 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302619 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302621 if (!pMsg)
2622 {
2623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2624 return;
2625 }
2626
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302627 spin_lock(&hdd_context_lock);
2628 context = &pHddCtx->ext_scan_context;
2629 ignore_cached_results = context->ignore_cached_results;
2630 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 if (ignore_cached_results) {
2633 hddLog(LOGE,
2634 FL("Ignore the cached results received after timeout"));
2635 return;
2636 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302637
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302638 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2639 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302642
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302643 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2644 scan_id_index++) {
2645 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302647 totalResults = result->num_results;
2648 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2649 result->scan_id, result->flags, totalResults);
2650 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302651
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302652 do{
2653 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2654 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2655 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302656
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302657 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2658 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2659
2660 if (!skb) {
2661 hddLog(VOS_TRACE_LEVEL_ERROR,
2662 FL("cfg80211_vendor_event_alloc failed"));
2663 return;
2664 }
2665
2666 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2667
2668 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2669 pData->requestId) ||
2670 nla_put_u32(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2672 resultsPerEvent)) {
2673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2674 goto fail;
2675 }
2676 if (nla_put_u8(skb,
2677 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2678 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302679 {
2680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2681 goto fail;
2682 }
2683
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302684 if (nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2686 result->scan_id)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302689 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302690
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302691 nla_results = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2693 if (!nla_results)
2694 goto fail;
2695
2696 if (resultsPerEvent) {
2697 struct nlattr *aps;
2698 struct nlattr *nla_result;
2699
2700 nla_result = nla_nest_start(skb, scan_id_index);
2701 if(!nla_result)
2702 goto fail;
2703
2704 if (nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2706 result->scan_id) ||
2707 nla_put_u32(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2709 result->flags) ||
2710 nla_put_u32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2712 totalResults)) {
2713 hddLog(LOGE, FL("put fail"));
2714 goto fail;
2715 }
2716
2717 aps = nla_nest_start(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2719 if (!aps)
2720 {
2721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2722 goto fail;
2723 }
2724
2725 head_ptr = (tpSirWifiScanResult) &(result->ap);
2726
2727 for (j = 0; j < resultsPerEvent; j++, i++) {
2728 struct nlattr *ap;
2729 pSirWifiScanResult = head_ptr + i;
2730
2731 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302732 * Firmware returns timestamp from extscan_start till
2733 * BSSID was cached (in micro seconds). Add this with
2734 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302735 * to derive the time since boot when the
2736 * BSSID was cached.
2737 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302738 pSirWifiScanResult->ts +=
2739 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302740 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2741 "Ssid (%s)"
2742 "Bssid: %pM "
2743 "Channel (%u)"
2744 "Rssi (%d)"
2745 "RTT (%u)"
2746 "RTT_SD (%u)"
2747 "Beacon Period %u"
2748 "Capability 0x%x "
2749 "Ie length %d",
2750 i,
2751 pSirWifiScanResult->ts,
2752 pSirWifiScanResult->ssid,
2753 pSirWifiScanResult->bssid,
2754 pSirWifiScanResult->channel,
2755 pSirWifiScanResult->rssi,
2756 pSirWifiScanResult->rtt,
2757 pSirWifiScanResult->rtt_sd,
2758 pSirWifiScanResult->beaconPeriod,
2759 pSirWifiScanResult->capability,
2760 ieLength);
2761
2762 ap = nla_nest_start(skb, j + 1);
2763 if (!ap)
2764 {
2765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2766 goto fail;
2767 }
2768
2769 if (nla_put_u64(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2771 pSirWifiScanResult->ts) )
2772 {
2773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2774 goto fail;
2775 }
2776 if (nla_put(skb,
2777 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2778 sizeof(pSirWifiScanResult->ssid),
2779 pSirWifiScanResult->ssid) )
2780 {
2781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2782 goto fail;
2783 }
2784 if (nla_put(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2786 sizeof(pSirWifiScanResult->bssid),
2787 pSirWifiScanResult->bssid) )
2788 {
2789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2790 goto fail;
2791 }
2792 if (nla_put_u32(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2794 pSirWifiScanResult->channel) )
2795 {
2796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2797 goto fail;
2798 }
2799 if (nla_put_s32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2801 pSirWifiScanResult->rssi) )
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2804 goto fail;
2805 }
2806 if (nla_put_u32(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2808 pSirWifiScanResult->rtt) )
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2811 goto fail;
2812 }
2813 if (nla_put_u32(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2815 pSirWifiScanResult->rtt_sd))
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2818 goto fail;
2819 }
2820 if (nla_put_u32(skb,
2821 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2822 pSirWifiScanResult->beaconPeriod))
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2825 goto fail;
2826 }
2827 if (nla_put_u32(skb,
2828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2829 pSirWifiScanResult->capability))
2830 {
2831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2832 goto fail;
2833 }
2834 if (nla_put_u32(skb,
2835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2836 ieLength))
2837 {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2839 goto fail;
2840 }
2841
2842 if (ieLength)
2843 if (nla_put(skb,
2844 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2845 ieLength, ie)) {
2846 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2847 goto fail;
2848 }
2849
2850 nla_nest_end(skb, ap);
2851 }
2852 nla_nest_end(skb, aps);
2853 nla_nest_end(skb, nla_result);
2854 }
2855
2856 nla_nest_end(skb, nla_results);
2857
2858 cfg80211_vendor_cmd_reply(skb);
2859
2860 } while (totalResults > 0);
2861 }
2862
2863 if (!pData->moreData) {
2864 spin_lock(&hdd_context_lock);
2865 context->response_status = 0;
2866 complete(&context->response_event);
2867 spin_unlock(&hdd_context_lock);
2868 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302869
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302870 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302871 return;
2872fail:
2873 kfree_skb(skb);
2874 return;
2875}
2876
2877static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2878 void *pMsg)
2879{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302880 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302881 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2882 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302883 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302885 ENTER();
2886
2887 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 hddLog(LOGE,
2889 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302890 return;
2891 }
2892 if (!pMsg)
2893 {
2894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 return;
2896 }
2897
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302898 if (pData->bss_found)
2899 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2900 else
2901 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2902
Dino Mycle6fb96c12014-06-10 11:52:40 +05302903 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2905 NULL,
2906#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302908 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909
2910 if (!skb) {
2911 hddLog(VOS_TRACE_LEVEL_ERROR,
2912 FL("cfg80211_vendor_event_alloc failed"));
2913 return;
2914 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302915
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2917 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2918 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2919 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2920
2921 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302922 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2923 "Ssid (%s) "
2924 "Bssid (" MAC_ADDRESS_STR ") "
2925 "Channel (%u) "
2926 "Rssi (%d) "
2927 "RTT (%u) "
2928 "RTT_SD (%u) ",
2929 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302930 pData->bssHotlist[i].ts,
2931 pData->bssHotlist[i].ssid,
2932 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2933 pData->bssHotlist[i].channel,
2934 pData->bssHotlist[i].rssi,
2935 pData->bssHotlist[i].rtt,
2936 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 }
2938
2939 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2940 pData->requestId) ||
2941 nla_put_u32(skb,
2942 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302943 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2945 goto fail;
2946 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302947 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302948 struct nlattr *aps;
2949
2950 aps = nla_nest_start(skb,
2951 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2952 if (!aps)
2953 goto fail;
2954
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302955 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302956 struct nlattr *ap;
2957
2958 ap = nla_nest_start(skb, i + 1);
2959 if (!ap)
2960 goto fail;
2961
2962 if (nla_put_u64(skb,
2963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302965 nla_put(skb,
2966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302967 sizeof(pData->bssHotlist[i].ssid),
2968 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 nla_put(skb,
2970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302971 sizeof(pData->bssHotlist[i].bssid),
2972 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 nla_put_s32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302978 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979 nla_put_u32(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302981 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 nla_put_u32(skb,
2983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302984 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302985 goto fail;
2986
2987 nla_nest_end(skb, ap);
2988 }
2989 nla_nest_end(skb, aps);
2990
2991 if (nla_put_u8(skb,
2992 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2993 pData->moreData))
2994 goto fail;
2995 }
2996
2997 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302998 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302999 return;
3000
3001fail:
3002 kfree_skb(skb);
3003 return;
3004
3005}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303007/**
3008 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3009 * Handle an SSID hotlist match event
3010 * @ctx: HDD context registered with SME
3011 * @event: The SSID hotlist match event
3012 *
3013 * This function will take an SSID match event that was generated by
3014 * firmware and will convert it into a cfg80211 vendor event which is
3015 * sent to userspace.
3016 *
3017 * Return: none
3018 */
3019static void
3020wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3021 void *pMsg)
3022{
3023 hdd_context_t *hdd_ctx = ctx;
3024 struct sk_buff *skb;
3025 tANI_U32 i, index;
3026 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3027
3028 ENTER();
3029
3030 if (wlan_hdd_validate_context(hdd_ctx)) {
3031 hddLog(LOGE,
3032 FL("HDD context is not valid or response"));
3033 return;
3034 }
3035 if (!pMsg)
3036 {
3037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3038 return;
3039 }
3040
3041 if (pData->ssid_found) {
3042 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3043 hddLog(LOG1, "SSID hotlist found");
3044 } else {
3045 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3046 hddLog(LOG1, "SSID hotlist lost");
3047 }
3048
3049 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3051 NULL,
3052#endif
3053 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3054 index, GFP_KERNEL);
3055
3056 if (!skb) {
3057 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3058 return;
3059 }
3060 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3061 pData->requestId, pData->numHotlistSsid, pData->moreData);
3062
3063 for (i = 0; i < pData->numHotlistSsid; i++) {
3064 hddLog(LOG1, "[i=%d] Timestamp %llu "
3065 "Ssid: %s "
3066 "Bssid (" MAC_ADDRESS_STR ") "
3067 "Channel %u "
3068 "Rssi %d "
3069 "RTT %u "
3070 "RTT_SD %u",
3071 i,
3072 pData->ssidHotlist[i].ts,
3073 pData->ssidHotlist[i].ssid,
3074 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3075 pData->ssidHotlist[i].channel,
3076 pData->ssidHotlist[i].rssi,
3077 pData->ssidHotlist[i].rtt,
3078 pData->ssidHotlist[i].rtt_sd);
3079 }
3080
3081 if (nla_put_u32(skb,
3082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3083 pData->requestId) ||
3084 nla_put_u32(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3086 pData->numHotlistSsid)) {
3087 hddLog(LOGE, FL("put fail"));
3088 goto fail;
3089 }
3090
3091 if (pData->numHotlistSsid) {
3092 struct nlattr *aps;
3093 aps = nla_nest_start(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3095 if (!aps) {
3096 hddLog(LOGE, FL("nest fail"));
3097 goto fail;
3098 }
3099
3100 for (i = 0; i < pData->numHotlistSsid; i++) {
3101 struct nlattr *ap;
3102
3103 ap = nla_nest_start(skb, i);
3104 if (!ap) {
3105 hddLog(LOGE, FL("nest fail"));
3106 goto fail;
3107 }
3108
3109 if (nla_put_u64(skb,
3110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3111 pData->ssidHotlist[i].ts) ||
3112 nla_put(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3114 sizeof(pData->ssidHotlist[i].ssid),
3115 pData->ssidHotlist[i].ssid) ||
3116 nla_put(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3118 sizeof(pData->ssidHotlist[i].bssid),
3119 pData->ssidHotlist[i].bssid) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3122 pData->ssidHotlist[i].channel) ||
3123 nla_put_s32(skb,
3124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3125 pData->ssidHotlist[i].rssi) ||
3126 nla_put_u32(skb,
3127 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3128 pData->ssidHotlist[i].rtt) ||
3129 nla_put_u32(skb,
3130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3131 pData->ssidHotlist[i].rtt_sd)) {
3132 hddLog(LOGE, FL("put fail"));
3133 goto fail;
3134 }
3135 nla_nest_end(skb, ap);
3136 }
3137 nla_nest_end(skb, aps);
3138
3139 if (nla_put_u8(skb,
3140 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3141 pData->moreData)) {
3142 hddLog(LOGE, FL("put fail"));
3143 goto fail;
3144 }
3145 }
3146
3147 cfg80211_vendor_event(skb, GFP_KERNEL);
3148 return;
3149
3150fail:
3151 kfree_skb(skb);
3152 return;
3153
3154}
3155
3156
Dino Mycle6fb96c12014-06-10 11:52:40 +05303157static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3158 void *pMsg)
3159{
3160 struct sk_buff *skb;
3161 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3162 tpSirWifiFullScanResultEvent pData =
3163 (tpSirWifiFullScanResultEvent) (pMsg);
3164
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303165 ENTER();
3166
3167 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303168 hddLog(LOGE,
3169 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303170 return;
3171 }
3172 if (!pMsg)
3173 {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303175 return;
3176 }
3177
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303178 /*
3179 * If the full scan result including IE data exceeds NL 4K size
3180 * limitation, drop that beacon/probe rsp frame.
3181 */
3182 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3183 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3184 return;
3185 }
3186
Dino Mycle6fb96c12014-06-10 11:52:40 +05303187 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3189 NULL,
3190#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3192 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3193 GFP_KERNEL);
3194
3195 if (!skb) {
3196 hddLog(VOS_TRACE_LEVEL_ERROR,
3197 FL("cfg80211_vendor_event_alloc failed"));
3198 return;
3199 }
3200
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3202 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3203 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3204 "Ssid (%s)"
3205 "Bssid (" MAC_ADDRESS_STR ")"
3206 "Channel (%u)"
3207 "Rssi (%d)"
3208 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303209 "RTT_SD (%u)"
3210 "Bcn Period %d"
3211 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303212 pData->ap.ts,
3213 pData->ap.ssid,
3214 MAC_ADDR_ARRAY(pData->ap.bssid),
3215 pData->ap.channel,
3216 pData->ap.rssi,
3217 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303218 pData->ap.rtt_sd,
3219 pData->ap.beaconPeriod,
3220 pData->ap.capability);
3221
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3223 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3224 pData->requestId) ||
3225 nla_put_u64(skb,
3226 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3227 pData->ap.ts) ||
3228 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3229 sizeof(pData->ap.ssid),
3230 pData->ap.ssid) ||
3231 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3232 WNI_CFG_BSSID_LEN,
3233 pData->ap.bssid) ||
3234 nla_put_u32(skb,
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3236 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303237 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303238 pData->ap.rssi) ||
3239 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3240 pData->ap.rtt) ||
3241 nla_put_u32(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3243 pData->ap.rtt_sd) ||
3244 nla_put_u16(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3246 pData->ap.beaconPeriod) ||
3247 nla_put_u16(skb,
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3249 pData->ap.capability) ||
3250 nla_put_u32(skb,
3251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303252 pData->ieLength) ||
3253 nla_put_u8(skb,
3254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3255 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303256 {
3257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3258 goto nla_put_failure;
3259 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303260
3261 if (pData->ieLength) {
3262 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3263 pData->ieLength,
3264 pData->ie))
3265 {
3266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3267 goto nla_put_failure;
3268 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303269 }
3270
3271 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303272 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273 return;
3274
3275nla_put_failure:
3276 kfree_skb(skb);
3277 return;
3278}
3279
3280static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3281 void *pMsg)
3282{
3283 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3284 struct sk_buff *skb = NULL;
3285 tpSirEXTScanResultsAvailableIndParams pData =
3286 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303288 ENTER();
3289
3290 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303291 hddLog(LOGE,
3292 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303293 return;
3294 }
3295 if (!pMsg)
3296 {
3297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
3301 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3303 NULL,
3304#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3306 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3307 GFP_KERNEL);
3308
3309 if (!skb) {
3310 hddLog(VOS_TRACE_LEVEL_ERROR,
3311 FL("cfg80211_vendor_event_alloc failed"));
3312 return;
3313 }
3314
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3316 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3317 pData->numResultsAvailable);
3318 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3319 pData->requestId) ||
3320 nla_put_u32(skb,
3321 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3322 pData->numResultsAvailable)) {
3323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3324 goto nla_put_failure;
3325 }
3326
3327 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303328 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303329 return;
3330
3331nla_put_failure:
3332 kfree_skb(skb);
3333 return;
3334}
3335
3336static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3337{
3338 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3339 struct sk_buff *skb = NULL;
3340 tpSirEXTScanProgressIndParams pData =
3341 (tpSirEXTScanProgressIndParams) pMsg;
3342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303343 ENTER();
3344
3345 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303346 hddLog(LOGE,
3347 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303348 return;
3349 }
3350 if (!pMsg)
3351 {
3352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 return;
3354 }
3355
3356 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303357#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3358 NULL,
3359#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3361 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3362 GFP_KERNEL);
3363
3364 if (!skb) {
3365 hddLog(VOS_TRACE_LEVEL_ERROR,
3366 FL("cfg80211_vendor_event_alloc failed"));
3367 return;
3368 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3371 pData->extScanEventType);
3372 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3373 pData->status);
3374
3375 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3376 pData->extScanEventType) ||
3377 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303378 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3379 pData->requestId) ||
3380 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3382 pData->status)) {
3383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3384 goto nla_put_failure;
3385 }
3386
3387 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303388 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303389 return;
3390
3391nla_put_failure:
3392 kfree_skb(skb);
3393 return;
3394}
3395
3396void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3397 void *pMsg)
3398{
3399 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3400
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303401 ENTER();
3402
Dino Mycle6fb96c12014-06-10 11:52:40 +05303403 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303404 return;
3405 }
3406
3407 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3408
3409
3410 switch(evType) {
3411 case SIR_HAL_EXTSCAN_START_RSP:
3412 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3413 break;
3414
3415 case SIR_HAL_EXTSCAN_STOP_RSP:
3416 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3417 break;
3418 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3419 /* There is no need to send this response to upper layer
3420 Just log the message */
3421 hddLog(VOS_TRACE_LEVEL_INFO,
3422 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3423 break;
3424 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3425 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3426 break;
3427
3428 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3429 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3430 break;
3431
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303432 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3433 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3434 break;
3435
3436 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3437 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3438 break;
3439
Dino Mycle6fb96c12014-06-10 11:52:40 +05303440 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303441 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442 break;
3443 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3444 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3445 break;
3446 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3447 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3448 break;
3449 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3450 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3451 break;
3452 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3453 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3454 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303455 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3456 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3457 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3459 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3460 break;
3461 default:
3462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3463 break;
3464 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303465 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466}
3467
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303468static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3469 struct wireless_dev *wdev,
3470 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471{
Dino Myclee8843b32014-07-04 14:21:45 +05303472 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 struct net_device *dev = wdev->netdev;
3474 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3475 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3476 struct nlattr
3477 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3478 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303479 struct hdd_ext_scan_context *context;
3480 unsigned long rc;
3481 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303483 ENTER();
3484
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485 status = wlan_hdd_validate_context(pHddCtx);
3486 if (0 != status)
3487 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return -EINVAL;
3489 }
Dino Myclee8843b32014-07-04 14:21:45 +05303490 /* check the EXTScan Capability */
3491 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303492 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3493 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303494 {
3495 hddLog(VOS_TRACE_LEVEL_ERROR,
3496 FL("EXTScan not enabled/supported by Firmware"));
3497 return -EINVAL;
3498 }
3499
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3501 data, dataLen,
3502 wlan_hdd_extscan_config_policy)) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3504 return -EINVAL;
3505 }
3506
3507 /* Parse and fetch request Id */
3508 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3510 return -EINVAL;
3511 }
3512
Dino Myclee8843b32014-07-04 14:21:45 +05303513 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303515 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516
Dino Myclee8843b32014-07-04 14:21:45 +05303517 reqMsg.sessionId = pAdapter->sessionId;
3518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303520 vos_spin_lock_acquire(&hdd_context_lock);
3521 context = &pHddCtx->ext_scan_context;
3522 context->request_id = reqMsg.requestId;
3523 INIT_COMPLETION(context->response_event);
3524 vos_spin_lock_release(&hdd_context_lock);
3525
Dino Myclee8843b32014-07-04 14:21:45 +05303526 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527 if (!HAL_STATUS_SUCCESS(status)) {
3528 hddLog(VOS_TRACE_LEVEL_ERROR,
3529 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530 return -EINVAL;
3531 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303532
3533 rc = wait_for_completion_timeout(&context->response_event,
3534 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3535 if (!rc) {
3536 hddLog(LOGE, FL("Target response timed out"));
3537 return -ETIMEDOUT;
3538 }
3539
3540 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3541 if (ret)
3542 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3543
3544 return ret;
3545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303546 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 return 0;
3548}
3549
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303550static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3551 struct wireless_dev *wdev,
3552 const void *data, int dataLen)
3553{
3554 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303556 vos_ssr_protect(__func__);
3557 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3558 vos_ssr_unprotect(__func__);
3559
3560 return ret;
3561}
3562
3563static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3564 struct wireless_dev *wdev,
3565 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566{
Dino Myclee8843b32014-07-04 14:21:45 +05303567 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 struct net_device *dev = wdev->netdev;
3569 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3570 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3571 struct nlattr
3572 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3573 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303574 struct hdd_ext_scan_context *context;
3575 unsigned long rc;
3576 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303577
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303578 ENTER();
3579
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303580 if (VOS_FTM_MODE == hdd_get_conparam()) {
3581 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3582 return -EINVAL;
3583 }
3584
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 status = wlan_hdd_validate_context(pHddCtx);
3586 if (0 != status)
3587 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303588 return -EINVAL;
3589 }
Dino Myclee8843b32014-07-04 14:21:45 +05303590 /* check the EXTScan Capability */
3591 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303592 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3593 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR,
3596 FL("EXTScan not enabled/supported by Firmware"));
3597 return -EINVAL;
3598 }
3599
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3601 data, dataLen,
3602 wlan_hdd_extscan_config_policy)) {
3603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3604 return -EINVAL;
3605 }
3606 /* Parse and fetch request Id */
3607 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3609 return -EINVAL;
3610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611
Dino Myclee8843b32014-07-04 14:21:45 +05303612 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3614
Dino Myclee8843b32014-07-04 14:21:45 +05303615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303616
Dino Myclee8843b32014-07-04 14:21:45 +05303617 reqMsg.sessionId = pAdapter->sessionId;
3618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619
3620 /* Parse and fetch flush parameter */
3621 if (!tb
3622 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3623 {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3625 goto failed;
3626 }
Dino Myclee8843b32014-07-04 14:21:45 +05303627 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3629
Dino Myclee8843b32014-07-04 14:21:45 +05303630 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 spin_lock(&hdd_context_lock);
3633 context = &pHddCtx->ext_scan_context;
3634 context->request_id = reqMsg.requestId;
3635 context->ignore_cached_results = false;
3636 INIT_COMPLETION(context->response_event);
3637 spin_unlock(&hdd_context_lock);
3638
Dino Myclee8843b32014-07-04 14:21:45 +05303639 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640 if (!HAL_STATUS_SUCCESS(status)) {
3641 hddLog(VOS_TRACE_LEVEL_ERROR,
3642 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643 return -EINVAL;
3644 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303645
3646 rc = wait_for_completion_timeout(&context->response_event,
3647 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3648 if (!rc) {
3649 hddLog(LOGE, FL("Target response timed out"));
3650 retval = -ETIMEDOUT;
3651 spin_lock(&hdd_context_lock);
3652 context->ignore_cached_results = true;
3653 spin_unlock(&hdd_context_lock);
3654 } else {
3655 spin_lock(&hdd_context_lock);
3656 retval = context->response_status;
3657 spin_unlock(&hdd_context_lock);
3658 }
3659
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303660 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303661 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
3663failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303664 return -EINVAL;
3665}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303666static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3667 struct wireless_dev *wdev,
3668 const void *data, int dataLen)
3669{
3670 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303672 vos_ssr_protect(__func__);
3673 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3674 vos_ssr_unprotect(__func__);
3675
3676 return ret;
3677}
3678
3679static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303681 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682{
3683 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3684 struct net_device *dev = wdev->netdev;
3685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3687 struct nlattr
3688 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3689 struct nlattr
3690 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3691 struct nlattr *apTh;
3692 eHalStatus status;
3693 tANI_U8 i = 0;
3694 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303695 struct hdd_ext_scan_context *context;
3696 tANI_U32 request_id;
3697 unsigned long rc;
3698 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303700 ENTER();
3701
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303702 if (VOS_FTM_MODE == hdd_get_conparam()) {
3703 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3704 return -EINVAL;
3705 }
3706
Dino Mycle6fb96c12014-06-10 11:52:40 +05303707 status = wlan_hdd_validate_context(pHddCtx);
3708 if (0 != status)
3709 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303710 return -EINVAL;
3711 }
Dino Myclee8843b32014-07-04 14:21:45 +05303712 /* check the EXTScan Capability */
3713 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303714 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3715 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303716 {
3717 hddLog(VOS_TRACE_LEVEL_ERROR,
3718 FL("EXTScan not enabled/supported by Firmware"));
3719 return -EINVAL;
3720 }
3721
Dino Mycle6fb96c12014-06-10 11:52:40 +05303722 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3723 data, dataLen,
3724 wlan_hdd_extscan_config_policy)) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3726 return -EINVAL;
3727 }
3728
3729 /* Parse and fetch request Id */
3730 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3732 return -EINVAL;
3733 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303734 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3735 vos_mem_malloc(sizeof(*pReqMsg));
3736 if (!pReqMsg) {
3737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3738 return -ENOMEM;
3739 }
3740
Dino Myclee8843b32014-07-04 14:21:45 +05303741
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 pReqMsg->requestId = nla_get_u32(
3743 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3744 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3745
3746 /* Parse and fetch number of APs */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3749 goto fail;
3750 }
3751
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303752 /* Parse and fetch lost ap sample size */
3753 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3754 hddLog(LOGE, FL("attr lost ap sample size failed"));
3755 goto fail;
3756 }
3757
3758 pReqMsg->lostBssidSampleSize = nla_get_u32(
3759 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3760 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3761
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762 pReqMsg->sessionId = pAdapter->sessionId;
3763 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3764
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303765 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303766 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768
3769 nla_for_each_nested(apTh,
3770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3771 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3772 nla_data(apTh), nla_len(apTh),
3773 NULL)) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3775 goto fail;
3776 }
3777
3778 /* Parse and fetch MAC address */
3779 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3780 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3781 goto fail;
3782 }
3783 memcpy(pReqMsg->ap[i].bssid, nla_data(
3784 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3785 sizeof(tSirMacAddr));
3786 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3787
3788 /* Parse and fetch low RSSI */
3789 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3791 goto fail;
3792 }
3793 pReqMsg->ap[i].low = nla_get_s32(
3794 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3795 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3796
3797 /* Parse and fetch high RSSI */
3798 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3800 goto fail;
3801 }
3802 pReqMsg->ap[i].high = nla_get_s32(
3803 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3804 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3805 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303806 i++;
3807 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303808
3809 context = &pHddCtx->ext_scan_context;
3810 spin_lock(&hdd_context_lock);
3811 INIT_COMPLETION(context->response_event);
3812 context->request_id = request_id = pReqMsg->requestId;
3813 spin_unlock(&hdd_context_lock);
3814
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3816 if (!HAL_STATUS_SUCCESS(status)) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR,
3818 FL("sme_SetBssHotlist failed(err=%d)"), status);
3819 vos_mem_free(pReqMsg);
3820 return -EINVAL;
3821 }
3822
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303823 /* request was sent -- wait for the response */
3824 rc = wait_for_completion_timeout(&context->response_event,
3825 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3826
3827 if (!rc) {
3828 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3829 retval = -ETIMEDOUT;
3830 } else {
3831 spin_lock(&hdd_context_lock);
3832 if (context->request_id == request_id)
3833 retval = context->response_status;
3834 else
3835 retval = -EINVAL;
3836 spin_unlock(&hdd_context_lock);
3837 }
3838
Dino Myclee8843b32014-07-04 14:21:45 +05303839 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303840 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303841 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842
3843fail:
3844 vos_mem_free(pReqMsg);
3845 return -EINVAL;
3846}
3847
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303848static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3849 struct wireless_dev *wdev,
3850 const void *data, int dataLen)
3851{
3852 int ret = 0;
3853
3854 vos_ssr_protect(__func__);
3855 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3856 dataLen);
3857 vos_ssr_unprotect(__func__);
3858
3859 return ret;
3860}
3861
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303862/*
3863 * define short names for the global vendor params
3864 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3865 */
3866#define PARAM_MAX \
3867QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3868#define PARAM_REQUEST_ID \
3869QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3870#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3872#define PARAMS_NUM_SSID \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3874#define THRESHOLD_PARAM \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3876#define PARAM_SSID \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3878#define PARAM_BAND \
3879QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3880#define PARAM_RSSI_LOW \
3881QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3882#define PARAM_RSSI_HIGH \
3883QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3884
3885/**
3886 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3887 * @wiphy: Pointer to wireless phy
3888 * @wdev: Pointer to wireless device
3889 * @data: Pointer to data
3890 * @data_len: Data length
3891 *
3892 * Return: 0 on success, negative errno on failure
3893 */
3894static int
3895__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3896 struct wireless_dev *wdev,
3897 const void *data,
3898 int data_len)
3899{
3900 tSirEXTScanSetSsidHotListReqParams *request;
3901 struct net_device *dev = wdev->netdev;
3902 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3903 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3904 struct nlattr *tb[PARAM_MAX + 1];
3905 struct nlattr *tb2[PARAM_MAX + 1];
3906 struct nlattr *ssids;
3907 struct hdd_ext_scan_context *context;
3908 uint32_t request_id;
3909 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3910 int ssid_len;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303911 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303912 eHalStatus status;
3913 int i, rem, retval;
3914 unsigned long rc;
3915
3916 ENTER();
3917
3918 if (VOS_FTM_MODE == hdd_get_conparam()) {
3919 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3920 return -EINVAL;
3921 }
3922
3923 retval = wlan_hdd_validate_context(hdd_ctx);
3924 if (0 != retval) {
3925 hddLog(LOGE, FL("HDD context is not valid"));
3926 return -EINVAL;
3927 }
3928
3929 /* check the EXTScan Capability */
3930 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303931 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3932 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303933 {
3934 hddLog(VOS_TRACE_LEVEL_ERROR,
3935 FL("EXTScan not enabled/supported by Firmware"));
3936 return -EINVAL;
3937 }
3938
3939 if (nla_parse(tb, PARAM_MAX,
3940 data, data_len,
3941 wlan_hdd_extscan_config_policy)) {
3942 hddLog(LOGE, FL("Invalid ATTR"));
3943 return -EINVAL;
3944 }
3945
3946 request = vos_mem_malloc(sizeof(*request));
3947 if (!request) {
3948 hddLog(LOGE, FL("vos_mem_malloc failed"));
3949 return -ENOMEM;
3950 }
3951
3952 /* Parse and fetch request Id */
3953 if (!tb[PARAM_REQUEST_ID]) {
3954 hddLog(LOGE, FL("attr request id failed"));
3955 goto fail;
3956 }
3957
3958 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3959 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3960
3961 /* Parse and fetch lost SSID sample size */
3962 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3963 hddLog(LOGE, FL("attr number of Ssid failed"));
3964 goto fail;
3965 }
3966 request->lost_ssid_sample_size =
3967 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3968 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3969 request->lost_ssid_sample_size);
3970
3971 /* Parse and fetch number of hotlist SSID */
3972 if (!tb[PARAMS_NUM_SSID]) {
3973 hddLog(LOGE, FL("attr number of Ssid failed"));
3974 goto fail;
3975 }
3976 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3977 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3978
3979 request->session_id = adapter->sessionId;
3980 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3981
3982 i = 0;
3983 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3984 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3985 hddLog(LOGE,
3986 FL("Too Many SSIDs, %d exceeds %d"),
3987 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3988 break;
3989 }
3990 if (nla_parse(tb2, PARAM_MAX,
3991 nla_data(ssids), nla_len(ssids),
3992 wlan_hdd_extscan_config_policy)) {
3993 hddLog(LOGE, FL("nla_parse failed"));
3994 goto fail;
3995 }
3996
3997 /* Parse and fetch SSID */
3998 if (!tb2[PARAM_SSID]) {
3999 hddLog(LOGE, FL("attr ssid failed"));
4000 goto fail;
4001 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05304002 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
4003 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304004 hddLog(LOG1, FL("SSID %s"),
4005 ssid_string);
4006 ssid_len = strlen(ssid_string);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304007 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4008 hddLog(LOGE, FL("Invalid ssid length"));
4009 goto fail;
4010 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304011 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4012 request->ssid[i].ssid.length = ssid_len;
4013 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4014 hddLog(LOG1, FL("After copying SSID %s"),
4015 request->ssid[i].ssid.ssId);
4016 hddLog(LOG1, FL("After copying length: %d"),
4017 ssid_len);
4018
4019 /* Parse and fetch low RSSI */
4020 if (!tb2[PARAM_BAND]) {
4021 hddLog(LOGE, FL("attr band failed"));
4022 goto fail;
4023 }
4024 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4025 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4026
4027 /* Parse and fetch low RSSI */
4028 if (!tb2[PARAM_RSSI_LOW]) {
4029 hddLog(LOGE, FL("attr low RSSI failed"));
4030 goto fail;
4031 }
4032 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4033 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4034
4035 /* Parse and fetch high RSSI */
4036 if (!tb2[PARAM_RSSI_HIGH]) {
4037 hddLog(LOGE, FL("attr high RSSI failed"));
4038 goto fail;
4039 }
4040 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4041 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4042 i++;
4043 }
4044
4045 context = &hdd_ctx->ext_scan_context;
4046 spin_lock(&hdd_context_lock);
4047 INIT_COMPLETION(context->response_event);
4048 context->request_id = request_id = request->request_id;
4049 spin_unlock(&hdd_context_lock);
4050
4051 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4052 if (!HAL_STATUS_SUCCESS(status)) {
4053 hddLog(LOGE,
4054 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4055 goto fail;
4056 }
4057
4058 vos_mem_free(request);
4059
4060 /* request was sent -- wait for the response */
4061 rc = wait_for_completion_timeout(&context->response_event,
4062 msecs_to_jiffies
4063 (WLAN_WAIT_TIME_EXTSCAN));
4064 if (!rc) {
4065 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4066 retval = -ETIMEDOUT;
4067 } else {
4068 spin_lock(&hdd_context_lock);
4069 if (context->request_id == request_id)
4070 retval = context->response_status;
4071 else
4072 retval = -EINVAL;
4073 spin_unlock(&hdd_context_lock);
4074 }
4075
4076 return retval;
4077
4078fail:
4079 vos_mem_free(request);
4080 return -EINVAL;
4081}
4082
4083/*
4084 * done with short names for the global vendor params
4085 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4086 */
4087#undef PARAM_MAX
4088#undef PARAM_REQUEST_ID
4089#undef PARAMS_NUM_SSID
4090#undef THRESHOLD_PARAM
4091#undef PARAM_SSID
4092#undef PARAM_BAND
4093#undef PARAM_RSSI_LOW
4094#undef PARAM_RSSI_HIGH
4095
4096static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4097 struct wireless_dev *wdev,
4098 const void *data, int dataLen)
4099{
4100 int ret = 0;
4101
4102 vos_ssr_protect(__func__);
4103 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4104 dataLen);
4105 vos_ssr_unprotect(__func__);
4106
4107 return ret;
4108}
4109
4110static int
4111__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4112 struct wireless_dev *wdev,
4113 const void *data,
4114 int data_len)
4115{
4116 tSirEXTScanResetSsidHotlistReqParams request;
4117 struct net_device *dev = wdev->netdev;
4118 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4119 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4120 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4121 struct hdd_ext_scan_context *context;
4122 uint32_t request_id;
4123 eHalStatus status;
4124 int retval;
4125 unsigned long rc;
4126
4127 ENTER();
4128
4129 if (VOS_FTM_MODE == hdd_get_conparam()) {
4130 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4131 return -EINVAL;
4132 }
4133
4134 retval = wlan_hdd_validate_context(hdd_ctx);
4135 if (0 != retval) {
4136 hddLog(LOGE, FL("HDD context is not valid"));
4137 return -EINVAL;
4138 }
4139
4140 /* check the EXTScan Capability */
4141 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304142 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4143 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304144 {
4145 hddLog(LOGE,
4146 FL("EXTScan not enabled/supported by Firmware"));
4147 return -EINVAL;
4148 }
4149
4150 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4151 data, data_len,
4152 wlan_hdd_extscan_config_policy)) {
4153 hddLog(LOGE, FL("Invalid ATTR"));
4154 return -EINVAL;
4155 }
4156
4157 /* Parse and fetch request Id */
4158 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4159 hddLog(LOGE, FL("attr request id failed"));
4160 return -EINVAL;
4161 }
4162
4163 request.requestId = nla_get_u32(
4164 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4165 request.sessionId = adapter->sessionId;
4166 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4167 request.sessionId);
4168
4169 context = &hdd_ctx->ext_scan_context;
4170 spin_lock(&hdd_context_lock);
4171 INIT_COMPLETION(context->response_event);
4172 context->request_id = request_id = request.requestId;
4173 spin_unlock(&hdd_context_lock);
4174
4175 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4176 if (!HAL_STATUS_SUCCESS(status)) {
4177 hddLog(LOGE,
4178 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4179 return -EINVAL;
4180 }
4181
4182 /* request was sent -- wait for the response */
4183 rc = wait_for_completion_timeout(&context->response_event,
4184 msecs_to_jiffies
4185 (WLAN_WAIT_TIME_EXTSCAN));
4186 if (!rc) {
4187 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4188 retval = -ETIMEDOUT;
4189 } else {
4190 spin_lock(&hdd_context_lock);
4191 if (context->request_id == request_id)
4192 retval = context->response_status;
4193 else
4194 retval = -EINVAL;
4195 spin_unlock(&hdd_context_lock);
4196 }
4197
4198 return retval;
4199}
4200
4201static int
4202wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4203 struct wireless_dev *wdev,
4204 const void *data,
4205 int data_len)
4206{
4207 int ret;
4208
4209 vos_ssr_protect(__func__);
4210 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4211 data, data_len);
4212 vos_ssr_unprotect(__func__);
4213
4214 return ret;
4215}
4216
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304217static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304219 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304221 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4222 struct net_device *dev = wdev->netdev;
4223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4224 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4225 uint8_t num_channels = 0;
4226 uint8_t num_chan_new = 0;
4227 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304228 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304229 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230 tWifiBand wifiBand;
4231 eHalStatus status;
4232 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304233 tANI_U8 i,j,k;
4234 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304236 ENTER();
4237
Dino Mycle6fb96c12014-06-10 11:52:40 +05304238 status = wlan_hdd_validate_context(pHddCtx);
4239 if (0 != status)
4240 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304241 return -EINVAL;
4242 }
Dino Myclee8843b32014-07-04 14:21:45 +05304243
Dino Mycle6fb96c12014-06-10 11:52:40 +05304244 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4245 data, dataLen,
4246 wlan_hdd_extscan_config_policy)) {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4248 return -EINVAL;
4249 }
4250
4251 /* Parse and fetch request Id */
4252 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4254 return -EINVAL;
4255 }
4256 requestId = nla_get_u32(
4257 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4259
4260 /* Parse and fetch wifi band */
4261 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4262 {
4263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4264 return -EINVAL;
4265 }
4266 wifiBand = nla_get_u32(
4267 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4268 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4269
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304270 /* Parse and fetch max channels */
4271 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4272 {
4273 hddLog(LOGE, FL("attr max channels failed"));
4274 return -EINVAL;
4275 }
4276 maxChannels = nla_get_u32(
4277 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4279
Dino Mycle6fb96c12014-06-10 11:52:40 +05304280 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304281 wifiBand, chan_list,
4282 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304283 if (eHAL_STATUS_SUCCESS != status) {
4284 hddLog(VOS_TRACE_LEVEL_ERROR,
4285 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4286 return -EINVAL;
4287 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304288
Agrawal Ashish16abf782016-08-18 22:42:59 +05304289 num_channels = VOS_MIN(num_channels, maxChannels);
4290 num_chan_new = num_channels;
4291 /* remove the indoor only channels if iface is SAP */
4292 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4293 {
4294 num_chan_new = 0;
4295 for (i = 0; i < num_channels; i++)
4296 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4297 if (wiphy->bands[j] == NULL)
4298 continue;
4299 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4300 if ((chan_list[i] ==
4301 wiphy->bands[j]->channels[k].center_freq) &&
4302 (!(wiphy->bands[j]->channels[k].flags &
4303 IEEE80211_CHAN_INDOOR_ONLY))) {
4304 chan_list[num_chan_new] = chan_list[i];
4305 num_chan_new++;
4306 }
4307 }
4308 }
4309 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304310
Agrawal Ashish16abf782016-08-18 22:42:59 +05304311 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4312 for (i = 0; i < num_chan_new; i++)
4313 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4314 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
4316 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304317 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 NLMSG_HDRLEN);
4319
4320 if (!replySkb) {
4321 hddLog(VOS_TRACE_LEVEL_ERROR,
4322 FL("valid channels: buffer alloc fail"));
4323 return -EINVAL;
4324 }
4325 if (nla_put_u32(replySkb,
4326 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304327 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304329 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330
4331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4332 kfree_skb(replySkb);
4333 return -EINVAL;
4334 }
4335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304336 ret = cfg80211_vendor_cmd_reply(replySkb);
4337
4338 EXIT();
4339 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304340}
4341
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304342static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4343 struct wireless_dev *wdev,
4344 const void *data, int dataLen)
4345{
4346 int ret = 0;
4347
4348 vos_ssr_protect(__func__);
4349 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4350 dataLen);
4351 vos_ssr_unprotect(__func__);
4352
4353 return ret;
4354}
4355
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304356static int hdd_extscan_start_fill_bucket_channel_spec(
4357 hdd_context_t *pHddCtx,
4358 tpSirEXTScanStartReqParams pReqMsg,
4359 struct nlattr **tb)
4360{
4361 struct nlattr *bucket[
4362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4363 struct nlattr *channel[
4364 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4365 struct nlattr *buckets;
4366 struct nlattr *channels;
4367 int rem1, rem2;
4368 eHalStatus status;
4369 tANI_U8 bktIndex, j, numChannels;
4370 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4371 tANI_U32 passive_max_chn_time, active_max_chn_time;
4372
4373 bktIndex = 0;
4374
4375 nla_for_each_nested(buckets,
4376 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4377 if (nla_parse(bucket,
4378 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4379 nla_data(buckets), nla_len(buckets), NULL)) {
4380 hddLog(LOGE, FL("nla_parse failed"));
4381 return -EINVAL;
4382 }
4383
4384 /* Parse and fetch bucket spec */
4385 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4386 hddLog(LOGE, FL("attr bucket index failed"));
4387 return -EINVAL;
4388 }
4389 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4390 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4391 hddLog(LOG1, FL("Bucket spec Index %d"),
4392 pReqMsg->buckets[bktIndex].bucket);
4393
4394 /* Parse and fetch wifi band */
4395 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4396 hddLog(LOGE, FL("attr wifi band failed"));
4397 return -EINVAL;
4398 }
4399 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4400 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4401 hddLog(LOG1, FL("Wifi band %d"),
4402 pReqMsg->buckets[bktIndex].band);
4403
4404 /* Parse and fetch period */
4405 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4406 hddLog(LOGE, FL("attr period failed"));
4407 return -EINVAL;
4408 }
4409 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4410 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4411 hddLog(LOG1, FL("period %d"),
4412 pReqMsg->buckets[bktIndex].period);
4413
4414 /* Parse and fetch report events */
4415 if (!bucket[
4416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4417 hddLog(LOGE, FL("attr report events failed"));
4418 return -EINVAL;
4419 }
4420 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4421 bucket[
4422 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4423 hddLog(LOG1, FL("report events %d"),
4424 pReqMsg->buckets[bktIndex].reportEvents);
4425
4426 /* Parse and fetch max period */
4427 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4428 hddLog(LOGE, FL("attr max period failed"));
4429 return -EINVAL;
4430 }
4431 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4432 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4433 hddLog(LOG1, FL("max period %u"),
4434 pReqMsg->buckets[bktIndex].max_period);
4435
4436 /* Parse and fetch exponent */
4437 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4438 hddLog(LOGE, FL("attr exponent failed"));
4439 return -EINVAL;
4440 }
4441 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4442 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4443 hddLog(LOG1, FL("exponent %u"),
4444 pReqMsg->buckets[bktIndex].exponent);
4445
4446 /* Parse and fetch step count */
4447 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4448 hddLog(LOGE, FL("attr step count failed"));
4449 return -EINVAL;
4450 }
4451 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4452 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4453 hddLog(LOG1, FL("Step count %u"),
4454 pReqMsg->buckets[bktIndex].step_count);
4455
4456 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4457 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4458
4459 /* Framework shall pass the channel list if the input WiFi band is
4460 * WIFI_BAND_UNSPECIFIED.
4461 * If the input WiFi band is specified (any value other than
4462 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4463 */
4464 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4465 numChannels = 0;
4466 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4467 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4468 pReqMsg->buckets[bktIndex].band,
4469 chanList, &numChannels);
4470 if (!HAL_STATUS_SUCCESS(status)) {
4471 hddLog(LOGE,
4472 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4473 status);
4474 return -EINVAL;
4475 }
4476
4477 pReqMsg->buckets[bktIndex].numChannels =
4478 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4479 hddLog(LOG1, FL("Num channels %d"),
4480 pReqMsg->buckets[bktIndex].numChannels);
4481
4482 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4483 j++) {
4484 pReqMsg->buckets[bktIndex].channels[j].channel =
4485 chanList[j];
4486 pReqMsg->buckets[bktIndex].channels[j].
4487 chnlClass = 0;
4488 if (CSR_IS_CHANNEL_DFS(
4489 vos_freq_to_chan(chanList[j]))) {
4490 pReqMsg->buckets[bktIndex].channels[j].
4491 passive = 1;
4492 pReqMsg->buckets[bktIndex].channels[j].
4493 dwellTimeMs = passive_max_chn_time;
4494 } else {
4495 pReqMsg->buckets[bktIndex].channels[j].
4496 passive = 0;
4497 pReqMsg->buckets[bktIndex].channels[j].
4498 dwellTimeMs = active_max_chn_time;
4499 }
4500
4501 hddLog(LOG1,
4502 "Channel %u Passive %u Dwell time %u ms",
4503 pReqMsg->buckets[bktIndex].channels[j].channel,
4504 pReqMsg->buckets[bktIndex].channels[j].passive,
4505 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4506 }
4507
4508 bktIndex++;
4509 continue;
4510 }
4511
4512 /* Parse and fetch number of channels */
4513 if (!bucket[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4515 hddLog(LOGE, FL("attr num channels failed"));
4516 return -EINVAL;
4517 }
4518
4519 pReqMsg->buckets[bktIndex].numChannels =
4520 nla_get_u32(bucket[
4521 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4522 hddLog(LOG1, FL("num channels %d"),
4523 pReqMsg->buckets[bktIndex].numChannels);
4524
4525 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4526 hddLog(LOGE, FL("attr channel spec failed"));
4527 return -EINVAL;
4528 }
4529
4530 j = 0;
4531 nla_for_each_nested(channels,
4532 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4533 if (nla_parse(channel,
4534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4535 nla_data(channels), nla_len(channels),
4536 wlan_hdd_extscan_config_policy)) {
4537 hddLog(LOGE, FL("nla_parse failed"));
4538 return -EINVAL;
4539 }
4540
4541 /* Parse and fetch channel */
4542 if (!channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4544 hddLog(LOGE, FL("attr channel failed"));
4545 return -EINVAL;
4546 }
4547 pReqMsg->buckets[bktIndex].channels[j].channel =
4548 nla_get_u32(channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4550 hddLog(LOG1, FL("channel %u"),
4551 pReqMsg->buckets[bktIndex].channels[j].channel);
4552
4553 /* Parse and fetch dwell time */
4554 if (!channel[
4555 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4556 hddLog(LOGE, FL("attr dwelltime failed"));
4557 return -EINVAL;
4558 }
4559 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4560 nla_get_u32(channel[
4561 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4562
4563 hddLog(LOG1, FL("Dwell time (%u ms)"),
4564 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4565
4566
4567 /* Parse and fetch channel spec passive */
4568 if (!channel[
4569 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4570 hddLog(LOGE,
4571 FL("attr channel spec passive failed"));
4572 return -EINVAL;
4573 }
4574 pReqMsg->buckets[bktIndex].channels[j].passive =
4575 nla_get_u8(channel[
4576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4577 hddLog(LOG1, FL("Chnl spec passive %u"),
4578 pReqMsg->buckets[bktIndex].channels[j].passive);
4579
4580 j++;
4581 }
4582
4583 bktIndex++;
4584 }
4585
4586 return 0;
4587}
4588
4589
4590/*
4591 * define short names for the global vendor params
4592 * used by wlan_hdd_cfg80211_extscan_start()
4593 */
4594#define PARAM_MAX \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4596#define PARAM_REQUEST_ID \
4597QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4598#define PARAM_BASE_PERIOD \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4600#define PARAM_MAX_AP_PER_SCAN \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4602#define PARAM_RPT_THRHLD_PERCENT \
4603QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4604#define PARAM_RPT_THRHLD_NUM_SCANS \
4605QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4606#define PARAM_NUM_BUCKETS \
4607QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4608
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304609static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304610 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304611 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612{
Dino Myclee8843b32014-07-04 14:21:45 +05304613 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 struct net_device *dev = wdev->netdev;
4615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4616 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4617 struct nlattr *tb[PARAM_MAX + 1];
4618 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304620 tANI_U32 request_id;
4621 struct hdd_ext_scan_context *context;
4622 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304624 ENTER();
4625
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304626 if (VOS_FTM_MODE == hdd_get_conparam()) {
4627 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4628 return -EINVAL;
4629 }
4630
Dino Mycle6fb96c12014-06-10 11:52:40 +05304631 status = wlan_hdd_validate_context(pHddCtx);
4632 if (0 != status)
4633 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304634 return -EINVAL;
4635 }
Dino Myclee8843b32014-07-04 14:21:45 +05304636 /* check the EXTScan Capability */
4637 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304638 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4639 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304640 {
4641 hddLog(VOS_TRACE_LEVEL_ERROR,
4642 FL("EXTScan not enabled/supported by Firmware"));
4643 return -EINVAL;
4644 }
4645
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304646 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647 data, dataLen,
4648 wlan_hdd_extscan_config_policy)) {
4649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4650 return -EINVAL;
4651 }
4652
4653 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4656 return -EINVAL;
4657 }
4658
Dino Myclee8843b32014-07-04 14:21:45 +05304659 pReqMsg = (tpSirEXTScanStartReqParams)
4660 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304661 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4663 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 }
4665
4666 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304667 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304668 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4669
4670 pReqMsg->sessionId = pAdapter->sessionId;
4671 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4672
4673 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304674 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4676 goto fail;
4677 }
4678 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4681 pReqMsg->basePeriod);
4682
4683 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4686 goto fail;
4687 }
4688 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304689 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304690 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4691 pReqMsg->maxAPperScan);
4692
4693 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304694 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4696 goto fail;
4697 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 pReqMsg->reportThresholdPercent = nla_get_u8(
4699 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304701 pReqMsg->reportThresholdPercent);
4702
4703 /* Parse and fetch report threshold num scans */
4704 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4705 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4706 goto fail;
4707 }
4708 pReqMsg->reportThresholdNumScans = nla_get_u8(
4709 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4710 hddLog(LOG1, FL("Report Threshold num scans %d"),
4711 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712
4713 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4716 goto fail;
4717 }
4718 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304719 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304720 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4721 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4722 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4723 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4724 }
4725 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4726 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304727
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4730 goto fail;
4731 }
4732
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304733 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304735 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4736 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304737
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304738 context = &pHddCtx->ext_scan_context;
4739 spin_lock(&hdd_context_lock);
4740 INIT_COMPLETION(context->response_event);
4741 context->request_id = request_id = pReqMsg->requestId;
4742 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304743
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4745 if (!HAL_STATUS_SUCCESS(status)) {
4746 hddLog(VOS_TRACE_LEVEL_ERROR,
4747 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304748 goto fail;
4749 }
4750
Srinivas Dasari91727c12016-03-23 17:59:06 +05304751 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4752
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304753 /* request was sent -- wait for the response */
4754 rc = wait_for_completion_timeout(&context->response_event,
4755 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4756
4757 if (!rc) {
4758 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4759 retval = -ETIMEDOUT;
4760 } else {
4761 spin_lock(&hdd_context_lock);
4762 if (context->request_id == request_id)
4763 retval = context->response_status;
4764 else
4765 retval = -EINVAL;
4766 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304767 }
4768
Dino Myclee8843b32014-07-04 14:21:45 +05304769 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304770 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304771 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304772
4773fail:
4774 vos_mem_free(pReqMsg);
4775 return -EINVAL;
4776}
4777
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304778/*
4779 * done with short names for the global vendor params
4780 * used by wlan_hdd_cfg80211_extscan_start()
4781 */
4782#undef PARAM_MAX
4783#undef PARAM_REQUEST_ID
4784#undef PARAM_BASE_PERIOD
4785#undef PARAMS_MAX_AP_PER_SCAN
4786#undef PARAMS_RPT_THRHLD_PERCENT
4787#undef PARAMS_RPT_THRHLD_NUM_SCANS
4788#undef PARAMS_NUM_BUCKETS
4789
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304790static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4791 struct wireless_dev *wdev,
4792 const void *data, int dataLen)
4793{
4794 int ret = 0;
4795
4796 vos_ssr_protect(__func__);
4797 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4798 vos_ssr_unprotect(__func__);
4799
4800 return ret;
4801}
4802
4803static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304804 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304805 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304806{
Dino Myclee8843b32014-07-04 14:21:45 +05304807 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 struct net_device *dev = wdev->netdev;
4809 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4810 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4811 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4812 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304813 int retval;
4814 unsigned long rc;
4815 struct hdd_ext_scan_context *context;
4816 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304817
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304818 ENTER();
4819
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304820 if (VOS_FTM_MODE == hdd_get_conparam()) {
4821 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4822 return -EINVAL;
4823 }
4824
Dino Mycle6fb96c12014-06-10 11:52:40 +05304825 status = wlan_hdd_validate_context(pHddCtx);
4826 if (0 != status)
4827 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304828 return -EINVAL;
4829 }
Dino Myclee8843b32014-07-04 14:21:45 +05304830 /* check the EXTScan Capability */
4831 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304832 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4833 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304834 {
4835 hddLog(VOS_TRACE_LEVEL_ERROR,
4836 FL("EXTScan not enabled/supported by Firmware"));
4837 return -EINVAL;
4838 }
4839
Dino Mycle6fb96c12014-06-10 11:52:40 +05304840 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4841 data, dataLen,
4842 wlan_hdd_extscan_config_policy)) {
4843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4844 return -EINVAL;
4845 }
4846
4847 /* Parse and fetch request Id */
4848 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4850 return -EINVAL;
4851 }
4852
Dino Myclee8843b32014-07-04 14:21:45 +05304853 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304856
Dino Myclee8843b32014-07-04 14:21:45 +05304857 reqMsg.sessionId = pAdapter->sessionId;
4858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304859
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304860 context = &pHddCtx->ext_scan_context;
4861 spin_lock(&hdd_context_lock);
4862 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304863 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304864 spin_unlock(&hdd_context_lock);
4865
Dino Myclee8843b32014-07-04 14:21:45 +05304866 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304867 if (!HAL_STATUS_SUCCESS(status)) {
4868 hddLog(VOS_TRACE_LEVEL_ERROR,
4869 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304870 return -EINVAL;
4871 }
4872
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304873 /* request was sent -- wait for the response */
4874 rc = wait_for_completion_timeout(&context->response_event,
4875 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4876
4877 if (!rc) {
4878 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4879 retval = -ETIMEDOUT;
4880 } else {
4881 spin_lock(&hdd_context_lock);
4882 if (context->request_id == request_id)
4883 retval = context->response_status;
4884 else
4885 retval = -EINVAL;
4886 spin_unlock(&hdd_context_lock);
4887 }
4888
4889 return retval;
4890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304891 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304892 return 0;
4893}
4894
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304895static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4896 struct wireless_dev *wdev,
4897 const void *data, int dataLen)
4898{
4899 int ret = 0;
4900
4901 vos_ssr_protect(__func__);
4902 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4903 vos_ssr_unprotect(__func__);
4904
4905 return ret;
4906}
4907
4908static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304909 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304910 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304911{
Dino Myclee8843b32014-07-04 14:21:45 +05304912 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304913 struct net_device *dev = wdev->netdev;
4914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4916 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4917 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304918 struct hdd_ext_scan_context *context;
4919 tANI_U32 request_id;
4920 unsigned long rc;
4921 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304922
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304923 ENTER();
4924
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304925 if (VOS_FTM_MODE == hdd_get_conparam()) {
4926 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4927 return -EINVAL;
4928 }
4929
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930 status = wlan_hdd_validate_context(pHddCtx);
4931 if (0 != status)
4932 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304933 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304934 return -EINVAL;
4935 }
Dino Myclee8843b32014-07-04 14:21:45 +05304936 /* check the EXTScan Capability */
4937 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304938 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4939 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304940 {
4941 hddLog(VOS_TRACE_LEVEL_ERROR,
4942 FL("EXTScan not enabled/supported by Firmware"));
4943 return -EINVAL;
4944 }
4945
Dino Mycle6fb96c12014-06-10 11:52:40 +05304946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4947 data, dataLen,
4948 wlan_hdd_extscan_config_policy)) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4950 return -EINVAL;
4951 }
4952
4953 /* Parse and fetch request Id */
4954 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4956 return -EINVAL;
4957 }
4958
Dino Myclee8843b32014-07-04 14:21:45 +05304959 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304960 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304961 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304962
Dino Myclee8843b32014-07-04 14:21:45 +05304963 reqMsg.sessionId = pAdapter->sessionId;
4964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304965
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304966 context = &pHddCtx->ext_scan_context;
4967 spin_lock(&hdd_context_lock);
4968 INIT_COMPLETION(context->response_event);
4969 context->request_id = request_id = reqMsg.requestId;
4970 spin_unlock(&hdd_context_lock);
4971
Dino Myclee8843b32014-07-04 14:21:45 +05304972 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304973 if (!HAL_STATUS_SUCCESS(status)) {
4974 hddLog(VOS_TRACE_LEVEL_ERROR,
4975 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304976 return -EINVAL;
4977 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304978
4979 /* request was sent -- wait for the response */
4980 rc = wait_for_completion_timeout(&context->response_event,
4981 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4982 if (!rc) {
4983 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4984 retval = -ETIMEDOUT;
4985 } else {
4986 spin_lock(&hdd_context_lock);
4987 if (context->request_id == request_id)
4988 retval = context->response_status;
4989 else
4990 retval = -EINVAL;
4991 spin_unlock(&hdd_context_lock);
4992 }
4993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304994 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304995 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304996}
4997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304998static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4999 struct wireless_dev *wdev,
5000 const void *data, int dataLen)
5001{
5002 int ret = 0;
5003
5004 vos_ssr_protect(__func__);
5005 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5006 vos_ssr_unprotect(__func__);
5007
5008 return ret;
5009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305010#endif /* WLAN_FEATURE_EXTSCAN */
5011
Atul Mittal115287b2014-07-08 13:26:33 +05305012/*EXT TDLS*/
5013static const struct nla_policy
5014wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5015{
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5017 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5019 {.type = NLA_S32 },
5020 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5021 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5022
5023};
5024
5025static const struct nla_policy
5026wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5027{
5028 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5029
5030};
5031
5032static const struct nla_policy
5033wlan_hdd_tdls_config_state_change_policy[
5034 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5035{
5036 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5037 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5038 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305039 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5040 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5041 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305042
5043};
5044
5045static const struct nla_policy
5046wlan_hdd_tdls_config_get_status_policy[
5047 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5048{
5049 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5050 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5051 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305052 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5053 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5054 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305055
5056};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305057
5058static const struct nla_policy
5059wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5060{
5061 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5062};
5063
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305064static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305065 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305066 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305067 int data_len)
5068{
5069
5070 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5071 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5072
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305073 ENTER();
5074
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305075 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305076 return -EINVAL;
5077 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305078 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305079 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305080 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305081 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305083 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 return -ENOTSUPP;
5085 }
5086
5087 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5088 data, data_len, wlan_hdd_mac_config)) {
5089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5090 return -EINVAL;
5091 }
5092
5093 /* Parse and fetch mac address */
5094 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5096 return -EINVAL;
5097 }
5098
5099 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5100 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5101 VOS_MAC_ADDR_LAST_3_BYTES);
5102
Siddharth Bhal76972212014-10-15 16:22:51 +05305103 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5104
5105 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305106 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5107 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305108 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5109 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5110 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5111 {
5112 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5113 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5114 VOS_MAC_ADDRESS_LEN);
5115 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305116 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305117
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305118 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5119 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305120
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305121 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305122 return 0;
5123}
5124
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305125static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5126 struct wireless_dev *wdev,
5127 const void *data,
5128 int data_len)
5129{
5130 int ret = 0;
5131
5132 vos_ssr_protect(__func__);
5133 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5134 vos_ssr_unprotect(__func__);
5135
5136 return ret;
5137}
5138
5139static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305140 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305141 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305142 int data_len)
5143{
5144 u8 peer[6] = {0};
5145 struct net_device *dev = wdev->netdev;
5146 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5147 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5148 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5149 eHalStatus ret;
5150 tANI_S32 state;
5151 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305152 tANI_S32 global_operating_class = 0;
5153 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305154 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305155 int retVal;
5156
5157 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305158
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305159 if (!pAdapter) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5161 return -EINVAL;
5162 }
5163
Atul Mittal115287b2014-07-08 13:26:33 +05305164 ret = wlan_hdd_validate_context(pHddCtx);
5165 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305167 return -EINVAL;
5168 }
5169 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305171 return -ENOTSUPP;
5172 }
5173 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5174 data, data_len,
5175 wlan_hdd_tdls_config_get_status_policy)) {
5176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5177 return -EINVAL;
5178 }
5179
5180 /* Parse and fetch mac address */
5181 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5183 return -EINVAL;
5184 }
5185
5186 memcpy(peer, nla_data(
5187 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5188 sizeof(peer));
5189 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5190
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305191 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305192
Atul Mittal115287b2014-07-08 13:26:33 +05305193 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305194 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305195 NLMSG_HDRLEN);
5196
5197 if (!skb) {
5198 hddLog(VOS_TRACE_LEVEL_ERROR,
5199 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5200 return -EINVAL;
5201 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305202 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 +05305203 reason,
5204 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305205 global_operating_class,
5206 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305207 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305208 if (nla_put_s32(skb,
5209 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5210 state) ||
5211 nla_put_s32(skb,
5212 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5213 reason) ||
5214 nla_put_s32(skb,
5215 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5216 global_operating_class) ||
5217 nla_put_s32(skb,
5218 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5219 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305220
5221 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5222 goto nla_put_failure;
5223 }
5224
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305225 retVal = cfg80211_vendor_cmd_reply(skb);
5226 EXIT();
5227 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305228
5229nla_put_failure:
5230 kfree_skb(skb);
5231 return -EINVAL;
5232}
5233
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305234static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5235 struct wireless_dev *wdev,
5236 const void *data,
5237 int data_len)
5238{
5239 int ret = 0;
5240
5241 vos_ssr_protect(__func__);
5242 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5243 vos_ssr_unprotect(__func__);
5244
5245 return ret;
5246}
5247
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305248static int wlan_hdd_cfg80211_exttdls_callback(
5249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5250 const tANI_U8* mac,
5251#else
5252 tANI_U8* mac,
5253#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305254 tANI_S32 state,
5255 tANI_S32 reason,
5256 void *ctx)
5257{
5258 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305259 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305260 tANI_S32 global_operating_class = 0;
5261 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305262 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305264 ENTER();
5265
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305266 if (!pAdapter) {
5267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5268 return -EINVAL;
5269 }
5270
5271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305272 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305274 return -EINVAL;
5275 }
5276
5277 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305279 return -ENOTSUPP;
5280 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305281 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5282#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5283 NULL,
5284#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305285 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5286 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5287 GFP_KERNEL);
5288
5289 if (!skb) {
5290 hddLog(VOS_TRACE_LEVEL_ERROR,
5291 FL("cfg80211_vendor_event_alloc failed"));
5292 return -EINVAL;
5293 }
5294 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305295 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5296 reason,
5297 state,
5298 global_operating_class,
5299 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305300 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5301 MAC_ADDR_ARRAY(mac));
5302
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305303 if (nla_put(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5305 VOS_MAC_ADDR_SIZE, mac) ||
5306 nla_put_s32(skb,
5307 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5308 state) ||
5309 nla_put_s32(skb,
5310 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5311 reason) ||
5312 nla_put_s32(skb,
5313 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5314 channel) ||
5315 nla_put_s32(skb,
5316 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5317 global_operating_class)
5318 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5320 goto nla_put_failure;
5321 }
5322
5323 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305324 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305325 return (0);
5326
5327nla_put_failure:
5328 kfree_skb(skb);
5329 return -EINVAL;
5330}
5331
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305332static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305333 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305334 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305335 int data_len)
5336{
5337 u8 peer[6] = {0};
5338 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305339 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5340 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5341 eHalStatus status;
5342 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305343 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305344 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305345
5346 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305347
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305348 if (!dev) {
5349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5350 return -EINVAL;
5351 }
5352
5353 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5354 if (!pAdapter) {
5355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5356 return -EINVAL;
5357 }
5358
Atul Mittal115287b2014-07-08 13:26:33 +05305359 status = wlan_hdd_validate_context(pHddCtx);
5360 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305362 return -EINVAL;
5363 }
5364 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305366 return -ENOTSUPP;
5367 }
5368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5369 data, data_len,
5370 wlan_hdd_tdls_config_enable_policy)) {
5371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5372 return -EINVAL;
5373 }
5374
5375 /* Parse and fetch mac address */
5376 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5378 return -EINVAL;
5379 }
5380
5381 memcpy(peer, nla_data(
5382 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5383 sizeof(peer));
5384 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5385
5386 /* Parse and fetch channel */
5387 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5389 return -EINVAL;
5390 }
5391 pReqMsg.channel = nla_get_s32(
5392 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5394
5395 /* Parse and fetch global operating class */
5396 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5398 return -EINVAL;
5399 }
5400 pReqMsg.global_operating_class = nla_get_s32(
5401 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5403 pReqMsg.global_operating_class);
5404
5405 /* Parse and fetch latency ms */
5406 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5408 return -EINVAL;
5409 }
5410 pReqMsg.max_latency_ms = nla_get_s32(
5411 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5412 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5413 pReqMsg.max_latency_ms);
5414
5415 /* Parse and fetch required bandwidth kbps */
5416 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5418 return -EINVAL;
5419 }
5420
5421 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5422 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5423 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5424 pReqMsg.min_bandwidth_kbps);
5425
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305426 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305427 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305428 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305429 wlan_hdd_cfg80211_exttdls_callback);
5430
5431 EXIT();
5432 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305433}
5434
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305435static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5436 struct wireless_dev *wdev,
5437 const void *data,
5438 int data_len)
5439{
5440 int ret = 0;
5441
5442 vos_ssr_protect(__func__);
5443 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5444 vos_ssr_unprotect(__func__);
5445
5446 return ret;
5447}
5448
5449static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305450 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305451 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305452 int data_len)
5453{
5454 u8 peer[6] = {0};
5455 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305456 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5457 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5458 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305459 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305460 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305461
5462 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305463
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305464 if (!dev) {
5465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5466 return -EINVAL;
5467 }
5468
5469 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5470 if (!pAdapter) {
5471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5472 return -EINVAL;
5473 }
5474
Atul Mittal115287b2014-07-08 13:26:33 +05305475 status = wlan_hdd_validate_context(pHddCtx);
5476 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305478 return -EINVAL;
5479 }
5480 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305482 return -ENOTSUPP;
5483 }
5484 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5485 data, data_len,
5486 wlan_hdd_tdls_config_disable_policy)) {
5487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5488 return -EINVAL;
5489 }
5490 /* Parse and fetch mac address */
5491 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5493 return -EINVAL;
5494 }
5495
5496 memcpy(peer, nla_data(
5497 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5498 sizeof(peer));
5499 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5500
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305501 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5502
5503 EXIT();
5504 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305505}
5506
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305507static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5508 struct wireless_dev *wdev,
5509 const void *data,
5510 int data_len)
5511{
5512 int ret = 0;
5513
5514 vos_ssr_protect(__func__);
5515 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5516 vos_ssr_unprotect(__func__);
5517
5518 return ret;
5519}
5520
Dasari Srinivas7875a302014-09-26 17:50:57 +05305521static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305522__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305523 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305524 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305525{
5526 struct net_device *dev = wdev->netdev;
5527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5529 struct sk_buff *skb = NULL;
5530 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305531 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305533 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305534
5535 ret = wlan_hdd_validate_context(pHddCtx);
5536 if (0 != ret)
5537 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305538 return ret;
5539 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305540 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5541 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5542 fset |= WIFI_FEATURE_INFRA;
5543 }
5544
5545 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5546 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5547 fset |= WIFI_FEATURE_INFRA_5G;
5548 }
5549
5550#ifdef WLAN_FEATURE_P2P
5551 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5552 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5553 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5554 fset |= WIFI_FEATURE_P2P;
5555 }
5556#endif
5557
5558 /* Soft-AP is supported currently by default */
5559 fset |= WIFI_FEATURE_SOFT_AP;
5560
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305561 /* HOTSPOT is a supplicant feature, enable it by default */
5562 fset |= WIFI_FEATURE_HOTSPOT;
5563
Dasari Srinivas7875a302014-09-26 17:50:57 +05305564#ifdef WLAN_FEATURE_EXTSCAN
5565 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305566 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5567 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5568 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305569 fset |= WIFI_FEATURE_EXTSCAN;
5570 }
5571#endif
5572
Dasari Srinivas7875a302014-09-26 17:50:57 +05305573 if (sme_IsFeatureSupportedByFW(NAN)) {
5574 hddLog(LOG1, FL("NAN is supported by firmware"));
5575 fset |= WIFI_FEATURE_NAN;
5576 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577
5578 /* D2D RTT is not supported currently by default */
5579 if (sme_IsFeatureSupportedByFW(RTT)) {
5580 hddLog(LOG1, FL("RTT is supported by firmware"));
5581 fset |= WIFI_FEATURE_D2AP_RTT;
5582 }
5583
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305584 if (sme_IsFeatureSupportedByFW(RTT3)) {
5585 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5586 fset |= WIFI_FEATURE_RTT3;
5587 }
5588
Dasari Srinivas7875a302014-09-26 17:50:57 +05305589#ifdef FEATURE_WLAN_BATCH_SCAN
5590 if (fset & WIFI_FEATURE_EXTSCAN) {
5591 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5592 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5593 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5594 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5595 fset |= WIFI_FEATURE_BATCH_SCAN;
5596 }
5597#endif
5598
5599#ifdef FEATURE_WLAN_SCAN_PNO
5600 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5601 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5602 hddLog(LOG1, FL("PNO is supported by firmware"));
5603 fset |= WIFI_FEATURE_PNO;
5604 }
5605#endif
5606
5607 /* STA+STA is supported currently by default */
5608 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5609
5610#ifdef FEATURE_WLAN_TDLS
5611 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5612 sme_IsFeatureSupportedByFW(TDLS)) {
5613 hddLog(LOG1, FL("TDLS is supported by firmware"));
5614 fset |= WIFI_FEATURE_TDLS;
5615 }
5616
5617 /* TDLS_OFFCHANNEL is not supported currently by default */
5618#endif
5619
5620#ifdef WLAN_AP_STA_CONCURRENCY
5621 /* AP+STA concurrency is supported currently by default */
5622 fset |= WIFI_FEATURE_AP_STA;
5623#endif
5624
Mukul Sharma5add0532015-08-17 15:57:47 +05305625#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5626 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5627 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5628#endif
5629
Dasari Srinivas7875a302014-09-26 17:50:57 +05305630 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5631 NLMSG_HDRLEN);
5632
5633 if (!skb) {
5634 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5635 return -EINVAL;
5636 }
5637 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5638
5639 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5640 hddLog(LOGE, FL("nla put fail"));
5641 goto nla_put_failure;
5642 }
5643
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305644 ret = cfg80211_vendor_cmd_reply(skb);
5645 EXIT();
5646 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305647
5648nla_put_failure:
5649 kfree_skb(skb);
5650 return -EINVAL;
5651}
5652
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305653static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305654wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5655 struct wireless_dev *wdev,
5656 const void *data, int data_len)
5657{
5658 int ret = 0;
5659
5660 vos_ssr_protect(__func__);
5661 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5662 vos_ssr_unprotect(__func__);
5663
5664 return ret;
5665}
5666
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305667
5668static const struct
5669nla_policy
5670qca_wlan_vendor_wifi_logger_get_ring_data_policy
5671[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5672 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5673 = {.type = NLA_U32 },
5674};
5675
5676static int
5677 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5678 struct wireless_dev *wdev,
5679 const void *data,
5680 int data_len)
5681{
5682 int ret;
5683 VOS_STATUS status;
5684 uint32_t ring_id;
5685 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5686 struct nlattr *tb
5687 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5688
5689 ENTER();
5690
5691 ret = wlan_hdd_validate_context(hdd_ctx);
5692 if (0 != ret) {
5693 return ret;
5694 }
5695
5696 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5697 data, data_len,
5698 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5699 hddLog(LOGE, FL("Invalid attribute"));
5700 return -EINVAL;
5701 }
5702
5703 /* Parse and fetch ring id */
5704 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5705 hddLog(LOGE, FL("attr ATTR failed"));
5706 return -EINVAL;
5707 }
5708
5709 ring_id = nla_get_u32(
5710 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5711
5712 hddLog(LOG1, FL("Bug report triggered by framework"));
5713
5714 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5715 WLAN_LOG_INDICATOR_FRAMEWORK,
5716 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305717 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305718 );
5719 if (VOS_STATUS_SUCCESS != status) {
5720 hddLog(LOGE, FL("Failed to trigger bug report"));
5721
5722 return -EINVAL;
5723 }
5724
5725 return 0;
5726
5727
5728}
5729
5730
5731static int
5732 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5733 struct wireless_dev *wdev,
5734 const void *data,
5735 int data_len)
5736{
5737 int ret = 0;
5738
5739 vos_ssr_protect(__func__);
5740 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5741 wdev, data, data_len);
5742 vos_ssr_unprotect(__func__);
5743
5744 return ret;
5745
5746}
5747
5748
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305749static int
5750__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305751 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305752 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305753{
5754 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5755 uint8_t i, feature_sets, max_feature_sets;
5756 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5757 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305758 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5759 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760
5761 ENTER();
5762
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305763 ret = wlan_hdd_validate_context(pHddCtx);
5764 if (0 != ret)
5765 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305766 return ret;
5767 }
5768
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5770 data, data_len, NULL)) {
5771 hddLog(LOGE, FL("Invalid ATTR"));
5772 return -EINVAL;
5773 }
5774
5775 /* Parse and fetch max feature set */
5776 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5777 hddLog(LOGE, FL("Attr max feature set size failed"));
5778 return -EINVAL;
5779 }
5780 max_feature_sets = nla_get_u32(
5781 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5782 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5783
5784 /* Fill feature combination matrix */
5785 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305786 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5787 WIFI_FEATURE_P2P;
5788
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_SOFT_AP;
5791
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305792 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5793 WIFI_FEATURE_SOFT_AP;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5796 WIFI_FEATURE_SOFT_AP |
5797 WIFI_FEATURE_P2P;
5798
5799 /* Add more feature combinations here */
5800
5801 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5802 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5803 hddLog(LOG1, "Feature set matrix");
5804 for (i = 0; i < feature_sets; i++)
5805 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5806
5807 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5808 sizeof(u32) * feature_sets +
5809 NLMSG_HDRLEN);
5810
5811 if (reply_skb) {
5812 if (nla_put_u32(reply_skb,
5813 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5814 feature_sets) ||
5815 nla_put(reply_skb,
5816 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5817 sizeof(u32) * feature_sets, feature_set_matrix)) {
5818 hddLog(LOGE, FL("nla put fail"));
5819 kfree_skb(reply_skb);
5820 return -EINVAL;
5821 }
5822
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305823 ret = cfg80211_vendor_cmd_reply(reply_skb);
5824 EXIT();
5825 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305826 }
5827 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5828 return -ENOMEM;
5829
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305830}
5831
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305832static int
5833wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5834 struct wireless_dev *wdev,
5835 const void *data, int data_len)
5836{
5837 int ret = 0;
5838
5839 vos_ssr_protect(__func__);
5840 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5841 data_len);
5842 vos_ssr_unprotect(__func__);
5843
5844 return ret;
5845}
5846
c_manjeecfd1efb2015-09-25 19:32:34 +05305847
5848static int
5849__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5850 struct wireless_dev *wdev,
5851 const void *data, int data_len)
5852{
5853 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5854 int ret;
5855 ENTER();
5856
5857 ret = wlan_hdd_validate_context(pHddCtx);
5858 if (0 != ret)
5859 {
5860 return ret;
5861 }
5862
5863 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5864 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5865 {
5866 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5867 return -EINVAL;
5868 }
5869 /*call common API for FW mem dump req*/
5870 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5871
Abhishek Singhc783fa72015-12-09 18:07:34 +05305872 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305873 {
5874 /*indicate to userspace the status of fw mem dump */
5875 wlan_indicate_mem_dump_complete(true);
5876 }
5877 else
5878 {
5879 /*else send failure to userspace */
5880 wlan_indicate_mem_dump_complete(false);
5881 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305882 EXIT();
5883 return ret;
5884}
5885
5886/**
5887 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5888 * @wiphy: pointer to wireless wiphy structure.
5889 * @wdev: pointer to wireless_dev structure.
5890 * @data: Pointer to the NL data.
5891 * @data_len:Length of @data
5892 *
5893 * This is called when wlan driver needs to get the firmware memory dump
5894 * via vendor specific command.
5895 *
5896 * Return: 0 on success, error number otherwise.
5897 */
5898
5899static int
5900wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5901 struct wireless_dev *wdev,
5902 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305903{
5904 int ret = 0;
5905 vos_ssr_protect(__func__);
5906 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5907 data_len);
5908 vos_ssr_unprotect(__func__);
5909 return ret;
5910}
c_manjeecfd1efb2015-09-25 19:32:34 +05305911
Sushant Kaushik8e644982015-09-23 12:18:54 +05305912static const struct
5913nla_policy
5914qca_wlan_vendor_wifi_logger_start_policy
5915[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5916 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5917 = {.type = NLA_U32 },
5918 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5919 = {.type = NLA_U32 },
5920 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5921 = {.type = NLA_U32 },
5922};
5923
5924/**
5925 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5926 * or disable the collection of packet statistics from the firmware
5927 * @wiphy: WIPHY structure pointer
5928 * @wdev: Wireless device structure pointer
5929 * @data: Pointer to the data received
5930 * @data_len: Length of the data received
5931 *
5932 * This function is used to enable or disable the collection of packet
5933 * statistics from the firmware
5934 *
5935 * Return: 0 on success and errno on failure
5936 */
5937static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5938 struct wireless_dev *wdev,
5939 const void *data,
5940 int data_len)
5941{
5942 eHalStatus status;
5943 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5944 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5945 tAniWifiStartLog start_log;
5946
5947 status = wlan_hdd_validate_context(hdd_ctx);
5948 if (0 != status) {
5949 return -EINVAL;
5950 }
5951
5952 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5953 data, data_len,
5954 qca_wlan_vendor_wifi_logger_start_policy)) {
5955 hddLog(LOGE, FL("Invalid attribute"));
5956 return -EINVAL;
5957 }
5958
5959 /* Parse and fetch ring id */
5960 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5961 hddLog(LOGE, FL("attr ATTR failed"));
5962 return -EINVAL;
5963 }
5964 start_log.ringId = nla_get_u32(
5965 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5966 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5967
5968 /* Parse and fetch verbose level */
5969 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5970 hddLog(LOGE, FL("attr verbose_level failed"));
5971 return -EINVAL;
5972 }
5973 start_log.verboseLevel = nla_get_u32(
5974 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5975 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5976
5977 /* Parse and fetch flag */
5978 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5979 hddLog(LOGE, FL("attr flag failed"));
5980 return -EINVAL;
5981 }
5982 start_log.flag = nla_get_u32(
5983 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5984 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5985
5986 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305987 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5988 !vos_isPktStatsEnabled()))
5989
Sushant Kaushik8e644982015-09-23 12:18:54 +05305990 {
5991 hddLog(LOGE, FL("per pkt stats not enabled"));
5992 return -EINVAL;
5993 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305994
Sushant Kaushik33200572015-08-05 16:46:20 +05305995 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305996 return 0;
5997}
5998
5999/**
6000 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6001 * or disable the collection of packet statistics from the firmware
6002 * @wiphy: WIPHY structure pointer
6003 * @wdev: Wireless device structure pointer
6004 * @data: Pointer to the data received
6005 * @data_len: Length of the data received
6006 *
6007 * This function is used to enable or disable the collection of packet
6008 * statistics from the firmware
6009 *
6010 * Return: 0 on success and errno on failure
6011 */
6012static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6013 struct wireless_dev *wdev,
6014 const void *data,
6015 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306016{
6017 int ret = 0;
6018
6019 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306020
6021 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6022 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306023 vos_ssr_unprotect(__func__);
6024
6025 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306026}
6027
6028
Agarwal Ashish738843c2014-09-25 12:27:56 +05306029static const struct nla_policy
6030wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6031 +1] =
6032{
6033 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6034};
6035
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306036static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306037 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306038 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306039 int data_len)
6040{
6041 struct net_device *dev = wdev->netdev;
6042 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6043 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6044 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6045 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6046 eHalStatus status;
6047 u32 dfsFlag = 0;
6048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306049 ENTER();
6050
Agarwal Ashish738843c2014-09-25 12:27:56 +05306051 status = wlan_hdd_validate_context(pHddCtx);
6052 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306053 return -EINVAL;
6054 }
6055 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6056 data, data_len,
6057 wlan_hdd_set_no_dfs_flag_config_policy)) {
6058 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6059 return -EINVAL;
6060 }
6061
6062 /* Parse and fetch required bandwidth kbps */
6063 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6065 return -EINVAL;
6066 }
6067
6068 dfsFlag = nla_get_u32(
6069 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6070 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6071 dfsFlag);
6072
6073 pHddCtx->disable_dfs_flag = dfsFlag;
6074
6075 sme_disable_dfs_channel(hHal, dfsFlag);
6076 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306077
6078 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306079 return 0;
6080}
Atul Mittal115287b2014-07-08 13:26:33 +05306081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306082static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6083 struct wireless_dev *wdev,
6084 const void *data,
6085 int data_len)
6086{
6087 int ret = 0;
6088
6089 vos_ssr_protect(__func__);
6090 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6091 vos_ssr_unprotect(__func__);
6092
6093 return ret;
6094
6095}
6096
Mukul Sharma2a271632014-10-13 14:59:01 +05306097const struct
6098nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6099{
6100 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6101 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6102};
6103
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306104static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306105 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306106{
6107
6108 u8 bssid[6] = {0};
6109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6111 eHalStatus status = eHAL_STATUS_SUCCESS;
6112 v_U32_t isFwrRoamEnabled = FALSE;
6113 int ret;
6114
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306115 ENTER();
6116
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306117 ret = wlan_hdd_validate_context(pHddCtx);
6118 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306119 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306120 }
6121
6122 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6123 data, data_len,
6124 qca_wlan_vendor_attr);
6125 if (ret){
6126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6127 return -EINVAL;
6128 }
6129
6130 /* Parse and fetch Enable flag */
6131 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6133 return -EINVAL;
6134 }
6135
6136 isFwrRoamEnabled = nla_get_u32(
6137 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6138
6139 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6140
6141 /* Parse and fetch bssid */
6142 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6144 return -EINVAL;
6145 }
6146
6147 memcpy(bssid, nla_data(
6148 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6149 sizeof(bssid));
6150 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6151
6152 //Update roaming
6153 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306154 if (!HAL_STATUS_SUCCESS(status)) {
6155 hddLog(LOGE,
6156 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6157 return -EINVAL;
6158 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306159 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306160 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306161}
6162
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306163static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6164 struct wireless_dev *wdev, const void *data, int data_len)
6165{
6166 int ret = 0;
6167
6168 vos_ssr_protect(__func__);
6169 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6170 vos_ssr_unprotect(__func__);
6171
6172 return ret;
6173}
6174
Sushant Kaushik847890c2015-09-28 16:05:17 +05306175static const struct
6176nla_policy
6177qca_wlan_vendor_get_wifi_info_policy[
6178 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6179 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6180 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6181};
6182
6183
6184/**
6185 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6186 * @wiphy: pointer to wireless wiphy structure.
6187 * @wdev: pointer to wireless_dev structure.
6188 * @data: Pointer to the data to be passed via vendor interface
6189 * @data_len:Length of the data to be passed
6190 *
6191 * This is called when wlan driver needs to send wifi driver related info
6192 * (driver/fw version) to the user space application upon request.
6193 *
6194 * Return: Return the Success or Failure code.
6195 */
6196static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6197 struct wireless_dev *wdev,
6198 const void *data, int data_len)
6199{
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6202 tSirVersionString version;
6203 uint32 version_len;
6204 uint8 attr;
6205 int status;
6206 struct sk_buff *reply_skb = NULL;
6207
6208 if (VOS_FTM_MODE == hdd_get_conparam()) {
6209 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6210 return -EINVAL;
6211 }
6212
6213 status = wlan_hdd_validate_context(hdd_ctx);
6214 if (0 != status) {
6215 hddLog(LOGE, FL("HDD context is not valid"));
6216 return -EINVAL;
6217 }
6218
6219 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6220 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6221 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6222 return -EINVAL;
6223 }
6224
6225 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6226 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6227 QWLAN_VERSIONSTR);
6228 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6229 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6230 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6231 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6232 hdd_ctx->fw_Version);
6233 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6234 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6235 } else {
6236 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6237 return -EINVAL;
6238 }
6239
6240 version_len = strlen(version);
6241 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6242 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6243 if (!reply_skb) {
6244 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6245 return -ENOMEM;
6246 }
6247
6248 if (nla_put(reply_skb, attr, version_len, version)) {
6249 hddLog(LOGE, FL("nla put fail"));
6250 kfree_skb(reply_skb);
6251 return -EINVAL;
6252 }
6253
6254 return cfg80211_vendor_cmd_reply(reply_skb);
6255}
6256
6257/**
6258 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6259 * @wiphy: pointer to wireless wiphy structure.
6260 * @wdev: pointer to wireless_dev structure.
6261 * @data: Pointer to the data to be passed via vendor interface
6262 * @data_len:Length of the data to be passed
6263 * @data_len: Length of the data received
6264 *
6265 * This function is used to enable or disable the collection of packet
6266 * statistics from the firmware
6267 *
6268 * Return: 0 on success and errno on failure
6269 */
6270
6271static int
6272wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6273 struct wireless_dev *wdev,
6274 const void *data, int data_len)
6275
6276
6277{
6278 int ret = 0;
6279
6280 vos_ssr_protect(__func__);
6281 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6282 wdev, data, data_len);
6283 vos_ssr_unprotect(__func__);
6284
6285 return ret;
6286}
6287
6288
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306289/*
6290 * define short names for the global vendor params
6291 * used by __wlan_hdd_cfg80211_monitor_rssi()
6292 */
6293#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6294#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6295#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6296#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6297#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6298
6299/**---------------------------------------------------------------------------
6300
6301 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6302 monitor start is completed successfully.
6303
6304 \return - None
6305
6306 --------------------------------------------------------------------------*/
6307void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6308{
6309 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6310
6311 if (NULL == pHddCtx)
6312 {
6313 hddLog(VOS_TRACE_LEVEL_ERROR,
6314 "%s: HDD context is NULL",__func__);
6315 return;
6316 }
6317
6318 if (VOS_STATUS_SUCCESS == status)
6319 {
6320 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6321 }
6322 else
6323 {
6324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6325 }
6326
6327 return;
6328}
6329
6330/**---------------------------------------------------------------------------
6331
6332 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6333 stop is completed successfully.
6334
6335 \return - None
6336
6337 --------------------------------------------------------------------------*/
6338void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6339{
6340 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6341
6342 if (NULL == pHddCtx)
6343 {
6344 hddLog(VOS_TRACE_LEVEL_ERROR,
6345 "%s: HDD context is NULL",__func__);
6346 return;
6347 }
6348
6349 if (VOS_STATUS_SUCCESS == status)
6350 {
6351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6352 }
6353 else
6354 {
6355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6356 }
6357
6358 return;
6359}
6360
6361/**
6362 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6363 * @wiphy: Pointer to wireless phy
6364 * @wdev: Pointer to wireless device
6365 * @data: Pointer to data
6366 * @data_len: Data length
6367 *
6368 * Return: 0 on success, negative errno on failure
6369 */
6370
6371static int
6372__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6373 struct wireless_dev *wdev,
6374 const void *data,
6375 int data_len)
6376{
6377 struct net_device *dev = wdev->netdev;
6378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6379 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6380 hdd_station_ctx_t *pHddStaCtx;
6381 struct nlattr *tb[PARAM_MAX + 1];
6382 tpSirRssiMonitorReq pReq;
6383 eHalStatus status;
6384 int ret;
6385 uint32_t control;
6386 static const struct nla_policy policy[PARAM_MAX + 1] = {
6387 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6388 [PARAM_CONTROL] = { .type = NLA_U32 },
6389 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6390 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6391 };
6392
6393 ENTER();
6394
6395 ret = wlan_hdd_validate_context(hdd_ctx);
6396 if (0 != ret) {
6397 return -EINVAL;
6398 }
6399
6400 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6401 hddLog(LOGE, FL("Not in Connected state!"));
6402 return -ENOTSUPP;
6403 }
6404
6405 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6406 hddLog(LOGE, FL("Invalid ATTR"));
6407 return -EINVAL;
6408 }
6409
6410 if (!tb[PARAM_REQUEST_ID]) {
6411 hddLog(LOGE, FL("attr request id failed"));
6412 return -EINVAL;
6413 }
6414
6415 if (!tb[PARAM_CONTROL]) {
6416 hddLog(LOGE, FL("attr control failed"));
6417 return -EINVAL;
6418 }
6419
6420 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6421
6422 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6423 if(NULL == pReq)
6424 {
6425 hddLog(LOGE,
6426 FL("vos_mem_alloc failed "));
6427 return eHAL_STATUS_FAILED_ALLOC;
6428 }
6429 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6430
6431 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6432 pReq->sessionId = pAdapter->sessionId;
6433 pReq->rssiMonitorCbContext = hdd_ctx;
6434 control = nla_get_u32(tb[PARAM_CONTROL]);
6435 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6436
6437 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6438 pReq->requestId, pReq->sessionId, control);
6439
6440 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6441 if (!tb[PARAM_MIN_RSSI]) {
6442 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306443 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306444 }
6445
6446 if (!tb[PARAM_MAX_RSSI]) {
6447 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306448 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306449 }
6450
6451 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6452 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6453 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6454
6455 if (!(pReq->minRssi < pReq->maxRssi)) {
6456 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6457 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306458 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306459 }
6460 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6461 pReq->minRssi, pReq->maxRssi);
6462 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6463
6464 }
6465 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6466 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6467 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6468 }
6469 else {
6470 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306471 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306472 }
6473
6474 if (!HAL_STATUS_SUCCESS(status)) {
6475 hddLog(LOGE,
6476 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306477 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306478 }
6479
6480 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306481fail:
6482 vos_mem_free(pReq);
6483 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306484}
6485
6486/*
6487 * done with short names for the global vendor params
6488 * used by __wlan_hdd_cfg80211_monitor_rssi()
6489 */
6490#undef PARAM_MAX
6491#undef PARAM_CONTROL
6492#undef PARAM_REQUEST_ID
6493#undef PARAM_MAX_RSSI
6494#undef PARAM_MIN_RSSI
6495
6496/**
6497 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6498 * @wiphy: wiphy structure pointer
6499 * @wdev: Wireless device structure pointer
6500 * @data: Pointer to the data received
6501 * @data_len: Length of @data
6502 *
6503 * Return: 0 on success; errno on failure
6504 */
6505static int
6506wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6507 const void *data, int data_len)
6508{
6509 int ret;
6510
6511 vos_ssr_protect(__func__);
6512 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6513 vos_ssr_unprotect(__func__);
6514
6515 return ret;
6516}
6517
6518/**
6519 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6520 * @hddctx: HDD context
6521 * @data: rssi breached event data
6522 *
6523 * This function reads the rssi breached event %data and fill in the skb with
6524 * NL attributes and send up the NL event.
6525 * This callback execute in atomic context and must not invoke any
6526 * blocking calls.
6527 *
6528 * Return: none
6529 */
6530void hdd_rssi_threshold_breached_cb(void *hddctx,
6531 struct rssi_breach_event *data)
6532{
6533 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6534 int status;
6535 struct sk_buff *skb;
6536
6537 ENTER();
6538 status = wlan_hdd_validate_context(pHddCtx);
6539
6540 if (0 != status) {
6541 return;
6542 }
6543
6544 if (!data) {
6545 hddLog(LOGE, FL("data is null"));
6546 return;
6547 }
6548
6549 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6551 NULL,
6552#endif
6553 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6554 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6555 GFP_KERNEL);
6556
6557 if (!skb) {
6558 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6559 return;
6560 }
6561
6562 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6563 data->request_id, data->curr_rssi);
6564 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6565 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6566
6567 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6568 data->request_id) ||
6569 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6570 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6571 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6572 data->curr_rssi)) {
6573 hddLog(LOGE, FL("nla put fail"));
6574 goto fail;
6575 }
6576
6577 cfg80211_vendor_event(skb, GFP_KERNEL);
6578 return;
6579
6580fail:
6581 kfree_skb(skb);
6582 return;
6583}
6584
6585
6586
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306587/**
6588 * __wlan_hdd_cfg80211_setband() - set band
6589 * @wiphy: Pointer to wireless phy
6590 * @wdev: Pointer to wireless device
6591 * @data: Pointer to data
6592 * @data_len: Data length
6593 *
6594 * Return: 0 on success, negative errno on failure
6595 */
6596static int
6597__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6598 struct wireless_dev *wdev,
6599 const void *data,
6600 int data_len)
6601{
6602 struct net_device *dev = wdev->netdev;
6603 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6604 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6605 int ret;
6606 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6607 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6608
6609 ENTER();
6610
6611 ret = wlan_hdd_validate_context(hdd_ctx);
6612 if (0 != ret) {
6613 hddLog(LOGE, FL("HDD context is not valid"));
6614 return ret;
6615 }
6616
6617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6618 policy)) {
6619 hddLog(LOGE, FL("Invalid ATTR"));
6620 return -EINVAL;
6621 }
6622
6623 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6624 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6625 return -EINVAL;
6626 }
6627
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306628 hdd_ctx->isSetBandByNL = TRUE;
6629 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306630 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306631 hdd_ctx->isSetBandByNL = FALSE;
6632
6633 EXIT();
6634 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306635}
6636
6637/**
6638 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6639 * @wiphy: wiphy structure pointer
6640 * @wdev: Wireless device structure pointer
6641 * @data: Pointer to the data received
6642 * @data_len: Length of @data
6643 *
6644 * Return: 0 on success; errno on failure
6645 */
6646static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6647 struct wireless_dev *wdev,
6648 const void *data,
6649 int data_len)
6650{
6651 int ret = 0;
6652
6653 vos_ssr_protect(__func__);
6654 ret = __wlan_hdd_cfg80211_setband(wiphy,
6655 wdev, data, data_len);
6656 vos_ssr_unprotect(__func__);
6657
6658 return ret;
6659}
6660
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306661#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6662/**
6663 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6664 * @hdd_ctx: HDD context
6665 * @request_id: [input] request id
6666 * @pattern_id: [output] pattern id
6667 *
6668 * This function loops through request id to pattern id array
6669 * if the slot is available, store the request id and return pattern id
6670 * if entry exists, return the pattern id
6671 *
6672 * Return: 0 on success and errno on failure
6673 */
6674static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6675 uint32_t request_id,
6676 uint8_t *pattern_id)
6677{
6678 uint32_t i;
6679
6680 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6681 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6682 {
6683 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6684 {
6685 hdd_ctx->op_ctx.op_table[i].request_id = 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 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6690 request_id) {
6691 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6692 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6693 return 0;
6694 }
6695 }
6696 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6697 return -EINVAL;
6698}
6699
6700/**
6701 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6702 * @hdd_ctx: HDD context
6703 * @request_id: [input] request id
6704 * @pattern_id: [output] pattern id
6705 *
6706 * This function loops through request id to pattern id array
6707 * reset request id to 0 (slot available again) and
6708 * return pattern id
6709 *
6710 * Return: 0 on success and errno on failure
6711 */
6712static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6713 uint32_t request_id,
6714 uint8_t *pattern_id)
6715{
6716 uint32_t i;
6717
6718 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6719 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6720 {
6721 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6722 {
6723 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6724 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6725 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6726 return 0;
6727 }
6728 }
6729 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6730 return -EINVAL;
6731}
6732
6733
6734/*
6735 * define short names for the global vendor params
6736 * used by __wlan_hdd_cfg80211_offloaded_packets()
6737 */
6738#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6739#define PARAM_REQUEST_ID \
6740 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6741#define PARAM_CONTROL \
6742 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6743#define PARAM_IP_PACKET \
6744 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6745#define PARAM_SRC_MAC_ADDR \
6746 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6747#define PARAM_DST_MAC_ADDR \
6748 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6749#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6750
6751/**
6752 * wlan_hdd_add_tx_ptrn() - add tx pattern
6753 * @adapter: adapter pointer
6754 * @hdd_ctx: hdd context
6755 * @tb: nl attributes
6756 *
6757 * This function reads the NL attributes and forms a AddTxPtrn message
6758 * posts it to SME.
6759 *
6760 */
6761static int
6762wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6763 struct nlattr **tb)
6764{
6765 struct sSirAddPeriodicTxPtrn *add_req;
6766 eHalStatus status;
6767 uint32_t request_id, ret, len;
6768 uint8_t pattern_id = 0;
6769 v_MACADDR_t dst_addr;
6770 uint16_t eth_type = htons(ETH_P_IP);
6771
6772 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6773 {
6774 hddLog(LOGE, FL("Not in Connected state!"));
6775 return -ENOTSUPP;
6776 }
6777
6778 add_req = vos_mem_malloc(sizeof(*add_req));
6779 if (!add_req)
6780 {
6781 hddLog(LOGE, FL("memory allocation failed"));
6782 return -ENOMEM;
6783 }
6784
6785 /* Parse and fetch request Id */
6786 if (!tb[PARAM_REQUEST_ID])
6787 {
6788 hddLog(LOGE, FL("attr request id failed"));
6789 goto fail;
6790 }
6791
6792 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6793 hddLog(LOG1, FL("Request Id: %u"), request_id);
6794 if (request_id == 0)
6795 {
6796 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306797 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306798 }
6799
6800 if (!tb[PARAM_PERIOD])
6801 {
6802 hddLog(LOGE, FL("attr period failed"));
6803 goto fail;
6804 }
6805 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6806 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6807 if (add_req->usPtrnIntervalMs == 0)
6808 {
6809 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6810 goto fail;
6811 }
6812
6813 if (!tb[PARAM_SRC_MAC_ADDR])
6814 {
6815 hddLog(LOGE, FL("attr source mac address failed"));
6816 goto fail;
6817 }
6818 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6819 VOS_MAC_ADDR_SIZE);
6820 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6821 MAC_ADDR_ARRAY(add_req->macAddress));
6822
6823 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6824 VOS_MAC_ADDR_SIZE))
6825 {
6826 hddLog(LOGE,
6827 FL("input src mac address and connected ap bssid are different"));
6828 goto fail;
6829 }
6830
6831 if (!tb[PARAM_DST_MAC_ADDR])
6832 {
6833 hddLog(LOGE, FL("attr dst mac address failed"));
6834 goto fail;
6835 }
6836 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6837 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6838 MAC_ADDR_ARRAY(dst_addr.bytes));
6839
6840 if (!tb[PARAM_IP_PACKET])
6841 {
6842 hddLog(LOGE, FL("attr ip packet failed"));
6843 goto fail;
6844 }
6845 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6846 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6847
6848 if (add_req->ucPtrnSize < 0 ||
6849 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6850 HDD_ETH_HEADER_LEN))
6851 {
6852 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6853 add_req->ucPtrnSize);
6854 goto fail;
6855 }
6856
6857 len = 0;
6858 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6859 len += VOS_MAC_ADDR_SIZE;
6860 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6861 VOS_MAC_ADDR_SIZE);
6862 len += VOS_MAC_ADDR_SIZE;
6863 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6864 len += 2;
6865
6866 /*
6867 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6868 * ------------------------------------------------------------
6869 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6870 * ------------------------------------------------------------
6871 */
6872 vos_mem_copy(&add_req->ucPattern[len],
6873 nla_data(tb[PARAM_IP_PACKET]),
6874 add_req->ucPtrnSize);
6875 add_req->ucPtrnSize += len;
6876
6877 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6878 add_req->ucPattern, add_req->ucPtrnSize);
6879
6880 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6881 if (ret)
6882 {
6883 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6884 goto fail;
6885 }
6886 add_req->ucPtrnId = pattern_id;
6887 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6888
6889 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6890 if (!HAL_STATUS_SUCCESS(status))
6891 {
6892 hddLog(LOGE,
6893 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6894 goto fail;
6895 }
6896
6897 EXIT();
6898 vos_mem_free(add_req);
6899 return 0;
6900
6901fail:
6902 vos_mem_free(add_req);
6903 return -EINVAL;
6904}
6905
6906/**
6907 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6908 * @adapter: adapter pointer
6909 * @hdd_ctx: hdd context
6910 * @tb: nl attributes
6911 *
6912 * This function reads the NL attributes and forms a DelTxPtrn message
6913 * posts it to SME.
6914 *
6915 */
6916static int
6917wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6918 struct nlattr **tb)
6919{
6920 struct sSirDelPeriodicTxPtrn *del_req;
6921 eHalStatus status;
6922 uint32_t request_id, ret;
6923 uint8_t pattern_id = 0;
6924
6925 /* Parse and fetch request Id */
6926 if (!tb[PARAM_REQUEST_ID])
6927 {
6928 hddLog(LOGE, FL("attr request id failed"));
6929 return -EINVAL;
6930 }
6931 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6932 if (request_id == 0)
6933 {
6934 hddLog(LOGE, FL("request_id cannot be zero"));
6935 return -EINVAL;
6936 }
6937
6938 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6939 if (ret)
6940 {
6941 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6942 return -EINVAL;
6943 }
6944
6945 del_req = vos_mem_malloc(sizeof(*del_req));
6946 if (!del_req)
6947 {
6948 hddLog(LOGE, FL("memory allocation failed"));
6949 return -ENOMEM;
6950 }
6951
6952 vos_mem_set(del_req, sizeof(*del_req), 0);
6953 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6954 VOS_MAC_ADDR_SIZE);
6955 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6956 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6957 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6958 request_id, pattern_id, del_req->ucPatternIdBitmap);
6959
6960 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6961 if (!HAL_STATUS_SUCCESS(status))
6962 {
6963 hddLog(LOGE,
6964 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6965 goto fail;
6966 }
6967
6968 EXIT();
6969 vos_mem_free(del_req);
6970 return 0;
6971
6972fail:
6973 vos_mem_free(del_req);
6974 return -EINVAL;
6975}
6976
6977
6978/**
6979 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6980 * @wiphy: Pointer to wireless phy
6981 * @wdev: Pointer to wireless device
6982 * @data: Pointer to data
6983 * @data_len: Data length
6984 *
6985 * Return: 0 on success, negative errno on failure
6986 */
6987static int
6988__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6989 struct wireless_dev *wdev,
6990 const void *data,
6991 int data_len)
6992{
6993 struct net_device *dev = wdev->netdev;
6994 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6995 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6996 struct nlattr *tb[PARAM_MAX + 1];
6997 uint8_t control;
6998 int ret;
6999 static const struct nla_policy policy[PARAM_MAX + 1] =
7000 {
7001 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7002 [PARAM_CONTROL] = { .type = NLA_U32 },
7003 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7004 .len = VOS_MAC_ADDR_SIZE },
7005 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7006 .len = VOS_MAC_ADDR_SIZE },
7007 [PARAM_PERIOD] = { .type = NLA_U32 },
7008 };
7009
7010 ENTER();
7011
7012 ret = wlan_hdd_validate_context(hdd_ctx);
7013 if (0 != ret)
7014 {
7015 hddLog(LOGE, FL("HDD context is not valid"));
7016 return ret;
7017 }
7018
7019 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7020 {
7021 hddLog(LOGE,
7022 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7023 return -ENOTSUPP;
7024 }
7025
7026 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7027 {
7028 hddLog(LOGE, FL("Invalid ATTR"));
7029 return -EINVAL;
7030 }
7031
7032 if (!tb[PARAM_CONTROL])
7033 {
7034 hddLog(LOGE, FL("attr control failed"));
7035 return -EINVAL;
7036 }
7037 control = nla_get_u32(tb[PARAM_CONTROL]);
7038 hddLog(LOG1, FL("Control: %d"), control);
7039
7040 if (control == WLAN_START_OFFLOADED_PACKETS)
7041 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7042 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7043 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7044 else
7045 {
7046 hddLog(LOGE, FL("Invalid control: %d"), control);
7047 return -EINVAL;
7048 }
7049}
7050
7051/*
7052 * done with short names for the global vendor params
7053 * used by __wlan_hdd_cfg80211_offloaded_packets()
7054 */
7055#undef PARAM_MAX
7056#undef PARAM_REQUEST_ID
7057#undef PARAM_CONTROL
7058#undef PARAM_IP_PACKET
7059#undef PARAM_SRC_MAC_ADDR
7060#undef PARAM_DST_MAC_ADDR
7061#undef PARAM_PERIOD
7062
7063/**
7064 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7065 * @wiphy: wiphy structure pointer
7066 * @wdev: Wireless device structure pointer
7067 * @data: Pointer to the data received
7068 * @data_len: Length of @data
7069 *
7070 * Return: 0 on success; errno on failure
7071 */
7072static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7073 struct wireless_dev *wdev,
7074 const void *data,
7075 int data_len)
7076{
7077 int ret = 0;
7078
7079 vos_ssr_protect(__func__);
7080 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7081 wdev, data, data_len);
7082 vos_ssr_unprotect(__func__);
7083
7084 return ret;
7085}
7086#endif
7087
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307088static const struct
7089nla_policy
7090qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7091 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7092};
7093
7094/**
7095 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7096 * get link properties like nss, rate flags and operating frequency for
7097 * the connection with the given peer.
7098 * @wiphy: WIPHY structure pointer
7099 * @wdev: Wireless device structure pointer
7100 * @data: Pointer to the data received
7101 * @data_len: Length of the data received
7102 *
7103 * This function return the above link properties on success.
7104 *
7105 * Return: 0 on success and errno on failure
7106 */
7107static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7108 struct wireless_dev *wdev,
7109 const void *data,
7110 int data_len)
7111{
7112 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7113 struct net_device *dev = wdev->netdev;
7114 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7115 hdd_station_ctx_t *hdd_sta_ctx;
7116 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7117 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7118 uint32_t sta_id;
7119 struct sk_buff *reply_skb;
7120 uint32_t rate_flags = 0;
7121 uint8_t nss;
7122 uint8_t final_rate_flags = 0;
7123 uint32_t freq;
7124 v_CONTEXT_t pVosContext = NULL;
7125 ptSapContext pSapCtx = NULL;
7126
7127 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7129 return -EINVAL;
7130 }
7131
7132 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7133 qca_wlan_vendor_attr_policy)) {
7134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7135 return -EINVAL;
7136 }
7137
7138 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7139 hddLog(VOS_TRACE_LEVEL_ERROR,
7140 FL("Attribute peerMac not provided for mode=%d"),
7141 adapter->device_mode);
7142 return -EINVAL;
7143 }
7144
7145 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7146 sizeof(peer_mac));
7147 hddLog(VOS_TRACE_LEVEL_INFO,
7148 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7149 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7150
7151 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7152 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7153 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7154 if ((hdd_sta_ctx->conn_info.connState !=
7155 eConnectionState_Associated) ||
7156 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7157 VOS_MAC_ADDRESS_LEN)) {
7158 hddLog(VOS_TRACE_LEVEL_ERROR,
7159 FL("Not Associated to mac "MAC_ADDRESS_STR),
7160 MAC_ADDR_ARRAY(peer_mac));
7161 return -EINVAL;
7162 }
7163
7164 nss = 1; //pronto supports only one spatial stream
7165 freq = vos_chan_to_freq(
7166 hdd_sta_ctx->conn_info.operationChannel);
7167 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7168
7169 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7170 adapter->device_mode == WLAN_HDD_SOFTAP) {
7171
7172 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7173 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7174 if(pSapCtx == NULL){
7175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7176 FL("psapCtx is NULL"));
7177 return -ENOENT;
7178 }
7179
7180
7181 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7182 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7183 !vos_is_macaddr_broadcast(
7184 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7185 vos_mem_compare(
7186 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7187 peer_mac, VOS_MAC_ADDRESS_LEN))
7188 break;
7189 }
7190
7191 if (WLAN_MAX_STA_COUNT == sta_id) {
7192 hddLog(VOS_TRACE_LEVEL_ERROR,
7193 FL("No active peer with mac="MAC_ADDRESS_STR),
7194 MAC_ADDR_ARRAY(peer_mac));
7195 return -EINVAL;
7196 }
7197
7198 nss = 1; //pronto supports only one spatial stream
7199 freq = vos_chan_to_freq(
7200 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7201 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7202 } else {
7203 hddLog(VOS_TRACE_LEVEL_ERROR,
7204 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7205 MAC_ADDR_ARRAY(peer_mac));
7206 return -EINVAL;
7207 }
7208
7209 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7210 if (rate_flags & eHAL_TX_RATE_VHT80) {
7211 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7212 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7213 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7214 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7215 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7216 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7217 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7218 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7219 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7220 if (rate_flags & eHAL_TX_RATE_HT40)
7221 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7222 }
7223
7224 if (rate_flags & eHAL_TX_RATE_SGI) {
7225 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7226 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7227 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7228 }
7229 }
7230
7231 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7232 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7233
7234 if (NULL == reply_skb) {
7235 hddLog(VOS_TRACE_LEVEL_ERROR,
7236 FL("getLinkProperties: skb alloc failed"));
7237 return -EINVAL;
7238 }
7239
7240 if (nla_put_u8(reply_skb,
7241 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7242 nss) ||
7243 nla_put_u8(reply_skb,
7244 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7245 final_rate_flags) ||
7246 nla_put_u32(reply_skb,
7247 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7248 freq)) {
7249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7250 kfree_skb(reply_skb);
7251 return -EINVAL;
7252 }
7253
7254 return cfg80211_vendor_cmd_reply(reply_skb);
7255}
7256
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307257#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7258#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7259#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7260#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307261#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7262 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307263
7264/**
7265 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7266 * vendor command
7267 *
7268 * @wiphy: wiphy device pointer
7269 * @wdev: wireless device pointer
7270 * @data: Vendor command data buffer
7271 * @data_len: Buffer length
7272 *
7273 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7274 *
7275 * Return: EOK or other error codes.
7276 */
7277
7278static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7279 struct wireless_dev *wdev,
7280 const void *data,
7281 int data_len)
7282{
7283 struct net_device *dev = wdev->netdev;
7284 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7285 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7286 hdd_station_ctx_t *pHddStaCtx;
7287 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7288 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307289 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307290 eHalStatus status;
7291 int ret_val;
7292 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7293 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7294 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307295 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7296 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7297 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307298 };
7299
7300 ENTER();
7301
7302 if (VOS_FTM_MODE == hdd_get_conparam()) {
7303 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7304 return -EINVAL;
7305 }
7306
7307 ret_val = wlan_hdd_validate_context(pHddCtx);
7308 if (ret_val) {
7309 return ret_val;
7310 }
7311
7312 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7313
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307314 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7315 hddLog(LOGE, FL("Invalid ATTR"));
7316 return -EINVAL;
7317 }
7318
7319 /* check the Wifi Capability */
7320 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7321 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7322 {
7323 hddLog(VOS_TRACE_LEVEL_ERROR,
7324 FL("WIFICONFIG not supported by Firmware"));
7325 return -EINVAL;
7326 }
7327
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307328 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7329 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7330 modifyRoamParamsReq.value =
7331 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7332
7333 if (eHAL_STATUS_SUCCESS !=
7334 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7335 {
7336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7337 ret_val = -EINVAL;
7338 }
7339 return ret_val;
7340 }
7341
7342 /* Moved this down in order to provide provision to set beacon
7343 * miss penalty count irrespective of connection state.
7344 */
7345 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7346 hddLog(LOGE, FL("Not in Connected state!"));
7347 return -ENOTSUPP;
7348 }
7349
7350 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307351
7352 if (!pReq) {
7353 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7354 "%s: Not able to allocate memory for tSetWifiConfigParams",
7355 __func__);
7356 return eHAL_STATUS_E_MALLOC_FAILED;
7357 }
7358
7359 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7360
7361 pReq->sessionId = pAdapter->sessionId;
7362 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7363
7364 if (tb[PARAM_MODULATED_DTIM]) {
7365 pReq->paramValue = nla_get_u32(
7366 tb[PARAM_MODULATED_DTIM]);
7367 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7368 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307369 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307370 hdd_set_pwrparams(pHddCtx);
7371 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7372 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7373
7374 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7375 iw_full_power_cbfn, pAdapter,
7376 eSME_FULL_PWR_NEEDED_BY_HDD);
7377 }
7378 else
7379 {
7380 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7381 }
7382 }
7383
7384 if (tb[PARAM_STATS_AVG_FACTOR]) {
7385 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7386 pReq->paramValue = nla_get_u16(
7387 tb[PARAM_STATS_AVG_FACTOR]);
7388 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7389 pReq->paramType, pReq->paramValue);
7390 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7391
7392 if (eHAL_STATUS_SUCCESS != status)
7393 {
7394 vos_mem_free(pReq);
7395 pReq = NULL;
7396 ret_val = -EPERM;
7397 return ret_val;
7398 }
7399 }
7400
7401
7402 if (tb[PARAM_GUARD_TIME]) {
7403 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7404 pReq->paramValue = nla_get_u32(
7405 tb[PARAM_GUARD_TIME]);
7406 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7407 pReq->paramType, pReq->paramValue);
7408 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7409
7410 if (eHAL_STATUS_SUCCESS != status)
7411 {
7412 vos_mem_free(pReq);
7413 pReq = NULL;
7414 ret_val = -EPERM;
7415 return ret_val;
7416 }
7417
7418 }
7419
7420 EXIT();
7421 return ret_val;
7422}
7423
7424/**
7425 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7426 * vendor command
7427 *
7428 * @wiphy: wiphy device pointer
7429 * @wdev: wireless device pointer
7430 * @data: Vendor command data buffer
7431 * @data_len: Buffer length
7432 *
7433 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7434 *
7435 * Return: EOK or other error codes.
7436 */
7437static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7438 struct wireless_dev *wdev,
7439 const void *data,
7440 int data_len)
7441{
7442 int ret;
7443
7444 vos_ssr_protect(__func__);
7445 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7446 data, data_len);
7447 vos_ssr_unprotect(__func__);
7448
7449 return ret;
7450}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307451const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7452{
Mukul Sharma2a271632014-10-13 14:59:01 +05307453 {
7454 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7455 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7456 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7457 WIPHY_VENDOR_CMD_NEED_NETDEV |
7458 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307459 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307460 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307461
7462 {
7463 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7464 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7465 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7466 WIPHY_VENDOR_CMD_NEED_NETDEV |
7467 WIPHY_VENDOR_CMD_NEED_RUNNING,
7468 .doit = wlan_hdd_cfg80211_nan_request
7469 },
7470
Sunil Duttc69bccb2014-05-26 21:30:20 +05307471#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7472 {
7473 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7474 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7475 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7476 WIPHY_VENDOR_CMD_NEED_NETDEV |
7477 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307478 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307479 },
7480
7481 {
7482 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7483 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7484 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7485 WIPHY_VENDOR_CMD_NEED_NETDEV |
7486 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307487 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307488 },
7489
7490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307496 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307497 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307498#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307499#ifdef WLAN_FEATURE_EXTSCAN
7500 {
7501 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7502 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7503 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7504 WIPHY_VENDOR_CMD_NEED_NETDEV |
7505 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307506 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307507 },
7508 {
7509 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7510 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7511 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7512 WIPHY_VENDOR_CMD_NEED_NETDEV |
7513 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307514 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307515 },
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307521 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307522 },
7523 {
7524 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7525 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7526 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7527 WIPHY_VENDOR_CMD_NEED_NETDEV |
7528 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307529 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307530 },
7531 {
7532 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7533 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7534 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7535 WIPHY_VENDOR_CMD_NEED_NETDEV |
7536 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307537 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307538 },
7539 {
7540 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7541 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7542 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7543 WIPHY_VENDOR_CMD_NEED_NETDEV |
7544 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307545 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307546 },
7547 {
7548 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7549 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7550 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7551 WIPHY_VENDOR_CMD_NEED_NETDEV |
7552 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307553 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307554 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307555 {
7556 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7557 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7558 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7559 WIPHY_VENDOR_CMD_NEED_NETDEV |
7560 WIPHY_VENDOR_CMD_NEED_RUNNING,
7561 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7562 },
7563 {
7564 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7565 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7566 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7567 WIPHY_VENDOR_CMD_NEED_NETDEV |
7568 WIPHY_VENDOR_CMD_NEED_RUNNING,
7569 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7570 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307571#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307572/*EXT TDLS*/
7573 {
7574 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7575 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7576 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7577 WIPHY_VENDOR_CMD_NEED_NETDEV |
7578 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307579 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307580 },
7581 {
7582 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7583 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7584 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7585 WIPHY_VENDOR_CMD_NEED_NETDEV |
7586 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307587 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307588 },
7589 {
7590 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7591 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7592 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7593 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307594 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307595 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307596 {
7597 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7598 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7599 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7600 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307601 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307602 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307603 {
7604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7607 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307608 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307609 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307610 {
7611 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7612 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7613 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7614 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307615 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307616 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307617 {
7618 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7619 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7620 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7621 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307622 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307623 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307624 {
7625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7628 WIPHY_VENDOR_CMD_NEED_NETDEV |
7629 WIPHY_VENDOR_CMD_NEED_RUNNING,
7630 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7631 },
7632 {
7633 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307634 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7635 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7636 WIPHY_VENDOR_CMD_NEED_NETDEV |
7637 WIPHY_VENDOR_CMD_NEED_RUNNING,
7638 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307639 },
7640 {
7641 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7642 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7643 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7644 WIPHY_VENDOR_CMD_NEED_NETDEV,
7645 .doit = wlan_hdd_cfg80211_wifi_logger_start
7646 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307647 {
7648 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7649 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7650 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7651 WIPHY_VENDOR_CMD_NEED_NETDEV|
7652 WIPHY_VENDOR_CMD_NEED_RUNNING,
7653 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307654 },
7655 {
7656 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7657 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7658 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7659 WIPHY_VENDOR_CMD_NEED_NETDEV |
7660 WIPHY_VENDOR_CMD_NEED_RUNNING,
7661 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307662 },
7663 {
7664 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7665 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7666 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7667 WIPHY_VENDOR_CMD_NEED_NETDEV |
7668 WIPHY_VENDOR_CMD_NEED_RUNNING,
7669 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307670 },
7671#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7672 {
7673 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7674 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7675 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7676 WIPHY_VENDOR_CMD_NEED_NETDEV |
7677 WIPHY_VENDOR_CMD_NEED_RUNNING,
7678 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307679 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307680#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 {
7682 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7683 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7684 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7685 WIPHY_VENDOR_CMD_NEED_NETDEV |
7686 WIPHY_VENDOR_CMD_NEED_RUNNING,
7687 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307688 },
7689 {
7690 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7691 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7692 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7693 WIPHY_VENDOR_CMD_NEED_NETDEV |
7694 WIPHY_VENDOR_CMD_NEED_RUNNING,
7695 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307696 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307697};
7698
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007699/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307700static const
7701struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007702{
7703#ifdef FEATURE_WLAN_CH_AVOID
7704 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307705 .vendor_id = QCA_NL80211_VENDOR_ID,
7706 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007707 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307708#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7709#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7710 {
7711 /* Index = 1*/
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7714 },
7715 {
7716 /* Index = 2*/
7717 .vendor_id = QCA_NL80211_VENDOR_ID,
7718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7719 },
7720 {
7721 /* Index = 3*/
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7724 },
7725 {
7726 /* Index = 4*/
7727 .vendor_id = QCA_NL80211_VENDOR_ID,
7728 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7729 },
7730 {
7731 /* Index = 5*/
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7734 },
7735 {
7736 /* Index = 6*/
7737 .vendor_id = QCA_NL80211_VENDOR_ID,
7738 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7739 },
7740#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307741#ifdef WLAN_FEATURE_EXTSCAN
7742 {
7743 .vendor_id = QCA_NL80211_VENDOR_ID,
7744 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7745 },
7746 {
7747 .vendor_id = QCA_NL80211_VENDOR_ID,
7748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7749 },
7750 {
7751 .vendor_id = QCA_NL80211_VENDOR_ID,
7752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7753 },
7754 {
7755 .vendor_id = QCA_NL80211_VENDOR_ID,
7756 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7757 },
7758 {
7759 .vendor_id = QCA_NL80211_VENDOR_ID,
7760 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7761 },
7762 {
7763 .vendor_id = QCA_NL80211_VENDOR_ID,
7764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7765 },
7766 {
7767 .vendor_id = QCA_NL80211_VENDOR_ID,
7768 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7769 },
7770 {
7771 .vendor_id = QCA_NL80211_VENDOR_ID,
7772 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7773 },
7774 {
7775 .vendor_id = QCA_NL80211_VENDOR_ID,
7776 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7777 },
7778 {
7779 .vendor_id = QCA_NL80211_VENDOR_ID,
7780 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7781 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307782 {
7783 .vendor_id = QCA_NL80211_VENDOR_ID,
7784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7785 },
7786 {
7787 .vendor_id = QCA_NL80211_VENDOR_ID,
7788 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7789 },
7790 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7791 .vendor_id = QCA_NL80211_VENDOR_ID,
7792 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7793 },
7794 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7795 .vendor_id = QCA_NL80211_VENDOR_ID,
7796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7797 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307798#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307799/*EXT TDLS*/
7800 {
7801 .vendor_id = QCA_NL80211_VENDOR_ID,
7802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7803 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307804 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7805 .vendor_id = QCA_NL80211_VENDOR_ID,
7806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7807 },
7808
Srinivas Dasari030bad32015-02-18 23:23:54 +05307809
7810 {
7811 .vendor_id = QCA_NL80211_VENDOR_ID,
7812 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7813 },
7814
Sushant Kaushik084f6592015-09-10 13:11:56 +05307815 {
7816 .vendor_id = QCA_NL80211_VENDOR_ID,
7817 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307818 },
7819 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7820 .vendor_id = QCA_NL80211_VENDOR_ID,
7821 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7822 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307823 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7824 .vendor_id = QCA_NL80211_VENDOR_ID,
7825 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7826 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307827
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007828};
7829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307831 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307832 * This function is called by hdd_wlan_startup()
7833 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307834 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307836struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007837{
7838 struct wiphy *wiphy;
7839 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307840 /*
7841 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 */
7843 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7844
7845 if (!wiphy)
7846 {
7847 /* Print error and jump into err label and free the memory */
7848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7849 return NULL;
7850 }
7851
Sunil Duttc69bccb2014-05-26 21:30:20 +05307852
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 return wiphy;
7854}
7855
7856/*
7857 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307858 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007859 * private ioctl to change the band value
7860 */
7861int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7862{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307863 int i, j;
7864 eNVChannelEnabledType channelEnabledState;
7865
Jeff Johnsone7245742012-09-05 17:12:55 -07007866 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307867
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307868 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307870
7871 if (NULL == wiphy->bands[i])
7872 {
7873 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7874 __func__, i);
7875 continue;
7876 }
7877
7878 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7879 {
7880 struct ieee80211_supported_band *band = wiphy->bands[i];
7881
7882 channelEnabledState = vos_nv_getChannelEnabledState(
7883 band->channels[j].hw_value);
7884
7885 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7886 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307887 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307888 continue;
7889 }
7890 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7891 {
7892 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7893 continue;
7894 }
7895
7896 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7897 NV_CHANNEL_INVALID == channelEnabledState)
7898 {
7899 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7900 }
7901 else if (NV_CHANNEL_DFS == channelEnabledState)
7902 {
7903 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7904 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7905 }
7906 else
7907 {
7908 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7909 |IEEE80211_CHAN_RADAR);
7910 }
7911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 }
7913 return 0;
7914}
7915/*
7916 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307917 * This function is called by hdd_wlan_startup()
7918 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 * This function is used to initialize and register wiphy structure.
7920 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307921int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 struct wiphy *wiphy,
7923 hdd_config_t *pCfg
7924 )
7925{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307926 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307927 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7928
Jeff Johnsone7245742012-09-05 17:12:55 -07007929 ENTER();
7930
Jeff Johnson295189b2012-06-20 16:38:30 -07007931 /* Now bind the underlying wlan device with wiphy */
7932 set_wiphy_dev(wiphy, dev);
7933
7934 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007935
Kiet Lam6c583332013-10-14 05:37:09 +05307936#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007937 /* the flag for the other case would be initialzed in
7938 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7940 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7941#else
Amar Singhal0a402232013-10-11 20:57:16 -07007942 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307943#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307944#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007945
Amar Singhalfddc28c2013-09-05 13:03:40 -07007946 /* This will disable updating of NL channels from passive to
7947 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7949 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7950#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007951 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307952#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007953
Amar Singhala49cbc52013-10-08 18:37:44 -07007954
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007956 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7957 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7958 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007959 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307961 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307962#else
7963 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7964#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007965#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007966
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007967#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007968 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007969#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007970 || pCfg->isFastRoamIniFeatureEnabled
7971#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007972#ifdef FEATURE_WLAN_ESE
7973 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007974#endif
7975 )
7976 {
7977 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7978 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007979#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007980#ifdef FEATURE_WLAN_TDLS
7981 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7982 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7983#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307984#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307985 if (pCfg->configPNOScanSupport)
7986 {
7987 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7988 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7989 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7990 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7991 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307992#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007993
Abhishek Singh10d85972015-04-17 10:27:23 +05307994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7995 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7996#endif
7997
Amar Singhalfddc28c2013-09-05 13:03:40 -07007998#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007999 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8000 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008001 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008002 driver need to determine what to do with both
8003 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008004
8005 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008006#else
8007 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008008#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008009
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308010 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8011
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308012 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008013
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308014 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8015
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308017 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8018 | BIT(NL80211_IFTYPE_ADHOC)
8019 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8020 | BIT(NL80211_IFTYPE_P2P_GO)
8021 | BIT(NL80211_IFTYPE_AP);
8022
8023 if (VOS_MONITOR_MODE == hdd_get_conparam())
8024 {
8025 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008027
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308028 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008029 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8031 if( pCfg->enableMCC )
8032 {
8033 /* Currently, supports up to two channels */
8034 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008035
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308036 if( !pCfg->allowMCCGODiffBI )
8037 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008038
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308039 }
8040 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8041 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008042#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308043 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008044
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 /* Before registering we need to update the ht capabilitied based
8046 * on ini values*/
8047 if( !pCfg->ShortGI20MhzEnable )
8048 {
8049 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8050 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 }
8052
8053 if( !pCfg->ShortGI40MhzEnable )
8054 {
8055 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8056 }
8057
8058 if( !pCfg->nChannelBondingMode5GHz )
8059 {
8060 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8061 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308062 /*
8063 * In case of static linked driver at the time of driver unload,
8064 * module exit doesn't happens. Module cleanup helps in cleaning
8065 * of static memory.
8066 * If driver load happens statically, at the time of driver unload,
8067 * wiphy flags don't get reset because of static memory.
8068 * It's better not to store channel in static memory.
8069 */
8070 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8071 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8072 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8073 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8074 {
8075 hddLog(VOS_TRACE_LEVEL_ERROR,
8076 FL("Not enough memory to allocate channels"));
8077 return -ENOMEM;
8078 }
8079 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8080 &hdd_channels_2_4_GHZ[0],
8081 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008082
Agrawal Ashish97dec502015-11-26 20:20:58 +05308083 if (true == hdd_is_5g_supported(pHddCtx))
8084 {
8085 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8086 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8087 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8088 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8089 {
8090 hddLog(VOS_TRACE_LEVEL_ERROR,
8091 FL("Not enough memory to allocate channels"));
8092 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8093 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8094 return -ENOMEM;
8095 }
8096 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8097 &hdd_channels_5_GHZ[0],
8098 sizeof(hdd_channels_5_GHZ));
8099 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308100
8101 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8102 {
8103
8104 if (NULL == wiphy->bands[i])
8105 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308106 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308107 __func__, i);
8108 continue;
8109 }
8110
8111 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8112 {
8113 struct ieee80211_supported_band *band = wiphy->bands[i];
8114
8115 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8116 {
8117 // Enable social channels for P2P
8118 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8119 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8120 else
8121 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8122 continue;
8123 }
8124 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8125 {
8126 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8127 continue;
8128 }
8129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 }
8131 /*Initialise the supported cipher suite details*/
8132 wiphy->cipher_suites = hdd_cipher_suites;
8133 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8134
8135 /*signal strength in mBm (100*dBm) */
8136 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8137
8138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308139 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008140#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008141
Sunil Duttc69bccb2014-05-26 21:30:20 +05308142 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8143 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008144 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8145 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8146
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308147 EXIT();
8148 return 0;
8149}
8150
8151/* In this function we are registering wiphy. */
8152int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8153{
8154 ENTER();
8155 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008156 if (0 > wiphy_register(wiphy))
8157 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308158 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8160 return -EIO;
8161 }
8162
8163 EXIT();
8164 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165}
Jeff Johnson295189b2012-06-20 16:38:30 -07008166
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308167/* In this function we are updating channel list when,
8168 regulatory domain is FCC and country code is US.
8169 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8170 As per FCC smart phone is not a indoor device.
8171 GO should not opeate on indoor channels */
8172void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8173{
8174 int j;
8175 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8176 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8177 //Default counrtycode from NV at the time of wiphy initialization.
8178 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8179 &defaultCountryCode[0]))
8180 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008181 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308182 }
8183 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8184 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308185 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8186 {
8187 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8188 return;
8189 }
8190 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8191 {
8192 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8193 // Mark UNII -1 band channel as passive
8194 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8195 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8196 }
8197 }
8198}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308199/* This function registers for all frame which supplicant is interested in */
8200void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008201{
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8203 /* Register for all P2P action, public action etc frames */
8204 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008205 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308206 /* Register frame indication call back */
8207 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 /* Right now we are registering these frame when driver is getting
8209 initialized. Once we will move to 2.6.37 kernel, in which we have
8210 frame register ops, we will move this code as a part of that */
8211 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8214
8215 /* GAS Initial Response */
8216 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8217 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308218
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 /* GAS Comeback Request */
8220 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8221 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8222
8223 /* GAS Comeback Response */
8224 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8225 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8226
8227 /* P2P Public Action */
8228 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308229 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 P2P_PUBLIC_ACTION_FRAME_SIZE );
8231
8232 /* P2P Action */
8233 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8234 (v_U8_t*)P2P_ACTION_FRAME,
8235 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008236
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308237 /* WNM BSS Transition Request frame */
8238 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8239 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8240 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008241
8242 /* WNM-Notification */
8243 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8244 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8245 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008246}
8247
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308248void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008249{
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8251 /* Register for all P2P action, public action etc frames */
8252 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8253
Jeff Johnsone7245742012-09-05 17:12:55 -07008254 ENTER();
8255
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 /* Right now we are registering these frame when driver is getting
8257 initialized. Once we will move to 2.6.37 kernel, in which we have
8258 frame register ops, we will move this code as a part of that */
8259 /* GAS Initial Request */
8260
8261 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8262 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8263
8264 /* GAS Initial Response */
8265 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8266 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308267
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 /* GAS Comeback Request */
8269 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8270 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8271
8272 /* GAS Comeback Response */
8273 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8274 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8275
8276 /* P2P Public Action */
8277 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308278 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 P2P_PUBLIC_ACTION_FRAME_SIZE );
8280
8281 /* P2P Action */
8282 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8283 (v_U8_t*)P2P_ACTION_FRAME,
8284 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008285 /* WNM-Notification */
8286 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8287 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8288 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008289}
8290
8291#ifdef FEATURE_WLAN_WAPI
8292void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308293 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008294{
8295 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8296 tCsrRoamSetKey setKey;
8297 v_BOOL_t isConnected = TRUE;
8298 int status = 0;
8299 v_U32_t roamId= 0xFF;
8300 tANI_U8 *pKeyPtr = NULL;
8301 int n = 0;
8302
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308303 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8304 __func__, hdd_device_modetoString(pAdapter->device_mode),
8305 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008306
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308307 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 setKey.keyId = key_index; // Store Key ID
8309 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8310 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8311 setKey.paeRole = 0 ; // the PAE role
8312 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8313 {
8314 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8315 }
8316 else
8317 {
8318 isConnected = hdd_connIsConnected(pHddStaCtx);
8319 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8320 }
8321 setKey.keyLength = key_Len;
8322 pKeyPtr = setKey.Key;
8323 memcpy( pKeyPtr, key, key_Len);
8324
Arif Hussain6d2a3322013-11-17 19:50:10 -08008325 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 __func__, key_Len);
8327 for (n = 0 ; n < key_Len; n++)
8328 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8329 __func__,n,setKey.Key[n]);
8330
8331 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8332 if ( isConnected )
8333 {
8334 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8335 pAdapter->sessionId, &setKey, &roamId );
8336 }
8337 if ( status != 0 )
8338 {
8339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8340 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8341 __LINE__, status );
8342 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8343 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308344 /* Need to clear any trace of key value in the memory.
8345 * Thus zero out the memory even though it is local
8346 * variable.
8347 */
8348 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008349}
8350#endif /* FEATURE_WLAN_WAPI*/
8351
8352#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308353int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 beacon_data_t **ppBeacon,
8355 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008356#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308357int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008358 beacon_data_t **ppBeacon,
8359 struct cfg80211_beacon_data *params,
8360 int dtim_period)
8361#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308362{
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 int size;
8364 beacon_data_t *beacon = NULL;
8365 beacon_data_t *old = NULL;
8366 int head_len,tail_len;
8367
Jeff Johnsone7245742012-09-05 17:12:55 -07008368 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308370 {
8371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8372 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008375
8376 old = pAdapter->sessionCtx.ap.beacon;
8377
8378 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308379 {
8380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8381 FL("session(%d) old and new heads points to NULL"),
8382 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308384 }
8385
8386 if (params->tail && !params->tail_len)
8387 {
8388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8389 FL("tail_len is zero but tail is not NULL"));
8390 return -EINVAL;
8391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008392
Jeff Johnson295189b2012-06-20 16:38:30 -07008393#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8394 /* Kernel 3.0 is not updating dtim_period for set beacon */
8395 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396 {
8397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8398 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008401#endif
8402
8403 if(params->head)
8404 head_len = params->head_len;
8405 else
8406 head_len = old->head_len;
8407
8408 if(params->tail || !old)
8409 tail_len = params->tail_len;
8410 else
8411 tail_len = old->tail_len;
8412
8413 size = sizeof(beacon_data_t) + head_len + tail_len;
8414
8415 beacon = kzalloc(size, GFP_KERNEL);
8416
8417 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308418 {
8419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8420 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008423
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008424#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 if(params->dtim_period || !old )
8426 beacon->dtim_period = params->dtim_period;
8427 else
8428 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008429#else
8430 if(dtim_period || !old )
8431 beacon->dtim_period = dtim_period;
8432 else
8433 beacon->dtim_period = old->dtim_period;
8434#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308435
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8437 beacon->tail = beacon->head + head_len;
8438 beacon->head_len = head_len;
8439 beacon->tail_len = tail_len;
8440
8441 if(params->head) {
8442 memcpy (beacon->head,params->head,beacon->head_len);
8443 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308444 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 if(old)
8446 memcpy (beacon->head,old->head,beacon->head_len);
8447 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308448
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 if(params->tail) {
8450 memcpy (beacon->tail,params->tail,beacon->tail_len);
8451 }
8452 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308453 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 memcpy (beacon->tail,old->tail,beacon->tail_len);
8455 }
8456
8457 *ppBeacon = beacon;
8458
8459 kfree(old);
8460
8461 return 0;
8462
8463}
Jeff Johnson295189b2012-06-20 16:38:30 -07008464
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308465v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8467 const v_U8_t *pIes,
8468#else
8469 v_U8_t *pIes,
8470#endif
8471 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008472{
8473 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308474 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308476
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308478 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 elem_id = ptr[0];
8480 elem_len = ptr[1];
8481 left -= 2;
8482 if(elem_len > left)
8483 {
8484 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008485 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 eid,elem_len,left);
8487 return NULL;
8488 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308489 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 {
8491 return ptr;
8492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308493
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 left -= elem_len;
8495 ptr += (elem_len + 2);
8496 }
8497 return NULL;
8498}
8499
Jeff Johnson295189b2012-06-20 16:38:30 -07008500/* Check if rate is 11g rate or not */
8501static int wlan_hdd_rate_is_11g(u8 rate)
8502{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008503 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 u8 i;
8505 for (i = 0; i < 8; i++)
8506 {
8507 if(rate == gRateArray[i])
8508 return TRUE;
8509 }
8510 return FALSE;
8511}
8512
8513/* Check for 11g rate and set proper 11g only mode */
8514static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8515 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8516{
8517 u8 i, num_rates = pIe[0];
8518
8519 pIe += 1;
8520 for ( i = 0; i < num_rates; i++)
8521 {
8522 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8523 {
8524 /* If rate set have 11g rate than change the mode to 11G */
8525 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8526 if (pIe[i] & BASIC_RATE_MASK)
8527 {
8528 /* If we have 11g rate as basic rate, it means mode
8529 is 11g only mode.
8530 */
8531 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8532 *pCheckRatesfor11g = FALSE;
8533 }
8534 }
8535 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8536 {
8537 *require_ht = TRUE;
8538 }
8539 }
8540 return;
8541}
8542
8543static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8544{
8545 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8546 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8547 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8548 u8 checkRatesfor11g = TRUE;
8549 u8 require_ht = FALSE;
8550 u8 *pIe=NULL;
8551
8552 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8553
8554 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8555 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8556 if (pIe != NULL)
8557 {
8558 pIe += 1;
8559 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8560 &pConfig->SapHw_mode);
8561 }
8562
8563 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8564 WLAN_EID_EXT_SUPP_RATES);
8565 if (pIe != NULL)
8566 {
8567
8568 pIe += 1;
8569 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8570 &pConfig->SapHw_mode);
8571 }
8572
8573 if( pConfig->channel > 14 )
8574 {
8575 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8576 }
8577
8578 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8579 WLAN_EID_HT_CAPABILITY);
8580
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308581 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 {
8583 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8584 if(require_ht)
8585 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8586 }
8587}
8588
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308589static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8590 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8591{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008592 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308593 v_U8_t *pIe = NULL;
8594 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8595
8596 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8597 pBeacon->tail, pBeacon->tail_len);
8598
8599 if (pIe)
8600 {
8601 ielen = pIe[1] + 2;
8602 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8603 {
8604 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8605 }
8606 else
8607 {
8608 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8609 return -EINVAL;
8610 }
8611 *total_ielen += ielen;
8612 }
8613 return 0;
8614}
8615
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008616static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8617 v_U8_t *genie, v_U8_t *total_ielen)
8618{
8619 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8620 int left = pBeacon->tail_len;
8621 v_U8_t *ptr = pBeacon->tail;
8622 v_U8_t elem_id, elem_len;
8623 v_U16_t ielen = 0;
8624
8625 if ( NULL == ptr || 0 == left )
8626 return;
8627
8628 while (left >= 2)
8629 {
8630 elem_id = ptr[0];
8631 elem_len = ptr[1];
8632 left -= 2;
8633 if (elem_len > left)
8634 {
8635 hddLog( VOS_TRACE_LEVEL_ERROR,
8636 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8637 elem_id, elem_len, left);
8638 return;
8639 }
8640 if (IE_EID_VENDOR == elem_id)
8641 {
8642 /* skipping the VSIE's which we don't want to include or
8643 * it will be included by existing code
8644 */
8645 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8646#ifdef WLAN_FEATURE_WFD
8647 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8648#endif
8649 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8650 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8651 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8652 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8653 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8654 {
8655 ielen = ptr[1] + 2;
8656 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8657 {
8658 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8659 *total_ielen += ielen;
8660 }
8661 else
8662 {
8663 hddLog( VOS_TRACE_LEVEL_ERROR,
8664 "IE Length is too big "
8665 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8666 elem_id, elem_len, *total_ielen);
8667 }
8668 }
8669 }
8670
8671 left -= elem_len;
8672 ptr += (elem_len + 2);
8673 }
8674 return;
8675}
8676
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008677#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008678static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8679 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008680#else
8681static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8682 struct cfg80211_beacon_data *params)
8683#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008684{
8685 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308686 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008688 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008689
8690 genie = vos_mem_malloc(MAX_GENIE_LEN);
8691
8692 if(genie == NULL) {
8693
8694 return -ENOMEM;
8695 }
8696
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308697 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8698 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308700 hddLog(LOGE,
8701 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308702 ret = -EINVAL;
8703 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 }
8705
8706#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308707 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8708 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8709 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308710 hddLog(LOGE,
8711 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308712 ret = -EINVAL;
8713 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 }
8715#endif
8716
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308717 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8718 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308720 hddLog(LOGE,
8721 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308722 ret = -EINVAL;
8723 goto done;
8724 }
8725
8726 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8727 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008728 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008730
8731 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8732 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8733 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8734 {
8735 hddLog(LOGE,
8736 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008737 ret = -EINVAL;
8738 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 }
8740
8741 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8742 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8743 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8744 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8745 ==eHAL_STATUS_FAILURE)
8746 {
8747 hddLog(LOGE,
8748 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008749 ret = -EINVAL;
8750 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 }
8752
8753 // Added for ProResp IE
8754 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8755 {
8756 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8757 u8 probe_rsp_ie_len[3] = {0};
8758 u8 counter = 0;
8759 /* Check Probe Resp Length if it is greater then 255 then Store
8760 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8761 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8762 Store More then 255 bytes into One Variable.
8763 */
8764 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8765 {
8766 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8767 {
8768 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8769 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8770 }
8771 else
8772 {
8773 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8774 rem_probe_resp_ie_len = 0;
8775 }
8776 }
8777
8778 rem_probe_resp_ie_len = 0;
8779
8780 if (probe_rsp_ie_len[0] > 0)
8781 {
8782 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8783 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8784 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8785 probe_rsp_ie_len[0], NULL,
8786 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8787 {
8788 hddLog(LOGE,
8789 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008790 ret = -EINVAL;
8791 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 }
8793 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8794 }
8795
8796 if (probe_rsp_ie_len[1] > 0)
8797 {
8798 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8799 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8800 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8801 probe_rsp_ie_len[1], NULL,
8802 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8803 {
8804 hddLog(LOGE,
8805 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008806 ret = -EINVAL;
8807 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 }
8809 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8810 }
8811
8812 if (probe_rsp_ie_len[2] > 0)
8813 {
8814 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8815 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8816 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8817 probe_rsp_ie_len[2], NULL,
8818 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8819 {
8820 hddLog(LOGE,
8821 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008822 ret = -EINVAL;
8823 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008824 }
8825 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8826 }
8827
8828 if (probe_rsp_ie_len[1] == 0 )
8829 {
8830 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8831 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8832 eANI_BOOLEAN_FALSE) )
8833 {
8834 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008835 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 }
8837 }
8838
8839 if (probe_rsp_ie_len[2] == 0 )
8840 {
8841 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8842 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8843 eANI_BOOLEAN_FALSE) )
8844 {
8845 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008846 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 }
8848 }
8849
8850 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8851 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8852 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8853 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8854 == eHAL_STATUS_FAILURE)
8855 {
8856 hddLog(LOGE,
8857 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008858 ret = -EINVAL;
8859 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 }
8861 }
8862 else
8863 {
8864 // Reset WNI_CFG_PROBE_RSP Flags
8865 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8866
8867 hddLog(VOS_TRACE_LEVEL_INFO,
8868 "%s: No Probe Response IE received in set beacon",
8869 __func__);
8870 }
8871
8872 // Added for AssocResp IE
8873 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8874 {
8875 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8876 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8877 params->assocresp_ies_len, NULL,
8878 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8879 {
8880 hddLog(LOGE,
8881 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008882 ret = -EINVAL;
8883 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
8885
8886 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8887 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8888 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8889 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8890 == eHAL_STATUS_FAILURE)
8891 {
8892 hddLog(LOGE,
8893 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008894 ret = -EINVAL;
8895 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 }
8897 }
8898 else
8899 {
8900 hddLog(VOS_TRACE_LEVEL_INFO,
8901 "%s: No Assoc Response IE received in set beacon",
8902 __func__);
8903
8904 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8905 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8906 eANI_BOOLEAN_FALSE) )
8907 {
8908 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008909 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 }
8911 }
8912
Jeff Johnsone7245742012-09-05 17:12:55 -07008913done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308915 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008916}
Jeff Johnson295189b2012-06-20 16:38:30 -07008917
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308918/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 * FUNCTION: wlan_hdd_validate_operation_channel
8920 * called by wlan_hdd_cfg80211_start_bss() and
8921 * wlan_hdd_cfg80211_set_channel()
8922 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308923 * channel list.
8924 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008925VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008926{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308927
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 v_U32_t num_ch = 0;
8929 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8930 u32 indx = 0;
8931 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308932 v_U8_t fValidChannel = FALSE, count = 0;
8933 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308934
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8936
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308937 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308939 /* Validate the channel */
8940 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308942 if ( channel == rfChannels[count].channelNum )
8943 {
8944 fValidChannel = TRUE;
8945 break;
8946 }
8947 }
8948 if (fValidChannel != TRUE)
8949 {
8950 hddLog(VOS_TRACE_LEVEL_ERROR,
8951 "%s: Invalid Channel [%d]", __func__, channel);
8952 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 }
8954 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308955 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308957 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8958 valid_ch, &num_ch))
8959 {
8960 hddLog(VOS_TRACE_LEVEL_ERROR,
8961 "%s: failed to get valid channel list", __func__);
8962 return VOS_STATUS_E_FAILURE;
8963 }
8964 for (indx = 0; indx < num_ch; indx++)
8965 {
8966 if (channel == valid_ch[indx])
8967 {
8968 break;
8969 }
8970 }
8971
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308972 if (indx >= num_ch)
8973 {
8974 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8975 {
8976 eCsrBand band;
8977 unsigned int freq;
8978
8979 sme_GetFreqBand(hHal, &band);
8980
8981 if (eCSR_BAND_5G == band)
8982 {
8983#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8984 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8985 {
8986 freq = ieee80211_channel_to_frequency(channel,
8987 IEEE80211_BAND_2GHZ);
8988 }
8989 else
8990 {
8991 freq = ieee80211_channel_to_frequency(channel,
8992 IEEE80211_BAND_5GHZ);
8993 }
8994#else
8995 freq = ieee80211_channel_to_frequency(channel);
8996#endif
8997 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8998 return VOS_STATUS_SUCCESS;
8999 }
9000 }
9001
9002 hddLog(VOS_TRACE_LEVEL_ERROR,
9003 "%s: Invalid Channel [%d]", __func__, channel);
9004 return VOS_STATUS_E_FAILURE;
9005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309009
Jeff Johnson295189b2012-06-20 16:38:30 -07009010}
9011
Viral Modi3a32cc52013-02-08 11:14:52 -08009012/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309013 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009014 * This function is used to set the channel number
9015 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309016static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009017 struct ieee80211_channel *chan,
9018 enum nl80211_channel_type channel_type
9019 )
9020{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309021 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009022 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009023 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009024 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309025 hdd_context_t *pHddCtx;
9026 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009027
9028 ENTER();
9029
9030 if( NULL == dev )
9031 {
9032 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009033 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009034 return -ENODEV;
9035 }
9036 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9039 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9040 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009041 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309042 "%s: device_mode = %s (%d) freq = %d", __func__,
9043 hdd_device_modetoString(pAdapter->device_mode),
9044 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309045
9046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9047 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309048 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009049 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309050 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009051 }
9052
9053 /*
9054 * Do freq to chan conversion
9055 * TODO: for 11a
9056 */
9057
9058 channel = ieee80211_frequency_to_channel(freq);
9059
9060 /* Check freq range */
9061 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9062 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9063 {
9064 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009065 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009066 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9067 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9068 return -EINVAL;
9069 }
9070
9071 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9072
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309073 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9074 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009075 {
9076 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9077 {
9078 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009079 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009080 return -EINVAL;
9081 }
9082 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9083 "%s: set channel to [%d] for device mode =%d",
9084 __func__, channel,pAdapter->device_mode);
9085 }
9086 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009087 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009088 )
9089 {
9090 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9091 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9092 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9093
9094 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9095 {
9096 /* Link is up then return cant set channel*/
9097 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009098 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009099 return -EINVAL;
9100 }
9101
9102 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9103 pHddStaCtx->conn_info.operationChannel = channel;
9104 pRoamProfile->ChannelInfo.ChannelList =
9105 &pHddStaCtx->conn_info.operationChannel;
9106 }
9107 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009108 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009109 )
9110 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309111 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9112 {
9113 if(VOS_STATUS_SUCCESS !=
9114 wlan_hdd_validate_operation_channel(pAdapter,channel))
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009117 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309118 return -EINVAL;
9119 }
9120 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9121 }
9122 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009123 {
9124 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9125
9126 /* If auto channel selection is configured as enable/ 1 then ignore
9127 channel set by supplicant
9128 */
9129 if ( cfg_param->apAutoChannelSelection )
9130 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309131 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9132 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009133 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309134 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9135 __func__, hdd_device_modetoString(pAdapter->device_mode),
9136 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009137 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309138 else
9139 {
9140 if(VOS_STATUS_SUCCESS !=
9141 wlan_hdd_validate_operation_channel(pAdapter,channel))
9142 {
9143 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009144 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309145 return -EINVAL;
9146 }
9147 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9148 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009149 }
9150 }
9151 else
9152 {
9153 hddLog(VOS_TRACE_LEVEL_FATAL,
9154 "%s: Invalid device mode failed to set valid channel", __func__);
9155 return -EINVAL;
9156 }
9157 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309158 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009159}
9160
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309161static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9162 struct net_device *dev,
9163 struct ieee80211_channel *chan,
9164 enum nl80211_channel_type channel_type
9165 )
9166{
9167 int ret;
9168
9169 vos_ssr_protect(__func__);
9170 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9171 vos_ssr_unprotect(__func__);
9172
9173 return ret;
9174}
9175
Anurag Chouhan83026002016-12-13 22:46:21 +05309176#ifdef DHCP_SERVER_OFFLOAD
9177void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9178 VOS_STATUS status)
9179{
9180 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9181
9182 ENTER();
9183
9184 if (NULL == adapter)
9185 {
9186 hddLog(VOS_TRACE_LEVEL_ERROR,
9187 "%s: adapter is NULL",__func__);
9188 return;
9189 }
9190
9191 adapter->dhcp_status.dhcp_offload_status = status;
9192 vos_event_set(&adapter->dhcp_status.vos_event);
9193 return;
9194}
9195
9196/**
9197 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9198 * @hostapd_adapter: pointer to hostapd adapter.
9199 *
9200 * Return: None
9201 */
9202static VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter)
9203{
9204 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9205 sir_dhcp_srv_offload_info dhcp_srv_info;
9206 tANI_U8 num_entries = 0;
9207 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9208 tANI_U8 num;
9209 tANI_U32 temp;
9210 VOS_STATUS ret;
9211
9212 ENTER();
9213
9214 ret = wlan_hdd_validate_context(hdd_ctx);
9215 if (0 != ret)
9216 return VOS_STATUS_E_INVAL;
9217
9218 /* Prepare the request to send to SME */
9219 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9220 if (NULL == dhcp_srv_info) {
9221 hddLog(VOS_TRACE_LEVEL_ERROR,
9222 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9223 return VOS_STATUS_E_NOMEM;
9224 }
9225
9226 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9227
9228 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9229 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9230 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9231 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9232 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9233 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9234
9235 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9236 srv_ip,
9237 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309238 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309239 if (num_entries != IPADDR_NUM_ENTRIES) {
9240 hddLog(VOS_TRACE_LEVEL_ERROR,
9241 "%s: incorrect IP address (%s) assigned for DHCP server!",
9242 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9243 vos_mem_free(dhcp_srv_info);
9244 return VOS_STATUS_E_FAILURE;
9245 }
9246
9247 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9248 hddLog(VOS_TRACE_LEVEL_ERROR,
9249 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9250 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9251 vos_mem_free(dhcp_srv_info);
9252 return VOS_STATUS_E_FAILURE;
9253 }
9254
9255 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9256 hddLog(VOS_TRACE_LEVEL_ERROR,
9257 "%s: invalid IP address (%s)! The last field must be less than 100!",
9258 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9259 vos_mem_free(dhcp_srv_info);
9260 return VOS_STATUS_E_FAILURE;
9261 }
9262
9263 for (num = 0; num < num_entries; num++) {
9264 temp = srv_ip[num];
9265 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9266 }
9267
9268 if (eHAL_STATUS_SUCCESS !=
9269 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9270 hddLog(VOS_TRACE_LEVEL_ERROR,
9271 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9272 vos_mem_free(dhcp_srv_info);
9273 return VOS_STATUS_E_FAILURE;
9274 }
9275
9276 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9277 "%s: enable DHCP Server offload successfully!", __func__);
9278
9279 vos_mem_free(dhcp_srv_info);
9280 return 0;
9281}
9282#endif /* DHCP_SERVER_OFFLOAD */
9283
Jeff Johnson295189b2012-06-20 16:38:30 -07009284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9285static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9286 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009287#else
9288static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9289 struct cfg80211_beacon_data *params,
9290 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309291 enum nl80211_hidden_ssid hidden_ssid,
9292 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009294{
9295 tsap_Config_t *pConfig;
9296 beacon_data_t *pBeacon = NULL;
9297 struct ieee80211_mgmt *pMgmt_frame;
9298 v_U8_t *pIe=NULL;
9299 v_U16_t capab_info;
9300 eCsrAuthType RSNAuthType;
9301 eCsrEncryptionType RSNEncryptType;
9302 eCsrEncryptionType mcRSNEncryptType;
9303 int status = VOS_STATUS_SUCCESS;
9304 tpWLAN_SAPEventCB pSapEventCallback;
9305 hdd_hostapd_state_t *pHostapdState;
9306 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9307 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309308 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309310 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009312 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309313 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009314 v_BOOL_t MFPCapable = VOS_FALSE;
9315 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309316 v_BOOL_t sapEnable11AC =
9317 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 ENTER();
9319
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309320 iniConfig = pHddCtx->cfg_ini;
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9323
9324 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9325
9326 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9327
9328 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9329
9330 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9331
9332 //channel is already set in the set_channel Call back
9333 //pConfig->channel = pCommitConfig->channel;
9334
9335 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309336 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9338
9339 pConfig->dtim_period = pBeacon->dtim_period;
9340
Arif Hussain6d2a3322013-11-17 19:50:10 -08009341 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 pConfig->dtim_period);
9343
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009344 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009345 {
9346 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309348 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9349 {
9350 tANI_BOOLEAN restartNeeded;
9351 pConfig->ieee80211d = 1;
9352 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9353 sme_setRegInfo(hHal, pConfig->countryCode);
9354 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9355 }
9356 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009358 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009359 pConfig->ieee80211d = 1;
9360 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9361 sme_setRegInfo(hHal, pConfig->countryCode);
9362 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009364 else
9365 {
9366 pConfig->ieee80211d = 0;
9367 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309368 /*
9369 * If auto channel is configured i.e. channel is 0,
9370 * so skip channel validation.
9371 */
9372 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9373 {
9374 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9375 {
9376 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009377 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309378 return -EINVAL;
9379 }
9380 }
9381 else
9382 {
9383 if(1 != pHddCtx->is_dynamic_channel_range_set)
9384 {
9385 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9386 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9387 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9388 }
9389 pHddCtx->is_dynamic_channel_range_set = 0;
9390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009392 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 {
9394 pConfig->ieee80211d = 0;
9395 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309396
9397#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9398 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9399 pConfig->authType = eSAP_OPEN_SYSTEM;
9400 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9401 pConfig->authType = eSAP_SHARED_KEY;
9402 else
9403 pConfig->authType = eSAP_AUTO_SWITCH;
9404#else
9405 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9406 pConfig->authType = eSAP_OPEN_SYSTEM;
9407 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9408 pConfig->authType = eSAP_SHARED_KEY;
9409 else
9410 pConfig->authType = eSAP_AUTO_SWITCH;
9411#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009412
9413 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414
9415 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309417#ifdef SAP_AUTH_OFFLOAD
9418 /* In case of sap offload, hostapd.conf is configuted with open mode and
9419 * security is configured from ini file. Due to open mode in hostapd.conf
9420 * privacy bit is set to false which will result in not sending,
9421 * data packets as encrypted.
9422 * If enable_sap_auth_offload is enabled in ini and
9423 * sap_auth_offload_sec_type is type of WPA2-PSK,
9424 * driver will set privacy bit to 1.
9425 */
9426 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9427 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9428 pConfig->privacy = VOS_TRUE;
9429#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
9431 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9432
9433 /*Set wps station to configured*/
9434 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9435
9436 if(pIe)
9437 {
9438 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9439 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009440 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 return -EINVAL;
9442 }
9443 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9444 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009445 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 /* Check 15 bit of WPS IE as it contain information for wps state
9447 * WPS state
9448 */
9449 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9450 {
9451 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9452 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9453 {
9454 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9455 }
9456 }
9457 }
9458 else
9459 {
9460 pConfig->wps_state = SAP_WPS_DISABLED;
9461 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
c_hpothufe599e92014-06-16 11:38:55 +05309464 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9465 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9466 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9467 eCSR_ENCRYPT_TYPE_NONE;
9468
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 pConfig->RSNWPAReqIELength = 0;
9470 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 WLAN_EID_RSN);
9473 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309474 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9476 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9477 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309478 /* The actual processing may eventually be more extensive than
9479 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 * by the app.
9481 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9484 &RSNEncryptType,
9485 &mcRSNEncryptType,
9486 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009487 &MFPCapable,
9488 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 pConfig->pRSNWPAReqIE[1]+2,
9490 pConfig->pRSNWPAReqIE );
9491
9492 if( VOS_STATUS_SUCCESS == status )
9493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309494 /* Now copy over all the security attributes you have
9495 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 * */
9497 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9498 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9499 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9500 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309501 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009502 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9504 }
9505 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309506
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9508 pBeacon->tail, pBeacon->tail_len);
9509
9510 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9511 {
9512 if (pConfig->pRSNWPAReqIE)
9513 {
9514 /*Mixed mode WPA/WPA2*/
9515 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9516 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9517 }
9518 else
9519 {
9520 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9521 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9522 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309523 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9525 &RSNEncryptType,
9526 &mcRSNEncryptType,
9527 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009528 &MFPCapable,
9529 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 pConfig->pRSNWPAReqIE[1]+2,
9531 pConfig->pRSNWPAReqIE );
9532
9533 if( VOS_STATUS_SUCCESS == status )
9534 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535 /* Now copy over all the security attributes you have
9536 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 * */
9538 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9539 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9540 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9541 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309542 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009543 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9545 }
9546 }
9547 }
9548
Jeff Johnson4416a782013-03-25 14:17:50 -07009549 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9550 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9551 return -EINVAL;
9552 }
9553
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9555
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009556#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 if (params->ssid != NULL)
9558 {
9559 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9560 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9561 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9562 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9563 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009564#else
9565 if (ssid != NULL)
9566 {
9567 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9568 pConfig->SSIDinfo.ssid.length = ssid_len;
9569 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9570 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9571 }
9572#endif
9573
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309574 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309576
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 /* default value */
9578 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9579 pConfig->num_accept_mac = 0;
9580 pConfig->num_deny_mac = 0;
9581
9582 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9583 pBeacon->tail, pBeacon->tail_len);
9584
9585 /* pIe for black list is following form:
9586 type : 1 byte
9587 length : 1 byte
9588 OUI : 4 bytes
9589 acl type : 1 byte
9590 no of mac addr in black list: 1 byte
9591 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 */
9593 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 {
9595 pConfig->SapMacaddr_acl = pIe[6];
9596 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009597 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309599 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9600 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9602 for (i = 0; i < pConfig->num_deny_mac; i++)
9603 {
9604 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9605 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 }
9608 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9609 pBeacon->tail, pBeacon->tail_len);
9610
9611 /* pIe for white list is following form:
9612 type : 1 byte
9613 length : 1 byte
9614 OUI : 4 bytes
9615 acl type : 1 byte
9616 no of mac addr in white list: 1 byte
9617 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618 */
9619 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 {
9621 pConfig->SapMacaddr_acl = pIe[6];
9622 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009623 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309625 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9626 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9628 for (i = 0; i < pConfig->num_accept_mac; i++)
9629 {
9630 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9631 acl_entry++;
9632 }
9633 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9636
Jeff Johnsone7245742012-09-05 17:12:55 -07009637#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009638 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309639 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9640 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309641 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9642 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009643 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9644 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309645 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9646 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009647 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309648 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009649 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309650 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009651
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309652 /* If ACS disable and selected channel <= 14
9653 * OR
9654 * ACS enabled and ACS operating band is choosen as 2.4
9655 * AND
9656 * VHT in 2.4G Disabled
9657 * THEN
9658 * Fallback to 11N mode
9659 */
9660 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9661 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309662 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309663 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009664 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309665 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9666 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009667 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9668 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009669 }
9670#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309671
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 // ht_capab is not what the name conveys,this is used for protection bitmap
9673 pConfig->ht_capab =
9674 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9675
9676 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9677 {
9678 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9679 return -EINVAL;
9680 }
9681
9682 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309683 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9685 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309686 pConfig->obssProtEnabled =
9687 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009688
Chet Lanctot8cecea22014-02-11 19:09:36 -08009689#ifdef WLAN_FEATURE_11W
9690 pConfig->mfpCapable = MFPCapable;
9691 pConfig->mfpRequired = MFPRequired;
9692 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9693 pConfig->mfpCapable, pConfig->mfpRequired);
9694#endif
9695
Arif Hussain6d2a3322013-11-17 19:50:10 -08009696 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009698 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9699 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9700 (int)pConfig->channel);
9701 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9702 pConfig->SapHw_mode, pConfig->privacy,
9703 pConfig->authType);
9704 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9705 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9706 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9707 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009708
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309709 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 {
9711 //Bss already started. just return.
9712 //TODO Probably it should update some beacon params.
9713 hddLog( LOGE, "Bss Already started...Ignore the request");
9714 EXIT();
9715 return 0;
9716 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309717
Agarwal Ashish51325b52014-06-16 16:50:49 +05309718 if (vos_max_concurrent_connections_reached()) {
9719 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9720 return -EINVAL;
9721 }
9722
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 pConfig->persona = pHostapdAdapter->device_mode;
9724
Peng Xu2446a892014-09-05 17:21:18 +05309725 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9726 if ( NULL != psmeConfig)
9727 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309728 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309729 sme_GetConfigParam(hHal, psmeConfig);
9730 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309731#ifdef WLAN_FEATURE_AP_HT40_24G
9732 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9733 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9734 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9735 {
9736 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9737 sme_UpdateConfig (hHal, psmeConfig);
9738 }
9739#endif
Peng Xu2446a892014-09-05 17:21:18 +05309740 vos_mem_free(psmeConfig);
9741 }
Peng Xuafc34e32014-09-25 13:23:55 +05309742 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309743
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 pSapEventCallback = hdd_hostapd_SAPEventCB;
9745 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9746 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9747 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009748 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 return -EINVAL;
9750 }
9751
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9754
9755 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309758 {
9759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009760 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009761 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 VOS_ASSERT(0);
9763 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309764
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309766 /* Initialize WMM configuation */
9767 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309768 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009769
Anurag Chouhan83026002016-12-13 22:46:21 +05309770#ifdef DHCP_SERVER_OFFLOAD
9771 /* set dhcp server offload */
9772 if (iniConfig->enable_dhcp_srv_offload &&
9773 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
9774 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
9775 if (!VOS_IS_STATUS_SUCCESS(status))
9776 {
9777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9778 ("HDD DHCP Server Offload Failed!!"));
9779 return -EINVAL;
9780 }
9781 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
9782 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9783 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9784 {
9785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9786 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9787 pHostapdAdapter->dhcp_status.dhcp_offload_status);
9788 return -EINVAL;
9789 }
9790 }
9791#endif /* DHCP_SERVER_OFFLOAD */
9792
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009793#ifdef WLAN_FEATURE_P2P_DEBUG
9794 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9795 {
9796 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9797 {
9798 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9799 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009800 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009801 }
9802 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9803 {
9804 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9805 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009806 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009807 }
9808 }
9809#endif
9810
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 pHostapdState->bCommit = TRUE;
9812 EXIT();
9813
9814 return 0;
9815}
9816
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309818static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 struct beacon_parameters *params)
9821{
9822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309823 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309824 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009825
9826 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309827
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9829 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9830 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309831 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9832 hdd_device_modetoString(pAdapter->device_mode),
9833 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009834
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9836 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309837 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009838 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309839 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009840 }
9841
Agarwal Ashish51325b52014-06-16 16:50:49 +05309842 if (vos_max_concurrent_connections_reached()) {
9843 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9844 return -EINVAL;
9845 }
9846
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309847 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 )
9850 {
9851 beacon_data_t *old,*new;
9852
9853 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309856 {
9857 hddLog(VOS_TRACE_LEVEL_WARN,
9858 FL("already beacon info added to session(%d)"),
9859 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009862
9863 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9864
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309865 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 {
9867 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009868 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 return -EINVAL;
9870 }
9871
9872 pAdapter->sessionCtx.ap.beacon = new;
9873
9874 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9875 }
9876
9877 EXIT();
9878 return status;
9879}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309880
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309881static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9882 struct net_device *dev,
9883 struct beacon_parameters *params)
9884{
9885 int ret;
9886
9887 vos_ssr_protect(__func__);
9888 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9889 vos_ssr_unprotect(__func__);
9890
9891 return ret;
9892}
9893
9894static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 struct net_device *dev,
9896 struct beacon_parameters *params)
9897{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309899 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9900 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309901 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009902
9903 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309904
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9906 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9907 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9908 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9909 __func__, hdd_device_modetoString(pAdapter->device_mode),
9910 pAdapter->device_mode);
9911
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309914 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009915 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309916 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009917 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309918
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 {
9923 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309924
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309928 {
9929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9930 FL("session(%d) old and new heads points to NULL"),
9931 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309933 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009934
9935 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9936
9937 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 return -EINVAL;
9941 }
9942
9943 pAdapter->sessionCtx.ap.beacon = new;
9944
9945 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9946 }
9947
9948 EXIT();
9949 return status;
9950}
9951
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309952static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9953 struct net_device *dev,
9954 struct beacon_parameters *params)
9955{
9956 int ret;
9957
9958 vos_ssr_protect(__func__);
9959 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9960 vos_ssr_unprotect(__func__);
9961
9962 return ret;
9963}
9964
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009965#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9966
9967#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309968static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009970#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309971static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009972 struct net_device *dev)
9973#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009974{
9975 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009976 hdd_context_t *pHddCtx = NULL;
9977 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309978 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309979 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009980
9981 ENTER();
9982
9983 if (NULL == pAdapter)
9984 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009986 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 return -ENODEV;
9988 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009989
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309990 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9991 TRACE_CODE_HDD_CFG80211_STOP_AP,
9992 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309993 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9994 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309995 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009996 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309997 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009998 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009999
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010000 pScanInfo = &pHddCtx->scan_info;
10001
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010002 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10003 __func__, hdd_device_modetoString(pAdapter->device_mode),
10004 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010005
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010006 ret = wlan_hdd_scan_abort(pAdapter);
10007
Girish Gowli4bf7a632014-06-12 13:42:11 +053010008 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010009 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10011 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010012
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010013 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010014 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10016 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010017
Jeff Johnsone7245742012-09-05 17:12:55 -070010018 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010019 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010020 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010021 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010022 }
10023
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010024 /* Delete all associated STAs before stopping AP/P2P GO */
10025 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010026 hdd_hostapd_stop(dev);
10027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 )
10031 {
10032 beacon_data_t *old;
10033
10034 old = pAdapter->sessionCtx.ap.beacon;
10035
10036 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010037 {
10038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10039 FL("session(%d) beacon data points to NULL"),
10040 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010042 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010043
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010045
10046 mutex_lock(&pHddCtx->sap_lock);
10047 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10048 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010049 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 {
10051 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10052
10053 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10054
10055 if (!VOS_IS_STATUS_SUCCESS(status))
10056 {
10057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010058 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010060 }
10061 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010063 /* BSS stopped, clear the active sessions for this device mode */
10064 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 }
10066 mutex_unlock(&pHddCtx->sap_lock);
10067
10068 if(status != VOS_STATUS_SUCCESS)
10069 {
10070 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010071 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 return -EINVAL;
10073 }
10074
Jeff Johnson4416a782013-03-25 14:17:50 -070010075 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10077 ==eHAL_STATUS_FAILURE)
10078 {
10079 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010080 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 }
10082
Jeff Johnson4416a782013-03-25 14:17:50 -070010083 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010084 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10085 eANI_BOOLEAN_FALSE) )
10086 {
10087 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010088 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010089 }
10090
10091 // Reset WNI_CFG_PROBE_RSP Flags
10092 wlan_hdd_reset_prob_rspies(pAdapter);
10093
10094 pAdapter->sessionCtx.ap.beacon = NULL;
10095 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010096#ifdef WLAN_FEATURE_P2P_DEBUG
10097 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10098 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10099 {
10100 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10101 "GO got removed");
10102 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10103 }
10104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 }
10106 EXIT();
10107 return status;
10108}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010109
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010110#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10111static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10112 struct net_device *dev)
10113{
10114 int ret;
10115
10116 vos_ssr_protect(__func__);
10117 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10118 vos_ssr_unprotect(__func__);
10119
10120 return ret;
10121}
10122#else
10123static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10124 struct net_device *dev)
10125{
10126 int ret;
10127
10128 vos_ssr_protect(__func__);
10129 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10130 vos_ssr_unprotect(__func__);
10131
10132 return ret;
10133}
10134#endif
10135
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010136#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10137
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010138static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010139 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010140 struct cfg80211_ap_settings *params)
10141{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010142 hdd_adapter_t *pAdapter;
10143 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010144 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010145
10146 ENTER();
10147
Girish Gowlib143d7a2015-02-18 19:39:55 +053010148 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010149 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010151 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010152 return -ENODEV;
10153 }
10154
10155 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10156 if (NULL == pAdapter)
10157 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010159 "%s: HDD adapter is Null", __func__);
10160 return -ENODEV;
10161 }
10162
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010163 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10164 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10165 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010166 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10167 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010169 "%s: HDD adapter magic is invalid", __func__);
10170 return -ENODEV;
10171 }
10172
10173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010174 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010175 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010176 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010177 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010178 }
10179
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010180 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10181 __func__, hdd_device_modetoString(pAdapter->device_mode),
10182 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010183
10184 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010185 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010186 )
10187 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010188 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010189
10190 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010191
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010192 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010193 {
10194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10195 FL("already beacon info added to session(%d)"),
10196 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010197 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010198 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010199
Girish Gowlib143d7a2015-02-18 19:39:55 +053010200#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10201 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10202 &new,
10203 &params->beacon);
10204#else
10205 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10206 &new,
10207 &params->beacon,
10208 params->dtim_period);
10209#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010210
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010211 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010212 {
10213 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010214 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010215 return -EINVAL;
10216 }
10217 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010219 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10220#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10221 params->channel, params->channel_type);
10222#else
10223 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10224#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010225#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010226 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010227 params->ssid_len, params->hidden_ssid,
10228 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010229 }
10230
10231 EXIT();
10232 return status;
10233}
10234
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010235static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10236 struct net_device *dev,
10237 struct cfg80211_ap_settings *params)
10238{
10239 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010240
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010241 vos_ssr_protect(__func__);
10242 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10243 vos_ssr_unprotect(__func__);
10244
10245 return ret;
10246}
10247
10248static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010249 struct net_device *dev,
10250 struct cfg80211_beacon_data *params)
10251{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010253 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010254 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010255
10256 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010257
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010258 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10259 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10260 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010261 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010262 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010263
10264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10265 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010266 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010267 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010268 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010269 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010270
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010272 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010273 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010274 {
10275 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010276
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010277 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010278
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010279 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010280 {
10281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10282 FL("session(%d) beacon data points to NULL"),
10283 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010284 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010285 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010286
10287 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10288
10289 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010291 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010292 return -EINVAL;
10293 }
10294
10295 pAdapter->sessionCtx.ap.beacon = new;
10296
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010297 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10298 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010299 }
10300
10301 EXIT();
10302 return status;
10303}
10304
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010305static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10306 struct net_device *dev,
10307 struct cfg80211_beacon_data *params)
10308{
10309 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010310
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010311 vos_ssr_protect(__func__);
10312 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10313 vos_ssr_unprotect(__func__);
10314
10315 return ret;
10316}
10317
10318#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010319
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010320static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 struct net_device *dev,
10322 struct bss_parameters *params)
10323{
10324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010325 hdd_context_t *pHddCtx;
10326 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010327
10328 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010329
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010330 if (NULL == pAdapter)
10331 {
10332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10333 "%s: HDD adapter is Null", __func__);
10334 return -ENODEV;
10335 }
10336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010337 ret = wlan_hdd_validate_context(pHddCtx);
10338 if (0 != ret)
10339 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010340 return ret;
10341 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010342 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10343 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10344 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10346 __func__, hdd_device_modetoString(pAdapter->device_mode),
10347 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010348
10349 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010351 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 {
10353 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10354 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010355 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 {
10357 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 }
10360
10361 EXIT();
10362 return 0;
10363}
10364
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010365static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10366 struct net_device *dev,
10367 struct bss_parameters *params)
10368{
10369 int ret;
10370
10371 vos_ssr_protect(__func__);
10372 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10373 vos_ssr_unprotect(__func__);
10374
10375 return ret;
10376}
Kiet Lam10841362013-11-01 11:36:50 +053010377/* FUNCTION: wlan_hdd_change_country_code_cd
10378* to wait for contry code completion
10379*/
10380void* wlan_hdd_change_country_code_cb(void *pAdapter)
10381{
10382 hdd_adapter_t *call_back_pAdapter = pAdapter;
10383 complete(&call_back_pAdapter->change_country_code);
10384 return NULL;
10385}
10386
Jeff Johnson295189b2012-06-20 16:38:30 -070010387/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010388 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10390 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010391int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010392 struct net_device *ndev,
10393 enum nl80211_iftype type,
10394 u32 *flags,
10395 struct vif_params *params
10396 )
10397{
10398 struct wireless_dev *wdev;
10399 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010400 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010401 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 tCsrRoamProfile *pRoamProfile = NULL;
10403 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010404 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 eMib_dot11DesiredBssType connectedBssType;
10406 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010407 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010408
10409 ENTER();
10410
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010411 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010412 {
10413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10414 "%s: Adapter context is null", __func__);
10415 return VOS_STATUS_E_FAILURE;
10416 }
10417
10418 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10419 if (!pHddCtx)
10420 {
10421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10422 "%s: HDD context is null", __func__);
10423 return VOS_STATUS_E_FAILURE;
10424 }
10425
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010426 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10427 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10428 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010429 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010430 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010432 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 }
10434
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010435 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10436 __func__, hdd_device_modetoString(pAdapter->device_mode),
10437 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010438
Agarwal Ashish51325b52014-06-16 16:50:49 +053010439 if (vos_max_concurrent_connections_reached()) {
10440 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10441 return -EINVAL;
10442 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010443 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 wdev = ndev->ieee80211_ptr;
10445
10446#ifdef WLAN_BTAMP_FEATURE
10447 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10448 (NL80211_IFTYPE_ADHOC == type)||
10449 (NL80211_IFTYPE_AP == type)||
10450 (NL80211_IFTYPE_P2P_GO == type))
10451 {
10452 pHddCtx->isAmpAllowed = VOS_FALSE;
10453 // stop AMP traffic
10454 status = WLANBAP_StopAmp();
10455 if(VOS_STATUS_SUCCESS != status )
10456 {
10457 pHddCtx->isAmpAllowed = VOS_TRUE;
10458 hddLog(VOS_TRACE_LEVEL_FATAL,
10459 "%s: Failed to stop AMP", __func__);
10460 return -EINVAL;
10461 }
10462 }
10463#endif //WLAN_BTAMP_FEATURE
10464 /* Reset the current device mode bit mask*/
10465 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10466
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010467 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10468 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10469 (type == NL80211_IFTYPE_P2P_GO)))
10470 {
10471 /* Notify Mode change in case of concurrency.
10472 * Below function invokes TDLS teardown Functionality Since TDLS is
10473 * not Supported in case of concurrency i.e Once P2P session
10474 * is detected disable offchannel and teardown TDLS links
10475 */
10476 hddLog(LOG1,
10477 FL("Device mode = %d Interface type = %d"),
10478 pAdapter->device_mode, type);
10479 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10480 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010481
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010484 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 )
10486 {
10487 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010488 if (!pWextState)
10489 {
10490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10491 "%s: pWextState is null", __func__);
10492 return VOS_STATUS_E_FAILURE;
10493 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 pRoamProfile = &pWextState->roamProfile;
10495 LastBSSType = pRoamProfile->BSSType;
10496
10497 switch (type)
10498 {
10499 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 hddLog(VOS_TRACE_LEVEL_INFO,
10502 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10503 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010504#ifdef WLAN_FEATURE_11AC
10505 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10506 {
10507 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10508 }
10509#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010510 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010511 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010513 //Check for sub-string p2p to confirm its a p2p interface
10514 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010515 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010516#ifdef FEATURE_WLAN_TDLS
10517 mutex_lock(&pHddCtx->tdls_lock);
10518 wlan_hdd_tdls_exit(pAdapter, TRUE);
10519 mutex_unlock(&pHddCtx->tdls_lock);
10520#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010521 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10522 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10523 }
10524 else
10525 {
10526 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010528 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010530
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 case NL80211_IFTYPE_ADHOC:
10532 hddLog(VOS_TRACE_LEVEL_INFO,
10533 "%s: setting interface Type to ADHOC", __func__);
10534 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10535 pRoamProfile->phyMode =
10536 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010537 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010539 hdd_set_ibss_ops( pAdapter );
10540 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010541
10542 status = hdd_sta_id_hash_attach(pAdapter);
10543 if (VOS_STATUS_SUCCESS != status) {
10544 hddLog(VOS_TRACE_LEVEL_ERROR,
10545 FL("Failed to initialize hash for IBSS"));
10546 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 break;
10548
10549 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 {
10552 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10553 "%s: setting interface Type to %s", __func__,
10554 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10555
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010556 //Cancel any remain on channel for GO mode
10557 if (NL80211_IFTYPE_P2P_GO == type)
10558 {
10559 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10560 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010561 if (NL80211_IFTYPE_AP == type)
10562 {
10563 /* As Loading WLAN Driver one interface being created for p2p device
10564 * address. This will take one HW STA and the max number of clients
10565 * that can connect to softAP will be reduced by one. so while changing
10566 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10567 * interface as it is not required in SoftAP mode.
10568 */
10569
10570 // Get P2P Adapter
10571 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10572
10573 if (pP2pAdapter)
10574 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010575 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010576 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010577 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10578 }
10579 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010580 //Disable IMPS & BMPS for SAP/GO
10581 if(VOS_STATUS_E_FAILURE ==
10582 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10583 {
10584 //Fail to Exit BMPS
10585 VOS_ASSERT(0);
10586 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010587
10588 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10589
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010590#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010591
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010592 /* A Mutex Lock is introduced while changing the mode to
10593 * protect the concurrent access for the Adapters by TDLS
10594 * module.
10595 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010596 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010597#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010599 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10602 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010603#ifdef FEATURE_WLAN_TDLS
10604 mutex_unlock(&pHddCtx->tdls_lock);
10605#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010606 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10607 (pConfig->apRandomBssidEnabled))
10608 {
10609 /* To meet Android requirements create a randomized
10610 MAC address of the form 02:1A:11:Fx:xx:xx */
10611 get_random_bytes(&ndev->dev_addr[3], 3);
10612 ndev->dev_addr[0] = 0x02;
10613 ndev->dev_addr[1] = 0x1A;
10614 ndev->dev_addr[2] = 0x11;
10615 ndev->dev_addr[3] |= 0xF0;
10616 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10617 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010618 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10619 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010620 }
10621
Jeff Johnson295189b2012-06-20 16:38:30 -070010622 hdd_set_ap_ops( pAdapter->dev );
10623
Kiet Lam10841362013-11-01 11:36:50 +053010624 /* This is for only SAP mode where users can
10625 * control country through ini.
10626 * P2P GO follows station country code
10627 * acquired during the STA scanning. */
10628 if((NL80211_IFTYPE_AP == type) &&
10629 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10630 {
10631 int status = 0;
10632 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10633 "%s: setting country code from INI ", __func__);
10634 init_completion(&pAdapter->change_country_code);
10635 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10636 (void *)(tSmeChangeCountryCallback)
10637 wlan_hdd_change_country_code_cb,
10638 pConfig->apCntryCode, pAdapter,
10639 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010640 eSIR_FALSE,
10641 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010642 if (eHAL_STATUS_SUCCESS == status)
10643 {
10644 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010645 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010646 &pAdapter->change_country_code,
10647 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010648 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010649 {
10650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010651 FL("SME Timed out while setting country code %ld"),
10652 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010653
10654 if (pHddCtx->isLogpInProgress)
10655 {
10656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10657 "%s: LOGP in Progress. Ignore!!!", __func__);
10658 return -EAGAIN;
10659 }
Kiet Lam10841362013-11-01 11:36:50 +053010660 }
10661 }
10662 else
10663 {
10664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010665 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010666 return -EINVAL;
10667 }
10668 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 status = hdd_init_ap_mode(pAdapter);
10670 if(status != VOS_STATUS_SUCCESS)
10671 {
10672 hddLog(VOS_TRACE_LEVEL_FATAL,
10673 "%s: Error initializing the ap mode", __func__);
10674 return -EINVAL;
10675 }
10676 hdd_set_conparam(1);
10677
Nirav Shah7e3c8132015-06-22 23:51:42 +053010678 status = hdd_sta_id_hash_attach(pAdapter);
10679 if (VOS_STATUS_SUCCESS != status)
10680 {
10681 hddLog(VOS_TRACE_LEVEL_ERROR,
10682 FL("Failed to initialize hash for AP"));
10683 return -EINVAL;
10684 }
10685
Jeff Johnson295189b2012-06-20 16:38:30 -070010686 /*interface type changed update in wiphy structure*/
10687 if(wdev)
10688 {
10689 wdev->iftype = type;
10690 pHddCtx->change_iface = type;
10691 }
10692 else
10693 {
10694 hddLog(VOS_TRACE_LEVEL_ERROR,
10695 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10696 return -EINVAL;
10697 }
10698 goto done;
10699 }
10700
10701 default:
10702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10703 __func__);
10704 return -EOPNOTSUPP;
10705 }
10706 }
10707 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 )
10710 {
10711 switch(type)
10712 {
10713 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010716
10717 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010718#ifdef FEATURE_WLAN_TDLS
10719
10720 /* A Mutex Lock is introduced while changing the mode to
10721 * protect the concurrent access for the Adapters by TDLS
10722 * module.
10723 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010724 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010725#endif
c_hpothu002231a2015-02-05 14:58:51 +053010726 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010728 //Check for sub-string p2p to confirm its a p2p interface
10729 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010730 {
10731 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10732 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10733 }
10734 else
10735 {
10736 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010738 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010739
10740 /* set con_mode to STA only when no SAP concurrency mode */
10741 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10742 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10745 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010746#ifdef FEATURE_WLAN_TDLS
10747 mutex_unlock(&pHddCtx->tdls_lock);
10748#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010749 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 if( VOS_STATUS_SUCCESS != status )
10751 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010752 /* In case of JB, for P2P-GO, only change interface will be called,
10753 * This is the right place to enable back bmps_imps()
10754 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010755 if (pHddCtx->hdd_wlan_suspended)
10756 {
10757 hdd_set_pwrparams(pHddCtx);
10758 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010759 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 goto done;
10761 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10765 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 goto done;
10767 default:
10768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10769 __func__);
10770 return -EOPNOTSUPP;
10771
10772 }
10773
10774 }
10775 else
10776 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010777 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10778 __func__, hdd_device_modetoString(pAdapter->device_mode),
10779 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010780 return -EOPNOTSUPP;
10781 }
10782
10783
10784 if(pRoamProfile)
10785 {
10786 if ( LastBSSType != pRoamProfile->BSSType )
10787 {
10788 /*interface type changed update in wiphy structure*/
10789 wdev->iftype = type;
10790
10791 /*the BSS mode changed, We need to issue disconnect
10792 if connected or in IBSS disconnect state*/
10793 if ( hdd_connGetConnectedBssType(
10794 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10795 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10796 {
10797 /*need to issue a disconnect to CSR.*/
10798 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10799 if( eHAL_STATUS_SUCCESS ==
10800 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10801 pAdapter->sessionId,
10802 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10803 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010804 ret = wait_for_completion_interruptible_timeout(
10805 &pAdapter->disconnect_comp_var,
10806 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10807 if (ret <= 0)
10808 {
10809 hddLog(VOS_TRACE_LEVEL_ERROR,
10810 FL("wait on disconnect_comp_var failed %ld"), ret);
10811 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 }
10813 }
10814 }
10815 }
10816
10817done:
10818 /*set bitmask based on updated value*/
10819 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010820
10821 /* Only STA mode support TM now
10822 * all other mode, TM feature should be disabled */
10823 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10824 (~VOS_STA & pHddCtx->concurrency_mode) )
10825 {
10826 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10827 }
10828
Jeff Johnson295189b2012-06-20 16:38:30 -070010829#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010830 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010831 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 {
10833 //we are ok to do AMP
10834 pHddCtx->isAmpAllowed = VOS_TRUE;
10835 }
10836#endif //WLAN_BTAMP_FEATURE
10837 EXIT();
10838 return 0;
10839}
10840
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010841/*
10842 * FUNCTION: wlan_hdd_cfg80211_change_iface
10843 * wrapper function to protect the actual implementation from SSR.
10844 */
10845int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10846 struct net_device *ndev,
10847 enum nl80211_iftype type,
10848 u32 *flags,
10849 struct vif_params *params
10850 )
10851{
10852 int ret;
10853
10854 vos_ssr_protect(__func__);
10855 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10856 vos_ssr_unprotect(__func__);
10857
10858 return ret;
10859}
10860
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010861#ifdef FEATURE_WLAN_TDLS
10862static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010863 struct net_device *dev,
10864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10865 const u8 *mac,
10866#else
10867 u8 *mac,
10868#endif
10869 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010870{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010871 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010872 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010873 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010874 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010875 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010876 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010877
10878 ENTER();
10879
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010880 if (!dev) {
10881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10882 return -EINVAL;
10883 }
10884
10885 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10886 if (!pAdapter) {
10887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10888 return -EINVAL;
10889 }
10890
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010891 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010892 {
10893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10894 "Invalid arguments");
10895 return -EINVAL;
10896 }
Hoonki Lee27511902013-03-14 18:19:06 -070010897
10898 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10899 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10900 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010902 "%s: TDLS mode is disabled OR not enabled in FW."
10903 MAC_ADDRESS_STR " Request declined.",
10904 __func__, MAC_ADDR_ARRAY(mac));
10905 return -ENOTSUPP;
10906 }
10907
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010908 if (pHddCtx->isLogpInProgress)
10909 {
10910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10911 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010912 wlan_hdd_tdls_set_link_status(pAdapter,
10913 mac,
10914 eTDLS_LINK_IDLE,
10915 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010916 return -EBUSY;
10917 }
10918
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010919 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010920 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010921
10922 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010924 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10925 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010926 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010927 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010928 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010929
10930 /* in add station, we accept existing valid staId if there is */
10931 if ((0 == update) &&
10932 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10933 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010934 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010936 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010937 " link_status %d. staId %d. add station ignored.",
10938 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010939 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010940 return 0;
10941 }
10942 /* in change station, we accept only when staId is valid */
10943 if ((1 == update) &&
10944 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10945 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10946 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010947 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010949 "%s: " MAC_ADDRESS_STR
10950 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010951 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10952 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10953 mutex_unlock(&pHddCtx->tdls_lock);
10954 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010955 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010956 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010957
10958 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010959 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010960 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10962 "%s: " MAC_ADDRESS_STR
10963 " TDLS setup is ongoing. Request declined.",
10964 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010965 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010966 }
10967
10968 /* first to check if we reached to maximum supported TDLS peer.
10969 TODO: for now, return -EPERM looks working fine,
10970 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010971 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10972 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010973 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10975 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010976 " TDLS Max peer already connected. Request declined."
10977 " Num of peers (%d), Max allowed (%d).",
10978 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10979 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010980 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010981 }
10982 else
10983 {
10984 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010985 mutex_lock(&pHddCtx->tdls_lock);
10986 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010987 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010988 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010989 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10991 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10992 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010993 return -EPERM;
10994 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010995 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010996 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010997 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010998 wlan_hdd_tdls_set_link_status(pAdapter,
10999 mac,
11000 eTDLS_LINK_CONNECTING,
11001 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011002
Jeff Johnsond75fe012013-04-06 10:53:06 -070011003 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011004 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011005 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011007 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011008 if(StaParams->htcap_present)
11009 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011011 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011013 "ht_capa->extended_capabilities: %0x",
11014 StaParams->HTCap.extendedHtCapInfo);
11015 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011017 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011019 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011020 if(StaParams->vhtcap_present)
11021 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011023 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11024 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11025 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11026 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011027 {
11028 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011030 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011032 "[%d]: %x ", i, StaParams->supported_rates[i]);
11033 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011034 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011035 else if ((1 == update) && (NULL == StaParams))
11036 {
11037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11038 "%s : update is true, but staParams is NULL. Error!", __func__);
11039 return -EPERM;
11040 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011041
11042 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11043
11044 if (!update)
11045 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011046 /*Before adding sta make sure that device exited from BMPS*/
11047 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11048 {
11049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11050 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11051 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11052 if (status != VOS_STATUS_SUCCESS) {
11053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11054 }
11055 }
11056
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011057 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011058 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011059 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011060 hddLog(VOS_TRACE_LEVEL_ERROR,
11061 FL("Failed to add TDLS peer STA. Enable Bmps"));
11062 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011063 return -EPERM;
11064 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011065 }
11066 else
11067 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011068 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011069 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011070 if (ret != eHAL_STATUS_SUCCESS) {
11071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11072 return -EPERM;
11073 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011074 }
11075
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011076 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011077 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11078
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011079 mutex_lock(&pHddCtx->tdls_lock);
11080 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11081
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011082 if ((pTdlsPeer != NULL) &&
11083 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011084 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011085 hddLog(VOS_TRACE_LEVEL_ERROR,
11086 FL("peer link status %u"), pTdlsPeer->link_status);
11087 mutex_unlock(&pHddCtx->tdls_lock);
11088 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011089 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011090 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011091
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011092 if (ret <= 0)
11093 {
11094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11095 "%s: timeout waiting for tdls add station indication %ld",
11096 __func__, ret);
11097 goto error;
11098 }
11099
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011100 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11101 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011103 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011104 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011105 }
11106
11107 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011108
11109error:
Atul Mittal115287b2014-07-08 13:26:33 +053011110 wlan_hdd_tdls_set_link_status(pAdapter,
11111 mac,
11112 eTDLS_LINK_IDLE,
11113 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011114 return -EPERM;
11115
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011116}
11117#endif
11118
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011119static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11122 const u8 *mac,
11123#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011124 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011125#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 struct station_parameters *params)
11127{
11128 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011129 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011130 hdd_context_t *pHddCtx;
11131 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011133 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011134#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011135 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011136 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011137 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011138 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011139#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011140
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011141 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011142
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011143 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011144 if ((NULL == pAdapter))
11145 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011147 "invalid adapter ");
11148 return -EINVAL;
11149 }
11150
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011151 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11152 TRACE_CODE_HDD_CHANGE_STATION,
11153 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011154 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011155
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011156 ret = wlan_hdd_validate_context(pHddCtx);
11157 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011158 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011159 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011160 }
11161
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011162 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11163
11164 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011165 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11167 "invalid HDD station context");
11168 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011169 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11171
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011172 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11173 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011175 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011177 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 WLANTL_STA_AUTHENTICATED);
11179
Gopichand Nakkala29149562013-05-10 21:43:41 +053011180 if (status != VOS_STATUS_SUCCESS)
11181 {
11182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11183 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11184 return -EINVAL;
11185 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 }
11187 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011188 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11189 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011190#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011191 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11192 StaParams.capability = params->capability;
11193 StaParams.uapsd_queues = params->uapsd_queues;
11194 StaParams.max_sp = params->max_sp;
11195
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011196 /* Convert (first channel , number of channels) tuple to
11197 * the total list of channels. This goes with the assumption
11198 * that if the first channel is < 14, then the next channels
11199 * are an incremental of 1 else an incremental of 4 till the number
11200 * of channels.
11201 */
11202 if (0 != params->supported_channels_len) {
11203 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11204 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11205 {
11206 int wifi_chan_index;
11207 StaParams.supported_channels[j] = params->supported_channels[i];
11208 wifi_chan_index =
11209 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11210 no_of_channels = params->supported_channels[i+1];
11211 for(k=1; k <= no_of_channels; k++)
11212 {
11213 StaParams.supported_channels[j+1] =
11214 StaParams.supported_channels[j] + wifi_chan_index;
11215 j+=1;
11216 }
11217 }
11218 StaParams.supported_channels_len = j;
11219 }
11220 vos_mem_copy(StaParams.supported_oper_classes,
11221 params->supported_oper_classes,
11222 params->supported_oper_classes_len);
11223 StaParams.supported_oper_classes_len =
11224 params->supported_oper_classes_len;
11225
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011226 if (0 != params->ext_capab_len)
11227 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11228 sizeof(StaParams.extn_capability));
11229
11230 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011231 {
11232 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011233 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011234 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011235
11236 StaParams.supported_rates_len = params->supported_rates_len;
11237
11238 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11239 * The supported_rates array , for all the structures propogating till Add Sta
11240 * to the firmware has to be modified , if the supplicant (ieee80211) is
11241 * modified to send more rates.
11242 */
11243
11244 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11245 */
11246 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11247 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11248
11249 if (0 != StaParams.supported_rates_len) {
11250 int i = 0;
11251 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11252 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011254 "Supported Rates with Length %d", StaParams.supported_rates_len);
11255 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011257 "[%d]: %0x", i, StaParams.supported_rates[i]);
11258 }
11259
11260 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011261 {
11262 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011263 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011264 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011265
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011266 if (0 != params->ext_capab_len ) {
11267 /*Define A Macro : TODO Sunil*/
11268 if ((1<<4) & StaParams.extn_capability[3]) {
11269 isBufSta = 1;
11270 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011271 /* TDLS Channel Switching Support */
11272 if ((1<<6) & StaParams.extn_capability[3]) {
11273 isOffChannelSupported = 1;
11274 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011275 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011276
11277 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011278 (params->ht_capa || params->vht_capa ||
11279 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011280 /* TDLS Peer is WME/QoS capable */
11281 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011282
11283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11284 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11285 __func__, isQosWmmSta, StaParams.htcap_present);
11286
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011287 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11288 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011289 isOffChannelSupported,
11290 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011291
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011292 if (VOS_STATUS_SUCCESS != status) {
11293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11294 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11295 return -EINVAL;
11296 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011297 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11298
11299 if (VOS_STATUS_SUCCESS != status) {
11300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11301 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11302 return -EINVAL;
11303 }
11304 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011305#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011306 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011307 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 return status;
11309}
11310
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11312static int wlan_hdd_change_station(struct wiphy *wiphy,
11313 struct net_device *dev,
11314 const u8 *mac,
11315 struct station_parameters *params)
11316#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011317static int wlan_hdd_change_station(struct wiphy *wiphy,
11318 struct net_device *dev,
11319 u8 *mac,
11320 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011321#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011322{
11323 int ret;
11324
11325 vos_ssr_protect(__func__);
11326 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11327 vos_ssr_unprotect(__func__);
11328
11329 return ret;
11330}
11331
Jeff Johnson295189b2012-06-20 16:38:30 -070011332/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011333 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 * This function is used to initialize the key information
11335 */
11336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011337static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 struct net_device *ndev,
11339 u8 key_index, bool pairwise,
11340 const u8 *mac_addr,
11341 struct key_params *params
11342 )
11343#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011344static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 struct net_device *ndev,
11346 u8 key_index, const u8 *mac_addr,
11347 struct key_params *params
11348 )
11349#endif
11350{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 tCsrRoamSetKey setKey;
11353 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011354 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011355 v_U32_t roamId= 0xFF;
11356 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 hdd_hostapd_state_t *pHostapdState;
11358 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011359 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011360 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011361
11362 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011363
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011364 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11365 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11366 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11368 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011369 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011370 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011371 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011372 }
11373
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11375 __func__, hdd_device_modetoString(pAdapter->device_mode),
11376 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011377
11378 if (CSR_MAX_NUM_KEY <= key_index)
11379 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 key_index);
11382
11383 return -EINVAL;
11384 }
11385
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011386 if (CSR_MAX_KEY_LEN < params->key_len)
11387 {
11388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11389 params->key_len);
11390
11391 return -EINVAL;
11392 }
11393
11394 hddLog(VOS_TRACE_LEVEL_INFO,
11395 "%s: called with key index = %d & key length %d",
11396 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011397
11398 /*extract key idx, key len and key*/
11399 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11400 setKey.keyId = key_index;
11401 setKey.keyLength = params->key_len;
11402 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11403
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011404 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 {
11406 case WLAN_CIPHER_SUITE_WEP40:
11407 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11408 break;
11409
11410 case WLAN_CIPHER_SUITE_WEP104:
11411 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11412 break;
11413
11414 case WLAN_CIPHER_SUITE_TKIP:
11415 {
11416 u8 *pKey = &setKey.Key[0];
11417 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11418
11419 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11420
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011421 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011422
11423 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011424 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 |--------------|----------|----------|
11426 <---16bytes---><--8bytes--><--8bytes-->
11427
11428 */
11429 /*Sme expects the 32 bytes key to be in the below order
11430
11431 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011432 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 |--------------|----------|----------|
11434 <---16bytes---><--8bytes--><--8bytes-->
11435 */
11436 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011437 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011438
11439 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011440 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011441
11442 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011443 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011444
11445
11446 break;
11447 }
11448
11449 case WLAN_CIPHER_SUITE_CCMP:
11450 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11451 break;
11452
11453#ifdef FEATURE_WLAN_WAPI
11454 case WLAN_CIPHER_SUITE_SMS4:
11455 {
11456 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11457 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11458 params->key, params->key_len);
11459 return 0;
11460 }
11461#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011462
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011463#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 case WLAN_CIPHER_SUITE_KRK:
11465 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11466 break;
11467#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011468
11469#ifdef WLAN_FEATURE_11W
11470 case WLAN_CIPHER_SUITE_AES_CMAC:
11471 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011472 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011473#endif
11474
Jeff Johnson295189b2012-06-20 16:38:30 -070011475 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011478 status = -EOPNOTSUPP;
11479 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 }
11481
11482 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11483 __func__, setKey.encType);
11484
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011485 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11487 (!pairwise)
11488#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011489 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011490#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011491 )
11492 {
11493 /* set group key*/
11494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11495 "%s- %d: setting Broadcast key",
11496 __func__, __LINE__);
11497 setKey.keyDirection = eSIR_RX_ONLY;
11498 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11499 }
11500 else
11501 {
11502 /* set pairwise key*/
11503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11504 "%s- %d: setting pairwise key",
11505 __func__, __LINE__);
11506 setKey.keyDirection = eSIR_TX_RX;
11507 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11508 }
11509 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11510 {
11511 setKey.keyDirection = eSIR_TX_RX;
11512 /*Set the group key*/
11513 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11514 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011515
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011516 if ( 0 != status )
11517 {
11518 hddLog(VOS_TRACE_LEVEL_ERROR,
11519 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011520 status = -EINVAL;
11521 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011522 }
11523 /*Save the keys here and call sme_RoamSetKey for setting
11524 the PTK after peer joins the IBSS network*/
11525 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11526 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011527 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011528 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011529 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11530 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11531 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011533 if( pHostapdState->bssState == BSS_START )
11534 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011535 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11536 vos_status = wlan_hdd_check_ula_done(pAdapter);
11537
11538 if ( vos_status != VOS_STATUS_SUCCESS )
11539 {
11540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11541 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11542 __LINE__, vos_status );
11543
11544 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11545
11546 status = -EINVAL;
11547 goto end;
11548 }
11549
Jeff Johnson295189b2012-06-20 16:38:30 -070011550 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11551
11552 if ( status != eHAL_STATUS_SUCCESS )
11553 {
11554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11555 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11556 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011557 status = -EINVAL;
11558 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011559 }
11560 }
11561
11562 /* Saving WEP keys */
11563 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11564 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11565 {
11566 //Save the wep key in ap context. Issue setkey after the BSS is started.
11567 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11568 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11569 }
11570 else
11571 {
11572 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011573 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11575 }
11576 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011577 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11578 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 {
11580 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11582
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11584 if (!pairwise)
11585#else
11586 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11587#endif
11588 {
11589 /* set group key*/
11590 if (pHddStaCtx->roam_info.deferKeyComplete)
11591 {
11592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11593 "%s- %d: Perform Set key Complete",
11594 __func__, __LINE__);
11595 hdd_PerformRoamSetKeyComplete(pAdapter);
11596 }
11597 }
11598
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11600
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011601 pWextState->roamProfile.Keys.defaultIndex = key_index;
11602
11603
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011604 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 params->key, params->key_len);
11606
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011607
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11609
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011610 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612 __func__, setKey.peerMac[0], setKey.peerMac[1],
11613 setKey.peerMac[2], setKey.peerMac[3],
11614 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 setKey.keyDirection);
11616
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011617 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011618
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011619 if ( vos_status != VOS_STATUS_SUCCESS )
11620 {
11621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11623 __LINE__, vos_status );
11624
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011625 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011626
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011627 status = -EINVAL;
11628 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011629
11630 }
11631
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011632#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011633 /* The supplicant may attempt to set the PTK once pre-authentication
11634 is done. Save the key in the UMAC and include it in the ADD BSS
11635 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011636 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011637 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011638 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011639 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11640 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011641 status = 0;
11642 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011643 }
11644 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11645 {
11646 hddLog(VOS_TRACE_LEVEL_ERROR,
11647 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011648 status = -EINVAL;
11649 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011650 }
11651#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011652
11653 /* issue set key request to SME*/
11654 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11655 pAdapter->sessionId, &setKey, &roamId );
11656
11657 if ( 0 != status )
11658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011659 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011660 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11661 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011662 status = -EINVAL;
11663 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 }
11665
11666
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 /* in case of IBSS as there was no information available about WEP keys during
11668 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011670 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11671 !( ( IW_AUTH_KEY_MGMT_802_1X
11672 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11674 )
11675 &&
11676 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11677 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11678 )
11679 )
11680 {
11681 setKey.keyDirection = eSIR_RX_ONLY;
11682 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11683
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011684 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 __func__, setKey.peerMac[0], setKey.peerMac[1],
11687 setKey.peerMac[2], setKey.peerMac[3],
11688 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 setKey.keyDirection);
11690
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 pAdapter->sessionId, &setKey, &roamId );
11693
11694 if ( 0 != status )
11695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 hddLog(VOS_TRACE_LEVEL_ERROR,
11697 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 __func__, status);
11699 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011700 status = -EINVAL;
11701 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 }
11703 }
11704 }
11705
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011706end:
11707 /* Need to clear any trace of key value in the memory.
11708 * Thus zero out the memory even though it is local
11709 * variable.
11710 */
11711 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011712 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011713 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011714}
11715
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11717static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11718 struct net_device *ndev,
11719 u8 key_index, bool pairwise,
11720 const u8 *mac_addr,
11721 struct key_params *params
11722 )
11723#else
11724static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11725 struct net_device *ndev,
11726 u8 key_index, const u8 *mac_addr,
11727 struct key_params *params
11728 )
11729#endif
11730{
11731 int ret;
11732 vos_ssr_protect(__func__);
11733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11734 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11735 mac_addr, params);
11736#else
11737 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11738 params);
11739#endif
11740 vos_ssr_unprotect(__func__);
11741
11742 return ret;
11743}
11744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011746 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 * This function is used to get the key information
11748 */
11749#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011750static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011751 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 const u8 *mac_addr, void *cookie,
11755 void (*callback)(void *cookie, struct key_params*)
11756 )
11757#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011758static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011759 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 struct net_device *ndev,
11761 u8 key_index, const u8 *mac_addr, void *cookie,
11762 void (*callback)(void *cookie, struct key_params*)
11763 )
11764#endif
11765{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011767 hdd_wext_state_t *pWextState = NULL;
11768 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011770 hdd_context_t *pHddCtx;
11771 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011772
11773 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011774
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011775 if (NULL == pAdapter)
11776 {
11777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11778 "%s: HDD adapter is Null", __func__);
11779 return -ENODEV;
11780 }
11781
11782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11783 ret = wlan_hdd_validate_context(pHddCtx);
11784 if (0 != ret)
11785 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011786 return ret;
11787 }
11788
11789 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11790 pRoamProfile = &(pWextState->roamProfile);
11791
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11793 __func__, hdd_device_modetoString(pAdapter->device_mode),
11794 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011795
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 memset(&params, 0, sizeof(params));
11797
11798 if (CSR_MAX_NUM_KEY <= key_index)
11799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011803
11804 switch(pRoamProfile->EncryptionType.encryptionType[0])
11805 {
11806 case eCSR_ENCRYPT_TYPE_NONE:
11807 params.cipher = IW_AUTH_CIPHER_NONE;
11808 break;
11809
11810 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11811 case eCSR_ENCRYPT_TYPE_WEP40:
11812 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11813 break;
11814
11815 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11816 case eCSR_ENCRYPT_TYPE_WEP104:
11817 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11818 break;
11819
11820 case eCSR_ENCRYPT_TYPE_TKIP:
11821 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11822 break;
11823
11824 case eCSR_ENCRYPT_TYPE_AES:
11825 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11826 break;
11827
11828 default:
11829 params.cipher = IW_AUTH_CIPHER_NONE;
11830 break;
11831 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011832
c_hpothuaaf19692014-05-17 17:01:48 +053011833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11834 TRACE_CODE_HDD_CFG80211_GET_KEY,
11835 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011836
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11838 params.seq_len = 0;
11839 params.seq = NULL;
11840 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11841 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011842 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 return 0;
11844}
11845
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11847static int wlan_hdd_cfg80211_get_key(
11848 struct wiphy *wiphy,
11849 struct net_device *ndev,
11850 u8 key_index, bool pairwise,
11851 const u8 *mac_addr, void *cookie,
11852 void (*callback)(void *cookie, struct key_params*)
11853 )
11854#else
11855static int wlan_hdd_cfg80211_get_key(
11856 struct wiphy *wiphy,
11857 struct net_device *ndev,
11858 u8 key_index, const u8 *mac_addr, void *cookie,
11859 void (*callback)(void *cookie, struct key_params*)
11860 )
11861#endif
11862{
11863 int ret;
11864
11865 vos_ssr_protect(__func__);
11866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11867 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11868 mac_addr, cookie, callback);
11869#else
11870 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11871 callback);
11872#endif
11873 vos_ssr_unprotect(__func__);
11874
11875 return ret;
11876}
11877
Jeff Johnson295189b2012-06-20 16:38:30 -070011878/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011879 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 * This function is used to delete the key information
11881 */
11882#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011883static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011885 u8 key_index,
11886 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 const u8 *mac_addr
11888 )
11889#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011890static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 struct net_device *ndev,
11892 u8 key_index,
11893 const u8 *mac_addr
11894 )
11895#endif
11896{
11897 int status = 0;
11898
11899 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011900 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 //it is observed that this is invalidating peer
11902 //key index whenever re-key is done. This is affecting data link.
11903 //It should be ok to ignore del_key.
11904#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11906 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11908 tCsrRoamSetKey setKey;
11909 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011910
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 ENTER();
11912
11913 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11914 __func__,pAdapter->device_mode);
11915
11916 if (CSR_MAX_NUM_KEY <= key_index)
11917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 key_index);
11920
11921 return -EINVAL;
11922 }
11923
11924 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11925 setKey.keyId = key_index;
11926
11927 if (mac_addr)
11928 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11929 else
11930 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11931
11932 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11933
11934 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011936 )
11937 {
11938
11939 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11941 if( pHostapdState->bssState == BSS_START)
11942 {
11943 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 if ( status != eHAL_STATUS_SUCCESS )
11946 {
11947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11948 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11949 __LINE__, status );
11950 }
11951 }
11952 }
11953 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 )
11956 {
11957 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11958
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11960
11961 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011963 __func__, setKey.peerMac[0], setKey.peerMac[1],
11964 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011966 if(pAdapter->sessionCtx.station.conn_info.connState ==
11967 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011969 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011971
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 if ( 0 != status )
11973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 "%s: sme_RoamSetKey failure, returned %d",
11976 __func__, status);
11977 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11978 return -EINVAL;
11979 }
11980 }
11981 }
11982#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011983 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 return status;
11985}
11986
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11988static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11989 struct net_device *ndev,
11990 u8 key_index,
11991 bool pairwise,
11992 const u8 *mac_addr
11993 )
11994#else
11995static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11996 struct net_device *ndev,
11997 u8 key_index,
11998 const u8 *mac_addr
11999 )
12000#endif
12001{
12002 int ret;
12003
12004 vos_ssr_protect(__func__);
12005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12006 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12007 mac_addr);
12008#else
12009 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12010#endif
12011 vos_ssr_unprotect(__func__);
12012
12013 return ret;
12014}
12015
Jeff Johnson295189b2012-06-20 16:38:30 -070012016/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012017 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 * This function is used to set the default tx key index
12019 */
12020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012021static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 struct net_device *ndev,
12023 u8 key_index,
12024 bool unicast, bool multicast)
12025#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012026static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 struct net_device *ndev,
12028 u8 key_index)
12029#endif
12030{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012032 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012033 hdd_wext_state_t *pWextState;
12034 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012036
12037 ENTER();
12038
Gopichand Nakkala29149562013-05-10 21:43:41 +053012039 if ((NULL == pAdapter))
12040 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012042 "invalid adapter");
12043 return -EINVAL;
12044 }
12045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12047 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12048 pAdapter->sessionId, key_index));
12049
Gopichand Nakkala29149562013-05-10 21:43:41 +053012050 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12051 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12052
12053 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12054 {
12055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12056 "invalid Wext state or HDD context");
12057 return -EINVAL;
12058 }
12059
Arif Hussain6d2a3322013-11-17 19:50:10 -080012060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012062
Jeff Johnson295189b2012-06-20 16:38:30 -070012063 if (CSR_MAX_NUM_KEY <= key_index)
12064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 key_index);
12067
12068 return -EINVAL;
12069 }
12070
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12072 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012073 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012074 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012075 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012076 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012077
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012079 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012080 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012082 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012083 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012084 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012085 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012087 {
12088 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012090
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 tCsrRoamSetKey setKey;
12092 v_U32_t roamId= 0xFF;
12093 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012094
12095 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012097
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 Keys->defaultIndex = (u8)key_index;
12099 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12100 setKey.keyId = key_index;
12101 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012102
12103 vos_mem_copy(&setKey.Key[0],
12104 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106
Gopichand Nakkala29149562013-05-10 21:43:41 +053012107 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012108
12109 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012110 &pHddStaCtx->conn_info.bssId[0],
12111 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012112
Gopichand Nakkala29149562013-05-10 21:43:41 +053012113 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12114 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12115 eCSR_ENCRYPT_TYPE_WEP104)
12116 {
12117 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12118 even though ap is configured for WEP-40 encryption. In this canse the key length
12119 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12120 type(104) and switching encryption type to 40*/
12121 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12122 eCSR_ENCRYPT_TYPE_WEP40;
12123 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12124 eCSR_ENCRYPT_TYPE_WEP40;
12125 }
12126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012127 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012131 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012132 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012133
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 if ( 0 != status )
12135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012136 hddLog(VOS_TRACE_LEVEL_ERROR,
12137 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 status);
12139 return -EINVAL;
12140 }
12141 }
12142 }
12143
12144 /* In SoftAp mode setting key direction for default mode */
12145 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12146 {
12147 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12148 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12149 (eCSR_ENCRYPT_TYPE_AES !=
12150 pWextState->roamProfile.EncryptionType.encryptionType[0])
12151 )
12152 {
12153 /* Saving key direction for default key index to TX default */
12154 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12155 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12156 }
12157 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012158 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 return status;
12160}
12161
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012162#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12163static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12164 struct net_device *ndev,
12165 u8 key_index,
12166 bool unicast, bool multicast)
12167#else
12168static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12169 struct net_device *ndev,
12170 u8 key_index)
12171#endif
12172{
12173 int ret;
12174 vos_ssr_protect(__func__);
12175#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12176 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12177 multicast);
12178#else
12179 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12180#endif
12181 vos_ssr_unprotect(__func__);
12182
12183 return ret;
12184}
12185
Jeff Johnson295189b2012-06-20 16:38:30 -070012186/*
12187 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12188 * This function is used to inform the BSS details to nl80211 interface.
12189 */
12190static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12191 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12192{
12193 struct net_device *dev = pAdapter->dev;
12194 struct wireless_dev *wdev = dev->ieee80211_ptr;
12195 struct wiphy *wiphy = wdev->wiphy;
12196 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12197 int chan_no;
12198 int ie_length;
12199 const char *ie;
12200 unsigned int freq;
12201 struct ieee80211_channel *chan;
12202 int rssi = 0;
12203 struct cfg80211_bss *bss = NULL;
12204
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 if( NULL == pBssDesc )
12206 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012207 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 return bss;
12209 }
12210
12211 chan_no = pBssDesc->channelId;
12212 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12213 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12214
12215 if( NULL == ie )
12216 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012217 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 return bss;
12219 }
12220
12221#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12222 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12223 {
12224 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12225 }
12226 else
12227 {
12228 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12229 }
12230#else
12231 freq = ieee80211_channel_to_frequency(chan_no);
12232#endif
12233
12234 chan = __ieee80211_get_channel(wiphy, freq);
12235
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012236 if (!chan) {
12237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12238 return NULL;
12239 }
12240
Abhishek Singhaee43942014-06-16 18:55:47 +053012241 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012242
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012243 return cfg80211_inform_bss(wiphy, chan,
12244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12245 CFG80211_BSS_FTYPE_UNKNOWN,
12246#endif
12247 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012248 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 pBssDesc->capabilityInfo,
12250 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012251 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012252}
12253
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012254/*
12255 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12256 * interface that BSS might have been lost.
12257 * @pAdapter: adaptor
12258 * @bssid: bssid which might have been lost
12259 *
12260 * Return: bss which is unlinked from kernel cache
12261 */
12262struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12263 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12264{
12265 struct net_device *dev = pAdapter->dev;
12266 struct wireless_dev *wdev = dev->ieee80211_ptr;
12267 struct wiphy *wiphy = wdev->wiphy;
12268 struct cfg80211_bss *bss = NULL;
12269
12270 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12271 NULL,
12272 0,
12273#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12274 && !defined(IEEE80211_PRIVACY)
12275 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12276#else
12277 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12278#endif
12279 if (bss == NULL) {
12280 hddLog(LOGE, FL("BSS not present"));
12281 } else {
12282 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12283 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12284 cfg80211_unlink_bss(wiphy, bss);
12285 }
12286 return bss;
12287}
Jeff Johnson295189b2012-06-20 16:38:30 -070012288
12289
12290/*
12291 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12292 * This function is used to inform the BSS details to nl80211 interface.
12293 */
12294struct cfg80211_bss*
12295wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12296 tSirBssDescription *bss_desc
12297 )
12298{
12299 /*
12300 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12301 already exists in bss data base of cfg80211 for that particular BSS ID.
12302 Using cfg80211_inform_bss_frame to update the bss entry instead of
12303 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12304 now there is no possibility to get the mgmt(probe response) frame from PE,
12305 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12306 cfg80211_inform_bss_frame.
12307 */
12308 struct net_device *dev = pAdapter->dev;
12309 struct wireless_dev *wdev = dev->ieee80211_ptr;
12310 struct wiphy *wiphy = wdev->wiphy;
12311 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012312#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12313 qcom_ie_age *qie_age = NULL;
12314 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12315#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012318 const char *ie =
12319 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12320 unsigned int freq;
12321 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012322 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 struct cfg80211_bss *bss_status = NULL;
12324 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12325 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012326 hdd_context_t *pHddCtx;
12327 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012328#ifdef WLAN_OPEN_SOURCE
12329 struct timespec ts;
12330#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012332
Wilson Yangf80a0542013-10-07 13:02:37 -070012333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12334 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012335 if (0 != status)
12336 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012337 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012338 }
12339
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012340 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012341 if (!mgmt)
12342 {
12343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12344 "%s: memory allocation failed ", __func__);
12345 return NULL;
12346 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012347
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012349
12350#ifdef WLAN_OPEN_SOURCE
12351 /* Android does not want the timestamp from the frame.
12352 Instead it wants a monotonic increasing value */
12353 get_monotonic_boottime(&ts);
12354 mgmt->u.probe_resp.timestamp =
12355 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12356#else
12357 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12359 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012360
12361#endif
12362
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12364 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012365
12366#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12367 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12368 /* Assuming this is the last IE, copy at the end */
12369 ie_length -=sizeof(qcom_ie_age);
12370 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12371 qie_age->element_id = QCOM_VENDOR_IE_ID;
12372 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12373 qie_age->oui_1 = QCOM_OUI1;
12374 qie_age->oui_2 = QCOM_OUI2;
12375 qie_age->oui_3 = QCOM_OUI3;
12376 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012377 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12378 * bss related timestamp is in units of ms. Due to this when scan results
12379 * are sent to lowi the scan age is high.To address this, send age in units
12380 * of 1/10 ms.
12381 */
12382 qie_age->age = (vos_timer_get_system_time() -
12383 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012384#endif
12385
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012387 if (bss_desc->fProbeRsp)
12388 {
12389 mgmt->frame_control |=
12390 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12391 }
12392 else
12393 {
12394 mgmt->frame_control |=
12395 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12396 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012397
12398#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012399 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12401 {
12402 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12403 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012404 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12406
12407 {
12408 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12409 }
12410 else
12411 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12413 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 kfree(mgmt);
12415 return NULL;
12416 }
12417#else
12418 freq = ieee80211_channel_to_frequency(chan_no);
12419#endif
12420 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012421 /*when the band is changed on the fly using the GUI, three things are done
12422 * 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)
12423 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12424 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12425 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12426 * and discards the channels correponding to previous band and calls back with zero bss results.
12427 * 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
12428 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12429 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12430 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12431 * So drop the bss and continue to next bss.
12432 */
12433 if(chan == NULL)
12434 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012435 hddLog(VOS_TRACE_LEVEL_ERROR,
12436 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12437 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012438 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012439 return NULL;
12440 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012441 /*To keep the rssi icon of the connected AP in the scan window
12442 *and the rssi icon of the wireless networks in sync
12443 * */
12444 if (( eConnectionState_Associated ==
12445 pAdapter->sessionCtx.station.conn_info.connState ) &&
12446 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12447 pAdapter->sessionCtx.station.conn_info.bssId,
12448 WNI_CFG_BSSID_LEN)) &&
12449 (pHddCtx->hdd_wlan_suspended == FALSE))
12450 {
12451 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12452 rssi = (pAdapter->rssi * 100);
12453 }
12454 else
12455 {
12456 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12457 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012458
Nirav Shah20ac06f2013-12-12 18:14:06 +053012459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012460 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12461 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012462
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12464 frame_len, rssi, GFP_KERNEL);
12465 kfree(mgmt);
12466 return bss_status;
12467}
12468
12469/*
12470 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12471 * This function is used to update the BSS data base of CFG8011
12472 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012473struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 tCsrRoamInfo *pRoamInfo
12475 )
12476{
12477 tCsrRoamConnectedProfile roamProfile;
12478 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12479 struct cfg80211_bss *bss = NULL;
12480
12481 ENTER();
12482
12483 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12484 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12485
12486 if (NULL != roamProfile.pBssDesc)
12487 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012488 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12489 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012490
12491 if (NULL == bss)
12492 {
12493 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12494 __func__);
12495 }
12496
12497 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12498 }
12499 else
12500 {
12501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12502 __func__);
12503 }
12504 return bss;
12505}
12506
12507/*
12508 * FUNCTION: wlan_hdd_cfg80211_update_bss
12509 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012510static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12511 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012513{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012514 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 tCsrScanResultInfo *pScanResult;
12516 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012517 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 tScanResultHandle pResult;
12519 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012520 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012521 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12525 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12526 NO_SESSION, pAdapter->sessionId));
12527
Wilson Yangf80a0542013-10-07 13:02:37 -070012528 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012529 ret = wlan_hdd_validate_context(pHddCtx);
12530 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012532 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012533 }
12534
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012535 if (pAdapter->request != NULL)
12536 {
12537 if ((pAdapter->request->n_ssids == 1)
12538 && (pAdapter->request->ssids != NULL)
12539 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12540 is_p2p_scan = true;
12541 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 /*
12543 * start getting scan results and populate cgf80211 BSS database
12544 */
12545 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12546
12547 /* no scan results */
12548 if (NULL == pResult)
12549 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012550 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12551 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012552 wlan_hdd_get_frame_logs(pAdapter,
12553 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 return status;
12555 }
12556
12557 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12558
12559 while (pScanResult)
12560 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012561 /*
12562 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12563 * entry already exists in bss data base of cfg80211 for that
12564 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12565 * bss entry instead of cfg80211_inform_bss, But this call expects
12566 * mgmt packet as input. As of now there is no possibility to get
12567 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 * ieee80211_mgmt(probe response) and passing to c
12569 * fg80211_inform_bss_frame.
12570 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012571 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12572 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12573 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012574 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12575 continue; //Skip the non p2p bss entries
12576 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12578 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012579
Jeff Johnson295189b2012-06-20 16:38:30 -070012580
12581 if (NULL == bss_status)
12582 {
12583 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012584 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 }
12586 else
12587 {
Yue Maf49ba872013-08-19 12:04:25 -070012588 cfg80211_put_bss(
12589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12590 wiphy,
12591#endif
12592 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 }
12594
12595 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12596 }
12597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012598 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012599 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012600 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012601}
12602
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012603void
12604hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12605{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012606 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012607 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012608} /****** end hddPrintMacAddr() ******/
12609
12610void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012611hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012613 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012614 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012615 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12616 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12617 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012618} /****** end hddPrintPmkId() ******/
12619
12620//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12621//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12622
12623//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12624//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12625
12626#define dump_bssid(bssid) \
12627 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012628 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12629 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012630 }
12631
12632#define dump_pmkid(pMac, pmkid) \
12633 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012634 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12635 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012636 }
12637
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012638#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012639/*
12640 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12641 * This function is used to notify the supplicant of a new PMKSA candidate.
12642 */
12643int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012644 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012645 int index, bool preauth )
12646{
Jeff Johnsone7245742012-09-05 17:12:55 -070012647#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012648 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012649 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012650
12651 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012652 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012653
12654 if( NULL == pRoamInfo )
12655 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012656 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012657 return -EINVAL;
12658 }
12659
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012660 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12661 {
12662 dump_bssid(pRoamInfo->bssid);
12663 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012664 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012665 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012666#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012667 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012668}
12669#endif //FEATURE_WLAN_LFR
12670
Yue Maef608272013-04-08 23:09:17 -070012671#ifdef FEATURE_WLAN_LFR_METRICS
12672/*
12673 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12674 * 802.11r/LFR metrics reporting function to report preauth initiation
12675 *
12676 */
12677#define MAX_LFR_METRICS_EVENT_LENGTH 100
12678VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12679 tCsrRoamInfo *pRoamInfo)
12680{
12681 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12682 union iwreq_data wrqu;
12683
12684 ENTER();
12685
12686 if (NULL == pAdapter)
12687 {
12688 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12689 return VOS_STATUS_E_FAILURE;
12690 }
12691
12692 /* create the event */
12693 memset(&wrqu, 0, sizeof(wrqu));
12694 memset(metrics_notification, 0, sizeof(metrics_notification));
12695
12696 wrqu.data.pointer = metrics_notification;
12697 wrqu.data.length = scnprintf(metrics_notification,
12698 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12699 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12700
12701 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12702
12703 EXIT();
12704
12705 return VOS_STATUS_SUCCESS;
12706}
12707
12708/*
12709 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12710 * 802.11r/LFR metrics reporting function to report preauth completion
12711 * or failure
12712 */
12713VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12714 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12715{
12716 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12717 union iwreq_data wrqu;
12718
12719 ENTER();
12720
12721 if (NULL == pAdapter)
12722 {
12723 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12724 return VOS_STATUS_E_FAILURE;
12725 }
12726
12727 /* create the event */
12728 memset(&wrqu, 0, sizeof(wrqu));
12729 memset(metrics_notification, 0, sizeof(metrics_notification));
12730
12731 scnprintf(metrics_notification, sizeof(metrics_notification),
12732 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12733 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12734
12735 if (1 == preauth_status)
12736 strncat(metrics_notification, " TRUE", 5);
12737 else
12738 strncat(metrics_notification, " FALSE", 6);
12739
12740 wrqu.data.pointer = metrics_notification;
12741 wrqu.data.length = strlen(metrics_notification);
12742
12743 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12744
12745 EXIT();
12746
12747 return VOS_STATUS_SUCCESS;
12748}
12749
12750/*
12751 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12752 * 802.11r/LFR metrics reporting function to report handover initiation
12753 *
12754 */
12755VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12756 tCsrRoamInfo *pRoamInfo)
12757{
12758 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12759 union iwreq_data wrqu;
12760
12761 ENTER();
12762
12763 if (NULL == pAdapter)
12764 {
12765 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12766 return VOS_STATUS_E_FAILURE;
12767 }
12768
12769 /* create the event */
12770 memset(&wrqu, 0, sizeof(wrqu));
12771 memset(metrics_notification, 0, sizeof(metrics_notification));
12772
12773 wrqu.data.pointer = metrics_notification;
12774 wrqu.data.length = scnprintf(metrics_notification,
12775 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12776 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12777
12778 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12779
12780 EXIT();
12781
12782 return VOS_STATUS_SUCCESS;
12783}
12784#endif
12785
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012786
12787/**
12788 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12789 * @scan_req: scan request to be checked
12790 *
12791 * Return: true or false
12792 */
12793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12794static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12795 cfg80211_scan_request
12796 *scan_req)
12797{
12798 if (!scan_req || !scan_req->wiphy) {
12799 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12800 return false;
12801 }
12802 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12803 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12804 return false;
12805 }
12806 return true;
12807}
12808#else
12809static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12810 cfg80211_scan_request
12811 *scan_req)
12812{
12813 if (!scan_req || !scan_req->wiphy) {
12814 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12815 return false;
12816 }
12817 return true;
12818}
12819#endif
12820
12821
Jeff Johnson295189b2012-06-20 16:38:30 -070012822/*
12823 * FUNCTION: hdd_cfg80211_scan_done_callback
12824 * scanning callback function, called after finishing scan
12825 *
12826 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012827static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12829{
12830 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012831 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012833 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 struct cfg80211_scan_request *req = NULL;
12835 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012836 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12838 bool iface_down = false;
12839#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012840 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012841 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012842 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012843
12844 ENTER();
12845
c_manjee1b4ab9a2016-10-26 11:36:55 +053012846 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12847 !pAdapter->dev) {
12848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12849 return 0;
12850 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012851 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012852 if (NULL == pHddCtx) {
12853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012854 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012855 }
12856
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12858 if (!(pAdapter->dev->flags & IFF_UP))
12859 {
12860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012861 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012862 }
12863#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012864 pScanInfo = &pHddCtx->scan_info;
12865
Jeff Johnson295189b2012-06-20 16:38:30 -070012866 hddLog(VOS_TRACE_LEVEL_INFO,
12867 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012868 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012869 __func__, halHandle, pContext, (int) scanId, (int) status);
12870
Kiet Lamac06e2c2013-10-23 16:25:07 +053012871 pScanInfo->mScanPendingCounter = 0;
12872
Jeff Johnson295189b2012-06-20 16:38:30 -070012873 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012874 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 &pScanInfo->scan_req_completion_event,
12876 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012877 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012879 hddLog(VOS_TRACE_LEVEL_ERROR,
12880 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012882 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 }
12884
Yue Maef608272013-04-08 23:09:17 -070012885 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 {
12887 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012888 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 }
12890
12891 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 {
12894 hddLog(VOS_TRACE_LEVEL_INFO,
12895 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012896 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 (int) scanId);
12898 }
12899
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012901 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012902#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012903 {
12904 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12905 pAdapter);
12906 if (0 > ret)
12907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012909
Jeff Johnson295189b2012-06-20 16:38:30 -070012910 /* If any client wait scan result through WEXT
12911 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012912 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 {
12914 /* The other scan request waiting for current scan finish
12915 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012916 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012917 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012918 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012919 }
12920 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012921 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 {
12923 struct net_device *dev = pAdapter->dev;
12924 union iwreq_data wrqu;
12925 int we_event;
12926 char *msg;
12927
12928 memset(&wrqu, '\0', sizeof(wrqu));
12929 we_event = SIOCGIWSCAN;
12930 msg = NULL;
12931 wireless_send_event(dev, we_event, &wrqu, msg);
12932 }
12933 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012934 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012935
12936 /* Get the Scan Req */
12937 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012938 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012939
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012940 /* Scan is no longer pending */
12941 pScanInfo->mScanPending = VOS_FALSE;
12942
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012943 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12947 iface_down ? "up" : "down");
12948#endif
12949
12950 if (pAdapter->dev) {
12951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12952 pAdapter->dev->name);
12953 }
mukul sharmae7041822015-12-03 15:09:21 +053012954 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 }
12957
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012958 /* last_scan_timestamp is used to decide if new scan
12959 * is needed or not on station interface. If last station
12960 * scan time and new station scan time is less then
12961 * last_scan_timestamp ; driver will return cached scan.
12962 */
12963 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12964 {
12965 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12966
12967 if ( req->n_channels )
12968 {
12969 for (i = 0; i < req->n_channels ; i++ )
12970 {
12971 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12972 }
12973 /* store no of channel scanned */
12974 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12975 }
12976
12977 }
12978
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012979 /*
12980 * cfg80211_scan_done informing NL80211 about completion
12981 * of scanning
12982 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012983 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12984 {
12985 aborted = true;
12986 }
mukul sharmae7041822015-12-03 15:09:21 +053012987
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12989 if (!iface_down)
12990#endif
12991 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012992
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012993 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012994
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012995allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012996 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12997 ) && (pHddCtx->spoofMacAddr.isEnabled
12998 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012999 /* Generate new random mac addr for next scan */
13000 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013001
13002 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13003 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013004 }
13005
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013006 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013007 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013008
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013009 /* Acquire wakelock to handle the case where APP's tries to suspend
13010 * immediatly after the driver gets connect request(i.e after scan)
13011 * from supplicant, this result in app's is suspending and not able
13012 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013013 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013014
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13016 if (!iface_down)
13017#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013018#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013019 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013020#endif
13021
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 EXIT();
13023 return 0;
13024}
13025
13026/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013027 * FUNCTION: hdd_isConnectionInProgress
13028 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013029 *
13030 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013031v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13032 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013033{
13034 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13035 hdd_station_ctx_t *pHddStaCtx = NULL;
13036 hdd_adapter_t *pAdapter = NULL;
13037 VOS_STATUS status = 0;
13038 v_U8_t staId = 0;
13039 v_U8_t *staMac = NULL;
13040
13041 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13042
13043 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13044 {
13045 pAdapter = pAdapterNode->pAdapter;
13046
13047 if( pAdapter )
13048 {
13049 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013050 "%s: Adapter with device mode %s (%d) exists",
13051 __func__, hdd_device_modetoString(pAdapter->device_mode),
13052 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013053 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013054 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13055 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13056 (eConnectionState_Connecting ==
13057 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13058 {
13059 hddLog(VOS_TRACE_LEVEL_ERROR,
13060 "%s: %p(%d) Connection is in progress", __func__,
13061 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013062 if (session_id && reason)
13063 {
13064 *session_id = pAdapter->sessionId;
13065 *reason = eHDD_CONNECTION_IN_PROGRESS;
13066 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013067 return VOS_TRUE;
13068 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013069 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013070 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013071 {
13072 hddLog(VOS_TRACE_LEVEL_ERROR,
13073 "%s: %p(%d) Reassociation is in progress", __func__,
13074 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013075 if (session_id && reason)
13076 {
13077 *session_id = pAdapter->sessionId;
13078 *reason = eHDD_REASSOC_IN_PROGRESS;
13079 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013080 return VOS_TRUE;
13081 }
13082 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013083 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13084 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013085 {
13086 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13087 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013088 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013089 {
13090 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13091 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013092 "%s: client " MAC_ADDRESS_STR
13093 " is in the middle of WPS/EAPOL exchange.", __func__,
13094 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013095 if (session_id && reason)
13096 {
13097 *session_id = pAdapter->sessionId;
13098 *reason = eHDD_EAPOL_IN_PROGRESS;
13099 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013100 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013101 }
13102 }
13103 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13104 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13105 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013106 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13107 ptSapContext pSapCtx = NULL;
13108 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13109 if(pSapCtx == NULL){
13110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13111 FL("psapCtx is NULL"));
13112 return VOS_FALSE;
13113 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013114 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13115 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013116 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13117 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013118 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013119 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013120
13121 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013122 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13123 "middle of WPS/EAPOL exchange.", __func__,
13124 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013125 if (session_id && reason)
13126 {
13127 *session_id = pAdapter->sessionId;
13128 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13129 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013130 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013131 }
13132 }
13133 }
13134 }
13135 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13136 pAdapterNode = pNext;
13137 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013138 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013139}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013140
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013141/**
13142 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13143 * to the Scan request
13144 * @scanRequest: Pointer to the csr scan request
13145 * @request: Pointer to the scan request from supplicant
13146 *
13147 * Return: None
13148 */
13149#ifdef CFG80211_SCAN_BSSID
13150static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13151 struct cfg80211_scan_request *request)
13152{
13153 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13154}
13155#else
13156static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13157 struct cfg80211_scan_request *request)
13158{
13159}
13160#endif
13161
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013162/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013163 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013164 * this scan respond to scan trigger and update cfg80211 scan database
13165 * later, scan dump command can be used to recieve scan results
13166 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013167int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013168#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13169 struct net_device *dev,
13170#endif
13171 struct cfg80211_scan_request *request)
13172{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013173 hdd_adapter_t *pAdapter = NULL;
13174 hdd_context_t *pHddCtx = NULL;
13175 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013176 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 tCsrScanRequest scanRequest;
13178 tANI_U8 *channelList = NULL, i;
13179 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013180 int status;
13181 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013182 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013183 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013184 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013185 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013186 v_U8_t curr_session_id;
13187 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013188
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13190 struct net_device *dev = NULL;
13191 if (NULL == request)
13192 {
13193 hddLog(VOS_TRACE_LEVEL_ERROR,
13194 "%s: scan req param null", __func__);
13195 return -EINVAL;
13196 }
13197 dev = request->wdev->netdev;
13198#endif
13199
13200 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13201 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13202 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13203
Jeff Johnson295189b2012-06-20 16:38:30 -070013204 ENTER();
13205
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13207 __func__, hdd_device_modetoString(pAdapter->device_mode),
13208 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013209
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013210 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013211 if (0 != status)
13212 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013213 return status;
13214 }
13215
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013216 if (NULL == pwextBuf)
13217 {
13218 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13219 __func__);
13220 return -EIO;
13221 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013222 cfg_param = pHddCtx->cfg_ini;
13223 pScanInfo = &pHddCtx->scan_info;
13224
Jeff Johnson295189b2012-06-20 16:38:30 -070013225#ifdef WLAN_BTAMP_FEATURE
13226 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013227 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013229 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 "%s: No scanning when AMP is on", __func__);
13231 return -EOPNOTSUPP;
13232 }
13233#endif
13234 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013235 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013237 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013238 "%s: Not scanning on device_mode = %s (%d)",
13239 __func__, hdd_device_modetoString(pAdapter->device_mode),
13240 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013241 return -EOPNOTSUPP;
13242 }
13243
13244 if (TRUE == pScanInfo->mScanPending)
13245 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013246 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13247 {
13248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13249 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013250 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 }
13252
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013253 // Don't allow scan if PNO scan is going on.
13254 if (pHddCtx->isPnoEnable)
13255 {
13256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13257 FL("pno scan in progress"));
13258 return -EBUSY;
13259 }
13260
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013261 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013262 //Channel and action frame is pending
13263 //Otherwise Cancel Remain On Channel and allow Scan
13264 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013265 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013266 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013268 return -EBUSY;
13269 }
13270
Jeff Johnson295189b2012-06-20 16:38:30 -070013271 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13272 {
13273 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013274 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013275 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013276 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13278 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013279 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013280 "%s: MAX TM Level Scan not allowed", __func__);
13281 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013282 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013283 }
13284 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13285
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013286 /* Check if scan is allowed at this point of time.
13287 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013288 if (TRUE == pHddCtx->btCoexModeSet)
13289 {
13290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13291 FL("BTCoex Mode operation in progress"));
13292 return -EBUSY;
13293 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013294 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013295 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013297 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13298 pHddCtx->last_scan_reject_reason != curr_reason ||
13299 !pHddCtx->last_scan_reject_timestamp)
13300 {
13301 pHddCtx->last_scan_reject_session_id = curr_session_id;
13302 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013303 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013304 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013305 else {
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013306 if ((jiffies_to_msecs(jiffies) -
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013307 pHddCtx->last_scan_reject_timestamp) >=
13308 SCAN_REJECT_THRESHOLD_TIME)
13309 {
13310 pHddCtx->last_scan_reject_timestamp = 0;
13311 if (pHddCtx->cfg_ini->enableFatalEvent)
13312 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13313 WLAN_LOG_INDICATOR_HOST_DRIVER,
13314 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13315 FALSE, FALSE);
13316 else
13317 {
13318 hddLog(LOGE, FL("Triggering SSR"));
13319 vos_wlanRestart();
13320 }
13321 }
13322 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013323 return -EBUSY;
13324 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013325 pHddCtx->last_scan_reject_timestamp = 0;
13326 pHddCtx->last_scan_reject_session_id = 0xFF;
13327 pHddCtx->last_scan_reject_reason = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013328
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13330
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013331 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13332 * Becasue of this, driver is assuming that this is not wildcard scan and so
13333 * is not aging out the scan results.
13334 */
13335 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013336 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013337 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013338 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013339
13340 if ((request->ssids) && (0 < request->n_ssids))
13341 {
13342 tCsrSSIDInfo *SsidInfo;
13343 int j;
13344 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13345 /* Allocate num_ssid tCsrSSIDInfo structure */
13346 SsidInfo = scanRequest.SSIDs.SSIDList =
13347 ( tCsrSSIDInfo *)vos_mem_malloc(
13348 request->n_ssids*sizeof(tCsrSSIDInfo));
13349
13350 if(NULL == scanRequest.SSIDs.SSIDList)
13351 {
13352 hddLog(VOS_TRACE_LEVEL_ERROR,
13353 "%s: memory alloc failed SSIDInfo buffer", __func__);
13354 return -ENOMEM;
13355 }
13356
13357 /* copy all the ssid's and their length */
13358 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13359 {
13360 /* get the ssid length */
13361 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13362 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13363 SsidInfo->SSID.length);
13364 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13365 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13366 j, SsidInfo->SSID.ssId);
13367 }
13368 /* set the scan type to active */
13369 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13370 }
13371 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013373 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13374 TRACE_CODE_HDD_CFG80211_SCAN,
13375 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 /* set the scan type to active */
13377 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013379 else
13380 {
13381 /*Set the scan type to default type, in this case it is ACTIVE*/
13382 scanRequest.scanType = pScanInfo->scan_mode;
13383 }
13384 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13385 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013386
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013387 csr_scan_request_assign_bssid(&scanRequest, request);
13388
Jeff Johnson295189b2012-06-20 16:38:30 -070013389 /* set BSSType to default type */
13390 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13391
13392 /*TODO: scan the requested channels only*/
13393
13394 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013395 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013397 hddLog(VOS_TRACE_LEVEL_WARN,
13398 "No of Scan Channels exceeded limit: %d", request->n_channels);
13399 request->n_channels = MAX_CHANNEL;
13400 }
13401
13402 hddLog(VOS_TRACE_LEVEL_INFO,
13403 "No of Scan Channels: %d", request->n_channels);
13404
13405
13406 if( request->n_channels )
13407 {
13408 char chList [(request->n_channels*5)+1];
13409 int len;
13410 channelList = vos_mem_malloc( request->n_channels );
13411 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013412 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013413 hddLog(VOS_TRACE_LEVEL_ERROR,
13414 "%s: memory alloc failed channelList", __func__);
13415 status = -ENOMEM;
13416 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013417 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013418
13419 for( i = 0, len = 0; i < request->n_channels ; i++ )
13420 {
13421 channelList[i] = request->channels[i]->hw_value;
13422 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13423 }
13424
Nirav Shah20ac06f2013-12-12 18:14:06 +053013425 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013426 "Channel-List: %s ", chList);
13427 }
c_hpothu53512302014-04-15 18:49:53 +053013428
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013429 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13430 scanRequest.ChannelInfo.ChannelList = channelList;
13431
13432 /* set requestType to full scan */
13433 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13434
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013435 /* if there is back to back scan happening in driver with in
13436 * nDeferScanTimeInterval interval driver should defer new scan request
13437 * and should provide last cached scan results instead of new channel list.
13438 * This rule is not applicable if scan is p2p scan.
13439 * This condition will work only in case when last request no of channels
13440 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013441 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013442 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013443 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013444
Sushant Kaushik86592172015-04-27 16:35:03 +053013445 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13446 /* if wps ie is NULL , then only defer scan */
13447 if ( pWpsIe == NULL &&
13448 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013449 {
13450 if ( pScanInfo->last_scan_timestamp !=0 &&
13451 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13452 {
13453 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13454 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13455 vos_mem_compare(pScanInfo->last_scan_channelList,
13456 channelList, pScanInfo->last_scan_numChannels))
13457 {
13458 hddLog(VOS_TRACE_LEVEL_WARN,
13459 " New and old station scan time differ is less then %u",
13460 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13461
13462 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013463 pAdapter);
13464
Agarwal Ashish57e84372014-12-05 18:26:53 +053013465 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013466 "Return old cached scan as all channels and no of channels are same");
13467
Agarwal Ashish57e84372014-12-05 18:26:53 +053013468 if (0 > ret)
13469 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013470
Agarwal Ashish57e84372014-12-05 18:26:53 +053013471 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013472
13473 status = eHAL_STATUS_SUCCESS;
13474 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013475 }
13476 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013477 }
13478
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013479 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13480 * search (Flush on both full scan and social scan but not on single
13481 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13482 */
13483
13484 /* Supplicant does single channel scan after 8-way handshake
13485 * and in that case driver shoudnt flush scan results. If
13486 * driver flushes the scan results here and unfortunately if
13487 * the AP doesnt respond to our probe req then association
13488 * fails which is not desired
13489 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013490 if ((request->n_ssids == 1)
13491 && (request->ssids != NULL)
13492 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13493 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013494
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013495 if( is_p2p_scan ||
13496 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013497 {
13498 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13499 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13500 pAdapter->sessionId );
13501 }
13502
13503 if( request->ie_len )
13504 {
13505 /* save this for future association (join requires this) */
13506 /*TODO: Array needs to be converted to dynamic allocation,
13507 * as multiple ie.s can be sent in cfg80211_scan_request structure
13508 * CR 597966
13509 */
13510 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13511 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13512 pScanInfo->scanAddIE.length = request->ie_len;
13513
13514 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13515 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13516 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013518 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013519 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013520 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13521 memcpy( pwextBuf->roamProfile.addIEScan,
13522 request->ie, request->ie_len);
13523 }
13524 else
13525 {
13526 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13527 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013528 }
13529
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013530 }
13531 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13532 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13533
13534 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13535 request->ie_len);
13536 if (pP2pIe != NULL)
13537 {
13538#ifdef WLAN_FEATURE_P2P_DEBUG
13539 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13540 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13541 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013542 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013543 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13544 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13545 "Go nego completed to Connection is started");
13546 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13547 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013548 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013549 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13550 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013552 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13553 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13554 "Disconnected state to Connection is started");
13555 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13556 "for 4way Handshake");
13557 }
13558#endif
13559
13560 /* no_cck will be set during p2p find to disable 11b rates */
13561 if(TRUE == request->no_cck)
13562 {
13563 hddLog(VOS_TRACE_LEVEL_INFO,
13564 "%s: This is a P2P Search", __func__);
13565 scanRequest.p2pSearch = 1;
13566
13567 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013568 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013569 /* set requestType to P2P Discovery */
13570 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13571 }
13572
13573 /*
13574 Skip Dfs Channel in case of P2P Search
13575 if it is set in ini file
13576 */
13577 if(cfg_param->skipDfsChnlInP2pSearch)
13578 {
13579 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013580 }
13581 else
13582 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013583 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013585
Agarwal Ashish4f616132013-12-30 23:32:50 +053013586 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 }
13588 }
13589
13590 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13591
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013592#ifdef FEATURE_WLAN_TDLS
13593 /* if tdls disagree scan right now, return immediately.
13594 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13595 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13596 */
13597 status = wlan_hdd_tdls_scan_callback (pAdapter,
13598 wiphy,
13599#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13600 dev,
13601#endif
13602 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013603 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013604 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013605 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13607 "scan rejected %d", __func__, status);
13608 else
13609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13610 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013611 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013612 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013613 }
13614#endif
13615
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013616 /* acquire the wakelock to avoid the apps suspend during the scan. To
13617 * address the following issues.
13618 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13619 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13620 * for long time, this result in apps running at full power for long time.
13621 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13622 * be stuck in full power because of resume BMPS
13623 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013624 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013625
Nirav Shah20ac06f2013-12-12 18:14:06 +053013626 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13627 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013628 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13629 scanRequest.requestType, scanRequest.scanType,
13630 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013631 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13632
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013633 if (pHddCtx->spoofMacAddr.isEnabled &&
13634 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013635 {
13636 hddLog(VOS_TRACE_LEVEL_INFO,
13637 "%s: MAC Spoofing enabled for current scan", __func__);
13638 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13639 * to fill TxBds for probe request during current scan
13640 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013641 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013642 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013643
13644 if(status != VOS_STATUS_SUCCESS)
13645 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013646 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013647 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013648#ifdef FEATURE_WLAN_TDLS
13649 wlan_hdd_tdls_scan_done_callback(pAdapter);
13650#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013651 goto free_mem;
13652 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013653 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013654 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013655 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 pAdapter->sessionId, &scanRequest, &scanId,
13657 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013658
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 if (eHAL_STATUS_SUCCESS != status)
13660 {
13661 hddLog(VOS_TRACE_LEVEL_ERROR,
13662 "%s: sme_ScanRequest returned error %d", __func__, status);
13663 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013664 if(eHAL_STATUS_RESOURCES == status)
13665 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13667 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013668 status = -EBUSY;
13669 } else {
13670 status = -EIO;
13671 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013672 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013673
13674#ifdef FEATURE_WLAN_TDLS
13675 wlan_hdd_tdls_scan_done_callback(pAdapter);
13676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 goto free_mem;
13678 }
13679
13680 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013681 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 pAdapter->request = request;
13683 pScanInfo->scanId = scanId;
13684
13685 complete(&pScanInfo->scan_req_completion_event);
13686
13687free_mem:
13688 if( scanRequest.SSIDs.SSIDList )
13689 {
13690 vos_mem_free(scanRequest.SSIDs.SSIDList);
13691 }
13692
13693 if( channelList )
13694 vos_mem_free( channelList );
13695
13696 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 return status;
13698}
13699
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013700int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13701#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13702 struct net_device *dev,
13703#endif
13704 struct cfg80211_scan_request *request)
13705{
13706 int ret;
13707
13708 vos_ssr_protect(__func__);
13709 ret = __wlan_hdd_cfg80211_scan(wiphy,
13710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13711 dev,
13712#endif
13713 request);
13714 vos_ssr_unprotect(__func__);
13715
13716 return ret;
13717}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013718
13719void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13720{
13721 v_U8_t iniDot11Mode =
13722 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13723 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13724
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013725 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13726 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013727 switch ( iniDot11Mode )
13728 {
13729 case eHDD_DOT11_MODE_AUTO:
13730 case eHDD_DOT11_MODE_11ac:
13731 case eHDD_DOT11_MODE_11ac_ONLY:
13732#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013733 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13734 sme_IsFeatureSupportedByFW(DOT11AC) )
13735 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13736 else
13737 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013738#else
13739 hddDot11Mode = eHDD_DOT11_MODE_11n;
13740#endif
13741 break;
13742 case eHDD_DOT11_MODE_11n:
13743 case eHDD_DOT11_MODE_11n_ONLY:
13744 hddDot11Mode = eHDD_DOT11_MODE_11n;
13745 break;
13746 default:
13747 hddDot11Mode = iniDot11Mode;
13748 break;
13749 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013750#ifdef WLAN_FEATURE_AP_HT40_24G
13751 if (operationChannel > SIR_11B_CHANNEL_END)
13752#endif
13753 {
13754 /* This call decides required channel bonding mode */
13755 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013756 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13757 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013758 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013759}
13760
Jeff Johnson295189b2012-06-20 16:38:30 -070013761/*
13762 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013763 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013765int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013766 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13767 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013768{
13769 int status = 0;
13770 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013771 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 v_U32_t roamId;
13773 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013775 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013776
13777 ENTER();
13778
13779 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13781
13782 status = wlan_hdd_validate_context(pHddCtx);
13783 if (status)
13784 {
Yue Mae36e3552014-03-05 17:06:20 -080013785 return status;
13786 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013787
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13789 {
13790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13791 return -EINVAL;
13792 }
13793
13794 pRoamProfile = &pWextState->roamProfile;
13795
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013796 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013798 hdd_station_ctx_t *pHddStaCtx;
13799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013800
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013801 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13802
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013803 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13805 {
13806 /*QoS not enabled in cfg file*/
13807 pRoamProfile->uapsd_mask = 0;
13808 }
13809 else
13810 {
13811 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13814 }
13815
13816 pRoamProfile->SSIDs.numOfSSIDs = 1;
13817 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13818 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013819 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13821 ssid, ssid_len);
13822
13823 if (bssid)
13824 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013825 pValidBssid = bssid;
13826 }
13827 else if (bssid_hint)
13828 {
13829 pValidBssid = bssid_hint;
13830 }
13831 if (pValidBssid)
13832 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013833 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013834 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 /* Save BSSID in seperate variable as well, as RoamProfile
13837 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 case of join failure we should send valid BSSID to supplicant
13839 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013840 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 WNI_CFG_BSSID_LEN);
13842 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013843 else
13844 {
13845 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13846 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013847
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013848 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13849 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13851 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013852 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 /*set gen ie*/
13854 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13855 /*set auth*/
13856 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13857 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013858#ifdef FEATURE_WLAN_WAPI
13859 if (pAdapter->wapi_info.nWapiMode)
13860 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013861 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 switch (pAdapter->wapi_info.wapiAuthMode)
13863 {
13864 case WAPI_AUTH_MODE_PSK:
13865 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013866 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 pAdapter->wapi_info.wapiAuthMode);
13868 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13869 break;
13870 }
13871 case WAPI_AUTH_MODE_CERT:
13872 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013873 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 pAdapter->wapi_info.wapiAuthMode);
13875 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13876 break;
13877 }
13878 } // End of switch
13879 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13880 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13881 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013882 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 pRoamProfile->AuthType.numEntries = 1;
13884 pRoamProfile->EncryptionType.numEntries = 1;
13885 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13886 pRoamProfile->mcEncryptionType.numEntries = 1;
13887 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13888 }
13889 }
13890#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013891#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013892 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013893 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13894 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13895 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013896 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13897 sizeof (tSirGtkOffloadParams));
13898 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013899 }
13900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 pRoamProfile->csrPersona = pAdapter->device_mode;
13902
Jeff Johnson32d95a32012-09-10 13:15:23 -070013903 if( operatingChannel )
13904 {
13905 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13906 pRoamProfile->ChannelInfo.numOfChannels = 1;
13907 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013908 else
13909 {
13910 pRoamProfile->ChannelInfo.ChannelList = NULL;
13911 pRoamProfile->ChannelInfo.numOfChannels = 0;
13912 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013913 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13914 {
13915 hdd_select_cbmode(pAdapter,operatingChannel);
13916 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013917
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013918 /*
13919 * Change conn_state to connecting before sme_RoamConnect(),
13920 * because sme_RoamConnect() has a direct path to call
13921 * hdd_smeRoamCallback(), which will change the conn_state
13922 * If direct path, conn_state will be accordingly changed
13923 * to NotConnected or Associated by either
13924 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13925 * in sme_RoamCallback()
13926 * if sme_RomConnect is to be queued,
13927 * Connecting state will remain until it is completed.
13928 * If connection state is not changed,
13929 * connection state will remain in eConnectionState_NotConnected state.
13930 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13931 * if conn state is eConnectionState_NotConnected.
13932 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13933 * informed of connect result indication which is an issue.
13934 */
13935
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013936 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13937 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013938 {
13939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013940 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013941 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13942 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013943 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013944 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 pAdapter->sessionId, pRoamProfile, &roamId);
13946
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013947 if ((eHAL_STATUS_SUCCESS != status) &&
13948 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13949 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013950
13951 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013952 hddLog(VOS_TRACE_LEVEL_ERROR,
13953 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13954 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013955 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013956 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013957 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013958 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013959
13960 pRoamProfile->ChannelInfo.ChannelList = NULL;
13961 pRoamProfile->ChannelInfo.numOfChannels = 0;
13962
Jeff Johnson295189b2012-06-20 16:38:30 -070013963 }
13964 else
13965 {
13966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13967 return -EINVAL;
13968 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013969 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 return status;
13971}
13972
13973/*
13974 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13975 * This function is used to set the authentication type (OPEN/SHARED).
13976 *
13977 */
13978static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13979 enum nl80211_auth_type auth_type)
13980{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013981 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13983
13984 ENTER();
13985
13986 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013987 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013990 hddLog(VOS_TRACE_LEVEL_INFO,
13991 "%s: set authentication type to AUTOSWITCH", __func__);
13992 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13993 break;
13994
13995 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013996#ifdef WLAN_FEATURE_VOWIFI_11R
13997 case NL80211_AUTHTYPE_FT:
13998#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013999 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 "%s: set authentication type to OPEN", __func__);
14001 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14002 break;
14003
14004 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014005 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 "%s: set authentication type to SHARED", __func__);
14007 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14008 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014009#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014011 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014012 "%s: set authentication type to CCKM WPA", __func__);
14013 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14014 break;
14015#endif
14016
14017
14018 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014019 hddLog(VOS_TRACE_LEVEL_ERROR,
14020 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 auth_type);
14022 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14023 return -EINVAL;
14024 }
14025
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 pHddStaCtx->conn_info.authType;
14028 return 0;
14029}
14030
14031/*
14032 * FUNCTION: wlan_hdd_set_akm_suite
14033 * This function is used to set the key mgmt type(PSK/8021x).
14034 *
14035 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 u32 key_mgmt
14038 )
14039{
14040 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14041 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014042 /* Should be in ieee802_11_defs.h */
14043#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
14044#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 /*set key mgmt type*/
14046 switch(key_mgmt)
14047 {
14048 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014049 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014050#ifdef WLAN_FEATURE_VOWIFI_11R
14051 case WLAN_AKM_SUITE_FT_PSK:
14052#endif
14053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 __func__);
14055 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14056 break;
14057
14058 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014059 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014060#ifdef WLAN_FEATURE_VOWIFI_11R
14061 case WLAN_AKM_SUITE_FT_8021X:
14062#endif
14063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 __func__);
14065 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14066 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014067#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014068#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14069#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14070 case WLAN_AKM_SUITE_CCKM:
14071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14072 __func__);
14073 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14074 break;
14075#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014076#ifndef WLAN_AKM_SUITE_OSEN
14077#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14078 case WLAN_AKM_SUITE_OSEN:
14079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14080 __func__);
14081 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14082 break;
14083#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014084
14085 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014087 __func__, key_mgmt);
14088 return -EINVAL;
14089
14090 }
14091 return 0;
14092}
14093
14094/*
14095 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014096 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 * (NONE/WEP40/WEP104/TKIP/CCMP).
14098 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14100 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 bool ucast
14102 )
14103{
14104 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014105 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14107
14108 ENTER();
14109
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014110 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014113 __func__, cipher);
14114 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14115 }
14116 else
14117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014118
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014120 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014121 {
14122 case IW_AUTH_CIPHER_NONE:
14123 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14124 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014125
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014127 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014131 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014132 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014133
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 case WLAN_CIPHER_SUITE_TKIP:
14135 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14136 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014137
Jeff Johnson295189b2012-06-20 16:38:30 -070014138 case WLAN_CIPHER_SUITE_CCMP:
14139 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14140 break;
14141#ifdef FEATURE_WLAN_WAPI
14142 case WLAN_CIPHER_SUITE_SMS4:
14143 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14144 break;
14145#endif
14146
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014147#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 case WLAN_CIPHER_SUITE_KRK:
14149 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14150 break;
14151#endif
14152 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014154 __func__, cipher);
14155 return -EOPNOTSUPP;
14156 }
14157 }
14158
14159 if (ucast)
14160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014161 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 __func__, encryptionType);
14163 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14164 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014165 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014166 encryptionType;
14167 }
14168 else
14169 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014171 __func__, encryptionType);
14172 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14173 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14174 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14175 }
14176
14177 return 0;
14178}
14179
14180
14181/*
14182 * FUNCTION: wlan_hdd_cfg80211_set_ie
14183 * This function is used to parse WPA/RSN IE's.
14184 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014185int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14187 const u8 *ie,
14188#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014189 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014191 size_t ie_len
14192 )
14193{
14194 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14196 const u8 *genie = ie;
14197#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014198 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014200 v_U16_t remLen = ie_len;
14201#ifdef FEATURE_WLAN_WAPI
14202 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14203 u16 *tmp;
14204 v_U16_t akmsuiteCount;
14205 int *akmlist;
14206#endif
14207 ENTER();
14208
14209 /* clear previous assocAddIE */
14210 pWextState->assocAddIE.length = 0;
14211 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014212 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014213
14214 while (remLen >= 2)
14215 {
14216 v_U16_t eLen = 0;
14217 v_U8_t elementId;
14218 elementId = *genie++;
14219 eLen = *genie++;
14220 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014221
Arif Hussain6d2a3322013-11-17 19:50:10 -080014222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014223 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014224
14225 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014227 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014228 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 -070014229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014230 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014231 "%s: Invalid WPA IE", __func__);
14232 return -EINVAL;
14233 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014234 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014235 {
14236 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014237 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014238 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014239
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014240 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014241 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014242 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14243 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 VOS_ASSERT(0);
14245 return -ENOMEM;
14246 }
14247 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14248 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14249 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014250
Jeff Johnson295189b2012-06-20 16:38:30 -070014251 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14252 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14253 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014255 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14256 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14258 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14259 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14260 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14261 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014263 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014264 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 {
14266 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014267 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014268 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014270 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014272 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14273 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 VOS_ASSERT(0);
14275 return -ENOMEM;
14276 }
14277 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14278 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14279 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014280
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14282 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014284#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014285 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14286 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 /*Consider WFD IE, only for P2P Client */
14288 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14289 {
14290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014293
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014294 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014295 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14297 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014298 VOS_ASSERT(0);
14299 return -ENOMEM;
14300 }
14301 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14302 // WPS IE + P2P IE + WFD IE
14303 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14304 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014305
Jeff Johnson295189b2012-06-20 16:38:30 -070014306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14308 }
14309#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014310 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014311 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014312 HS20_OUI_TYPE_SIZE)) )
14313 {
14314 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014315 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014316 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014317
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014318 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014319 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014320 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14321 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014322 VOS_ASSERT(0);
14323 return -ENOMEM;
14324 }
14325 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14326 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014327
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014328 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14329 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14330 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014331 /* Appending OSEN Information Element in Assiciation Request */
14332 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14333 OSEN_OUI_TYPE_SIZE)) )
14334 {
14335 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14336 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14337 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014338
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014339 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014340 {
14341 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14342 "Need bigger buffer space");
14343 VOS_ASSERT(0);
14344 return -ENOMEM;
14345 }
14346 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14347 pWextState->assocAddIE.length += eLen + 2;
14348
14349 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14350 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14351 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14352 }
14353
Abhishek Singh4322e622015-06-10 15:42:54 +053014354 /* Update only for WPA IE */
14355 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14356 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014357
14358 /* populating as ADDIE in beacon frames */
14359 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014360 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014361 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14362 {
14363 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14364 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14365 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14366 {
14367 hddLog(LOGE,
14368 "Coldn't pass "
14369 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14370 }
14371 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14372 else
14373 hddLog(LOGE,
14374 "Could not pass on "
14375 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14376
14377 /* IBSS mode doesn't contain params->proberesp_ies still
14378 beaconIE's need to be populated in probe response frames */
14379 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14380 {
14381 u16 rem_probe_resp_ie_len = eLen + 2;
14382 u8 probe_rsp_ie_len[3] = {0};
14383 u8 counter = 0;
14384
14385 /* Check Probe Resp Length if it is greater then 255 then
14386 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14387 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14388 not able Store More then 255 bytes into One Variable */
14389
14390 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14391 {
14392 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14393 {
14394 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14395 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14396 }
14397 else
14398 {
14399 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14400 rem_probe_resp_ie_len = 0;
14401 }
14402 }
14403
14404 rem_probe_resp_ie_len = 0;
14405
14406 if (probe_rsp_ie_len[0] > 0)
14407 {
14408 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14409 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14410 (tANI_U8*)(genie - 2),
14411 probe_rsp_ie_len[0], NULL,
14412 eANI_BOOLEAN_FALSE)
14413 == eHAL_STATUS_FAILURE)
14414 {
14415 hddLog(LOGE,
14416 "Could not pass"
14417 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14418 }
14419 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14420 }
14421
14422 if (probe_rsp_ie_len[1] > 0)
14423 {
14424 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14425 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14426 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14427 probe_rsp_ie_len[1], NULL,
14428 eANI_BOOLEAN_FALSE)
14429 == eHAL_STATUS_FAILURE)
14430 {
14431 hddLog(LOGE,
14432 "Could not pass"
14433 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14434 }
14435 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14436 }
14437
14438 if (probe_rsp_ie_len[2] > 0)
14439 {
14440 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14441 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14442 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14443 probe_rsp_ie_len[2], NULL,
14444 eANI_BOOLEAN_FALSE)
14445 == eHAL_STATUS_FAILURE)
14446 {
14447 hddLog(LOGE,
14448 "Could not pass"
14449 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14450 }
14451 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14452 }
14453
14454 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14455 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14456 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14457 {
14458 hddLog(LOGE,
14459 "Could not pass"
14460 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14461 }
14462 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014463 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 break;
14465 case DOT11F_EID_RSN:
14466 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14467 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14468 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14469 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14470 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14471 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014472
Abhishek Singhb16f3562016-01-20 11:08:32 +053014473 /* Appending extended capabilities with Interworking or
14474 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014475 *
14476 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014477 * interworkingService or bsstransition bit is set to 1.
14478 * Driver is only interested in interworkingService and
14479 * bsstransition capability from supplicant.
14480 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014481 * required from supplicat, it needs to be handled while
14482 * sending Assoc Req in LIM.
14483 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014484 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014485 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014486 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014487 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014488 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014489
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014490 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014491 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014492 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14493 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014494 VOS_ASSERT(0);
14495 return -ENOMEM;
14496 }
14497 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14498 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014499
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014500 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14501 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14502 break;
14503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014504#ifdef FEATURE_WLAN_WAPI
14505 case WLAN_EID_WAPI:
14506 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014507 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 pAdapter->wapi_info.nWapiMode);
14509 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014510 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 akmsuiteCount = WPA_GET_LE16(tmp);
14512 tmp = tmp + 1;
14513 akmlist = (int *)(tmp);
14514 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14515 {
14516 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14517 }
14518 else
14519 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014520 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 VOS_ASSERT(0);
14522 return -EINVAL;
14523 }
14524
14525 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14526 {
14527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014528 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014529 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014530 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014532 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014534 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14536 }
14537 break;
14538#endif
14539 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014540 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014541 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014542 /* when Unknown IE is received we should break and continue
14543 * to the next IE in the buffer instead we were returning
14544 * so changing this to break */
14545 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014546 }
14547 genie += eLen;
14548 remLen -= eLen;
14549 }
14550 EXIT();
14551 return 0;
14552}
14553
14554/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014555 * FUNCTION: hdd_isWPAIEPresent
14556 * Parse the received IE to find the WPA IE
14557 *
14558 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014559static bool hdd_isWPAIEPresent(
14560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14561 const u8 *ie,
14562#else
14563 u8 *ie,
14564#endif
14565 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014566{
14567 v_U8_t eLen = 0;
14568 v_U16_t remLen = ie_len;
14569 v_U8_t elementId = 0;
14570
14571 while (remLen >= 2)
14572 {
14573 elementId = *ie++;
14574 eLen = *ie++;
14575 remLen -= 2;
14576 if (eLen > remLen)
14577 {
14578 hddLog(VOS_TRACE_LEVEL_ERROR,
14579 "%s: IE length is wrong %d", __func__, eLen);
14580 return FALSE;
14581 }
14582 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14583 {
14584 /* OUI - 0x00 0X50 0XF2
14585 WPA Information Element - 0x01
14586 WPA version - 0x01*/
14587 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14588 return TRUE;
14589 }
14590 ie += eLen;
14591 remLen -= eLen;
14592 }
14593 return FALSE;
14594}
14595
14596/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014597 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014598 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014599 * parameters during connect operation.
14600 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014601int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014603 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014604{
14605 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014606 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014607 ENTER();
14608
14609 /*set wpa version*/
14610 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14611
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014612 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014613 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014614 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014615 {
14616 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14617 }
14618 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14619 {
14620 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14621 }
14622 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014623
14624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014625 pWextState->wpaVersion);
14626
14627 /*set authentication type*/
14628 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14629
14630 if (0 > status)
14631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014632 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014633 "%s: failed to set authentication type ", __func__);
14634 return status;
14635 }
14636
14637 /*set key mgmt type*/
14638 if (req->crypto.n_akm_suites)
14639 {
14640 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14641 if (0 > status)
14642 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014644 __func__);
14645 return status;
14646 }
14647 }
14648
14649 /*set pairwise cipher type*/
14650 if (req->crypto.n_ciphers_pairwise)
14651 {
14652 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14653 req->crypto.ciphers_pairwise[0], true);
14654 if (0 > status)
14655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 "%s: failed to set unicast cipher type", __func__);
14658 return status;
14659 }
14660 }
14661 else
14662 {
14663 /*Reset previous cipher suite to none*/
14664 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14665 if (0 > status)
14666 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014667 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014668 "%s: failed to set unicast cipher type", __func__);
14669 return status;
14670 }
14671 }
14672
14673 /*set group cipher type*/
14674 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14675 false);
14676
14677 if (0 > status)
14678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 __func__);
14681 return status;
14682 }
14683
Chet Lanctot186b5732013-03-18 10:26:30 -070014684#ifdef WLAN_FEATURE_11W
14685 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14686#endif
14687
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14689 if (req->ie_len)
14690 {
14691 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14692 if ( 0 > status)
14693 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 __func__);
14696 return status;
14697 }
14698 }
14699
14700 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014701 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014702 {
14703 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14704 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14705 )
14706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014707 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 __func__);
14712 return -EOPNOTSUPP;
14713 }
14714 else
14715 {
14716 u8 key_len = req->key_len;
14717 u8 key_idx = req->key_idx;
14718
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014719 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 && (CSR_MAX_NUM_KEY > key_idx)
14721 )
14722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014723 hddLog(VOS_TRACE_LEVEL_INFO,
14724 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 __func__, key_idx, key_len);
14726 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014727 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014729 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 (u8)key_len;
14731 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14732 }
14733 }
14734 }
14735 }
14736
14737 return status;
14738}
14739
14740/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014741 * FUNCTION: wlan_hdd_try_disconnect
14742 * This function is used to disconnect from previous
14743 * connection
14744 */
14745static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14746{
14747 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014748 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014749 hdd_station_ctx_t *pHddStaCtx;
14750 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014751 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014752
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014753 ret = wlan_hdd_validate_context(pHddCtx);
14754 if (0 != ret)
14755 {
14756 return ret;
14757 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014758 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14759
14760 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14761
14762 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14763 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014764 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014765 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14766 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014767 spin_lock_bh(&pAdapter->lock_for_active_session);
14768 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14769 {
14770 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14771 }
14772 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014773 hdd_connSetConnectionState(pHddStaCtx,
14774 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014775 /* Issue disconnect to CSR */
14776 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014777 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014778 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014779 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14780 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14781 hddLog(LOG1,
14782 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14783 } else if ( 0 != status ) {
14784 hddLog(LOGE,
14785 FL("csrRoamDisconnect failure, returned %d"),
14786 (int)status );
14787 result = -EINVAL;
14788 goto disconnected;
14789 }
14790 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014791 &pAdapter->disconnect_comp_var,
14792 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014793 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14794 hddLog(LOGE,
14795 "%s: Failed to disconnect, timed out", __func__);
14796 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014797 }
14798 }
14799 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14800 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014801 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014802 &pAdapter->disconnect_comp_var,
14803 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014804 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014805 {
14806 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014807 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014808 }
14809 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014810disconnected:
14811 hddLog(LOG1,
14812 FL("Set HDD connState to eConnectionState_NotConnected"));
14813 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14814 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014815}
14816
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014817/**
14818 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14819 * @adapter: Pointer to the HDD adapter
14820 * @req: Pointer to the structure cfg_connect_params receieved from user space
14821 *
14822 * This function will start reassociation if bssid hint, channel hint and
14823 * previous bssid parameters are present in the connect request
14824 *
14825 * Return: success if reassociation is happening
14826 * Error code if reassociation is not permitted or not happening
14827 */
14828#ifdef CFG80211_CONNECT_PREV_BSSID
14829static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14830 struct cfg80211_connect_params *req)
14831{
14832 int status = -EPERM;
14833 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14834 hddLog(VOS_TRACE_LEVEL_INFO,
14835 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14836 req->channel_hint->hw_value,
14837 MAC_ADDR_ARRAY(req->bssid_hint));
14838 status = hdd_reassoc(adapter, req->bssid_hint,
14839 req->channel_hint->hw_value,
14840 CONNECT_CMD_USERSPACE);
14841 }
14842 return status;
14843}
14844#else
14845static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14846 struct cfg80211_connect_params *req)
14847{
14848 return -EPERM;
14849}
14850#endif
14851
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014852/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014853 * FUNCTION: __wlan_hdd_cfg80211_connect
14854 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014856static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 struct net_device *ndev,
14858 struct cfg80211_connect_params *req
14859 )
14860{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014861 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014862 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14864 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014865 const u8 *bssid_hint = req->bssid_hint;
14866#else
14867 const u8 *bssid_hint = NULL;
14868#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014871 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014872
14873 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014874
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014875 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14876 TRACE_CODE_HDD_CFG80211_CONNECT,
14877 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014878 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014879 "%s: device_mode = %s (%d)", __func__,
14880 hdd_device_modetoString(pAdapter->device_mode),
14881 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014882
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014883 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014884 if (!pHddCtx)
14885 {
14886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14887 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014888 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014889 }
14890
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014891 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014892 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014893 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014894 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 }
14896
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014897 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14898 if (0 == status)
14899 return status;
14900
Agarwal Ashish51325b52014-06-16 16:50:49 +053014901
Jeff Johnson295189b2012-06-20 16:38:30 -070014902#ifdef WLAN_BTAMP_FEATURE
14903 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014904 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014906 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014907 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014908 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 }
14910#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014911
14912 //If Device Mode is Station Concurrent Sessions Exit BMps
14913 //P2P Mode will be taken care in Open/close adapter
14914 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014915 (vos_concurrent_open_sessions_running())) {
14916 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14917 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014918 }
14919
14920 /*Try disconnecting if already in connected state*/
14921 status = wlan_hdd_try_disconnect(pAdapter);
14922 if ( 0 > status)
14923 {
14924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14925 " connection"));
14926 return -EALREADY;
14927 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014928 /* Check for max concurrent connections after doing disconnect if any*/
14929 if (vos_max_concurrent_connections_reached()) {
14930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14931 return -ECONNREFUSED;
14932 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014933
Jeff Johnson295189b2012-06-20 16:38:30 -070014934 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014935 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014936
14937 if ( 0 > status)
14938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 __func__);
14941 return status;
14942 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014943
14944 if (pHddCtx->spoofMacAddr.isEnabled)
14945 {
14946 hddLog(VOS_TRACE_LEVEL_INFO,
14947 "%s: MAC Spoofing enabled ", __func__);
14948 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14949 * to fill TxBds for probe request during SSID scan which may happen
14950 * as part of connect command
14951 */
14952 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14953 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14954 if (status != VOS_STATUS_SUCCESS)
14955 return -ECONNREFUSED;
14956 }
14957
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014958 if (req->channel)
14959 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014960 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014961 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053014962
14963 /* Abort if any scan is going on */
14964 status = wlan_hdd_scan_abort(pAdapter);
14965 if (0 != status)
14966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
14967
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014968 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14969 req->ssid_len, req->bssid,
14970 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014971
Sushant Kaushikd7083982015-03-18 14:33:24 +053014972 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 {
14974 //ReEnable BMPS if disabled
14975 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14976 (NULL != pHddCtx))
14977 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014978 if (pHddCtx->hdd_wlan_suspended)
14979 {
14980 hdd_set_pwrparams(pHddCtx);
14981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 //ReEnable Bmps and Imps back
14983 hdd_enable_bmps_imps(pHddCtx);
14984 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 return status;
14987 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014988 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 EXIT();
14990 return status;
14991}
14992
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014993static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14994 struct net_device *ndev,
14995 struct cfg80211_connect_params *req)
14996{
14997 int ret;
14998 vos_ssr_protect(__func__);
14999 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15000 vos_ssr_unprotect(__func__);
15001
15002 return ret;
15003}
Jeff Johnson295189b2012-06-20 16:38:30 -070015004
15005/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015006 * FUNCTION: wlan_hdd_disconnect
15007 * This function is used to issue a disconnect request to SME
15008 */
15009int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15010{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015011 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015013 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015014 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015015 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015016
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015017 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015019 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015020 if (0 != status)
15021 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015022 return status;
15023 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015024 /* Indicate sme of disconnect so that in progress connection or preauth
15025 * can be aborted
15026 */
15027 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015028 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015029 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015030
Agarwal Ashish47d18112014-08-04 19:55:07 +053015031 /* Need to apply spin lock before decreasing active sessions
15032 * as there can be chance for double decrement if context switch
15033 * Calls hdd_DisConnectHandler.
15034 */
15035
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015036 prev_conn_state = pHddStaCtx->conn_info.connState;
15037
Agarwal Ashish47d18112014-08-04 19:55:07 +053015038 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015039 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15040 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015041 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15042 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015043 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15044 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015045
Abhishek Singhf4669da2014-05-26 15:07:49 +053015046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015047 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15048
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015049 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015050
Mihir Shete182a0b22014-08-18 16:08:48 +053015051 /*
15052 * stop tx queues before deleting STA/BSS context from the firmware.
15053 * tx has to be disabled because the firmware can get busy dropping
15054 * the tx frames after BSS/STA has been deleted and will not send
15055 * back a response resulting in WDI timeout
15056 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015058 netif_tx_disable(pAdapter->dev);
15059 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015060
Mihir Shete182a0b22014-08-18 16:08:48 +053015061 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015062 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15063 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015064 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15065 prev_conn_state != eConnectionState_Connecting)
15066 {
15067 hddLog(LOG1,
15068 FL("status = %d, already disconnected"), status);
15069 result = 0;
15070 goto disconnected;
15071 }
15072 /*
15073 * Wait here instead of returning directly, this will block the next
15074 * connect command and allow processing of the scan for ssid and
15075 * the previous connect command in CSR. Else we might hit some
15076 * race conditions leading to SME and HDD out of sync.
15077 */
15078 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015079 {
15080 hddLog(LOG1,
15081 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015082 }
15083 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015084 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015085 hddLog(LOGE,
15086 FL("csrRoamDisconnect failure, returned %d"),
15087 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015088 result = -EINVAL;
15089 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015090 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015091 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015092 &pAdapter->disconnect_comp_var,
15093 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015094 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015095 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015096 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015097 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015098 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015099 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015100disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015101 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015102 FL("Set HDD connState to eConnectionState_NotConnected"));
15103 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015104#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15105 /* Sending disconnect event to userspace for kernel version < 3.11
15106 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15107 */
15108 hddLog(LOG1, FL("Send disconnected event to userspace"));
15109
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015110 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015111 WLAN_REASON_UNSPECIFIED);
15112#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015114 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015115 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015116}
15117
15118
15119/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015120 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015121 * This function is used to issue a disconnect request to SME
15122 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015123static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 struct net_device *dev,
15125 u16 reason
15126 )
15127{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015128 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015129 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015130 tCsrRoamProfile *pRoamProfile;
15131 hdd_station_ctx_t *pHddStaCtx;
15132 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015133#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015134 tANI_U8 staIdx;
15135#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015136
Jeff Johnson295189b2012-06-20 16:38:30 -070015137 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015138
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015139 if (!pAdapter) {
15140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15141 return -EINVAL;
15142 }
15143
15144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15145 if (!pHddStaCtx) {
15146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15147 return -EINVAL;
15148 }
15149
15150 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15151 status = wlan_hdd_validate_context(pHddCtx);
15152 if (0 != status)
15153 {
15154 return status;
15155 }
15156
15157 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15158
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015159 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15160 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15161 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15163 __func__, hdd_device_modetoString(pAdapter->device_mode),
15164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015165
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15167 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015168
Jeff Johnson295189b2012-06-20 16:38:30 -070015169 if (NULL != pRoamProfile)
15170 {
15171 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015172 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15173 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015175 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015176 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015177 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015178 switch(reason)
15179 {
15180 case WLAN_REASON_MIC_FAILURE:
15181 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15182 break;
15183
15184 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15185 case WLAN_REASON_DISASSOC_AP_BUSY:
15186 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15187 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15188 break;
15189
15190 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15191 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015192 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15194 break;
15195
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 default:
15197 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15198 break;
15199 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015200 pScanInfo = &pHddCtx->scan_info;
15201 if (pScanInfo->mScanPending)
15202 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015203 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015204 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015205 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015206 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015207 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015208 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015209#ifdef FEATURE_WLAN_TDLS
15210 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015211 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015212 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015213 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15214 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015215 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015216 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015217 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015219 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015220 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015221 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015222 status = sme_DeleteTdlsPeerSta(
15223 WLAN_HDD_GET_HAL_CTX(pAdapter),
15224 pAdapter->sessionId,
15225 mac);
15226 if (status != eHAL_STATUS_SUCCESS) {
15227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15228 return -EPERM;
15229 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015230 }
15231 }
15232#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015233
15234 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15235 reasonCode,
15236 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015237 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15238 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 {
15240 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015241 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015242 __func__, (int)status );
15243 return -EINVAL;
15244 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015245 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015246 else
15247 {
15248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15249 "called while in %d state", __func__,
15250 pHddStaCtx->conn_info.connState);
15251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015252 }
15253 else
15254 {
15255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15256 }
15257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015258 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 return status;
15260}
15261
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015262static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15263 struct net_device *dev,
15264 u16 reason
15265 )
15266{
15267 int ret;
15268 vos_ssr_protect(__func__);
15269 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15270 vos_ssr_unprotect(__func__);
15271
15272 return ret;
15273}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015274
Jeff Johnson295189b2012-06-20 16:38:30 -070015275/*
15276 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015277 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 * settings in IBSS mode.
15279 */
15280static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015281 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 struct cfg80211_ibss_params *params
15283 )
15284{
15285 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015286 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15288 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 ENTER();
15291
15292 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015293 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015294
15295 if (params->ie_len && ( NULL != params->ie) )
15296 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015297 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15298 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015299 {
15300 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15301 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15302 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015303 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015304 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015305 tDot11fIEWPA dot11WPAIE;
15306 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015307 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015308
Wilson Yang00256342013-10-10 23:13:38 -070015309 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015310 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15311 params->ie_len, DOT11F_EID_WPA);
15312 if ( NULL != ie )
15313 {
15314 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15315 // Unpack the WPA IE
15316 //Skip past the EID byte and length byte - and four byte WiFi OUI
15317 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15318 &ie[2+4],
15319 ie[1] - 4,
15320 &dot11WPAIE);
15321 /*Extract the multicast cipher, the encType for unicast
15322 cipher for wpa-none is none*/
15323 encryptionType =
15324 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15325 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015326 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015327
Jeff Johnson295189b2012-06-20 16:38:30 -070015328 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15329
15330 if (0 > status)
15331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015333 __func__);
15334 return status;
15335 }
15336 }
15337
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015338 pWextState->roamProfile.AuthType.authType[0] =
15339 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15341
15342 if (params->privacy)
15343 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015344 /* Security enabled IBSS, At this time there is no information available
15345 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015347 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015348 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015349 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015350 *enable privacy bit in beacons */
15351
15352 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15353 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015354 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15355 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015356 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15357 pWextState->roamProfile.EncryptionType.numEntries = 1;
15358 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015359 return status;
15360}
15361
15362/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015363 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015364 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015365 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015366static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015367 struct net_device *dev,
15368 struct cfg80211_ibss_params *params
15369 )
15370{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15373 tCsrRoamProfile *pRoamProfile;
15374 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015375 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15376 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015377 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015378
15379 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015380
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15382 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15383 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015384 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015385 "%s: device_mode = %s (%d)", __func__,
15386 hdd_device_modetoString(pAdapter->device_mode),
15387 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015388
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015389 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015390 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015391 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015392 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015393 }
15394
15395 if (NULL == pWextState)
15396 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015397 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 __func__);
15399 return -EIO;
15400 }
15401
Agarwal Ashish51325b52014-06-16 16:50:49 +053015402 if (vos_max_concurrent_connections_reached()) {
15403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15404 return -ECONNREFUSED;
15405 }
15406
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015407 /*Try disconnecting if already in connected state*/
15408 status = wlan_hdd_try_disconnect(pAdapter);
15409 if ( 0 > status)
15410 {
15411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15412 " IBSS connection"));
15413 return -EALREADY;
15414 }
15415
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 pRoamProfile = &pWextState->roamProfile;
15417
15418 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15419 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015420 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015421 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015422 return -EINVAL;
15423 }
15424
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015425 /* BSSID is provided by upper layers hence no need to AUTO generate */
15426 if (NULL != params->bssid) {
15427 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15428 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15429 hddLog (VOS_TRACE_LEVEL_ERROR,
15430 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15431 return -EIO;
15432 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015433 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015434 }
krunal sonie9002db2013-11-25 14:24:17 -080015435 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15436 {
15437 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15438 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15439 {
15440 hddLog (VOS_TRACE_LEVEL_ERROR,
15441 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15442 return -EIO;
15443 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015444
15445 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015446 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015447 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015448 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015449
Jeff Johnson295189b2012-06-20 16:38:30 -070015450 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015451 if (NULL !=
15452#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15453 params->chandef.chan)
15454#else
15455 params->channel)
15456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 {
15458 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015459 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15460 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15461 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15462 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015463
15464 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015465 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015466 ieee80211_frequency_to_channel(
15467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15468 params->chandef.chan->center_freq);
15469#else
15470 params->channel->center_freq);
15471#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015472
15473 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15474 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15477 __func__);
15478 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015480
15481 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015483 if (channelNum == validChan[indx])
15484 {
15485 break;
15486 }
15487 }
15488 if (indx >= numChans)
15489 {
15490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015491 __func__, channelNum);
15492 return -EINVAL;
15493 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015494 /* Set the Operational Channel */
15495 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15496 channelNum);
15497 pRoamProfile->ChannelInfo.numOfChannels = 1;
15498 pHddStaCtx->conn_info.operationChannel = channelNum;
15499 pRoamProfile->ChannelInfo.ChannelList =
15500 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015501 }
15502
15503 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015504 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 if (status < 0)
15506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 __func__);
15509 return status;
15510 }
15511
15512 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015513 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015514 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015515 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015516
15517 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015519
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015520 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015521 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015522}
15523
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015524static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15525 struct net_device *dev,
15526 struct cfg80211_ibss_params *params
15527 )
15528{
15529 int ret = 0;
15530
15531 vos_ssr_protect(__func__);
15532 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15533 vos_ssr_unprotect(__func__);
15534
15535 return ret;
15536}
15537
Jeff Johnson295189b2012-06-20 16:38:30 -070015538/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015539 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015540 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015542static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015543 struct net_device *dev
15544 )
15545{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015547 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15548 tCsrRoamProfile *pRoamProfile;
15549 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015550 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015551 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015552#ifdef WLAN_FEATURE_RMC
15553 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15554#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015555
15556 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015557
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15559 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15560 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015561 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015562 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015563 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015564 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015565 }
15566
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015567 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15568 hdd_device_modetoString(pAdapter->device_mode),
15569 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 if (NULL == pWextState)
15571 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015572 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 __func__);
15574 return -EIO;
15575 }
15576
15577 pRoamProfile = &pWextState->roamProfile;
15578
15579 /* Issue disconnect only if interface type is set to IBSS */
15580 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015582 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015583 __func__);
15584 return -EINVAL;
15585 }
15586
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015587#ifdef WLAN_FEATURE_RMC
15588 /* Clearing add IE of beacon */
15589 if (ccmCfgSetStr(pHddCtx->hHal,
15590 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15591 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15592 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15593 {
15594 hddLog (VOS_TRACE_LEVEL_ERROR,
15595 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15596 return -EINVAL;
15597 }
15598 if (ccmCfgSetInt(pHddCtx->hHal,
15599 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15600 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15601 {
15602 hddLog (VOS_TRACE_LEVEL_ERROR,
15603 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15604 __func__);
15605 return -EINVAL;
15606 }
15607
15608 // Reset WNI_CFG_PROBE_RSP Flags
15609 wlan_hdd_reset_prob_rspies(pAdapter);
15610
15611 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15612 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15613 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15614 {
15615 hddLog (VOS_TRACE_LEVEL_ERROR,
15616 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15617 __func__);
15618 return -EINVAL;
15619 }
15620#endif
15621
Jeff Johnson295189b2012-06-20 16:38:30 -070015622 /* Issue Disconnect request */
15623 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015624 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15625 pAdapter->sessionId,
15626 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15627 if (!HAL_STATUS_SUCCESS(hal_status)) {
15628 hddLog(LOGE,
15629 FL("sme_RoamDisconnect failed hal_status(%d)"),
15630 hal_status);
15631 return -EAGAIN;
15632 }
15633 status = wait_for_completion_timeout(
15634 &pAdapter->disconnect_comp_var,
15635 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15636 if (!status) {
15637 hddLog(LOGE,
15638 FL("wait on disconnect_comp_var failed"));
15639 return -ETIMEDOUT;
15640 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015642 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015643 return 0;
15644}
15645
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015646static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15647 struct net_device *dev
15648 )
15649{
15650 int ret = 0;
15651
15652 vos_ssr_protect(__func__);
15653 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15654 vos_ssr_unprotect(__func__);
15655
15656 return ret;
15657}
15658
Jeff Johnson295189b2012-06-20 16:38:30 -070015659/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015660 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015661 * This function is used to set the phy parameters
15662 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15663 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015664static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015665 u32 changed)
15666{
15667 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15668 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015669 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015670
15671 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015672
15673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015674 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15675 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015677 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015678 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015679 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015680 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015681 }
15682
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15684 {
15685 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15686 WNI_CFG_RTS_THRESHOLD_STAMAX :
15687 wiphy->rts_threshold;
15688
15689 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015690 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015692 hddLog(VOS_TRACE_LEVEL_ERROR,
15693 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015694 __func__, rts_threshold);
15695 return -EINVAL;
15696 }
15697
15698 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15699 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015700 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015701 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015702 hddLog(VOS_TRACE_LEVEL_ERROR,
15703 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 __func__, rts_threshold);
15705 return -EIO;
15706 }
15707
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015708 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015709 rts_threshold);
15710 }
15711
15712 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15713 {
15714 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15715 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15716 wiphy->frag_threshold;
15717
15718 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015719 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015721 hddLog(VOS_TRACE_LEVEL_ERROR,
15722 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015723 frag_threshold);
15724 return -EINVAL;
15725 }
15726
15727 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15728 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015729 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015730 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015731 hddLog(VOS_TRACE_LEVEL_ERROR,
15732 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015733 __func__, frag_threshold);
15734 return -EIO;
15735 }
15736
15737 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15738 frag_threshold);
15739 }
15740
15741 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15742 || (changed & WIPHY_PARAM_RETRY_LONG))
15743 {
15744 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15745 wiphy->retry_short :
15746 wiphy->retry_long;
15747
15748 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15749 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 __func__, retry_value);
15753 return -EINVAL;
15754 }
15755
15756 if (changed & WIPHY_PARAM_RETRY_SHORT)
15757 {
15758 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15759 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015760 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015762 hddLog(VOS_TRACE_LEVEL_ERROR,
15763 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015764 __func__, retry_value);
15765 return -EIO;
15766 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015767 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015768 __func__, retry_value);
15769 }
15770 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15771 {
15772 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15773 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015774 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015776 hddLog(VOS_TRACE_LEVEL_ERROR,
15777 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015778 __func__, retry_value);
15779 return -EIO;
15780 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015781 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015782 __func__, retry_value);
15783 }
15784 }
15785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015786 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015787 return 0;
15788}
15789
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015790static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15791 u32 changed)
15792{
15793 int ret;
15794
15795 vos_ssr_protect(__func__);
15796 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15797 vos_ssr_unprotect(__func__);
15798
15799 return ret;
15800}
15801
Jeff Johnson295189b2012-06-20 16:38:30 -070015802/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015803 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015804 * This function is used to set the txpower
15805 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015806static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015807#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15808 struct wireless_dev *wdev,
15809#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015810#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015811 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015812#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015813 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015814#endif
15815 int dbm)
15816{
15817 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015818 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015819 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15820 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015821 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015822
15823 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015824
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015825 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15826 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15827 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015828 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015829 if (0 != status)
15830 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015831 return status;
15832 }
15833
15834 hHal = pHddCtx->hHal;
15835
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015836 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15837 dbm, ccmCfgSetCallback,
15838 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015840 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015841 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15842 return -EIO;
15843 }
15844
15845 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15846 dbm);
15847
15848 switch(type)
15849 {
15850 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15851 /* Fall through */
15852 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15853 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15854 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15856 __func__);
15857 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 }
15859 break;
15860 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015862 __func__);
15863 return -EOPNOTSUPP;
15864 break;
15865 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15867 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 return -EIO;
15869 }
15870
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015871 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 return 0;
15873}
15874
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015875static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15876#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15877 struct wireless_dev *wdev,
15878#endif
15879#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15880 enum tx_power_setting type,
15881#else
15882 enum nl80211_tx_power_setting type,
15883#endif
15884 int dbm)
15885{
15886 int ret;
15887 vos_ssr_protect(__func__);
15888 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15889#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15890 wdev,
15891#endif
15892#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15893 type,
15894#else
15895 type,
15896#endif
15897 dbm);
15898 vos_ssr_unprotect(__func__);
15899
15900 return ret;
15901}
15902
Jeff Johnson295189b2012-06-20 16:38:30 -070015903/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015904 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 * This function is used to read the txpower
15906 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015907static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015908#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15909 struct wireless_dev *wdev,
15910#endif
15911 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015912{
15913
15914 hdd_adapter_t *pAdapter;
15915 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015916 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015917
Jeff Johnsone7245742012-09-05 17:12:55 -070015918 ENTER();
15919
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015920 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015921 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015922 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015923 *dbm = 0;
15924 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015925 }
15926
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15928 if (NULL == pAdapter)
15929 {
15930 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15931 return -ENOENT;
15932 }
15933
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15935 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15936 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 wlan_hdd_get_classAstats(pAdapter);
15938 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15939
Jeff Johnsone7245742012-09-05 17:12:55 -070015940 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015941 return 0;
15942}
15943
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015944static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15945#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15946 struct wireless_dev *wdev,
15947#endif
15948 int *dbm)
15949{
15950 int ret;
15951
15952 vos_ssr_protect(__func__);
15953 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15954#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15955 wdev,
15956#endif
15957 dbm);
15958 vos_ssr_unprotect(__func__);
15959
15960 return ret;
15961}
15962
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015963static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15965 const u8* mac,
15966#else
15967 u8* mac,
15968#endif
15969 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015970{
15971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15972 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15973 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015974 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015975
15976 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15977 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015978
15979 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15980 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15981 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15982 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15983 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15984 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15985 tANI_U16 maxRate = 0;
15986 tANI_U16 myRate;
15987 tANI_U16 currentRate = 0;
15988 tANI_U8 maxSpeedMCS = 0;
15989 tANI_U8 maxMCSIdx = 0;
15990 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015991 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015992 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015993 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015994
Leo Chang6f8870f2013-03-26 18:11:36 -070015995#ifdef WLAN_FEATURE_11AC
15996 tANI_U32 vht_mcs_map;
15997 eDataRate11ACMaxMcs vhtMaxMcs;
15998#endif /* WLAN_FEATURE_11AC */
15999
Jeff Johnsone7245742012-09-05 17:12:55 -070016000 ENTER();
16001
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16003 (0 == ssidlen))
16004 {
16005 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16006 " Invalid ssidlen, %d", __func__, ssidlen);
16007 /*To keep GUI happy*/
16008 return 0;
16009 }
16010
Mukul Sharma811205f2014-07-09 21:07:30 +053016011 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16012 {
16013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16014 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016015 /* return a cached value */
16016 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016017 return 0;
16018 }
16019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016020 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016021 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016022 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016023 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016024 }
16025
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016026 wlan_hdd_get_station_stats(pAdapter);
16027 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016028
Kiet Lam3b17fc82013-09-27 05:24:08 +053016029 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16030 sinfo->filled |= STATION_INFO_SIGNAL;
16031
c_hpothu09f19542014-05-30 21:53:31 +053016032 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016033 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16034 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016035 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016036 {
16037 rate_flags = pAdapter->maxRateFlags;
16038 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016039
Jeff Johnson295189b2012-06-20 16:38:30 -070016040 //convert to the UI units of 100kbps
16041 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16042
16043#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016044 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 -070016045 sinfo->signal,
16046 pCfg->reportMaxLinkSpeed,
16047 myRate,
16048 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016049 (int) pCfg->linkSpeedRssiMid,
16050 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016051 (int) rate_flags,
16052 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016053#endif //LINKSPEED_DEBUG_ENABLED
16054
16055 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16056 {
16057 // we do not want to necessarily report the current speed
16058 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16059 {
16060 // report the max possible speed
16061 rssidx = 0;
16062 }
16063 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16064 {
16065 // report the max possible speed with RSSI scaling
16066 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16067 {
16068 // report the max possible speed
16069 rssidx = 0;
16070 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016071 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016072 {
16073 // report middle speed
16074 rssidx = 1;
16075 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016076 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16077 {
16078 // report middle speed
16079 rssidx = 2;
16080 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016081 else
16082 {
16083 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016084 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016085 }
16086 }
16087 else
16088 {
16089 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16090 hddLog(VOS_TRACE_LEVEL_ERROR,
16091 "%s: Invalid value for reportMaxLinkSpeed: %u",
16092 __func__, pCfg->reportMaxLinkSpeed);
16093 rssidx = 0;
16094 }
16095
16096 maxRate = 0;
16097
16098 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016099 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16100 OperationalRates, &ORLeng))
16101 {
16102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16103 /*To keep GUI happy*/
16104 return 0;
16105 }
16106
Jeff Johnson295189b2012-06-20 16:38:30 -070016107 for (i = 0; i < ORLeng; i++)
16108 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016109 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 {
16111 /* Validate Rate Set */
16112 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16113 {
16114 currentRate = supported_data_rate[j].supported_rate[rssidx];
16115 break;
16116 }
16117 }
16118 /* Update MAX rate */
16119 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16120 }
16121
16122 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016123 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16124 ExtendedRates, &ERLeng))
16125 {
16126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16127 /*To keep GUI happy*/
16128 return 0;
16129 }
16130
Jeff Johnson295189b2012-06-20 16:38:30 -070016131 for (i = 0; i < ERLeng; i++)
16132 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016133 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 {
16135 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16136 {
16137 currentRate = supported_data_rate[j].supported_rate[rssidx];
16138 break;
16139 }
16140 }
16141 /* Update MAX rate */
16142 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16143 }
c_hpothu79aab322014-07-14 21:11:01 +053016144
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016145 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016146 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016147 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016148 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 {
c_hpothu79aab322014-07-14 21:11:01 +053016150 if (rate_flags & eHAL_TX_RATE_VHT80)
16151 mode = 2;
16152 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16153 mode = 1;
16154 else
16155 mode = 0;
16156
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016157 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16158 MCSRates, &MCSLeng))
16159 {
16160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16161 /*To keep GUI happy*/
16162 return 0;
16163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016164 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016165#ifdef WLAN_FEATURE_11AC
16166 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016167 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016169 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016170 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016171 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016173 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016175 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016177 maxMCSIdx = 7;
16178 }
16179 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16180 {
16181 maxMCSIdx = 8;
16182 }
16183 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16184 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016185 //VHT20 is supporting 0~8
16186 if (rate_flags & eHAL_TX_RATE_VHT20)
16187 maxMCSIdx = 8;
16188 else
16189 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016190 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016191
c_hpothu79aab322014-07-14 21:11:01 +053016192 if (0 != rssidx)/*check for scaled */
16193 {
16194 //get middle rate MCS index if rssi=1/2
16195 for (i=0; i <= maxMCSIdx; i++)
16196 {
16197 if (sinfo->signal <= rssiMcsTbl[mode][i])
16198 {
16199 maxMCSIdx = i;
16200 break;
16201 }
16202 }
16203 }
16204
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016205 if (rate_flags & eHAL_TX_RATE_VHT80)
16206 {
16207 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16208 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16209 }
16210 else if (rate_flags & eHAL_TX_RATE_VHT40)
16211 {
16212 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16213 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16214 }
16215 else if (rate_flags & eHAL_TX_RATE_VHT20)
16216 {
16217 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16218 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16219 }
16220
Leo Chang6f8870f2013-03-26 18:11:36 -070016221 maxSpeedMCS = 1;
16222 if (currentRate > maxRate)
16223 {
16224 maxRate = currentRate;
16225 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016226
Leo Chang6f8870f2013-03-26 18:11:36 -070016227 }
16228 else
16229#endif /* WLAN_FEATURE_11AC */
16230 {
16231 if (rate_flags & eHAL_TX_RATE_HT40)
16232 {
16233 rateFlag |= 1;
16234 }
16235 if (rate_flags & eHAL_TX_RATE_SGI)
16236 {
16237 rateFlag |= 2;
16238 }
16239
Girish Gowli01abcee2014-07-31 20:18:55 +053016240 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016241 if (rssidx == 1 || rssidx == 2)
16242 {
16243 //get middle rate MCS index if rssi=1/2
16244 for (i=0; i <= 7; i++)
16245 {
16246 if (sinfo->signal <= rssiMcsTbl[mode][i])
16247 {
16248 temp = i+1;
16249 break;
16250 }
16251 }
16252 }
c_hpothu79aab322014-07-14 21:11:01 +053016253
16254 for (i = 0; i < MCSLeng; i++)
16255 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016256 for (j = 0; j < temp; j++)
16257 {
16258 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16259 {
16260 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016261 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016262 break;
16263 }
16264 }
16265 if ((j < temp) && (currentRate > maxRate))
16266 {
16267 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016268 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016270 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016271 }
16272 }
16273
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016274 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16275 {
16276 maxRate = myRate;
16277 maxSpeedMCS = 1;
16278 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16279 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016281 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 {
16283 maxRate = myRate;
16284 if (rate_flags & eHAL_TX_RATE_LEGACY)
16285 {
16286 maxSpeedMCS = 0;
16287 }
16288 else
16289 {
16290 maxSpeedMCS = 1;
16291 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16292 }
16293 }
16294
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016295 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016296 {
16297 sinfo->txrate.legacy = maxRate;
16298#ifdef LINKSPEED_DEBUG_ENABLED
16299 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16300#endif //LINKSPEED_DEBUG_ENABLED
16301 }
16302 else
16303 {
16304 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016305#ifdef WLAN_FEATURE_11AC
16306 sinfo->txrate.nss = 1;
16307 if (rate_flags & eHAL_TX_RATE_VHT80)
16308 {
16309 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016310 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016311 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016312 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016313 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016314 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16315 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16316 }
16317 else if (rate_flags & eHAL_TX_RATE_VHT20)
16318 {
16319 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16320 }
16321#endif /* WLAN_FEATURE_11AC */
16322 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16323 {
16324 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16325 if (rate_flags & eHAL_TX_RATE_HT40)
16326 {
16327 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16328 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016329 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016330 if (rate_flags & eHAL_TX_RATE_SGI)
16331 {
16332 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16333 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016334
Jeff Johnson295189b2012-06-20 16:38:30 -070016335#ifdef LINKSPEED_DEBUG_ENABLED
16336 pr_info("Reporting MCS rate %d flags %x\n",
16337 sinfo->txrate.mcs,
16338 sinfo->txrate.flags );
16339#endif //LINKSPEED_DEBUG_ENABLED
16340 }
16341 }
16342 else
16343 {
16344 // report current rate instead of max rate
16345
16346 if (rate_flags & eHAL_TX_RATE_LEGACY)
16347 {
16348 //provide to the UI in units of 100kbps
16349 sinfo->txrate.legacy = myRate;
16350#ifdef LINKSPEED_DEBUG_ENABLED
16351 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16352#endif //LINKSPEED_DEBUG_ENABLED
16353 }
16354 else
16355 {
16356 //must be MCS
16357 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016358#ifdef WLAN_FEATURE_11AC
16359 sinfo->txrate.nss = 1;
16360 if (rate_flags & eHAL_TX_RATE_VHT80)
16361 {
16362 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16363 }
16364 else
16365#endif /* WLAN_FEATURE_11AC */
16366 {
16367 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16368 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016369 if (rate_flags & eHAL_TX_RATE_SGI)
16370 {
16371 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16372 }
16373 if (rate_flags & eHAL_TX_RATE_HT40)
16374 {
16375 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16376 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016377#ifdef WLAN_FEATURE_11AC
16378 else if (rate_flags & eHAL_TX_RATE_VHT80)
16379 {
16380 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16381 }
16382#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016383#ifdef LINKSPEED_DEBUG_ENABLED
16384 pr_info("Reporting actual MCS rate %d flags %x\n",
16385 sinfo->txrate.mcs,
16386 sinfo->txrate.flags );
16387#endif //LINKSPEED_DEBUG_ENABLED
16388 }
16389 }
16390 sinfo->filled |= STATION_INFO_TX_BITRATE;
16391
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016392 sinfo->tx_packets =
16393 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16394 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16395 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16396 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16397
16398 sinfo->tx_retries =
16399 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16400 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16401 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16402 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16403
16404 sinfo->tx_failed =
16405 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16406 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16407 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16408 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16409
16410 sinfo->filled |=
16411 STATION_INFO_TX_PACKETS |
16412 STATION_INFO_TX_RETRIES |
16413 STATION_INFO_TX_FAILED;
16414
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016415 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16416 sinfo->filled |= STATION_INFO_RX_PACKETS;
16417
16418 if (rate_flags & eHAL_TX_RATE_LEGACY)
16419 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16420 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16421 sinfo->rx_packets);
16422 else
16423 hddLog(LOG1,
16424 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16425 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16426 sinfo->tx_packets, sinfo->rx_packets);
16427
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16429 TRACE_CODE_HDD_CFG80211_GET_STA,
16430 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016431 EXIT();
16432 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016433}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16435static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16436 const u8* mac, struct station_info *sinfo)
16437#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016438static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16439 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016440#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016441{
16442 int ret;
16443
16444 vos_ssr_protect(__func__);
16445 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16446 vos_ssr_unprotect(__func__);
16447
16448 return ret;
16449}
16450
16451static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016452 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016453{
16454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016455 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016456 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016457 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016458
Jeff Johnsone7245742012-09-05 17:12:55 -070016459 ENTER();
16460
Jeff Johnson295189b2012-06-20 16:38:30 -070016461 if (NULL == pAdapter)
16462 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016464 return -ENODEV;
16465 }
16466
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16468 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16469 pAdapter->sessionId, timeout));
16470
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016472 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016473 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016474 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016475 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016476 }
16477
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016478 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16479 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16480 (pHddCtx->cfg_ini->fhostArpOffload) &&
16481 (eConnectionState_Associated ==
16482 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16483 {
Amar Singhald53568e2013-09-26 11:03:45 -070016484
16485 hddLog(VOS_TRACE_LEVEL_INFO,
16486 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016487 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016488 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16489 {
16490 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016491 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016492 __func__, vos_status);
16493 }
16494 }
16495
Jeff Johnson295189b2012-06-20 16:38:30 -070016496 /**The get power cmd from the supplicant gets updated by the nl only
16497 *on successful execution of the function call
16498 *we are oppositely mapped w.r.t mode in the driver
16499 **/
16500 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16501
16502 if (VOS_STATUS_E_FAILURE == vos_status)
16503 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16505 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 return -EINVAL;
16507 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016508 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016509 return 0;
16510}
16511
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016512static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16513 struct net_device *dev, bool mode, int timeout)
16514{
16515 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016516
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016517 vos_ssr_protect(__func__);
16518 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16519 vos_ssr_unprotect(__func__);
16520
16521 return ret;
16522}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016523
Jeff Johnson295189b2012-06-20 16:38:30 -070016524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016525static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16526 struct net_device *netdev,
16527 u8 key_index)
16528{
16529 ENTER();
16530 return 0;
16531}
16532
Jeff Johnson295189b2012-06-20 16:38:30 -070016533static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016534 struct net_device *netdev,
16535 u8 key_index)
16536{
16537 int ret;
16538 vos_ssr_protect(__func__);
16539 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16540 vos_ssr_unprotect(__func__);
16541 return ret;
16542}
16543#endif //LINUX_VERSION_CODE
16544
16545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16546static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16547 struct net_device *dev,
16548 struct ieee80211_txq_params *params)
16549{
16550 ENTER();
16551 return 0;
16552}
16553#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16554static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16555 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016556{
Jeff Johnsone7245742012-09-05 17:12:55 -070016557 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016558 return 0;
16559}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016561
16562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16563static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016564 struct net_device *dev,
16565 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016566{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016567 int ret;
16568
16569 vos_ssr_protect(__func__);
16570 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16571 vos_ssr_unprotect(__func__);
16572 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016573}
16574#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16575static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16576 struct ieee80211_txq_params *params)
16577{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016578 int ret;
16579
16580 vos_ssr_protect(__func__);
16581 ret = __wlan_hdd_set_txq_params(wiphy, params);
16582 vos_ssr_unprotect(__func__);
16583 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016584}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016585#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016586
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016587static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016588 struct net_device *dev,
16589 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016590{
16591 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016592 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016593 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016594 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016595 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016596 v_CONTEXT_t pVosContext = NULL;
16597 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016598
Jeff Johnsone7245742012-09-05 17:12:55 -070016599 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016601 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 return -EINVAL;
16605 }
16606
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16608 TRACE_CODE_HDD_CFG80211_DEL_STA,
16609 pAdapter->sessionId, pAdapter->device_mode));
16610
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16612 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016613 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016614 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016615 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016616 }
16617
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016619 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016620 )
16621 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016622 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16623 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16624 if(pSapCtx == NULL){
16625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16626 FL("psapCtx is NULL"));
16627 return -ENOENT;
16628 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016629 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 {
16631 v_U16_t i;
16632 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16633 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016634 if ((pSapCtx->aStaInfo[i].isUsed) &&
16635 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016636 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016637 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016638 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016639 ETHER_ADDR_LEN);
16640
Jeff Johnson295189b2012-06-20 16:38:30 -070016641 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016642 "%s: Delete STA with MAC::"
16643 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016644 __func__,
16645 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16646 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016647 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016648 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016649 }
16650 }
16651 }
16652 else
16653 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016654
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016655 vos_status = hdd_softap_GetStaId(pAdapter,
16656 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016657 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16658 {
16659 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016660 "%s: Skip this DEL STA as this is not used::"
16661 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016662 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016663 return -ENOENT;
16664 }
16665
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016666 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016667 {
16668 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016669 "%s: Skip this DEL STA as deauth is in progress::"
16670 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016671 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016672 return -ENOENT;
16673 }
16674
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016675 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016676
Jeff Johnson295189b2012-06-20 16:38:30 -070016677 hddLog(VOS_TRACE_LEVEL_INFO,
16678 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016679 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016680 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016681 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016682
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016683 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016684 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16685 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016686 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016687 hddLog(VOS_TRACE_LEVEL_INFO,
16688 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016689 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016690 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016691 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016692 return -ENOENT;
16693 }
16694
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 }
16696 }
16697
16698 EXIT();
16699
16700 return 0;
16701}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016702
16703#ifdef CFG80211_DEL_STA_V2
16704static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16705 struct net_device *dev,
16706 struct station_del_parameters *param)
16707#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16709static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16710 struct net_device *dev, const u8 *mac)
16711#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016712static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16713 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016714#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016715#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016716{
16717 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016718 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016719
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016720 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016721
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016722#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016723 if (NULL == param) {
16724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016725 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016726 return -EINVAL;
16727 }
16728
16729 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16730 param->subtype, &delStaParams);
16731
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016732#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016733 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016734 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016735#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016736 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16737
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016738 vos_ssr_unprotect(__func__);
16739
16740 return ret;
16741}
16742
16743static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016744 struct net_device *dev,
16745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16746 const u8 *mac,
16747#else
16748 u8 *mac,
16749#endif
16750 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016751{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016752 hdd_adapter_t *pAdapter;
16753 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016754 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016755#ifdef FEATURE_WLAN_TDLS
16756 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016757
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016758 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016759
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016760 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16761 if (NULL == pAdapter)
16762 {
16763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16764 "%s: Adapter is NULL",__func__);
16765 return -EINVAL;
16766 }
16767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16768 status = wlan_hdd_validate_context(pHddCtx);
16769 if (0 != status)
16770 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016771 return status;
16772 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016773
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16775 TRACE_CODE_HDD_CFG80211_ADD_STA,
16776 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016777 mask = params->sta_flags_mask;
16778
16779 set = params->sta_flags_set;
16780
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016782 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16783 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016784
16785 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16786 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016787 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016788 }
16789 }
16790#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016791 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016792 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016793}
16794
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016795#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16796static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16797 struct net_device *dev, const u8 *mac,
16798 struct station_parameters *params)
16799#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016800static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16801 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016802#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016803{
16804 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016805
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016806 vos_ssr_protect(__func__);
16807 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16808 vos_ssr_unprotect(__func__);
16809
16810 return ret;
16811}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016812#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016813
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016814static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016815 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016816{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016817 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16818 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016819 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016820 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016821 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016822 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016823
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016824 ENTER();
16825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016826 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016827 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016830 return -EINVAL;
16831 }
16832
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016833 if (!pmksa) {
16834 hddLog(LOGE, FL("pmksa is NULL"));
16835 return -EINVAL;
16836 }
16837
16838 if (!pmksa->bssid || !pmksa->pmkid) {
16839 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16840 pmksa->bssid, pmksa->pmkid);
16841 return -EINVAL;
16842 }
16843
16844 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16845 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16846
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016847 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16848 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016849 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016851 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016852 }
16853
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016854 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016855 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16856
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016857 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16858 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016859
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016860 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016861 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016862 &pmk_id, 1, FALSE);
16863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16865 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16866 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016868 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016869 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016870}
16871
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016872static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16873 struct cfg80211_pmksa *pmksa)
16874{
16875 int ret;
16876
16877 vos_ssr_protect(__func__);
16878 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16879 vos_ssr_unprotect(__func__);
16880
16881 return ret;
16882}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016883
Wilson Yang6507c4e2013-10-01 20:11:19 -070016884
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016885static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016886 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016887{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16889 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016890 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016891 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016892
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016893 ENTER();
16894
Wilson Yang6507c4e2013-10-01 20:11:19 -070016895 /* Validate pAdapter */
16896 if (NULL == pAdapter)
16897 {
16898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16899 return -EINVAL;
16900 }
16901
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016902 if (!pmksa) {
16903 hddLog(LOGE, FL("pmksa is NULL"));
16904 return -EINVAL;
16905 }
16906
16907 if (!pmksa->bssid) {
16908 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16909 return -EINVAL;
16910 }
16911
Kiet Lam98c46a12014-10-31 15:34:57 -070016912 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16913 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16914
Wilson Yang6507c4e2013-10-01 20:11:19 -070016915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16916 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016917 if (0 != status)
16918 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016919 return status;
16920 }
16921
16922 /*Retrieve halHandle*/
16923 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16924
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16926 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16927 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016928 /* Delete the PMKID CSR cache */
16929 if (eHAL_STATUS_SUCCESS !=
16930 sme_RoamDelPMKIDfromCache(halHandle,
16931 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16932 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16933 MAC_ADDR_ARRAY(pmksa->bssid));
16934 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016935 }
16936
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016937 EXIT();
16938 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016939}
16940
Wilson Yang6507c4e2013-10-01 20:11:19 -070016941
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016942static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16943 struct cfg80211_pmksa *pmksa)
16944{
16945 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016946
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016947 vos_ssr_protect(__func__);
16948 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16949 vos_ssr_unprotect(__func__);
16950
16951 return ret;
16952
16953}
16954
16955static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016956{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16958 tHalHandle halHandle;
16959 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016960 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016961
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016962 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016963
16964 /* Validate pAdapter */
16965 if (NULL == pAdapter)
16966 {
16967 hddLog(VOS_TRACE_LEVEL_ERROR,
16968 "%s: Invalid Adapter" ,__func__);
16969 return -EINVAL;
16970 }
16971
16972 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16973 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016974 if (0 != status)
16975 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016976 return status;
16977 }
16978
16979 /*Retrieve halHandle*/
16980 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16981
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016982 /* Flush the PMKID cache in CSR */
16983 if (eHAL_STATUS_SUCCESS !=
16984 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16986 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016987 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016988 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016989 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016990}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016991
16992static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16993{
16994 int ret;
16995
16996 vos_ssr_protect(__func__);
16997 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16998 vos_ssr_unprotect(__func__);
16999
17000 return ret;
17001}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017002#endif
17003
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017004#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017005static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17006 struct net_device *dev,
17007 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017008{
17009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17010 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017011 hdd_context_t *pHddCtx;
17012 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017014 ENTER();
17015
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017016 if (NULL == pAdapter)
17017 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017019 return -ENODEV;
17020 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17022 ret = wlan_hdd_validate_context(pHddCtx);
17023 if (0 != ret)
17024 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017025 return ret;
17026 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017027 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017028 if (NULL == pHddStaCtx)
17029 {
17030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17031 return -EINVAL;
17032 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17035 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17036 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017037 // Added for debug on reception of Re-assoc Req.
17038 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17039 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017040 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017041 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017042 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017043 }
17044
17045#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017046 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017047 ftie->ie_len);
17048#endif
17049
17050 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017051 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17052 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017053 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017054
17055 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017056 return 0;
17057}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017058
17059static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17060 struct net_device *dev,
17061 struct cfg80211_update_ft_ies_params *ftie)
17062{
17063 int ret;
17064
17065 vos_ssr_protect(__func__);
17066 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17067 vos_ssr_unprotect(__func__);
17068
17069 return ret;
17070}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017071#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017072
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017073#ifdef FEATURE_WLAN_SCAN_PNO
17074
17075void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17076 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17077{
17078 int ret;
17079 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17080 hdd_context_t *pHddCtx;
17081
Nirav Shah80830bf2013-12-31 16:35:12 +053017082 ENTER();
17083
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017084 if (NULL == pAdapter)
17085 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017087 "%s: HDD adapter is Null", __func__);
17088 return ;
17089 }
17090
17091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17092 if (NULL == pHddCtx)
17093 {
17094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17095 "%s: HDD context is Null!!!", __func__);
17096 return ;
17097 }
17098
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017099 spin_lock(&pHddCtx->schedScan_lock);
17100 if (TRUE == pHddCtx->isWiphySuspended)
17101 {
17102 pHddCtx->isSchedScanUpdatePending = TRUE;
17103 spin_unlock(&pHddCtx->schedScan_lock);
17104 hddLog(VOS_TRACE_LEVEL_INFO,
17105 "%s: Update cfg80211 scan database after it resume", __func__);
17106 return ;
17107 }
17108 spin_unlock(&pHddCtx->schedScan_lock);
17109
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017110 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17111
17112 if (0 > ret)
17113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017114 else
17115 {
17116 /* Acquire wakelock to handle the case where APP's tries to suspend
17117 * immediatly after the driver gets connect request(i.e after pno)
17118 * from supplicant, this result in app's is suspending and not able
17119 * to process the connect request to AP */
17120 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17121 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017122 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17124 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017125}
17126
17127/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017128 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017129 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017130 */
17131static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17132{
17133 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17134 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017135 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017136 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17137 int status = 0;
17138 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17139
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017140 /* The current firmware design does not allow PNO during any
17141 * active sessions. Hence, determine the active sessions
17142 * and return a failure.
17143 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017144 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17145 {
17146 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017147 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017148
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017149 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17150 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17151 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17152 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
17153 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017154 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017155 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017156 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017157 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017158 }
17159 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17160 pAdapterNode = pNext;
17161 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017162 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017163}
17164
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017165void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17166{
17167 hdd_adapter_t *pAdapter = callbackContext;
17168 hdd_context_t *pHddCtx;
17169
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017170 ENTER();
17171
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017172 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17173 {
17174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17175 FL("Invalid adapter or adapter has invalid magic"));
17176 return;
17177 }
17178
17179 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17180 if (0 != wlan_hdd_validate_context(pHddCtx))
17181 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017182 return;
17183 }
17184
c_hpothub53c45d2014-08-18 16:53:14 +053017185 if (VOS_STATUS_SUCCESS != status)
17186 {
17187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017188 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017189 pHddCtx->isPnoEnable = FALSE;
17190 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017191
17192 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17193 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017194 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017195}
17196
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017197/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017198 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17199 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017200 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017201static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017202 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17203{
17204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017205 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017206 hdd_context_t *pHddCtx;
17207 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017208 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017209 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17210 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017211 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17212 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017213 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017214 hdd_config_t *pConfig = NULL;
17215 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017217 ENTER();
17218
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017219 if (NULL == pAdapter)
17220 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017222 "%s: HDD adapter is Null", __func__);
17223 return -ENODEV;
17224 }
17225
17226 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017227 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017228
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017229 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017230 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017231 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017232 }
17233
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017234 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017235 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17236 if (NULL == hHal)
17237 {
17238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17239 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017240 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017241 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017242 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17243 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17244 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053017245 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017246 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017247 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017248 {
17249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17250 "%s: aborting the existing scan is unsuccessfull", __func__);
17251 return -EBUSY;
17252 }
17253
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017254 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017255 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017257 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017258 return -EBUSY;
17259 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017260
c_hpothu37f21312014-04-09 21:49:54 +053017261 if (TRUE == pHddCtx->isPnoEnable)
17262 {
17263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17264 FL("already PNO is enabled"));
17265 return -EBUSY;
17266 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017267
17268 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17269 {
17270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17271 "%s: abort ROC failed ", __func__);
17272 return -EBUSY;
17273 }
17274
c_hpothu37f21312014-04-09 21:49:54 +053017275 pHddCtx->isPnoEnable = TRUE;
17276
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017277 pnoRequest.enable = 1; /*Enable PNO */
17278 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017279
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017280 if (( !pnoRequest.ucNetworksCount ) ||
17281 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017282 {
17283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017284 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017285 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017286 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017287 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017288 goto error;
17289 }
17290
17291 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17292 {
17293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017294 "%s: Incorrect number of channels %d",
17295 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017296 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017297 goto error;
17298 }
17299
17300 /* Framework provides one set of channels(all)
17301 * common for all saved profile */
17302 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17303 channels_allowed, &num_channels_allowed))
17304 {
17305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17306 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017307 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017308 goto error;
17309 }
17310 /* Checking each channel against allowed channel list */
17311 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017312 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017313 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017314 char chList [(request->n_channels*5)+1];
17315 int len;
17316 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017317 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017318 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017319 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017320 if (request->channels[i]->hw_value == channels_allowed[indx])
17321 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017322 if ((!pConfig->enableDFSPnoChnlScan) &&
17323 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17324 {
17325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17326 "%s : Dropping DFS channel : %d",
17327 __func__,channels_allowed[indx]);
17328 num_ignore_dfs_ch++;
17329 break;
17330 }
17331
Nirav Shah80830bf2013-12-31 16:35:12 +053017332 valid_ch[num_ch++] = request->channels[i]->hw_value;
17333 len += snprintf(chList+len, 5, "%d ",
17334 request->channels[i]->hw_value);
17335 break ;
17336 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017337 }
17338 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017339 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017340
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017341 /*If all channels are DFS and dropped, then ignore the PNO request*/
17342 if (num_ignore_dfs_ch == request->n_channels)
17343 {
17344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17345 "%s : All requested channels are DFS channels", __func__);
17346 ret = -EINVAL;
17347 goto error;
17348 }
17349 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017350
17351 pnoRequest.aNetworks =
17352 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17353 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017354 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017355 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17356 FL("failed to allocate memory aNetworks %u"),
17357 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17358 goto error;
17359 }
17360 vos_mem_zero(pnoRequest.aNetworks,
17361 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17362
17363 /* Filling per profile params */
17364 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17365 {
17366 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017367 request->match_sets[i].ssid.ssid_len;
17368
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017369 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17370 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017371 {
17372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017373 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017374 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017375 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017376 goto error;
17377 }
17378
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017379 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017380 request->match_sets[i].ssid.ssid,
17381 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17383 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017384 i, pnoRequest.aNetworks[i].ssId.ssId);
17385 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17386 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17387 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017388
17389 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017390 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17391 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017392
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017393 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017394 }
17395
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017396 for (i = 0; i < request->n_ssids; i++)
17397 {
17398 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017399 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017400 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017401 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017402 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017403 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017404 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017405 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017406 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017407 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017408 break;
17409 }
17410 j++;
17411 }
17412 }
17413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17414 "Number of hidden networks being Configured = %d",
17415 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017417 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017418
17419 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17420 if (pnoRequest.p24GProbeTemplate == NULL)
17421 {
17422 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17423 FL("failed to allocate memory p24GProbeTemplate %u"),
17424 SIR_PNO_MAX_PB_REQ_SIZE);
17425 goto error;
17426 }
17427
17428 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17429 if (pnoRequest.p5GProbeTemplate == NULL)
17430 {
17431 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17432 FL("failed to allocate memory p5GProbeTemplate %u"),
17433 SIR_PNO_MAX_PB_REQ_SIZE);
17434 goto error;
17435 }
17436
17437 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17438 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17439
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017440 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17441 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017442 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017443 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17444 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17445 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017446
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017447 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17448 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17449 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017450 }
17451
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017452 /* Driver gets only one time interval which is hardcoded in
17453 * supplicant for 10000ms. Taking power consumption into account 6 timers
17454 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17455 * 80,160,320 secs. And number of scan cycle for each timer
17456 * is configurable through INI param gPNOScanTimerRepeatValue.
17457 * If it is set to 0 only one timer will be used and PNO scan cycle
17458 * will be repeated after each interval specified by supplicant
17459 * till PNO is disabled.
17460 */
17461 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017462 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017463 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017464 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017465 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17466
17467 tempInterval = (request->interval)/1000;
17468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17469 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17470 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017471 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017472 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017473 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017474 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017475 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017476 tempInterval *= 2;
17477 }
17478 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017479 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017480
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017481 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017482
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017483 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017484 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17485 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017486 pAdapter->pno_req_status = 0;
17487
Nirav Shah80830bf2013-12-31 16:35:12 +053017488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17489 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017490 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17491 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017492
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017493 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017494 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017495 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17496 if (eHAL_STATUS_SUCCESS != status)
17497 {
17498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017499 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017500 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017501 goto error;
17502 }
17503
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017504 ret = wait_for_completion_timeout(
17505 &pAdapter->pno_comp_var,
17506 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17507 if (0 >= ret)
17508 {
17509 // Did not receive the response for PNO enable in time.
17510 // Assuming the PNO enable was success.
17511 // Returning error from here, because we timeout, results
17512 // in side effect of Wifi (Wifi Setting) not to work.
17513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17514 FL("Timed out waiting for PNO to be Enabled"));
17515 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017516 }
17517
17518 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017519 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017520
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017521error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17523 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017524 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017525 if (pnoRequest.aNetworks)
17526 vos_mem_free(pnoRequest.aNetworks);
17527 if (pnoRequest.p24GProbeTemplate)
17528 vos_mem_free(pnoRequest.p24GProbeTemplate);
17529 if (pnoRequest.p5GProbeTemplate)
17530 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017531
17532 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017533 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017534}
17535
17536/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017537 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17538 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017539 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017540static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17541 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17542{
17543 int ret;
17544
17545 vos_ssr_protect(__func__);
17546 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17547 vos_ssr_unprotect(__func__);
17548
17549 return ret;
17550}
17551
17552/*
17553 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17554 * Function to disable PNO
17555 */
17556static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017557 struct net_device *dev)
17558{
17559 eHalStatus status = eHAL_STATUS_FAILURE;
17560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17561 hdd_context_t *pHddCtx;
17562 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017563 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017564 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017565
17566 ENTER();
17567
17568 if (NULL == pAdapter)
17569 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017571 "%s: HDD adapter is Null", __func__);
17572 return -ENODEV;
17573 }
17574
17575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017576
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017577 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017578 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017580 "%s: HDD context is Null", __func__);
17581 return -ENODEV;
17582 }
17583
17584 /* The return 0 is intentional when isLogpInProgress and
17585 * isLoadUnloadInProgress. We did observe a crash due to a return of
17586 * failure in sched_scan_stop , especially for a case where the unload
17587 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17588 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17589 * success. If it returns a failure , then its next invocation due to the
17590 * clean up of the second interface will have the dev pointer corresponding
17591 * to the first one leading to a crash.
17592 */
17593 if (pHddCtx->isLogpInProgress)
17594 {
17595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17596 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017597 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017598 return ret;
17599 }
17600
Mihir Shete18156292014-03-11 15:38:30 +053017601 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017602 {
17603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17604 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17605 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017606 }
17607
17608 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17609 if (NULL == hHal)
17610 {
17611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17612 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017613 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017614 }
17615
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017616 pnoRequest.enable = 0; /* Disable PNO */
17617 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017618
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17620 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17621 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017622
17623 INIT_COMPLETION(pAdapter->pno_comp_var);
17624 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17625 pnoRequest.callbackContext = pAdapter;
17626 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017627 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017628 pAdapter->sessionId,
17629 NULL, pAdapter);
17630 if (eHAL_STATUS_SUCCESS != status)
17631 {
17632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17633 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017634 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017635 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017636 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017637 ret = wait_for_completion_timeout(
17638 &pAdapter->pno_comp_var,
17639 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17640 if (0 >= ret)
17641 {
17642 // Did not receive the response for PNO disable in time.
17643 // Assuming the PNO disable was success.
17644 // Returning error from here, because we timeout, results
17645 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017647 FL("Timed out waiting for PNO to be disabled"));
17648 ret = 0;
17649 }
17650
17651 ret = pAdapter->pno_req_status;
17652 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017653
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017654error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017656 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017657
17658 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017659 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017660}
17661
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017662/*
17663 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17664 * NL interface to disable PNO
17665 */
17666static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17667 struct net_device *dev)
17668{
17669 int ret;
17670
17671 vos_ssr_protect(__func__);
17672 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17673 vos_ssr_unprotect(__func__);
17674
17675 return ret;
17676}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017677#endif /*FEATURE_WLAN_SCAN_PNO*/
17678
17679
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017680#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017681#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017682static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17683 struct net_device *dev,
17684 u8 *peer, u8 action_code,
17685 u8 dialog_token,
17686 u16 status_code, u32 peer_capability,
17687 const u8 *buf, size_t len)
17688#else /* TDLS_MGMT_VERSION2 */
17689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17690static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17691 struct net_device *dev,
17692 const u8 *peer, u8 action_code,
17693 u8 dialog_token, u16 status_code,
17694 u32 peer_capability, bool initiator,
17695 const u8 *buf, size_t len)
17696#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17697static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17698 struct net_device *dev,
17699 const u8 *peer, u8 action_code,
17700 u8 dialog_token, u16 status_code,
17701 u32 peer_capability, const u8 *buf,
17702 size_t len)
17703#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17704static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17705 struct net_device *dev,
17706 u8 *peer, u8 action_code,
17707 u8 dialog_token,
17708 u16 status_code, u32 peer_capability,
17709 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017710#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017711static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17712 struct net_device *dev,
17713 u8 *peer, u8 action_code,
17714 u8 dialog_token,
17715 u16 status_code, const u8 *buf,
17716 size_t len)
17717#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017718#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017719{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017720 hdd_adapter_t *pAdapter;
17721 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017722 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017723 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017724 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017725 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017726 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017727 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017728#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017729 u32 peer_capability = 0;
17730#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017731 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017732 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017733
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017734 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17735 if (NULL == pAdapter)
17736 {
17737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17738 "%s: Adapter is NULL",__func__);
17739 return -EINVAL;
17740 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17742 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17743 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017744
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017745 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017746 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017749 "Invalid arguments");
17750 return -EINVAL;
17751 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017752
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017753 if (pHddCtx->isLogpInProgress)
17754 {
17755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17756 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017757 wlan_hdd_tdls_set_link_status(pAdapter,
17758 peer,
17759 eTDLS_LINK_IDLE,
17760 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017761 return -EBUSY;
17762 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017763
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017764 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17765 {
17766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17767 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17768 return -EAGAIN;
17769 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017770
Hoonki Lee27511902013-03-14 18:19:06 -070017771 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017772 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017774 "%s: TDLS mode is disabled OR not enabled in FW."
17775 MAC_ADDRESS_STR " action %d declined.",
17776 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017777 return -ENOTSUPP;
17778 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017779
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017780 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17781
17782 if( NULL == pHddStaCtx )
17783 {
17784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17785 "%s: HDD station context NULL ",__func__);
17786 return -EINVAL;
17787 }
17788
17789 /* STA should be connected and authenticated
17790 * before sending any TDLS frames
17791 */
17792 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17793 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17794 {
17795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17796 "STA is not connected or unauthenticated. "
17797 "connState %u, uIsAuthenticated %u",
17798 pHddStaCtx->conn_info.connState,
17799 pHddStaCtx->conn_info.uIsAuthenticated);
17800 return -EAGAIN;
17801 }
17802
Hoonki Lee27511902013-03-14 18:19:06 -070017803 /* other than teardown frame, other mgmt frames are not sent if disabled */
17804 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17805 {
17806 /* if tdls_mode is disabled to respond to peer's request */
17807 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17808 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017810 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017811 " TDLS mode is disabled. action %d declined.",
17812 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017813
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017814 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017815 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017816
17817 if (vos_max_concurrent_connections_reached())
17818 {
17819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17820 return -EINVAL;
17821 }
Hoonki Lee27511902013-03-14 18:19:06 -070017822 }
17823
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017824 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17825 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017826 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017827 {
17828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017829 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017830 " TDLS setup is ongoing. action %d declined.",
17831 __func__, MAC_ADDR_ARRAY(peer), action_code);
17832 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017833 }
17834 }
17835
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017836 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17837 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017838 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017839 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17840 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017841 {
17842 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17843 we return error code at 'add_station()'. Hence we have this
17844 check again in addtion to add_station().
17845 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017846 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017847 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17849 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017850 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17851 __func__, MAC_ADDR_ARRAY(peer), action_code,
17852 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017853 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017854 }
17855 else
17856 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017857 /* maximum reached. tweak to send error code to peer and return
17858 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017859 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17861 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017862 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17863 __func__, MAC_ADDR_ARRAY(peer), status_code,
17864 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017865 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017866 /* fall through to send setup resp with failure status
17867 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017868 }
17869 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017870 else
17871 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017872 mutex_lock(&pHddCtx->tdls_lock);
17873 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017874 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017875 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017876 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017878 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17879 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017880 return -EPERM;
17881 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017882 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017883 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017884 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017885
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017887 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017888 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17889 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017890
Hoonki Leea34dd892013-02-05 22:56:02 -080017891 /*Except teardown responder will not be used so just make 0*/
17892 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017893 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017894 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017895
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017896 mutex_lock(&pHddCtx->tdls_lock);
17897 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017898
17899 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17900 responder = pTdlsPeer->is_responder;
17901 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017902 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017904 "%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 -070017905 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17906 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017907 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017908 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017909 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017910 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017911 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017912
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017913 /* Discard TDLS setup if peer is removed by user app */
17914 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17915 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17916 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17917 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17918
17919 mutex_lock(&pHddCtx->tdls_lock);
17920 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17921 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17922 mutex_unlock(&pHddCtx->tdls_lock);
17923 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17924 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17925 MAC_ADDR_ARRAY(peer), action_code);
17926 return -EINVAL;
17927 }
17928 mutex_unlock(&pHddCtx->tdls_lock);
17929 }
17930
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017931 /* For explicit trigger of DIS_REQ come out of BMPS for
17932 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017933 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017934 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017935 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17936 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017937 {
17938 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17939 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017941 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017942 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17943 if (status != VOS_STATUS_SUCCESS) {
17944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17945 }
Hoonki Lee14621352013-04-16 17:51:19 -070017946 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017947 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017948 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17950 }
17951 }
Hoonki Lee14621352013-04-16 17:51:19 -070017952 }
17953
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017954 /* make sure doesn't call send_mgmt() while it is pending */
17955 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17956 {
17957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017958 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017959 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017960 ret = -EBUSY;
17961 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017962 }
17963
17964 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017965 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17966
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017967 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17968 pAdapter->sessionId, peer, action_code, dialog_token,
17969 status_code, peer_capability, (tANI_U8 *)buf, len,
17970 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017971
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017972 if (VOS_STATUS_SUCCESS != status)
17973 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17975 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017976 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017977 ret = -EINVAL;
17978 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017979 }
17980
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17982 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17983 WAIT_TIME_TDLS_MGMT);
17984
Hoonki Leed37cbb32013-04-20 00:31:14 -070017985 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17986 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17987
17988 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017989 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017991 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017992 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017993 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017994
17995 if (pHddCtx->isLogpInProgress)
17996 {
17997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17998 "%s: LOGP in Progress. Ignore!!!", __func__);
17999 return -EAGAIN;
18000 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018001 if (rc <= 0)
18002 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18003 WLAN_LOG_INDICATOR_HOST_DRIVER,
18004 WLAN_LOG_REASON_HDD_TIME_OUT,
18005 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018006
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018007 ret = -EINVAL;
18008 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018009 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018010 else
18011 {
18012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18013 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18014 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18015 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018016
Gopichand Nakkala05922802013-03-14 12:23:19 -070018017 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018018 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018019 ret = max_sta_failed;
18020 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018021 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018022
Hoonki Leea34dd892013-02-05 22:56:02 -080018023 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18024 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018025 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18027 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018028 }
18029 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18030 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018031 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18033 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018034 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018035
18036 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018037
18038tx_failed:
18039 /* add_station will be called before sending TDLS_SETUP_REQ and
18040 * TDLS_SETUP_RSP and as part of add_station driver will enable
18041 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18042 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18043 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18044 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18045 */
18046
18047 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18048 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18049 wlan_hdd_tdls_check_bmps(pAdapter);
18050 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018051}
18052
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018053#if TDLS_MGMT_VERSION2
18054static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18055 u8 *peer, u8 action_code, u8 dialog_token,
18056 u16 status_code, u32 peer_capability,
18057 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018058#else /* TDLS_MGMT_VERSION2 */
18059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18060static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18061 struct net_device *dev,
18062 const u8 *peer, u8 action_code,
18063 u8 dialog_token, u16 status_code,
18064 u32 peer_capability, bool initiator,
18065 const u8 *buf, size_t len)
18066#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18067static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18068 struct net_device *dev,
18069 const u8 *peer, u8 action_code,
18070 u8 dialog_token, u16 status_code,
18071 u32 peer_capability, const u8 *buf,
18072 size_t len)
18073#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18074static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18075 struct net_device *dev,
18076 u8 *peer, u8 action_code,
18077 u8 dialog_token,
18078 u16 status_code, u32 peer_capability,
18079 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018080#else
18081static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18082 u8 *peer, u8 action_code, u8 dialog_token,
18083 u16 status_code, const u8 *buf, size_t len)
18084#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018085#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018086{
18087 int ret;
18088
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018089 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018090#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018091 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18092 dialog_token, status_code,
18093 peer_capability, buf, len);
18094#else /* TDLS_MGMT_VERSION2 */
18095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18096 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18097 dialog_token, status_code,
18098 peer_capability, initiator,
18099 buf, len);
18100#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18101 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18102 dialog_token, status_code,
18103 peer_capability, buf, len);
18104#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18105 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18106 dialog_token, status_code,
18107 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018108#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018109 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18110 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018111#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018112#endif
18113 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018114
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018115 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018116}
Atul Mittal115287b2014-07-08 13:26:33 +053018117
18118int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018119#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18120 const u8 *peer,
18121#else
Atul Mittal115287b2014-07-08 13:26:33 +053018122 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018123#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018124 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018125 cfg80211_exttdls_callback callback)
18126{
18127
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018128 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018129 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018130 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18132 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18133 __func__, MAC_ADDR_ARRAY(peer));
18134
18135 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18136 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18137
18138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018139 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18140 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18141 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018142 return -ENOTSUPP;
18143 }
18144
18145 /* To cater the requirement of establishing the TDLS link
18146 * irrespective of the data traffic , get an entry of TDLS peer.
18147 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018148 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018149 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18150 if (pTdlsPeer == NULL) {
18151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18152 "%s: peer " MAC_ADDRESS_STR " not existing",
18153 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018154 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018155 return -EINVAL;
18156 }
18157
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018158 /* check FW TDLS Off Channel capability */
18159 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018160 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018161 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018162 {
18163 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18164 pTdlsPeer->peerParams.global_operating_class =
18165 tdls_peer_params->global_operating_class;
18166 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18167 pTdlsPeer->peerParams.min_bandwidth_kbps =
18168 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018169 /* check configured channel is valid, non dfs and
18170 * not current operating channel */
18171 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18172 tdls_peer_params->channel)) &&
18173 (pHddStaCtx) &&
18174 (tdls_peer_params->channel !=
18175 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018176 {
18177 pTdlsPeer->isOffChannelConfigured = TRUE;
18178 }
18179 else
18180 {
18181 pTdlsPeer->isOffChannelConfigured = FALSE;
18182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18183 "%s: Configured Tdls Off Channel is not valid", __func__);
18184
18185 }
18186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018187 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18188 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018189 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018190 pTdlsPeer->isOffChannelConfigured,
18191 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018192 }
18193 else
18194 {
18195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018196 "%s: TDLS off channel FW capability %d, "
18197 "host capab %d or Invalid TDLS Peer Params", __func__,
18198 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18199 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018200 }
18201
Atul Mittal115287b2014-07-08 13:26:33 +053018202 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18203
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018204 mutex_unlock(&pHddCtx->tdls_lock);
18205
Atul Mittal115287b2014-07-08 13:26:33 +053018206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18207 " %s TDLS Add Force Peer Failed",
18208 __func__);
18209 return -EINVAL;
18210 }
18211 /*EXT TDLS*/
18212
18213 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018214 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18216 " %s TDLS set callback Failed",
18217 __func__);
18218 return -EINVAL;
18219 }
18220
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018221 mutex_unlock(&pHddCtx->tdls_lock);
18222
Atul Mittal115287b2014-07-08 13:26:33 +053018223 return(0);
18224
18225}
18226
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018227int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18229 const u8 *peer
18230#else
18231 u8 *peer
18232#endif
18233)
Atul Mittal115287b2014-07-08 13:26:33 +053018234{
18235
18236 hddTdlsPeer_t *pTdlsPeer;
18237 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018238
Atul Mittal115287b2014-07-08 13:26:33 +053018239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18240 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18241 __func__, MAC_ADDR_ARRAY(peer));
18242
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018243 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18245 return -EINVAL;
18246 }
18247
Atul Mittal115287b2014-07-08 13:26:33 +053018248 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18249 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18250
18251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018252 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18253 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18254 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018255 return -ENOTSUPP;
18256 }
18257
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018258 mutex_lock(&pHddCtx->tdls_lock);
18259 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018260
18261 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018262 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018264 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018265 __func__, MAC_ADDR_ARRAY(peer));
18266 return -EINVAL;
18267 }
18268 else {
18269 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18270 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018271 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18272 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018273 /* if channel switch is configured, reset
18274 the channel for this peer */
18275 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18276 {
18277 pTdlsPeer->peerParams.channel = 0;
18278 pTdlsPeer->isOffChannelConfigured = FALSE;
18279 }
Atul Mittal115287b2014-07-08 13:26:33 +053018280 }
18281
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018282 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018283 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018285 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018286 }
Atul Mittal115287b2014-07-08 13:26:33 +053018287
18288 /*EXT TDLS*/
18289
18290 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018291 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18293 " %s TDLS set callback Failed",
18294 __func__);
18295 return -EINVAL;
18296 }
Atul Mittal115287b2014-07-08 13:26:33 +053018297
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018298 mutex_unlock(&pHddCtx->tdls_lock);
18299
18300 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018301}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018302static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18304 const u8 *peer,
18305#else
18306 u8 *peer,
18307#endif
18308 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018309{
18310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18311 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018312 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018313 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018315 ENTER();
18316
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018317 if (!pAdapter) {
18318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18319 return -EINVAL;
18320 }
18321
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18323 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18324 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018325 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018326 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018328 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018329 return -EINVAL;
18330 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018331
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018332 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018333 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018335 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018336 }
18337
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018338
18339 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018340 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018341 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018343 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18344 "Cannot process TDLS commands",
18345 pHddCtx->cfg_ini->fEnableTDLSSupport,
18346 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018347 return -ENOTSUPP;
18348 }
18349
18350 switch (oper) {
18351 case NL80211_TDLS_ENABLE_LINK:
18352 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018353 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018354 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018355 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18356 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018357 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018358 tANI_U16 numCurrTdlsPeers = 0;
18359 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018360 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018361 tSirMacAddr peerMac;
18362 int channel;
18363 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018364
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18366 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18367 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018368
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018369 mutex_lock(&pHddCtx->tdls_lock);
18370 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018371 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018372 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018373 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18375 " (oper %d) not exsting. ignored",
18376 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18377 return -EINVAL;
18378 }
18379
18380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18381 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18382 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18383 "NL80211_TDLS_ENABLE_LINK");
18384
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018385 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18386 {
18387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18388 MAC_ADDRESS_STR " failed",
18389 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018390 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018391 return -EINVAL;
18392 }
18393
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018394 /* before starting tdls connection, set tdls
18395 * off channel established status to default value */
18396 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018397
18398 mutex_unlock(&pHddCtx->tdls_lock);
18399
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018400 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018401 /* TDLS Off Channel, Disable tdls channel switch,
18402 when there are more than one tdls link */
18403 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018404 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018405 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018406 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018407 /* get connected peer and send disable tdls off chan */
18408 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018409 if ((connPeer) &&
18410 (connPeer->isOffChannelSupported == TRUE) &&
18411 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018412 {
18413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18414 "%s: More then one peer connected, Disable "
18415 "TDLS channel switch", __func__);
18416
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018417 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018418 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18419 channel = connPeer->peerParams.channel;
18420
18421 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018422
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018423 ret = sme_SendTdlsChanSwitchReq(
18424 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018425 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018426 peerMac,
18427 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018428 TDLS_OFF_CHANNEL_BW_OFFSET,
18429 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018430 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018431 hddLog(VOS_TRACE_LEVEL_ERROR,
18432 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018433 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018434 }
18435 else
18436 {
18437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18438 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018439 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018440 "isOffChannelConfigured %d",
18441 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018442 (connPeer ? (connPeer->isOffChannelSupported)
18443 : -1),
18444 (connPeer ? (connPeer->isOffChannelConfigured)
18445 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018446 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018447 }
18448 }
18449
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018450 mutex_lock(&pHddCtx->tdls_lock);
18451 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18452 if ( NULL == pTdlsPeer ) {
18453 mutex_unlock(&pHddCtx->tdls_lock);
18454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18455 "%s: " MAC_ADDRESS_STR
18456 " (oper %d) peer got freed in other context. ignored",
18457 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18458 return -EINVAL;
18459 }
18460 peer_status = pTdlsPeer->link_status;
18461 mutex_unlock(&pHddCtx->tdls_lock);
18462
18463 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018464 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018465 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018466
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018467 if (0 != wlan_hdd_tdls_get_link_establish_params(
18468 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018470 return -EINVAL;
18471 }
18472 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018473
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018474 ret = sme_SendTdlsLinkEstablishParams(
18475 WLAN_HDD_GET_HAL_CTX(pAdapter),
18476 pAdapter->sessionId, peer,
18477 &tdlsLinkEstablishParams);
18478 if (ret != VOS_STATUS_SUCCESS) {
18479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18480 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018481 /* Send TDLS peer UAPSD capabilities to the firmware and
18482 * register with the TL on after the response for this operation
18483 * is received .
18484 */
18485 ret = wait_for_completion_interruptible_timeout(
18486 &pAdapter->tdls_link_establish_req_comp,
18487 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018488
18489 mutex_lock(&pHddCtx->tdls_lock);
18490 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18491 if ( NULL == pTdlsPeer ) {
18492 mutex_unlock(&pHddCtx->tdls_lock);
18493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18494 "%s %d: " MAC_ADDRESS_STR
18495 " (oper %d) peer got freed in other context. ignored",
18496 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18497 (int)oper);
18498 return -EINVAL;
18499 }
18500 peer_status = pTdlsPeer->link_status;
18501 mutex_unlock(&pHddCtx->tdls_lock);
18502
18503 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018504 {
18505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018506 FL("Link Establish Request Failed Status %ld"),
18507 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018508 return -EINVAL;
18509 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018510 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018511
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018512 mutex_lock(&pHddCtx->tdls_lock);
18513 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18514 if ( NULL == pTdlsPeer ) {
18515 mutex_unlock(&pHddCtx->tdls_lock);
18516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18517 "%s: " MAC_ADDRESS_STR
18518 " (oper %d) peer got freed in other context. ignored",
18519 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18520 return -EINVAL;
18521 }
18522
Atul Mittal115287b2014-07-08 13:26:33 +053018523 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18524 eTDLS_LINK_CONNECTED,
18525 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018526 staDesc.ucSTAId = pTdlsPeer->staId;
18527 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018528
18529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18530 "%s: tdlsLinkEstablishParams of peer "
18531 MAC_ADDRESS_STR "uapsdQueues: %d"
18532 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18533 "isResponder: %d peerstaId: %d",
18534 __func__,
18535 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18536 tdlsLinkEstablishParams.uapsdQueues,
18537 tdlsLinkEstablishParams.qos,
18538 tdlsLinkEstablishParams.maxSp,
18539 tdlsLinkEstablishParams.isBufSta,
18540 tdlsLinkEstablishParams.isOffChannelSupported,
18541 tdlsLinkEstablishParams.isResponder,
18542 pTdlsPeer->staId);
18543
18544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18545 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18546 __func__,
18547 staDesc.ucSTAId,
18548 staDesc.ucQosEnabled);
18549
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018550 ret = WLANTL_UpdateTdlsSTAClient(
18551 pHddCtx->pvosContext,
18552 &staDesc);
18553 if (ret != VOS_STATUS_SUCCESS) {
18554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18555 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018556
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018557 /* Mark TDLS client Authenticated .*/
18558 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18559 pTdlsPeer->staId,
18560 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018561 if (VOS_STATUS_SUCCESS == status)
18562 {
Hoonki Lee14621352013-04-16 17:51:19 -070018563 if (pTdlsPeer->is_responder == 0)
18564 {
18565 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018566 tdlsConnInfo_t *tdlsInfo;
18567
18568 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18569
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018570 if (!vos_timer_is_initialized(
18571 &pTdlsPeer->initiatorWaitTimeoutTimer))
18572 {
18573 /* Initialize initiator wait callback */
18574 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018575 &pTdlsPeer->initiatorWaitTimeoutTimer,
18576 VOS_TIMER_TYPE_SW,
18577 wlan_hdd_tdls_initiator_wait_cb,
18578 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018579 }
Hoonki Lee14621352013-04-16 17:51:19 -070018580 wlan_hdd_tdls_timer_restart(pAdapter,
18581 &pTdlsPeer->initiatorWaitTimeoutTimer,
18582 WAIT_TIME_TDLS_INITIATOR);
18583 /* suspend initiator TX until it receives direct packet from the
18584 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018585 ret = WLANTL_SuspendDataTx(
18586 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18587 &staId, NULL);
18588 if (ret != VOS_STATUS_SUCCESS) {
18589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18590 }
Hoonki Lee14621352013-04-16 17:51:19 -070018591 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018592
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018593 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018594 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018595 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018596 suppChannelLen =
18597 tdlsLinkEstablishParams.supportedChannelsLen;
18598
18599 if ((suppChannelLen > 0) &&
18600 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18601 {
18602 tANI_U8 suppPeerChannel = 0;
18603 int i = 0;
18604 for (i = 0U; i < suppChannelLen; i++)
18605 {
18606 suppPeerChannel =
18607 tdlsLinkEstablishParams.supportedChannels[i];
18608
18609 pTdlsPeer->isOffChannelSupported = FALSE;
18610 if (suppPeerChannel ==
18611 pTdlsPeer->peerParams.channel)
18612 {
18613 pTdlsPeer->isOffChannelSupported = TRUE;
18614 break;
18615 }
18616 }
18617 }
18618 else
18619 {
18620 pTdlsPeer->isOffChannelSupported = FALSE;
18621 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018622 }
18623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18624 "%s: TDLS channel switch request for channel "
18625 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018626 "%d isOffChannelSupported %d", __func__,
18627 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018628 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018629 suppChannelLen,
18630 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018631
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018632 /* TDLS Off Channel, Enable tdls channel switch,
18633 when their is only one tdls link and it supports */
18634 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18635 if ((numCurrTdlsPeers == 1) &&
18636 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18637 (TRUE == pTdlsPeer->isOffChannelConfigured))
18638 {
18639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18640 "%s: Send TDLS channel switch request for channel %d",
18641 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018642
18643 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018644 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18645 channel = pTdlsPeer->peerParams.channel;
18646
18647 mutex_unlock(&pHddCtx->tdls_lock);
18648
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018649 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18650 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018651 peerMac,
18652 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018653 TDLS_OFF_CHANNEL_BW_OFFSET,
18654 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018655 if (ret != VOS_STATUS_SUCCESS) {
18656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18657 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018658 }
18659 else
18660 {
18661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18662 "%s: TDLS channel switch request not sent"
18663 " numCurrTdlsPeers %d "
18664 "isOffChannelSupported %d "
18665 "isOffChannelConfigured %d",
18666 __func__, numCurrTdlsPeers,
18667 pTdlsPeer->isOffChannelSupported,
18668 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018669 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018670 }
18671
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018672 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018673 else
18674 mutex_unlock(&pHddCtx->tdls_lock);
18675
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018676 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018677
18678 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018679 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18680 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018681 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018682 int ac;
18683 uint8 ucAc[4] = { WLANTL_AC_VO,
18684 WLANTL_AC_VI,
18685 WLANTL_AC_BK,
18686 WLANTL_AC_BE };
18687 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18688 for(ac=0; ac < 4; ac++)
18689 {
18690 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18691 pTdlsPeer->staId, ucAc[ac],
18692 tlTid[ac], tlTid[ac], 0, 0,
18693 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018694 if (status != VOS_STATUS_SUCCESS) {
18695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18696 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018697 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018698 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018699 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018700
Bhargav Shah66896792015-10-01 18:17:37 +053018701 /* stop TCP delack timer if TDLS is enable */
18702 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18703 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018704 hdd_wlan_tdls_enable_link_event(peer,
18705 pTdlsPeer->isOffChannelSupported,
18706 pTdlsPeer->isOffChannelConfigured,
18707 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018708 }
18709 break;
18710 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018711 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018712 tANI_U16 numCurrTdlsPeers = 0;
18713 hddTdlsPeer_t *connPeer = NULL;
18714
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18716 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18717 __func__, MAC_ADDR_ARRAY(peer));
18718
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018719 mutex_lock(&pHddCtx->tdls_lock);
18720 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018721
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018722
Sunil Dutt41de4e22013-11-14 18:09:02 +053018723 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018724 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18726 " (oper %d) not exsting. ignored",
18727 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18728 return -EINVAL;
18729 }
18730
18731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18732 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18733 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18734 "NL80211_TDLS_DISABLE_LINK");
18735
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018736 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018737 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018738 long status;
18739
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018740 /* set tdls off channel status to false for this peer */
18741 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018742 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18743 eTDLS_LINK_TEARING,
18744 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18745 eTDLS_LINK_UNSPECIFIED:
18746 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018747 mutex_unlock(&pHddCtx->tdls_lock);
18748
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018749 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18750
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018751 status = sme_DeleteTdlsPeerSta(
18752 WLAN_HDD_GET_HAL_CTX(pAdapter),
18753 pAdapter->sessionId, peer );
18754 if (status != VOS_STATUS_SUCCESS) {
18755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18756 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018757
18758 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18759 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018760
18761 mutex_lock(&pHddCtx->tdls_lock);
18762 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18763 if ( NULL == pTdlsPeer ) {
18764 mutex_unlock(&pHddCtx->tdls_lock);
18765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18766 " peer was freed in other context",
18767 __func__, MAC_ADDR_ARRAY(peer));
18768 return -EINVAL;
18769 }
18770
Atul Mittal271a7652014-09-12 13:18:22 +053018771 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018772 eTDLS_LINK_IDLE,
18773 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018774 mutex_unlock(&pHddCtx->tdls_lock);
18775
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018776 if (status <= 0)
18777 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18779 "%s: Del station failed status %ld",
18780 __func__, status);
18781 return -EPERM;
18782 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018783
18784 /* TDLS Off Channel, Enable tdls channel switch,
18785 when their is only one tdls link and it supports */
18786 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18787 if (numCurrTdlsPeers == 1)
18788 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018789 tSirMacAddr peerMac;
18790 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018791
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018792 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018793 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018794
18795 if (connPeer == NULL) {
18796 mutex_unlock(&pHddCtx->tdls_lock);
18797 hddLog(VOS_TRACE_LEVEL_ERROR,
18798 "%s connPeer is NULL", __func__);
18799 return -EINVAL;
18800 }
18801
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018802 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18803 channel = connPeer->peerParams.channel;
18804
18805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18806 "%s: TDLS channel switch "
18807 "isOffChannelSupported %d "
18808 "isOffChannelConfigured %d "
18809 "isOffChannelEstablished %d",
18810 __func__,
18811 (connPeer ? connPeer->isOffChannelSupported : -1),
18812 (connPeer ? connPeer->isOffChannelConfigured : -1),
18813 (connPeer ? connPeer->isOffChannelEstablished : -1));
18814
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018815 if ((connPeer) &&
18816 (connPeer->isOffChannelSupported == TRUE) &&
18817 (connPeer->isOffChannelConfigured == TRUE))
18818 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018819 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018820 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018821 status = sme_SendTdlsChanSwitchReq(
18822 WLAN_HDD_GET_HAL_CTX(pAdapter),
18823 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018824 peerMac,
18825 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018826 TDLS_OFF_CHANNEL_BW_OFFSET,
18827 TDLS_CHANNEL_SWITCH_ENABLE);
18828 if (status != VOS_STATUS_SUCCESS) {
18829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18830 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018831 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018832 else
18833 mutex_unlock(&pHddCtx->tdls_lock);
18834 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018835 else
18836 {
18837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18838 "%s: TDLS channel switch request not sent "
18839 "numCurrTdlsPeers %d ",
18840 __func__, numCurrTdlsPeers);
18841 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018842 }
18843 else
18844 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018845 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18847 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018848 }
Bhargav Shah66896792015-10-01 18:17:37 +053018849 if (numCurrTdlsPeers == 0) {
18850 /* start TCP delack timer if TDLS is disable */
18851 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18852 hdd_manage_delack_timer(pHddCtx);
18853 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018854 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018855 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018856 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018857 {
Atul Mittal115287b2014-07-08 13:26:33 +053018858 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018859
Atul Mittal115287b2014-07-08 13:26:33 +053018860 if (0 != status)
18861 {
18862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018863 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018864 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018865 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018866 break;
18867 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018868 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018869 {
Atul Mittal115287b2014-07-08 13:26:33 +053018870 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18871 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018872 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018873 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018874
Atul Mittal115287b2014-07-08 13:26:33 +053018875 if (0 != status)
18876 {
18877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018878 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018879 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018880 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018881 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018882 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018883 case NL80211_TDLS_DISCOVERY_REQ:
18884 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018886 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018887 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018888 return -ENOTSUPP;
18889 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18891 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018892 return -ENOTSUPP;
18893 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018894
18895 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018896 return 0;
18897}
Chilam NG571c65a2013-01-19 12:27:36 +053018898
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018899static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18901 const u8 *peer,
18902#else
18903 u8 *peer,
18904#endif
18905 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018906{
18907 int ret;
18908
18909 vos_ssr_protect(__func__);
18910 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18911 vos_ssr_unprotect(__func__);
18912
18913 return ret;
18914}
18915
Chilam NG571c65a2013-01-19 12:27:36 +053018916int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18917 struct net_device *dev, u8 *peer)
18918{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018919 hddLog(VOS_TRACE_LEVEL_INFO,
18920 "tdls send discover req: "MAC_ADDRESS_STR,
18921 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018922#if TDLS_MGMT_VERSION2
18923 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18924 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18925#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18927 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18928 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18929#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18930 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18931 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18932#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18933 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18934 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18935#else
Chilam NG571c65a2013-01-19 12:27:36 +053018936 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18937 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018938#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018939#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018940}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018941#endif
18942
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018943#ifdef WLAN_FEATURE_GTK_OFFLOAD
18944/*
18945 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18946 * Callback rountine called upon receiving response for
18947 * get offload info
18948 */
18949void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18950 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18951{
18952
18953 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018954 tANI_U8 tempReplayCounter[8];
18955 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018956
18957 ENTER();
18958
18959 if (NULL == pAdapter)
18960 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018962 "%s: HDD adapter is Null", __func__);
18963 return ;
18964 }
18965
18966 if (NULL == pGtkOffloadGetInfoRsp)
18967 {
18968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18969 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18970 return ;
18971 }
18972
18973 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18974 {
18975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18976 "%s: wlan Failed to get replay counter value",
18977 __func__);
18978 return ;
18979 }
18980
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018981 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18982 /* Update replay counter */
18983 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18984 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18985
18986 {
18987 /* changing from little to big endian since supplicant
18988 * works on big endian format
18989 */
18990 int i;
18991 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18992
18993 for (i = 0; i < 8; i++)
18994 {
18995 tempReplayCounter[7-i] = (tANI_U8)p[i];
18996 }
18997 }
18998
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018999 /* Update replay counter to NL */
19000 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019001 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019002}
19003
19004/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019005 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019006 * This function is used to offload GTK rekeying job to the firmware.
19007 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019008int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019009 struct cfg80211_gtk_rekey_data *data)
19010{
19011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19012 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19013 hdd_station_ctx_t *pHddStaCtx;
19014 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019015 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019016 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019017 eHalStatus status = eHAL_STATUS_FAILURE;
19018
19019 ENTER();
19020
19021 if (NULL == pAdapter)
19022 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019024 "%s: HDD adapter is Null", __func__);
19025 return -ENODEV;
19026 }
19027
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19029 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19030 pAdapter->sessionId, pAdapter->device_mode));
19031
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019032 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019033 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019035 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019036 }
19037
19038 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19039 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19040 if (NULL == hHal)
19041 {
19042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19043 "%s: HAL context is Null!!!", __func__);
19044 return -EAGAIN;
19045 }
19046
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019047 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19048 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19049 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19050 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019051 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019052 {
19053 /* changing from big to little endian since driver
19054 * works on little endian format
19055 */
19056 tANI_U8 *p =
19057 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19058 int i;
19059
19060 for (i = 0; i < 8; i++)
19061 {
19062 p[7-i] = data->replay_ctr[i];
19063 }
19064 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019065
19066 if (TRUE == pHddCtx->hdd_wlan_suspended)
19067 {
19068 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019069 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19070 sizeof (tSirGtkOffloadParams));
19071 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019072 pAdapter->sessionId);
19073
19074 if (eHAL_STATUS_SUCCESS != status)
19075 {
19076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19077 "%s: sme_SetGTKOffload failed, returned %d",
19078 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019079
19080 /* Need to clear any trace of key value in the memory.
19081 * Thus zero out the memory even though it is local
19082 * variable.
19083 */
19084 vos_mem_zero(&hddGtkOffloadReqParams,
19085 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019086 return status;
19087 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19089 "%s: sme_SetGTKOffload successfull", __func__);
19090 }
19091 else
19092 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19094 "%s: wlan not suspended GTKOffload request is stored",
19095 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019096 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019097
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019098 /* Need to clear any trace of key value in the memory.
19099 * Thus zero out the memory even though it is local
19100 * variable.
19101 */
19102 vos_mem_zero(&hddGtkOffloadReqParams,
19103 sizeof(hddGtkOffloadReqParams));
19104
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019105 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019106 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019107}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019108
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019109int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19110 struct cfg80211_gtk_rekey_data *data)
19111{
19112 int ret;
19113
19114 vos_ssr_protect(__func__);
19115 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19116 vos_ssr_unprotect(__func__);
19117
19118 return ret;
19119}
19120#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019121/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019122 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019123 * This function is used to set access control policy
19124 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019125static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19126 struct net_device *dev,
19127 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019128{
19129 int i;
19130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19131 hdd_hostapd_state_t *pHostapdState;
19132 tsap_Config_t *pConfig;
19133 v_CONTEXT_t pVosContext = NULL;
19134 hdd_context_t *pHddCtx;
19135 int status;
19136
19137 ENTER();
19138
19139 if (NULL == pAdapter)
19140 {
19141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19142 "%s: HDD adapter is Null", __func__);
19143 return -ENODEV;
19144 }
19145
19146 if (NULL == params)
19147 {
19148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19149 "%s: params is Null", __func__);
19150 return -EINVAL;
19151 }
19152
19153 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19154 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019155 if (0 != status)
19156 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019157 return status;
19158 }
19159
19160 pVosContext = pHddCtx->pvosContext;
19161 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19162
19163 if (NULL == pHostapdState)
19164 {
19165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19166 "%s: pHostapdState is Null", __func__);
19167 return -EINVAL;
19168 }
19169
19170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19171 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19173 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19174 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019175
19176 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19177 {
19178 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19179
19180 /* default value */
19181 pConfig->num_accept_mac = 0;
19182 pConfig->num_deny_mac = 0;
19183
19184 /**
19185 * access control policy
19186 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19187 * listed in hostapd.deny file.
19188 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19189 * listed in hostapd.accept file.
19190 */
19191 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19192 {
19193 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19194 }
19195 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19196 {
19197 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19198 }
19199 else
19200 {
19201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19202 "%s:Acl Policy : %d is not supported",
19203 __func__, params->acl_policy);
19204 return -ENOTSUPP;
19205 }
19206
19207 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19208 {
19209 pConfig->num_accept_mac = params->n_acl_entries;
19210 for (i = 0; i < params->n_acl_entries; i++)
19211 {
19212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19213 "** Add ACL MAC entry %i in WhiletList :"
19214 MAC_ADDRESS_STR, i,
19215 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19216
19217 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19218 sizeof(qcmacaddr));
19219 }
19220 }
19221 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19222 {
19223 pConfig->num_deny_mac = params->n_acl_entries;
19224 for (i = 0; i < params->n_acl_entries; i++)
19225 {
19226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19227 "** Add ACL MAC entry %i in BlackList :"
19228 MAC_ADDRESS_STR, i,
19229 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19230
19231 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19232 sizeof(qcmacaddr));
19233 }
19234 }
19235
19236 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19237 {
19238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19239 "%s: SAP Set Mac Acl fail", __func__);
19240 return -EINVAL;
19241 }
19242 }
19243 else
19244 {
19245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019246 "%s: Invalid device_mode = %s (%d)",
19247 __func__, hdd_device_modetoString(pAdapter->device_mode),
19248 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019249 return -EINVAL;
19250 }
19251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019252 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019253 return 0;
19254}
19255
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019256static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19257 struct net_device *dev,
19258 const struct cfg80211_acl_data *params)
19259{
19260 int ret;
19261 vos_ssr_protect(__func__);
19262 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19263 vos_ssr_unprotect(__func__);
19264
19265 return ret;
19266}
19267
Leo Chang9056f462013-08-01 19:21:11 -070019268#ifdef WLAN_NL80211_TESTMODE
19269#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019270void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019271(
19272 void *pAdapter,
19273 void *indCont
19274)
19275{
Leo Changd9df8aa2013-09-26 13:32:26 -070019276 tSirLPHBInd *lphbInd;
19277 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019278 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019279
19280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019281 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019282
c_hpothu73f35e62014-04-18 13:40:08 +053019283 if (pAdapter == NULL)
19284 {
19285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19286 "%s: pAdapter is NULL\n",__func__);
19287 return;
19288 }
19289
Leo Chang9056f462013-08-01 19:21:11 -070019290 if (NULL == indCont)
19291 {
19292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019293 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019294 return;
19295 }
19296
c_hpothu73f35e62014-04-18 13:40:08 +053019297 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019298 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019299 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019300 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019301 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019302 GFP_ATOMIC);
19303 if (!skb)
19304 {
19305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19306 "LPHB timeout, NL buffer alloc fail");
19307 return;
19308 }
19309
Leo Changac3ba772013-10-07 09:47:04 -070019310 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019311 {
19312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19313 "WLAN_HDD_TM_ATTR_CMD put fail");
19314 goto nla_put_failure;
19315 }
Leo Changac3ba772013-10-07 09:47:04 -070019316 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019317 {
19318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19319 "WLAN_HDD_TM_ATTR_TYPE put fail");
19320 goto nla_put_failure;
19321 }
Leo Changac3ba772013-10-07 09:47:04 -070019322 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019323 sizeof(tSirLPHBInd), lphbInd))
19324 {
19325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19326 "WLAN_HDD_TM_ATTR_DATA put fail");
19327 goto nla_put_failure;
19328 }
Leo Chang9056f462013-08-01 19:21:11 -070019329 cfg80211_testmode_event(skb, GFP_ATOMIC);
19330 return;
19331
19332nla_put_failure:
19333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19334 "NLA Put fail");
19335 kfree_skb(skb);
19336
19337 return;
19338}
19339#endif /* FEATURE_WLAN_LPHB */
19340
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019341static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019342{
19343 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19344 int err = 0;
19345#ifdef FEATURE_WLAN_LPHB
19346 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019347 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019348
19349 ENTER();
19350
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019351 err = wlan_hdd_validate_context(pHddCtx);
19352 if (0 != err)
19353 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019354 return err;
19355 }
Leo Chang9056f462013-08-01 19:21:11 -070019356#endif /* FEATURE_WLAN_LPHB */
19357
19358 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19359 if (err)
19360 {
19361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19362 "%s Testmode INV ATTR", __func__);
19363 return err;
19364 }
19365
19366 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19367 {
19368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19369 "%s Testmode INV CMD", __func__);
19370 return -EINVAL;
19371 }
19372
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019373 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19374 TRACE_CODE_HDD_CFG80211_TESTMODE,
19375 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019376 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19377 {
19378#ifdef FEATURE_WLAN_LPHB
19379 /* Low Power Heartbeat configuration request */
19380 case WLAN_HDD_TM_CMD_WLAN_HB:
19381 {
19382 int buf_len;
19383 void *buf;
19384 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019385 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019386
19387 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19388 {
19389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19390 "%s Testmode INV DATA", __func__);
19391 return -EINVAL;
19392 }
19393
19394 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19395 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019396
19397 hb_params_temp =(tSirLPHBReq *)buf;
19398 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19399 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19400 return -EINVAL;
19401
Leo Chang9056f462013-08-01 19:21:11 -070019402 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19403 if (NULL == hb_params)
19404 {
19405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19406 "%s Request Buffer Alloc Fail", __func__);
19407 return -EINVAL;
19408 }
19409
19410 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019411 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19412 hb_params,
19413 wlan_hdd_cfg80211_lphb_ind_handler);
19414 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019415 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19417 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019418 vos_mem_free(hb_params);
19419 }
Leo Chang9056f462013-08-01 19:21:11 -070019420 return 0;
19421 }
19422#endif /* FEATURE_WLAN_LPHB */
19423 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19425 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019426 return -EOPNOTSUPP;
19427 }
19428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019429 EXIT();
19430 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019431}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019432
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019433static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19435 struct wireless_dev *wdev,
19436#endif
19437 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019438{
19439 int ret;
19440
19441 vos_ssr_protect(__func__);
19442 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19443 vos_ssr_unprotect(__func__);
19444
19445 return ret;
19446}
Leo Chang9056f462013-08-01 19:21:11 -070019447#endif /* CONFIG_NL80211_TESTMODE */
19448
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019449extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019450static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019451 struct net_device *dev,
19452 int idx, struct survey_info *survey)
19453{
19454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19455 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019456 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019457 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019458 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019459 v_S7_t snr,rssi;
19460 int status, i, j, filled = 0;
19461
19462 ENTER();
19463
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019464 if (NULL == pAdapter)
19465 {
19466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19467 "%s: HDD adapter is Null", __func__);
19468 return -ENODEV;
19469 }
19470
19471 if (NULL == wiphy)
19472 {
19473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19474 "%s: wiphy is Null", __func__);
19475 return -ENODEV;
19476 }
19477
19478 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19479 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019480 if (0 != status)
19481 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019482 return status;
19483 }
19484
Mihir Sheted9072e02013-08-21 17:02:29 +053019485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19486
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019487 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019488 0 != pAdapter->survey_idx ||
19489 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019490 {
19491 /* The survey dump ops when implemented completely is expected to
19492 * return a survey of all channels and the ops is called by the
19493 * kernel with incremental values of the argument 'idx' till it
19494 * returns -ENONET. But we can only support the survey for the
19495 * operating channel for now. survey_idx is used to track
19496 * that the ops is called only once and then return -ENONET for
19497 * the next iteration
19498 */
19499 pAdapter->survey_idx = 0;
19500 return -ENONET;
19501 }
19502
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019503 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19504 {
19505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19506 "%s: Roaming in progress, hence return ", __func__);
19507 return -ENONET;
19508 }
19509
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019510 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19511
19512 wlan_hdd_get_snr(pAdapter, &snr);
19513 wlan_hdd_get_rssi(pAdapter, &rssi);
19514
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19516 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19517 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019518 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19519 hdd_wlan_get_freq(channel, &freq);
19520
19521
19522 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19523 {
19524 if (NULL == wiphy->bands[i])
19525 {
19526 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19527 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19528 continue;
19529 }
19530
19531 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19532 {
19533 struct ieee80211_supported_band *band = wiphy->bands[i];
19534
19535 if (band->channels[j].center_freq == (v_U16_t)freq)
19536 {
19537 survey->channel = &band->channels[j];
19538 /* The Rx BDs contain SNR values in dB for the received frames
19539 * while the supplicant expects noise. So we calculate and
19540 * return the value of noise (dBm)
19541 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19542 */
19543 survey->noise = rssi - snr;
19544 survey->filled = SURVEY_INFO_NOISE_DBM;
19545 filled = 1;
19546 }
19547 }
19548 }
19549
19550 if (filled)
19551 pAdapter->survey_idx = 1;
19552 else
19553 {
19554 pAdapter->survey_idx = 0;
19555 return -ENONET;
19556 }
19557
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019558 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019559 return 0;
19560}
19561
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019562static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19563 struct net_device *dev,
19564 int idx, struct survey_info *survey)
19565{
19566 int ret;
19567
19568 vos_ssr_protect(__func__);
19569 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19570 vos_ssr_unprotect(__func__);
19571
19572 return ret;
19573}
19574
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019575/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019576 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019577 * this is called when cfg80211 driver resume
19578 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19579 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019580int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019581{
19582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19583 hdd_adapter_t *pAdapter;
19584 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19585 VOS_STATUS status = VOS_STATUS_SUCCESS;
19586
19587 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019588
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019589 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019590 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019591 return 0;
19592 }
19593
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019594 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19595 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019596
19597 if ((VOS_STA_SAP_MODE == hdd_get_conparam()) &&
19598 pHddCtx->is_ap_mode_wow_supported)
19599 {
19600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19601 "%s: Resume SoftAP", __func__);
19602 hdd_set_wlan_suspend_mode(false);
19603 }
19604
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019605 spin_lock(&pHddCtx->schedScan_lock);
19606 pHddCtx->isWiphySuspended = FALSE;
19607 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19608 {
19609 spin_unlock(&pHddCtx->schedScan_lock);
19610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19611 "%s: Return resume is not due to PNO indication", __func__);
19612 return 0;
19613 }
19614 // Reset flag to avoid updatating cfg80211 data old results again
19615 pHddCtx->isSchedScanUpdatePending = FALSE;
19616 spin_unlock(&pHddCtx->schedScan_lock);
19617
19618 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19619
19620 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19621 {
19622 pAdapter = pAdapterNode->pAdapter;
19623 if ( (NULL != pAdapter) &&
19624 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19625 {
19626 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019627 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19629 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019630 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019631 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019632 {
19633 /* Acquire wakelock to handle the case where APP's tries to
19634 * suspend immediately after updating the scan results. Whis
19635 * results in app's is in suspended state and not able to
19636 * process the connect request to AP
19637 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019638 hdd_prevent_suspend_timeout(2000,
19639 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019640 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019641 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019642
19643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19644 "%s : cfg80211 scan result database updated", __func__);
19645
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019646 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019647 return 0;
19648
19649 }
19650 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19651 pAdapterNode = pNext;
19652 }
19653
19654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19655 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019656 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019657 return 0;
19658}
19659
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019660int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19661{
19662 int ret;
19663
19664 vos_ssr_protect(__func__);
19665 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19666 vos_ssr_unprotect(__func__);
19667
19668 return ret;
19669}
19670
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019671/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019672 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019673 * this is called when cfg80211 driver suspends
19674 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019675int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019676 struct cfg80211_wowlan *wow)
19677{
19678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019679 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019680
19681 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019682
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019683 ret = wlan_hdd_validate_context(pHddCtx);
19684 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019685 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019686 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019687 }
19688
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019689 if ((VOS_STA_SAP_MODE == hdd_get_conparam()) &&
19690 (pHddCtx->is_ap_mode_wow_supported)) {
19691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19692 "%s: Suspend SoftAP", __func__);
19693 hdd_set_wlan_suspend_mode(true);
19694 }
19695
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019696
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019697 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19698 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19699 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019700 pHddCtx->isWiphySuspended = TRUE;
19701
19702 EXIT();
19703
19704 return 0;
19705}
19706
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019707int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19708 struct cfg80211_wowlan *wow)
19709{
19710 int ret;
19711
19712 vos_ssr_protect(__func__);
19713 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19714 vos_ssr_unprotect(__func__);
19715
19716 return ret;
19717}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019718
19719#ifdef FEATURE_OEM_DATA_SUPPORT
19720static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019721 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019722{
19723 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19724
19725 ENTER();
19726
19727 if (wlan_hdd_validate_context(pHddCtx)) {
19728 return;
19729 }
19730 if (!pMsg)
19731 {
19732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19733 return;
19734 }
19735
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019736 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019737
19738 EXIT();
19739 return;
19740
19741}
19742
19743void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019744 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019745{
19746 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19747
19748 ENTER();
19749
19750 if (wlan_hdd_validate_context(pHddCtx)) {
19751 return;
19752 }
19753
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019754 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019755
19756 switch(evType) {
19757 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019758 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019759 break;
19760 default:
19761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19762 break;
19763 }
19764 EXIT();
19765}
19766#endif
19767
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19769 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019770/**
19771 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19772 * @wiphy: Pointer to wiphy
19773 * @wdev: Pointer to wireless device structure
19774 *
19775 * This function is used to abort an ongoing scan
19776 *
19777 * Return: None
19778 */
19779static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19780 struct wireless_dev *wdev)
19781{
19782 struct net_device *dev = wdev->netdev;
19783 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19784 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19785 int ret;
19786
19787 ENTER();
19788
19789 if (NULL == adapter) {
19790 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19791 return;
19792 }
19793
19794 ret = wlan_hdd_validate_context(hdd_ctx);
19795 if (0 != ret)
19796 return;
19797
19798 wlan_hdd_scan_abort(adapter);
19799
19800 return;
19801}
19802
19803/**
19804 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19805 * @wiphy: Pointer to wiphy
19806 * @wdev: Pointer to wireless device structure
19807 *
19808 * Return: None
19809 */
19810void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19811 struct wireless_dev *wdev)
19812{
19813 vos_ssr_protect(__func__);
19814 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19815 vos_ssr_unprotect(__func__);
19816
19817 return;
19818}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019819#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019820
Jeff Johnson295189b2012-06-20 16:38:30 -070019821/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019822static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019823{
19824 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19825 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19826 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19827 .change_station = wlan_hdd_change_station,
19828#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19829 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19830 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19831 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019832#else
19833 .start_ap = wlan_hdd_cfg80211_start_ap,
19834 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19835 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019836#endif
19837 .change_bss = wlan_hdd_cfg80211_change_bss,
19838 .add_key = wlan_hdd_cfg80211_add_key,
19839 .get_key = wlan_hdd_cfg80211_get_key,
19840 .del_key = wlan_hdd_cfg80211_del_key,
19841 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019842#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019843 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019844#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019845 .scan = wlan_hdd_cfg80211_scan,
19846 .connect = wlan_hdd_cfg80211_connect,
19847 .disconnect = wlan_hdd_cfg80211_disconnect,
19848 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19849 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19850 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19851 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19852 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019853 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19854 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019855 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19857 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19858 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19859 .set_txq_params = wlan_hdd_set_txq_params,
19860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019861 .get_station = wlan_hdd_cfg80211_get_station,
19862 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19863 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019864 .add_station = wlan_hdd_cfg80211_add_station,
19865#ifdef FEATURE_WLAN_LFR
19866 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19867 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19868 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19869#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019870#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19871 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19872#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019873#ifdef FEATURE_WLAN_TDLS
19874 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19875 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19876#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019877#ifdef WLAN_FEATURE_GTK_OFFLOAD
19878 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19879#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019880#ifdef FEATURE_WLAN_SCAN_PNO
19881 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19882 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19883#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019884 .resume = wlan_hdd_cfg80211_resume_wlan,
19885 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019886 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019887#ifdef WLAN_NL80211_TESTMODE
19888 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19889#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019890 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19892 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019893 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019895};
19896