blob: 3475a18c9622afd8733cbf1a71b85a154b231961 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -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/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_assoc.c
30 *
31 * WLAN Host Device Driver implementation
32 *
33 */
34
35#include "wlan_hdd_includes.h"
36#include <ani_global.h>
37#include "dot11f.h"
38#include "wlan_hdd_power.h"
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +053039#include "wlan_hdd_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include <linux/ieee80211.h>
41#include <linux/wireless.h>
42#include <linux/etherdevice.h>
43#include <net/cfg80211.h>
44#include "wlan_hdd_cfg80211.h"
45#include "csr_inside_api.h"
46#include "wlan_hdd_p2p.h"
47#ifdef FEATURE_WLAN_TDLS
48#include "wlan_hdd_tdls.h"
49#endif
50#include "sme_api.h"
51#include "wlan_hdd_hostapd.h"
52#include <wlan_hdd_ipa.h>
53#include <cds_sched.h>
54#include "cds_concurrency.h"
55#include "sme_power_save_api.h"
56#include "ol_txrx_ctrl_api.h"
57#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080058#include "ol_txrx.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080059#include "cdp_txrx_flow_ctrl_legacy.h"
60#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061
62/* These are needed to recognize WPA and RSN suite types */
63#define HDD_WPA_OUI_SIZE 4
64#define HDD_RSN_OUI_SIZE 4
65uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
66uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
67uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
68uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
69uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
70uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
71
72#ifdef FEATURE_WLAN_ESE
73/* CCKM */
74uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
75/* CCKM */
76uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
77#endif /* FEATURE_WLAN_ESE */
78
79/* group cipher */
80uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
81
82/* WEP-40 or RSN */
83uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
84
85/* TKIP or RSN-PSK */
86uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
87
88/* Reserved */
89uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
90
91/* AES-CCMP */
92uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
93
94/* WEP-104 */
95uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
96
97#ifdef WLAN_FEATURE_11W
98/* RSN-PSK-SHA256 */
99uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
100
101/* RSN-8021X-SHA256 */
102uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
103#endif
104
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105/* Offset where the EID-Len-IE, start. */
106#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
107#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800108
109#define BEACON_FRAME_IES_OFFSET 12
110#define HDD_PEER_AUTHORIZE_WAIT 10
111
112/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700113 * beacon_filter_table - table of IEs used for beacon filtering
114 */
115static const int beacon_filter_table[] = {
116 SIR_MAC_DS_PARAM_SET_EID,
117 SIR_MAC_ERP_INFO_EID,
118 SIR_MAC_EDCA_PARAM_SET_EID,
119 SIR_MAC_QOS_CAPABILITY_EID,
120 SIR_MAC_HT_INFO_EID,
121 SIR_MAC_VHT_OPMODE_EID,
122 SIR_MAC_VHT_OPERATION_EID,
123};
124
125/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126 * hdd_conn_set_authenticated() - set authentication state
127 * @pAdapter: pointer to the adapter
128 * @authState: authentication state
129 *
130 * This function updates the global HDD station context
131 * authentication state.
132 *
133 * Return: none
134 */
135static void
136hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
137{
138 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
139 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
140
141 /* save the new connection state */
142 hddLog(LOG1,
143 FL("Authenticated state Changed from oldState:%d to State:%d"),
144 pHddStaCtx->conn_info.uIsAuthenticated, authState);
145 pHddStaCtx->conn_info.uIsAuthenticated = authState;
146
147 /* Check is pending ROC request or not when auth state changed */
148 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
149}
150
151/**
152 * hdd_conn_set_connection_state() - set connection state
153 * @pAdapter: pointer to the adapter
154 * @connState: connection state
155 *
156 * This function updates the global HDD station context connection state.
157 *
158 * Return: none
159 */
160void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
161 eConnectionState connState)
162{
163 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
165
166 /* save the new connection state */
167 hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"),
168 pHddStaCtx->conn_info.connState, connState);
169 pHddStaCtx->conn_info.connState = connState;
170
171 /* Check is pending ROC request or not when connection state changed */
172 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
173}
174
175/**
176 * hdd_conn_get_connection_state() - get connection state
177 * @pAdapter: pointer to the adapter
178 * @pConnState: pointer to connection state
179 *
180 * This function updates the global HDD station context connection state.
181 *
182 * Return: true if (Infra Associated or IBSS Connected)
183 * and sets output parameter pConnState;
184 * false otherwise
185 */
186static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
187 eConnectionState *pConnState)
188{
189 bool fConnected = false;
190 eConnectionState connState;
191
192 /* get the connection state. */
193 connState = pHddStaCtx->conn_info.connState;
194
195 if (eConnectionState_Associated == connState ||
196 eConnectionState_IbssConnected == connState ||
197 eConnectionState_IbssDisconnected == connState) {
198 fConnected = true;
199 }
200
201 if (pConnState)
202 *pConnState = connState;
203
204 return fConnected;
205}
206
207/**
208 * hdd_is_connecting() - Function to check connection progress
209 * @hdd_sta_ctx: pointer to global HDD Station context
210 *
211 * Return: true if connecting, false otherwise
212 */
213bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
214{
215 return hdd_sta_ctx->conn_info.connState ==
216 eConnectionState_Connecting;
217}
218
219/**
220 * hdd_conn_is_connected() - Function to check connection status
221 * @pHddStaCtx: pointer to global HDD Station context
222 *
223 * Return: false if any errors encountered, true otherwise
224 */
225bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
226{
227 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
228}
229
230/**
231 * hdd_conn_get_connected_band() - get current connection radio band
232 * @pHddStaCtx: pointer to global HDD Station context
233 *
234 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
235 * eCSR_BAND_ALL if not connected
236 */
237eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
238{
239 uint8_t staChannel = 0;
240
241 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
242 staChannel = pHddStaCtx->conn_info.operationChannel;
243
244 if (staChannel > 0 && staChannel < 14)
245 return eCSR_BAND_24;
246 else if (staChannel >= 36 && staChannel <= 184)
247 return eCSR_BAND_5G;
248 else /* If station is not connected return as eCSR_BAND_ALL */
249 return eCSR_BAND_ALL;
250}
251
252/**
253 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
254 * @pHddStaCtx: pointer to global HDD Station context
255 * @pConnectedCipherAlgo: pointer to connected cipher algo
256 *
257 * Return: false if any errors encountered, true otherwise
258 */
259static inline bool
260hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
261 eCsrEncryptionType *pConnectedCipherAlgo)
262{
263 bool fConnected = false;
264
265 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
266
267 if (pConnectedCipherAlgo)
268 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
269
270 return fConnected;
271}
272
273/**
274 * hdd_conn_get_connected_bss_type() - get current bss type
275 * @pHddStaCtx: pointer to global HDD Station context
276 * @pConnectedBssType: pointer to connected bss type
277 *
278 * Return: false if any errors encountered, true otherwise
279 */
280inline bool
281hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
282 eMib_dot11DesiredBssType *pConnectedBssType)
283{
284 bool fConnected = false;
285
286 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
287
288 if (pConnectedBssType) {
289 *pConnectedBssType =
290 pHddStaCtx->conn_info.connDot11DesiredBssType;
291 }
292
293 return fConnected;
294}
295
296/**
297 * hdd_conn_save_connected_bss_type() - set connected bss type
298 * @pHddStaCtx: pointer to global HDD Station context
299 * @csr_roamBssType: bss type
300 *
301 * Return: none
302 */
303static inline void
304hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
305 eCsrRoamBssType csr_roamBssType)
306{
307 switch (csr_roamBssType) {
308 case eCSR_BSS_TYPE_INFRASTRUCTURE:
309 pHddStaCtx->conn_info.connDot11DesiredBssType =
310 eMib_dot11DesiredBssType_infrastructure;
311 break;
312
313 case eCSR_BSS_TYPE_IBSS:
314 case eCSR_BSS_TYPE_START_IBSS:
315 pHddStaCtx->conn_info.connDot11DesiredBssType =
316 eMib_dot11DesiredBssType_independent;
317 break;
318
319 /** We will never set the BssType to 'any' when attempting a connection
320 so CSR should never send this back to us.*/
321 case eCSR_BSS_TYPE_ANY:
322 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530323 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324 break;
325 }
326}
327
328/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700329 * hdd_remove_beacon_filter() - remove beacon filter
330 * @adapter: Pointer to the hdd adapter
331 *
332 * Return: 0 on success and errno on failure
333 */
334static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
335{
336 QDF_STATUS status;
337 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
338
339 status = sme_remove_beacon_filter(hdd_ctx->hHal,
340 adapter->sessionId);
341 if (!QDF_IS_STATUS_SUCCESS(status)) {
342 hdd_err("sme_remove_beacon_filter() failed");
343 return -EFAULT;
344 }
345
346 return 0;
347}
348
349/**
350 * hdd_add_beacon_filter() - add beacon filter
351 * @adapter: Pointer to the hdd adapter
352 *
353 * Return: 0 on success and errno on failure
354 */
355static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
356{
357 int i;
358 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
359 QDF_STATUS status;
360 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
361
362 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
363 qdf_set_bit((beacon_filter_table[i] - 1),
364 (unsigned long int *)ie_map);
365
366 status = sme_add_beacon_filter(hdd_ctx->hHal,
367 adapter->sessionId, ie_map);
368 if (!QDF_IS_STATUS_SUCCESS(status)) {
369 hdd_err("sme_add_beacon_filter() failed");
370 return -EFAULT;
371 }
372 return 0;
373}
374
375/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800376 * hdd_conn_save_connect_info() - save current connection information
377 * @pAdapter: pointer to adapter
378 * @pRoamInfo: pointer to roam info
379 * @eBssType: bss type
380 *
381 * Return: none
382 */
383static void
384hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
385 eCsrRoamBssType eBssType)
386{
387 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
388 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
389
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530390 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391
392 if (pRoamInfo) {
393 /* Save the BSSID for the connection */
394 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530395 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530396 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800397 &pRoamInfo->bssid);
398
399 /*
400 * Save the Station ID for this station from
401 * the 'Roam Info'. For IBSS mode, staId is
402 * assigned in NEW_PEER_IND. For reassoc,
403 * the staID doesn't change and it may be invalid
404 * in this structure so no change here.
405 */
406 if (!pRoamInfo->fReassocReq) {
407 pHddStaCtx->conn_info.staId[0] =
408 pRoamInfo->staId;
409 }
410 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530411 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412 &pRoamInfo->bssid);
413 } else {
414 /*
415 * can't happen. We need a valid IBSS or Infra setting
416 * in the BSSDescription or we can't function.
417 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530418 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800419 }
420
421 /* notify WMM */
422 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
423
424 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530425 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 } else {
427 /* Get Multicast Encryption Type */
428 encryptType =
429 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
430 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
431 /* Get Unicast Encryption Type */
432 encryptType =
433 pRoamInfo->u.pConnectedProfile->EncryptionType;
434 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
435
436 pHddStaCtx->conn_info.authType =
437 pRoamInfo->u.pConnectedProfile->AuthType;
438
439 pHddStaCtx->conn_info.operationChannel =
440 pRoamInfo->u.pConnectedProfile->operationChannel;
441
442 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530443 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 &pRoamInfo->u.pConnectedProfile->SSID,
445 sizeof(tSirMacSSid));
446
447 /* Save dot11mode in which STA associated to AP */
448 pHddStaCtx->conn_info.dot11Mode =
449 pRoamInfo->u.pConnectedProfile->dot11Mode;
450
451 pHddStaCtx->conn_info.proxyARPService =
452 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530453
454 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
455
456 pHddStaCtx->conn_info.rate_flags =
457 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 }
459 }
460 /* save the connected BssType */
461 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
462}
463
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464/**
465 * hdd_send_ft_assoc_response() - send fast transition assoc response
466 * @dev: pointer to net device
467 * @pAdapter: pointer to adapter
468 * @pCsrRoamInfo: pointer to roam info
469 *
470 * Send the 11R key information to the supplicant. Only then can the supplicant
471 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
472 * for the same purpose.)
473 *
474 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
475 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
476 * This is the Assoc Response.
477 *
478 * Return: none
479 */
480static void
481hdd_send_ft_assoc_response(struct net_device *dev,
482 hdd_adapter_t *pAdapter,
483 tCsrRoamInfo *pCsrRoamInfo)
484{
485 union iwreq_data wrqu;
486 char *buff;
487 unsigned int len = 0;
488 u8 *pFTAssocRsp = NULL;
489
490 if (pCsrRoamInfo->nAssocRspLength == 0) {
491 hddLog(LOGE,
492 FL("pCsrRoamInfo->nAssocRspLength=%d"),
493 (int)pCsrRoamInfo->nAssocRspLength);
494 return;
495 }
496
497 pFTAssocRsp =
498 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
499 pCsrRoamInfo->nAssocReqLength);
500 if (pFTAssocRsp == NULL) {
501 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
502 return;
503 }
504 /* pFTAssocRsp needs to point to the IEs */
505 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
506 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
507 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
508
509 /* We need to send the IEs to the supplicant. */
510 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
511 if (buff == NULL) {
512 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
513 return;
514 }
515 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
516 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
517 wrqu.data.length = len;
518 memset(buff, 0, IW_GENERIC_IE_MAX);
519 memcpy(buff, pFTAssocRsp, len);
520 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
521
522 kfree(buff);
523}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800525/**
526 * hdd_send_ft_event() - send fast transition event
527 * @pAdapter: pointer to adapter
528 *
529 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
530 * FT events to the supplicant. At the reception of Auth2 we send the RIC
531 * followed by the auth response IEs to the supplicant.
532 * Once both are received in the supplicant, an FT event is generated
533 * to the supplicant.
534 *
535 * Return: none
536 */
537static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
538{
539 uint16_t auth_resp_len = 0;
540 uint32_t ric_ies_length = 0;
541 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
542
543#if defined(KERNEL_SUPPORT_11R_CFG80211)
544 struct cfg80211_ft_event_params ftEvent;
545 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
546 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
547 struct net_device *dev = pAdapter->dev;
548#else
549 char *buff;
550 union iwreq_data wrqu;
551 uint16_t str_len;
552#endif
553
554#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530555 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
556 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557
558 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
559 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
560 if (ric_ies_length == 0) {
561 hddLog(LOGW,
562 FL("RIC IEs is of length 0 not sending RIC Information for now"));
563 }
564
565 ftEvent.ric_ies = ricIe;
566 ftEvent.ric_ies_len = ric_ies_length;
567 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
568
569 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
570 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
571 &auth_resp_len);
572
573 if (auth_resp_len == 0) {
574 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
575 return;
576 }
577
578 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
579
580 ftEvent.target_ap = ftIe;
581
Anurag Chouhan6d760662016-02-20 16:05:43 +0530582 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
583 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584
585 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
586 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
587 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
588 ftEvent.target_ap[0], ftEvent.target_ap[1],
589 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
590 ftEvent.target_ap[5]);
591
592 (void)cfg80211_ft_event(dev, &ftEvent);
593
594#else
595 /* We need to send the IEs to the supplicant */
596 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
597 if (buff == NULL) {
598 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
599 return;
600 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530601 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602
603 /* Sme needs to send the RIC IEs first */
604 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
605 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
606 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
607 &ric_ies_length);
608 if (ric_ies_length == 0) {
609 hddLog(LOGW,
610 FL("RIC IEs is of length 0 not sending RIC Information for now"));
611 } else {
612 wrqu.data.length = str_len + ric_ies_length;
613 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
614 }
615
616 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530617 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
619 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
620 (u8 *) &buff[str_len],
621 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
622
623 if (auth_resp_len == 0) {
624 kfree(buff);
625 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
626 return;
627 }
628
629 wrqu.data.length = str_len + auth_resp_len;
630 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
631
632 kfree(buff);
633#endif
634}
635
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636#ifdef FEATURE_WLAN_ESE
637/**
638 * hdd_send_new_ap_channel_info() - send new ap channel info
639 * @dev: pointer to net device
640 * @pAdapter: pointer to adapter
641 * @pCsrRoamInfo: pointer to roam info
642 *
643 * Send the ESE required "new AP Channel info" to the supplicant.
644 * (This keeps the supplicant "up to date" on the current channel.)
645 *
646 * The current (new AP) channel information is passed in.
647 *
648 * Return: none
649 */
650static void
651hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
652 tCsrRoamInfo *pCsrRoamInfo)
653{
654 union iwreq_data wrqu;
655 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
656
657 if (descriptor == NULL) {
658 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
659 return;
660 }
661 /*
662 * Send the Channel event, the supplicant needs this to generate
663 * the Adjacent AP report.
664 */
665 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
666 descriptor->channelId);
667 memset(&wrqu, '\0', sizeof(wrqu));
668 wrqu.freq.m = descriptor->channelId;
669 wrqu.freq.e = 0;
670 wrqu.freq.i = 0;
671 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
672}
673
674#endif /* FEATURE_WLAN_ESE */
675
676/**
677 * hdd_send_update_beacon_ies_event() - send update beacons ie event
678 * @pAdapter: pointer to adapter
679 * @pCsrRoamInfo: pointer to roam info
680 *
681 * Return: none
682 */
683static void
684hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
685 tCsrRoamInfo *pCsrRoamInfo)
686{
687 union iwreq_data wrqu;
688 u8 *pBeaconIes;
689 u8 currentLen = 0;
690 char *buff;
691 int totalIeLen = 0, currentOffset = 0, strLen;
692
693 memset(&wrqu, '\0', sizeof(wrqu));
694
695 if (0 == pCsrRoamInfo->nBeaconLength) {
696 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
697 return;
698 }
699 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
700 if (pBeaconIes == NULL) {
701 hddLog(LOGW, FL("Beacon IEs is NULL"));
702 return;
703 }
704 /* pBeaconIes needs to point to the IEs */
705 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
706 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
707 hddLog(LOG1, FL("Beacon IEs length = %d"),
708 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
709
710 /* We need to send the IEs to the supplicant. */
711 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
712 if (buff == NULL) {
713 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
714 return;
715 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530716 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717
718 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
719 currentLen = strLen + 1;
720
721 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
722 do {
723 /*
724 * If the beacon size exceeds max CUSTOM event size, break it
725 * into chunks of CUSTOM event max size and send it to
726 * supplicant. Changes are done in supplicant to handle this.
727 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530728 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530730 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530731 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 currentLen);
733 currentOffset += currentLen;
734 totalIeLen -= currentLen;
735 wrqu.data.length = strLen + 1 + currentLen;
736 if (totalIeLen)
737 buff[strLen] = 1; /* more chunks pending */
738 else
739 buff[strLen] = 0; /* last chunk */
740
741 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
742 currentLen);
743 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
744 } while (totalIeLen > 0);
745
746 kfree(buff);
747}
748
749/**
750 * hdd_send_association_event() - send association event
751 * @dev: pointer to net device
752 * @pCsrRoamInfo: pointer to roam info
753 *
754 * Return: none
755 */
756static void hdd_send_association_event(struct net_device *dev,
757 tCsrRoamInfo *pCsrRoamInfo)
758{
759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
761 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
762 union iwreq_data wrqu;
763 int we_event;
764 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530765 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 /* Added to find the auth type on the fly at run time */
768 /* rather than with cfg to see if FT is enabled */
769 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
770 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771
772 memset(&wrqu, '\0', sizeof(wrqu));
773 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
774 we_event = SIOCGIWAP;
775#ifdef WLAN_FEATURE_ROAM_OFFLOAD
776 if (NULL != pCsrRoamInfo)
777 if (pCsrRoamInfo->roamSynchInProgress)
778 /* change logging before release */
779 hddLog(LOG4, "LFR3:hdd_send_association_event");
780#endif
781 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
782 if (!pCsrRoamInfo) {
783 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
784 return;
785 }
786
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800787 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
788 cds_incr_active_session(pAdapter->device_mode,
789 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
791 sizeof(pCsrRoamInfo->pBssDesc->bssId));
792
793#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800794 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 if (global_p2p_connection_status ==
796 P2P_CLIENT_CONNECTING_STATE_1) {
797 global_p2p_connection_status =
798 P2P_CLIENT_CONNECTED_STATE_1;
799 hddLog(LOGE,
800 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
801 } else if (global_p2p_connection_status ==
802 P2P_CLIENT_CONNECTING_STATE_2) {
803 global_p2p_connection_status =
804 P2P_CLIENT_COMPLETED_STATE;
805 hddLog(LOGE,
806 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
807 }
808 }
809#endif
810 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
811 MAC_ADDRESS_STR "\n",
812 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
813 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
814 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
815
816 /*
817 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
818 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800819 * fFTEnable is true.
820 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 if ((pRoamProfile->AuthType.authType[0] ==
823 eCSR_AUTH_TYPE_FT_RSN_PSK)
824 || (pRoamProfile->AuthType.authType[0] ==
825 eCSR_AUTH_TYPE_FT_RSN)
826#ifdef FEATURE_WLAN_ESE
827 || (pRoamProfile->AuthType.authType[0] ==
828 eCSR_AUTH_TYPE_CCKM_RSN)
829 || (pRoamProfile->AuthType.authType[0] ==
830 eCSR_AUTH_TYPE_CCKM_WPA)
831#endif
832 ) {
833 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
834 }
Krunal Sonibe766b02016-03-10 13:00:44 -0800835 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 tSirSmeChanInfo chan_info;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530837 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 &pHddStaCtx->conn_info.bssId);
839 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
840 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
841 chan_info.info = pCsrRoamInfo->chan_info.info;
842 chan_info.band_center_freq1 =
843 pCsrRoamInfo->chan_info.band_center_freq1;
844 chan_info.band_center_freq2 =
845 pCsrRoamInfo->chan_info.band_center_freq2;
846 chan_info.reg_info_1 =
847 pCsrRoamInfo->chan_info.reg_info_1;
848 chan_info.reg_info_2 =
849 pCsrRoamInfo->chan_info.reg_info_2;
850
851 /* send peer status indication to oem app */
852 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
853 ePeerConnected,
854 pCsrRoamInfo->
855 timingMeasCap,
856 pAdapter->sessionId,
857 &chan_info);
858 }
859#ifdef MSM_PLATFORM
860#ifdef CONFIG_CNSS
861 /* start timer in sta/p2p_cli */
862 spin_lock_bh(&pHddCtx->bus_bw_lock);
863 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
864 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
865 spin_unlock_bh(&pHddCtx->bus_bw_lock);
866 hdd_start_bus_bw_compute_timer(pAdapter);
867#endif
868#endif
869 } else if (eConnectionState_IbssConnected == /* IBss Associated */
870 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800871 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
873 ETH_ALEN);
874 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
875 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
876 } else { /* Not Associated */
877
878 pr_info("wlan: disconnected\n");
879 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530880 cds_decr_session_set_pcl(pAdapter->device_mode,
881 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883
884#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
885 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
886#endif
887
Krunal Sonibe766b02016-03-10 13:00:44 -0800888 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530889 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890 &pHddStaCtx->conn_info.bssId);
891
892 /* send peer status indication to oem app */
893 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
894 ePeerDisconnected, 0,
895 pAdapter->sessionId,
896 NULL);
897 }
898#ifdef WLAN_FEATURE_LPSS
899 pAdapter->rssi_send = false;
900 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
901#endif
902#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800903 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 (pCsrRoamInfo)) {
905 hddLog(LOG4,
906 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
907 pCsrRoamInfo->tdls_prohibited,
908 pCsrRoamInfo->tdls_chan_swit_prohibited);
909
910 wlan_hdd_update_tdls_info(pAdapter,
911 pCsrRoamInfo->tdls_prohibited,
912 pCsrRoamInfo->tdls_chan_swit_prohibited);
913 }
914#endif
915#ifdef MSM_PLATFORM
916 /* stop timer in sta/p2p_cli */
917 spin_lock_bh(&pHddCtx->bus_bw_lock);
918 pAdapter->prev_tx_packets = 0;
919 pAdapter->prev_rx_packets = 0;
920 spin_unlock_bh(&pHddCtx->bus_bw_lock);
921 hdd_stop_bus_bw_compute_timer(pAdapter);
922#endif
923 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800924 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 /* Send SCC/MCC Switching event to IPA */
926 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
927
928 msg = NULL;
929 /*During the WLAN uninitialization,supplicant is stopped before the
930 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800931 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 wireless_send_event(dev, we_event, &wrqu, msg);
933#ifdef FEATURE_WLAN_ESE
934 if (eConnectionState_Associated ==
935 pHddStaCtx->conn_info.connState) {
936 if ((pRoamProfile->AuthType.authType[0] ==
937 eCSR_AUTH_TYPE_CCKM_RSN) ||
938 (pRoamProfile->AuthType.authType[0] ==
939 eCSR_AUTH_TYPE_CCKM_WPA))
940 hdd_send_new_ap_channel_info(dev, pAdapter,
941 pCsrRoamInfo);
942 }
943#endif
944 }
945}
946
947/**
948 * hdd_conn_remove_connect_info() - remove connection info
949 * @pHddStaCtx: pointer to global HDD station context
950 * @pCsrRoamInfo: pointer to roam info
951 *
952 * Return: none
953 */
954static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
955{
956 /* Remove staId, bssId and peerMacAddress */
957 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530958 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
959 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530960 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961
962 /* Clear all security settings */
963 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
964 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
965 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
966
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530967 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
968 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969
970 /* Set not-connected state */
971 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
972 pHddStaCtx->conn_info.proxyARPService = 0;
973
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530974 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800975}
976
977/**
978 * hdd_roam_deregister_sta() - deregister station
979 * @pAdapter: pointer to adapter
980 * @staId: station identifier
981 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530982 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800983 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530984static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
986{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530987 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
989
990 if (eConnectionState_IbssDisconnected ==
991 pHddStaCtx->conn_info.connState) {
992 /*
993 * Do not set the carrier off when the last peer leaves.
994 * We will set the carrier off while stopping the IBSS.
995 */
996 }
997
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530998 qdf_status = ol_txrx_clear_peer(staId);
999 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000 hddLog(LOGE,
1001 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301002 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301004 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001005}
1006
1007/**
1008 * hdd_dis_connect_handler() - disconnect event handler
1009 * @pAdapter: pointer to adapter
1010 * @pRoamInfo: pointer to roam info
1011 * @roamId: roam identifier
1012 * @roamStatus: roam status
1013 * @roamResult: roam result
1014 *
1015 * This function handles disconnect event:
1016 * 1. Disable transmit queues;
1017 * 2. Clean up internal connection states and data structures;
1018 * 3. Send disconnect indication to supplicant.
1019 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301020 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301022static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023 tCsrRoamInfo *pRoamInfo,
1024 uint32_t roamId,
1025 eRoamCmdStatus roamStatus,
1026 eCsrRoamResult roamResult)
1027{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301028 QDF_STATUS status = QDF_STATUS_SUCCESS;
1029 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 struct net_device *dev = pAdapter->dev;
1031 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1032 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1033 uint8_t sta_id;
1034 bool sendDisconInd = true;
1035
1036 if (dev == NULL) {
1037 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301038 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039 }
1040 /* notify apps that we can't pass traffic anymore */
1041 hddLog(LOG1, FL("Disabling queues"));
1042 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1043 WLAN_CONTROL_PATH);
1044
1045 if (hdd_ipa_is_enabled(pHddCtx))
1046 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1047 WLAN_STA_DISCONNECT,
1048 pHddStaCtx->conn_info.bssId.bytes);
1049
1050#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1051 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1052#endif
1053
1054#ifdef QCA_PKT_PROTO_TRACE
1055 /* STA disconnected, update into trace buffer */
1056 if (pHddCtx->config->gEnableDebugLog)
1057 cds_pkt_trace_buf_update("ST:DISASC");
1058#endif /* QCA_PKT_PROTO_TRACE */
1059
1060 /* HDD has initiated disconnect, do not send disconnect indication
1061 * to kernel. Sending disconnected event to kernel for userspace
1062 * initiated disconnect will be handled by hdd_DisConnectHandler call
1063 * to cfg80211_disconnected.
1064 */
1065 if ((eConnectionState_Disconnecting ==
1066 pHddStaCtx->conn_info.connState) ||
1067 (eConnectionState_NotConnected ==
1068 pHddStaCtx->conn_info.connState)) {
1069 hddLog(LOG1,
1070 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1071 sendDisconInd = false;
1072 }
1073
1074 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1075 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1076 hddLog(LOG1,
1077 FL("Set HDD connState to eConnectionState_Disconnecting"));
1078 hdd_conn_set_connection_state(pAdapter,
1079 eConnectionState_Disconnecting);
1080 }
1081
1082 hdd_clear_roam_profile_ie(pAdapter);
1083 hdd_wmm_init(pAdapter);
1084
1085 /* indicate 'disconnect' status to wpa_supplicant... */
1086 hdd_send_association_event(dev, pRoamInfo);
1087 /* indicate disconnected event to nl80211 */
1088 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1089 /*
1090 * Only send indication to kernel if not initiated
1091 * by kernel
1092 */
1093 if (sendDisconInd) {
1094 /*
1095 * To avoid wpa_supplicant sending "HANGED" CMD
1096 * to ICS UI.
1097 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001098 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1099 if (pRoamInfo->reasonCode ==
1100 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1101 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001102 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001103 reasonCode, NULL, 0,
1104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1105 true,
1106#endif
1107 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001108 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001110 WLAN_REASON_UNSPECIFIED, NULL, 0,
1111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1112 true,
1113#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001115 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116
1117 hdd_info("sent disconnected event to nl80211, rssi: %d",
1118 pAdapter->rssi);
1119 }
1120 /*
1121 * During the WLAN uninitialization,supplicant is stopped
1122 * before the driver so not sending the status of the
1123 * connection to supplicant.
1124 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001125 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001127 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128 if (global_p2p_connection_status ==
1129 P2P_CLIENT_CONNECTED_STATE_1) {
1130 global_p2p_connection_status =
1131 P2P_CLIENT_DISCONNECTED_STATE;
1132 hddLog(LOGE,
1133 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1134 } else if (global_p2p_connection_status ==
1135 P2P_CLIENT_COMPLETED_STATE) {
1136 global_p2p_connection_status =
1137 P2P_NOT_ACTIVE;
1138 hddLog(LOGE,
1139 "[P2P State] P2P Client is removed and moved to inactive state");
1140 }
1141 }
1142#endif
1143
1144 }
1145 }
1146
1147 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001148 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001149 if (hdd_remove_beacon_filter(pAdapter) != 0)
1150 hdd_err("hdd_remove_beacon_filter() failed");
1151
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301153 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301154 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301156 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301157 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1158 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301159 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160 }
1161 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301162 /* Clear all the peer sta register with TL. */
1163 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1164 if (0 == pHddStaCtx->conn_info.staId[i])
1165 continue;
1166 sta_id = pHddStaCtx->conn_info.staId[i];
1167 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1168 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301169 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301170 hddLog(LOGE,
1171 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1172 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301173 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301174 }
1175 /* set the staid and peer mac as 0, all other
1176 * reset are done in hdd_connRemoveConnectInfo.
1177 */
1178 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301179 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301180 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301181 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1182 pHddCtx->sta_to_adapter[sta_id] = NULL;
1183 }
1184 } else {
1185 sta_id = pHddStaCtx->conn_info.staId[0];
1186 /* We should clear all sta register with TL,
1187 * for now, only one.
1188 */
1189 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301190 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301191 hddLog(LOGE,
1192 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1193 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301194 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301195 }
1196 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 /* Clear saved connection information in HDD */
1199 hdd_conn_remove_connect_info(pHddStaCtx);
1200 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1201 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1202#ifdef WLAN_FEATURE_GTK_OFFLOAD
Krunal Sonibe766b02016-03-10 13:00:44 -08001203 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1204 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1206 sizeof(tSirGtkOffloadParams));
1207 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1208 }
1209#endif
1210
1211#ifdef FEATURE_WLAN_TDLS
1212 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1213 wlan_hdd_tdls_disconnection_callback(pAdapter);
1214#endif
1215
Krunal Sonibe766b02016-03-10 13:00:44 -08001216 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1217 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001218 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1219 (pAdapter),
1220 pAdapter->sessionId);
1221 }
1222 /* Unblock anyone waiting for disconnect to complete */
1223 complete(&pAdapter->disconnect_comp_var);
1224 return status;
1225}
1226
1227/**
1228 * hdd_set_peer_authorized_event() - set peer_authorized_event
1229 * @vdev_id: vdevid
1230 *
1231 * Return: None
1232 */
1233void hdd_set_peer_authorized_event(uint32_t vdev_id)
1234{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301235 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 hdd_adapter_t *adapter = NULL;
1237
1238 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1239 if (adapter == NULL) {
1240 hddLog(LOGE,
1241 "%s: Invalid vdev_id", __func__);
1242 }
1243 complete(&adapter->sta_authorized_event);
1244}
1245
1246/**
1247 * hdd_change_peer_state() - change peer state
1248 * @pAdapter: HDD adapter
1249 * @sta_state: peer state
1250 * @roam_synch_in_progress: roam synch in progress
1251 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301252 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301254QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 uint8_t sta_id,
1256 enum ol_txrx_peer_state sta_state,
1257 bool roam_synch_in_progress)
1258{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301259 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001260 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001261 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001262 ol_txrx_vdev_handle vdev;
1263 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264
1265 if (!pdev) {
1266 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301267 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 }
1269
1270 if (sta_id >= WLAN_MAX_STA_COUNT) {
1271 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301272 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 }
1274
1275 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1276 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301277 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001279 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1280 if (peer_mac_addr == NULL) {
1281 hddLog(LOGE, "peer mac addr is NULL");
1282 return QDF_STATUS_E_FAULT;
1283 }
1284
1285 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301286 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301288 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289 }
1290#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1291 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301292 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001293#endif
1294
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001295 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1297 /* make sure event is reset */
1298 INIT_COMPLETION(pAdapter->sta_authorized_event);
1299#endif
1300
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001301 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 hdd_set_peer_authorized_event,
1303 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301304 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301306 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307 }
1308
Krunal Sonibe766b02016-03-10 13:00:44 -08001309 if (pAdapter->device_mode == QDF_STA_MODE ||
1310 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1312 unsigned long rc;
1313
1314 /* wait for event from firmware to set the event */
1315 rc = wait_for_completion_timeout(
1316 &pAdapter->sta_authorized_event,
1317 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1318 if (!rc) {
1319 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1320 __func__);
1321 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001322 vdev = ol_txrx_get_vdev_for_peer(peer);
1323 ol_txrx_vdev_unpause(vdev,
1324 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325#endif
1326 }
1327 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301328 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329}
1330
1331/**
1332 * hdd_roam_register_sta() - register station
1333 * @pAdapter: pointer to adapter
1334 * @pRoamInfo: pointer to roam info
1335 * @staId: station identifier
1336 * @pPeerMacAddress: peer MAC address
1337 * @pBssDesc: pointer to BSS description
1338 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301339 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301341static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 tCsrRoamInfo *pRoamInfo,
1343 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301344 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345 tSirBssDescription *pBssDesc)
1346{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301347 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 struct ol_txrx_desc_type staDesc = { 0 };
1349 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001350 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351
1352 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301353 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354
1355 /* Get the Station ID from the one saved during the association */
1356 staDesc.sta_id = staId;
1357
1358 /* set the QoS field appropriately */
1359 if (hdd_wmm_is_active(pAdapter))
1360 staDesc.is_qos_enabled = 1;
1361 else
1362 staDesc.is_qos_enabled = 0;
1363
1364#ifdef FEATURE_WLAN_WAPI
1365 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1366 pAdapter->wapi_info.fIsWapiSta);
1367 if (pAdapter->wapi_info.fIsWapiSta)
1368 staDesc.is_wapi_supported = 1;
1369 else
1370 staDesc.is_wapi_supported = 0;
1371#endif /* FEATURE_WLAN_WAPI */
1372
Dhanashri Atre50141c52016-04-07 13:15:29 -07001373 /* Register the vdev transmit and receive functions */
1374 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1375 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1376 ol_txrx_vdev_register(
1377 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1378 pAdapter, &txrx_ops);
1379 pAdapter->tx_fn = txrx_ops.tx.tx;
1380
Dhanashri Atre182b0272016-02-17 15:35:07 -08001381 qdf_status = ol_txrx_register_peer(&staDesc);
1382
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301383 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 hddLog(LOGW,
1385 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301386 qdf_status, qdf_status);
1387 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 }
1389
1390 if (!pRoamInfo->fAuthRequired) {
1391 /*
1392 * Connections that do not need Upper layer auth, transition
1393 * TLSHIM directly to 'Authenticated' state
1394 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301395 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001397 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1399 pRoamInfo->roamSynchInProgress
1400#else
1401 false
1402#endif
1403 );
1404
1405 hdd_conn_set_authenticated(pAdapter, true);
1406 } else {
1407 hddLog(LOG3,
1408 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1409 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301410 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001412 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1414 pRoamInfo->roamSynchInProgress
1415#else
1416 false
1417#endif
1418 );
1419 hdd_conn_set_authenticated(pAdapter, false);
1420 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301421 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422}
1423
1424/**
1425 * hdd_send_re_assoc_event() - send reassoc event
1426 * @dev: pointer to net device
1427 * @pAdapter: pointer to adapter
1428 * @pCsrRoamInfo: pointer to roam info
1429 * @reqRsnIe: pointer to RSN Information element
1430 * @reqRsnLength: length of RSN IE
1431 *
1432 * Return: none
1433 */
1434static void hdd_send_re_assoc_event(struct net_device *dev,
1435 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1436 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1437{
1438 unsigned int len = 0;
1439 u8 *pFTAssocRsp = NULL;
1440 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001441 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001442 uint32_t rspRsnLength = 0;
1443 struct ieee80211_channel *chan;
1444 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1445 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1446 uint8_t *buf_ptr, ssid_ie_len;
1447 struct cfg80211_bss *bss = NULL;
1448 uint8_t *final_req_ie = NULL;
1449 tCsrRoamConnectedProfile roam_profile;
1450 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1451
1452 if (!rspRsnIe) {
1453 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001454 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001455 }
1456
Naveen Rawat14298b92015-11-25 16:27:41 -08001457 if (!assoc_req_ies) {
1458 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001459 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001460 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 if (pCsrRoamInfo == NULL) {
1462 hddLog(LOGE, FL("Invalid CSR roam info"));
1463 goto done;
1464 }
1465
1466 if (pCsrRoamInfo->nAssocRspLength == 0) {
1467 hddLog(LOGE, FL("Invalid assoc response length"));
1468 goto done;
1469 }
1470
1471 pFTAssocRsp =
1472 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1473 pCsrRoamInfo->nAssocReqLength);
1474 if (pFTAssocRsp == NULL)
1475 goto done;
1476
1477 /* pFTAssocRsp needs to point to the IEs */
1478 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1479 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1480 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1481
1482 /*
1483 * Active session count is decremented upon disconnection, but during
1484 * roaming, there is no disconnect indication and hence active session
1485 * count is not decremented.
1486 * After roaming is completed, active session count is incremented
1487 * as a part of connect indication but effectively after roaming the
1488 * active session count should still be the same and hence upon
1489 * successful reassoc decrement the active session count here.
1490 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001491 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301492 cds_decr_session_set_pcl(pAdapter->device_mode,
1493 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494
1495 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1496 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1497 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301498 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1499 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500
1501 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1502 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301503 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1505 &roam_profile);
1506 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1507 pCsrRoamInfo->bssid.bytes,
1508 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001509#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001511#else
1512 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1513#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514
1515 if (bss == NULL)
1516 hddLog(LOGE, FL("Get BSS returned NULL"));
1517 buf_ptr = buf_ssid_ie;
1518 *buf_ptr = SIR_MAC_SSID_EID;
1519 buf_ptr++;
1520 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1521 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301522 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 roam_profile.SSID.length);
1524 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001525 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301526 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001527 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1529 if (final_req_ie == NULL)
1530 goto done;
1531 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301532 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301534 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1535 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1536 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001538 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301539 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001540 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 cfg80211_roamed_bss(dev, bss,
1542 final_req_ie, (ssid_ie_len + reqRsnLength),
1543 rspRsnIe, rspRsnLength, GFP_KERNEL);
1544
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301545 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001546 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1547 pCsrRoamInfo->nAssocReqLength);
1548
1549 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301550 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001551 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1552
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001553 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001554 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1555 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001556 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001558 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 if (final_req_ie)
1560 kfree(final_req_ie);
1561 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001562 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563}
1564
1565/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301566 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001567 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301568 *
1569 * Return: roam sync status if roaming offloaded else false
1570 */
1571#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001572bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301573{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001574 if (roaminfo)
1575 return roaminfo->roamSynchInProgress;
1576 else
1577 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301578}
1579#endif
1580
1581
1582/**
1583 * hdd_change_sta_state_authenticated()-
1584 * This function changes STA state to authenticated
1585 * @adapter: pointer to the adapter structure.
1586 * @roaminfo: pointer to the RoamInfo structure.
1587 *
1588 * This is called from hdd_RoamSetKeyCompleteHandler
1589 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1590 *
1591 * Return: 0 on success and errno on failure
1592 */
1593static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1594 tCsrRoamInfo *roaminfo)
1595{
1596 int ret;
1597 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1598
1599 hddLog(LOG1,
1600 "Changing TL state to AUTHENTICATED for StaId= %d",
1601 hddstactx->conn_info.staId[0]);
1602
1603 /* Connections that do not need Upper layer authentication,
1604 * transition TL to 'Authenticated' state after the keys are set
1605 */
1606 ret = hdd_change_peer_state(adapter,
1607 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001608 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301609 hdd_is_roam_sync_in_progress(roaminfo));
1610 hdd_conn_set_authenticated(adapter, true);
Krunal Sonibe766b02016-03-10 13:00:44 -08001611 if ((QDF_STA_MODE == adapter->device_mode) ||
1612 (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301613 sme_ps_enable_auto_ps_timer(
1614 WLAN_HDD_GET_HAL_CTX(adapter),
1615 adapter->sessionId,
1616 hddstactx->hdd_ReassocScenario);
1617 }
1618
1619 return ret;
1620}
1621
1622/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 * hdd_roam_set_key_complete_handler() - Update the security parameters
1624 * @pAdapter: pointer to adapter
1625 * @pRoamInfo: pointer to roam info
1626 * @roamId: roam id
1627 * @roamStatus: roam status
1628 * @roamResult: roam result
1629 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301630 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301632static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 tCsrRoamInfo *pRoamInfo,
1634 uint32_t roamId,
1635 eRoamCmdStatus roamStatus,
1636 eCsrRoamResult roamResult)
1637{
1638 eCsrEncryptionType connectedCipherAlgo;
1639 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301640 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301642 tHalHandle hal_ctx = WLAN_HDD_GET_HAL_CTX(pAdapter);
1643 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 ENTER();
1646
1647 if (NULL == pRoamInfo) {
1648 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301649 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 }
1651 /*
1652 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1653 * then go to 'authenticated'. For all other authentication types
1654 * (those that do not require upper layer authentication) we can put TL
1655 * directly into 'authenticated' state.
1656 */
1657 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1658 MAC_ADDRESS_STR, roamStatus, roamResult,
1659 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1660
1661 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1662 &connectedCipherAlgo);
1663 if (fConnected) {
Krunal Sonibe766b02016-03-10 13:00:44 -08001664 if (QDF_IBSS_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 uint8_t staId;
1666
Anurag Chouhanc5548422016-02-24 18:33:27 +05301667 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 pHddStaCtx->roam_info.roamingState =
1669 HDD_ROAM_STATE_NONE;
1670 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301671 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 pHddStaCtx,
1673 &pRoamInfo->peerMac,
1674 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301675 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 hddLog(LOG2,
1677 "WLAN TL STA Ptk Installed for STAID=%d",
1678 staId);
1679 pHddStaCtx->roam_info.roamingState =
1680 HDD_ROAM_STATE_NONE;
1681 }
1682 }
1683 } else {
1684 /*
1685 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301686 * HDD later.This routine is invoked twice.
1687 * 1)set PTK 2)set GTK.The following if
1688 * statement will be TRUE when setting GTK.
1689 * At this time we don't handle the state in detail.
1690 * Related CR: 174048 - TL not in authenticated state
1691 */
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301692 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301693 pHddStaCtx->conn_info.gtk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301694 /*
1695 * PTK exchange happens in preauthentication
1696 * itself if key_mgmt is FT-PSK, ptk_installed
1697 * was false as there is no set PTK after
1698 * roaming. STA TL state moves to authenticated
1699 * only if ptk_installed is true. So, make
1700 * ptk_installed to true in case of 11R roaming.
1701 */
1702 if (csr_neighbor_roam_is11r_assoc(mac_ctx,
1703 pAdapter->sessionId))
1704 pHddStaCtx->conn_info.ptk_installed =
1705 true;
1706 } else {
Govind Singhedc5cda2015-10-23 17:11:35 +05301707 pHddStaCtx->conn_info.ptk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301708 }
Govind Singhedc5cda2015-10-23 17:11:35 +05301709
1710 /* In WPA case move STA to authenticated when
1711 * ptk is installed.Earlier in WEP case STA
1712 * was moved to AUTHENTICATED prior to setting
1713 * the unicast key and it was resulting in sending
1714 * few un-encrypted packet. Now in WEP case
1715 * STA state will be moved to AUTHENTICATED
1716 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301718 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1719 eCSR_ENCRYPT_TYPE_WEP40) ||
1720 (pHddStaCtx->conn_info.ucEncryptionType ==
1721 eCSR_ENCRYPT_TYPE_WEP104) ||
1722 (pHddStaCtx->conn_info.ucEncryptionType ==
1723 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1724 (pHddStaCtx->conn_info.ucEncryptionType ==
1725 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1726 if (pHddStaCtx->conn_info.gtk_installed &&
1727 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301728 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301729 hdd_change_sta_state_authenticated(pAdapter,
1730 pRoamInfo);
1731 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301732 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301733 hdd_change_sta_state_authenticated(pAdapter,
1734 pRoamInfo);
1735 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736
Govind Singhedc5cda2015-10-23 17:11:35 +05301737 if (pHddStaCtx->conn_info.gtk_installed &&
1738 pHddStaCtx->conn_info.ptk_installed) {
1739 pHddStaCtx->conn_info.gtk_installed = false;
1740 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 }
1742
1743 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301744 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 }
1746 } else {
1747 /*
1748 * possible disassoc after issuing set key and waiting
1749 * set key complete.
1750 */
1751 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1752 }
1753
1754 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301755 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001756}
1757
1758/**
1759 * hdd_perform_roam_set_key_complete() - perform set key complete
1760 * @pAdapter: pointer to adapter
1761 *
1762 * Return: none
1763 */
1764void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1765{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301766 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1768 tCsrRoamInfo roamInfo;
1769 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301770 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301771 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301772 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301773 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001774
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301775 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 hdd_roam_set_key_complete_handler(pAdapter,
1777 &roamInfo,
1778 pHddStaCtx->roam_info.roamId,
1779 pHddStaCtx->roam_info.roamStatus,
1780 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301781 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782 hddLog(LOGE, FL("Set Key complete failure"));
1783
1784 pHddStaCtx->roam_info.deferKeyComplete = false;
1785}
1786
1787/**
1788 * hdd_association_completion_handler() - association completion handler
1789 * @pAdapter: pointer to adapter
1790 * @pRoamInfo: pointer to roam info
1791 * @roamId: roam id
1792 * @roamStatus: roam status
1793 * @roamResult: roam result
1794 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301795 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301797static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 tCsrRoamInfo *pRoamInfo,
1799 uint32_t roamId,
1800 eRoamCmdStatus roamStatus,
1801 eCsrRoamResult roamResult)
1802{
1803 struct net_device *dev = pAdapter->dev;
1804 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1805 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301806 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1808 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001809 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 bool hddDisconInProgress = false;
1811 unsigned long rc;
1812
1813 if (!pHddCtx) {
1814 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301815 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001816 }
1817
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 /* HDD has initiated disconnect, do not send connect result indication
1819 * to kernel as it will be handled by __cfg80211_disconnect.
1820 */
1821 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1822 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1823 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1824 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1825 hddDisconInProgress = true;
1826 }
1827
1828 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1829 if (NULL == pRoamInfo) {
1830 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301831 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001832 }
1833 if (!hddDisconInProgress) {
1834 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1835 hdd_conn_set_connection_state(pAdapter,
1836 eConnectionState_Associated);
1837 }
1838 /* Save the connection info from CSR... */
1839 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1840 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001841
1842 if (hdd_add_beacon_filter(pAdapter) != 0)
1843 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001844#ifdef FEATURE_WLAN_WAPI
1845 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1846 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1847 || pRoamInfo->u.pConnectedProfile->AuthType ==
1848 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1849 pAdapter->wapi_info.fIsWapiSta = 1;
1850 } else {
1851 pAdapter->wapi_info.fIsWapiSta = 0;
1852 }
1853#endif /* FEATURE_WLAN_WAPI */
1854
1855 /* Indicate 'connect' status to user space */
1856 hdd_send_association_event(dev, pRoamInfo);
1857
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001858 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001859 if (pHddCtx->miracast_value)
1860 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1861 }
1862
1863 /* Initialize the Linkup event completion variable */
1864 INIT_COMPLETION(pAdapter->linkup_event_var);
1865
1866 /*
1867 * Sometimes Switching ON the Carrier is taking time to activate
1868 * the device properly. Before allowing any packet to go up to
1869 * the application, device activation has to be ensured for
1870 * proper queue mapping by the kernel. we have registered net
1871 * device notifier for device change notification. With this we
1872 * will come to know that the device is getting
1873 * activated properly.
1874 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001876 /*
1877 * Enable Linkup Event Servicing which allows the net
1878 * device notifier to set the linkup event variable.
1879 */
1880 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001882 /* Switch on the Carrier to activate the device */
1883 wlan_hdd_netif_queue_control(pAdapter,
1884 WLAN_NETIF_CARRIER_ON,
1885 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001886
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001887 /*
1888 * Wait for the Link to up to ensure all the queues
1889 * are set properly by the kernel.
1890 */
1891 rc = wait_for_completion_timeout(
1892 &pAdapter->linkup_event_var,
1893 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1894 );
1895 if (!rc)
1896 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001897
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001898 /*
1899 * Disable Linkup Event Servicing - no more service
1900 * required from the net device notifier call.
1901 */
1902 pAdapter->isLinkUpSvcNeeded = false;
1903 } else {
1904 pHddStaCtx->ft_carrier_on = false;
1905 ft_carrier_on = true;
1906 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1908 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1909 else
1910 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1911 pRoamInfo->staId);
1912
1913 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1914
1915 if (hdd_ipa_is_enabled(pHddCtx))
1916 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1917 WLAN_STA_CONNECT,
1918 pRoamInfo->bssid.bytes);
1919
1920#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1921 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1922#endif
1923
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301924 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001925 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926 pAdapter);
1927
1928#ifdef FEATURE_WLAN_TDLS
1929 wlan_hdd_tdls_connection_callback(pAdapter);
1930#endif
1931
1932#ifdef QCA_PKT_PROTO_TRACE
1933 /* STA Associated, update into trace buffer */
1934 if (pHddCtx->config->gEnableDebugLog)
1935 cds_pkt_trace_buf_update("ST:ASSOC");
1936#endif /* QCA_PKT_PROTO_TRACE */
1937 /*
1938 * For reassoc, the station is already registered, all we need
1939 * is to change the state of the STA in TL.
1940 * If authentication is required (WPA/WPA2/DWEP), change TL to
1941 * CONNECTED instead of AUTHENTICATED.
1942 */
1943 if (!pRoamInfo->fReassocReq) {
1944 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001945 u8 *pFTAssocRsp = NULL;
1946 unsigned int assocRsplen = 0;
1947 u8 *pFTAssocReq = NULL;
1948 unsigned int assocReqlen = 0;
1949 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1951 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1952
1953 /* add bss_id to cfg80211 data base */
1954 bss =
1955 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1956 pRoamInfo);
1957 if (NULL == bss) {
1958 pr_err("wlan: Not able to create BSS entry\n");
1959 wlan_hdd_netif_queue_control(pAdapter,
1960 WLAN_NETIF_CARRIER_OFF,
1961 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301962 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001963 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1965 eCSR_AUTH_TYPE_FT_RSN
1966 || pRoamInfo->u.pConnectedProfile->AuthType ==
1967 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1968
1969 /* Association Response */
1970 pFTAssocRsp =
1971 (u8 *) (pRoamInfo->pbFrames +
1972 pRoamInfo->nBeaconLength +
1973 pRoamInfo->nAssocReqLength);
1974 if (pFTAssocRsp != NULL) {
1975 /*
1976 * pFTAssocRsp needs to point to the IEs
1977 */
1978 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1979 hddLog(LOG1,
1980 FL("AssocRsp is now at %02x%02x"),
1981 (unsigned int)pFTAssocRsp[0],
1982 (unsigned int)pFTAssocRsp[1]);
1983 assocRsplen =
1984 pRoamInfo->nAssocRspLength -
1985 FT_ASSOC_RSP_IES_OFFSET;
1986 } else {
1987 hddLog(LOGE, FL("AssocRsp is NULL"));
1988 assocRsplen = 0;
1989 }
1990
1991 /* Association Request */
1992 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1993 pRoamInfo->nBeaconLength);
1994 if (pFTAssocReq != NULL) {
1995 if (!ft_carrier_on) {
1996 /*
1997 * pFTAssocReq needs to point to
1998 * the IEs
1999 */
2000 pFTAssocReq +=
2001 FT_ASSOC_REQ_IES_OFFSET;
2002 hddLog(LOG1,
2003 FL("pFTAssocReq is now at %02x%02x"),
2004 (unsigned int)
2005 pFTAssocReq[0],
2006 (unsigned int)
2007 pFTAssocReq[1]);
2008 assocReqlen =
2009 pRoamInfo->nAssocReqLength -
2010 FT_ASSOC_REQ_IES_OFFSET;
2011 } else {
2012 /*
2013 * This should contain only the
2014 * FTIEs
2015 */
2016 assocReqlen =
2017 pRoamInfo->nAssocReqLength;
2018 }
2019 } else {
2020 hddLog(LOGE, FL("AssocReq is NULL"));
2021 assocReqlen = 0;
2022 }
2023
2024 if (ft_carrier_on) {
2025 if (!hddDisconInProgress) {
2026 /*
2027 * After roaming is completed,
2028 * active session count is
2029 * incremented as a part of
2030 * connect indication but
2031 * effectively the active
2032 * session count should still
2033 * be the same and hence upon
2034 * successful reassoc
2035 * decrement the active session
2036 * count here.
2037 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002038 if (!hdd_is_roam_sync_in_progress
2039 (pRoamInfo))
2040 cds_decr_session_set_pcl
2041 (pAdapter->device_mode,
2042 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 hddLog(LOG1,
2044 FL("ft_carrier_on is %d, sending roamed indication"),
2045 ft_carrier_on);
2046 chan =
2047 ieee80211_get_channel
2048 (pAdapter->wdev.wiphy,
2049 (int)pRoamInfo->pBssDesc->
2050 channelId);
2051 hddLog(LOG1,
2052 "assocReqlen %d assocRsplen %d",
2053 assocReqlen,
2054 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002055
2056 hdd_notice(
2057 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302058 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302059 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302060 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002061 pFTAssocReq,
2062 assocReqlen);
2063
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002064 cfg80211_roamed(dev, chan,
2065 pRoamInfo->
2066 bssid.bytes,
2067 pFTAssocReq,
2068 assocReqlen,
2069 pFTAssocRsp,
2070 assocRsplen,
2071 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002072 wlan_hdd_send_roam_auth_event(
2073 pHddCtx,
2074 pRoamInfo->bssid.bytes,
2075 pFTAssocReq,
2076 assocReqlen,
2077 pFTAssocRsp,
2078 assocRsplen,
2079 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 }
2081 if (sme_get_ftptk_state
2082 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2083 pAdapter->sessionId)) {
2084 sme_set_ftptk_state
2085 (WLAN_HDD_GET_HAL_CTX
2086 (pAdapter),
2087 pAdapter->sessionId,
2088 false);
2089 pRoamInfo->fAuthRequired =
2090 false;
2091
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302092 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093 roam_info.bssid,
2094 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302095 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302096 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 roam_info.peerMac,
2098 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302099 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 pHddStaCtx->roam_info.roamId =
2101 roamId;
2102 pHddStaCtx->roam_info.
2103 roamStatus = roamStatus;
2104 pHddStaCtx->roam_info.
2105 deferKeyComplete = true;
2106 }
2107 } else if (!hddDisconInProgress) {
2108 hddLog(LOG1,
2109 FL("ft_carrier_on is %d, sending connect indication"),
2110 ft_carrier_on);
2111 cfg80211_connect_result(dev,
2112 pRoamInfo->
2113 bssid.bytes,
2114 pFTAssocReq,
2115 assocReqlen,
2116 pFTAssocRsp,
2117 assocRsplen,
2118 WLAN_STATUS_SUCCESS,
2119 GFP_KERNEL);
2120 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002121 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002122 /*
2123 * wpa supplicant expecting WPA/RSN IE in
2124 * connect result.
2125 */
2126 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2127 (pAdapter),
2128 pAdapter->sessionId,
2129 &reqRsnLength,
2130 reqRsnIe);
2131
2132 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2133 (pAdapter),
2134 pAdapter->sessionId,
2135 &rspRsnLength,
2136 rspRsnIe);
2137 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 if (ft_carrier_on)
2139 hdd_send_re_assoc_event(dev,
2140 pAdapter,
2141 pRoamInfo,
2142 reqRsnIe,
2143 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002144 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145 hddLog(LOG1,
2146 FL("sending connect indication to nl80211:for bssid "
2147 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302148 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 MAC_ADDR_ARRAY
2150 (pRoamInfo->bssid.bytes),
2151 roamResult, roamStatus);
2152
2153 /* inform connect result to nl80211 */
2154 cfg80211_connect_result(dev,
2155 pRoamInfo->
2156 bssid.bytes,
2157 reqRsnIe,
2158 reqRsnLength,
2159 rspRsnIe,
2160 rspRsnLength,
2161 WLAN_STATUS_SUCCESS,
2162 GFP_KERNEL);
2163 }
2164 }
2165 }
2166 if (!hddDisconInProgress) {
2167 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002169 bss);
2170
2171 /*
2172 * Perform any WMM-related association
2173 * processing.
2174 */
2175 hdd_wmm_assoc(pAdapter, pRoamInfo,
2176 eCSR_BSS_TYPE_INFRASTRUCTURE);
2177
2178 /*
2179 * Start the Queue - Start tx queues before
2180 * hdd_roam_register_sta, since
2181 * hdd_roam_register_sta will flush any cached
2182 * data frames immediately.
2183 */
2184 hddLog(LOG1, FL("Enabling queues"));
2185 wlan_hdd_netif_queue_control(pAdapter,
2186 WLAN_WAKE_ALL_NETIF_QUEUE,
2187 WLAN_CONTROL_PATH);
2188
2189 /*
2190 * Register the Station with TL after associated
2191 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302192 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002193 pRoamInfo,
2194 pHddStaCtx->
2195 conn_info.
2196 staId[0],
2197 NULL,
2198 pRoamInfo->
2199 pBssDesc);
2200 }
2201 } else {
2202 /*
2203 * wpa supplicant expecting WPA/RSN IE in connect result
2204 * in case of reassociation also need to indicate it to
2205 * supplicant.
2206 */
2207 csr_roam_get_wpa_rsn_req_ie(
2208 WLAN_HDD_GET_HAL_CTX(pAdapter),
2209 pAdapter->sessionId,
2210 &reqRsnLength, reqRsnIe);
2211
2212 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2213 reqRsnIe, reqRsnLength);
2214 /* Reassoc successfully */
2215 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302216 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002217 hdd_change_peer_state(pAdapter,
2218 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002219 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2221 pRoamInfo->roamSynchInProgress
2222#else
2223 false
2224#endif
2225 );
2226 hdd_conn_set_authenticated(pAdapter, false);
2227 } else {
2228 hddLog(LOG2,
2229 FL("staId: %d Changing TL state to AUTHENTICATED"),
2230 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302231 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232 hdd_change_peer_state(pAdapter,
2233 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002234 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002235#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2236 pRoamInfo->roamSynchInProgress
2237#else
2238 false
2239#endif
2240 );
2241 hdd_conn_set_authenticated(pAdapter, true);
2242 }
2243
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302244 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245 /*
2246 * Perform any WMM-related association
2247 * processing
2248 */
2249 hdd_wmm_assoc(pAdapter, pRoamInfo,
2250 eCSR_BSS_TYPE_INFRASTRUCTURE);
2251 }
2252
2253 /* Start the tx queues */
2254#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2255 if (pRoamInfo->roamSynchInProgress)
2256 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2257#endif
2258 hddLog(LOG1, FL("Enabling queues"));
2259 wlan_hdd_netif_queue_control(pAdapter,
2260 WLAN_WAKE_ALL_NETIF_QUEUE,
2261 WLAN_CONTROL_PATH);
2262 }
2263
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302264 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265 hddLog(LOGE,
2266 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302267 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 }
2269#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302270 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002271 sizeof(pAdapter->hdd_stats.hddPmfStats));
2272#endif
2273 } else {
2274 hdd_wext_state_t *pWextState =
2275 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2276 if (pRoamInfo)
2277 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302278 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002279 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2280 roamResult, roamStatus);
2281 else
2282 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302283 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002284 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2285 roamResult, roamStatus);
2286
2287 /*
2288 * CR465478: Only send up a connection failure result when CSR
2289 * has completed operation - with a ASSOCIATION_FAILURE status.
2290 */
2291 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2292 && !hddDisconInProgress) {
2293 if (pRoamInfo)
2294 hddLog(LOGE,
2295 FL("send connect failure to nl80211: for bssid "
2296 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302297 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002298 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302299 roamResult, roamStatus,
2300 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301 else
2302 hddLog(LOGE,
2303 FL("connect failed: for bssid "
2304 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302305 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002306 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2307 roamResult, roamStatus);
2308
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309 /* inform association failure event to nl80211 */
2310 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2311 roamResult) {
2312 if (pRoamInfo)
2313 cfg80211_connect_result(dev,
2314 pRoamInfo->bssid.bytes,
2315 NULL, 0, NULL, 0,
2316 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2317 GFP_KERNEL);
2318 else
2319 cfg80211_connect_result(dev,
2320 pWextState->req_bssId.bytes,
2321 NULL, 0, NULL, 0,
2322 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2323 GFP_KERNEL);
2324 } else {
2325 if (pRoamInfo) {
2326 eCsrAuthType authType =
2327 pWextState->roamProfile.AuthType.
2328 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302329 eCsrEncryptionType encryption_type =
2330 pWextState->roamProfile.
2331 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002332 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302333 (((authType ==
2334 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302336 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2337 ((encryption_type ==
2338 eCSR_ENCRYPT_TYPE_WEP40) ||
2339 (encryption_type ==
2340 eCSR_ENCRYPT_TYPE_WEP104) ||
2341 (encryption_type ==
2342 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2343 (encryption_type ==
2344 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345 /*
2346 * In case of OPEN-WEP or SHARED-WEP
2347 * authentication, send exact protocol
2348 * reason code. This enables user
2349 * applications to reconnect the station
2350 * with correct configuration.
2351 */
2352 cfg80211_connect_result(dev,
2353 pRoamInfo->bssid.bytes, NULL, 0,
2354 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302355 (isWep &&
2356 pRoamInfo->reasonCode) ?
2357 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002358 WLAN_STATUS_UNSPECIFIED_FAILURE,
2359 GFP_KERNEL);
2360 } else
2361 cfg80211_connect_result(dev,
2362 pWextState->req_bssId.bytes,
2363 NULL, 0, NULL, 0,
2364 WLAN_STATUS_UNSPECIFIED_FAILURE,
2365 GFP_KERNEL);
2366 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302367 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002368 }
2369
2370 if (pRoamInfo) {
2371 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2372 pRoamInfo->statusCode)
2373 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2374 pRoamInfo->statusCode)
2375 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2376 pRoamInfo->statusCode)) {
2377 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2378 pRoamInfo);
2379 }
2380 }
2381
2382 /*
2383 * Set connection state to eConnectionState_NotConnected only
2384 * when CSR has completed operation - with a
2385 * ASSOCIATION_FAILURE status.
2386 */
2387 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2388 && !hddDisconInProgress) {
2389 hddLog(LOG1,
2390 FL("state to eConnectionState_NotConnected"));
2391 hdd_conn_set_connection_state(pAdapter,
2392 eConnectionState_NotConnected);
2393 }
2394 hdd_wmm_init(pAdapter);
2395
2396 hddLog(LOG1, FL("Disabling queues"));
2397 wlan_hdd_netif_queue_control(pAdapter,
2398 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2399 WLAN_CONTROL_PATH);
2400 }
2401
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302402 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302404 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405
Govind Singh24db1ed2015-12-18 15:54:59 +05302406 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2407 cds_force_sap_on_scc(roamResult,
2408 pRoamInfo->pBssDesc->channelId);
2409 } else {
2410 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302411 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302412 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302414 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002415}
2416
2417/**
2418 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2419 * @pAdapter: pointer to adapter
2420 * @pRoamInfo: pointer to roam info
2421 * @roamId: roam id
2422 * @roamStatus: roam status
2423 * @roamResult: roam result
2424 *
2425 * Here we update the status of the Ibss when we receive information that we
2426 * have started/joined an ibss session.
2427 *
2428 * Return: none
2429 */
2430static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2431 tCsrRoamInfo *pRoamInfo,
2432 uint32_t roamId,
2433 eRoamCmdStatus roamStatus,
2434 eCsrRoamResult roamResult)
2435{
2436 hddLog(LOG1, "%s: id %d, status %d, result %d",
2437 pAdapter->dev->name, roamId, roamStatus, roamResult);
2438
2439 switch (roamResult) {
2440 /* both IBSS Started and IBSS Join should come in here. */
2441 case eCSR_ROAM_RESULT_IBSS_STARTED:
2442 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2443 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2444 {
2445 hdd_context_t *pHddCtx =
2446 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302447 hdd_station_ctx_t *hdd_sta_ctx =
2448 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302449 struct qdf_mac_addr broadcastMacAddr =
2450 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002451
2452 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302453 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002454 return;
2455 }
2456
2457 /* When IBSS Started comes from CSR, we need to move
2458 * connection state to IBSS Disconnected (meaning no peers
2459 * are in the IBSS).
2460 */
2461 hddLog(LOG1,
2462 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2463 hdd_conn_set_connection_state(pAdapter,
2464 eConnectionState_IbssDisconnected);
2465 /* notify wmm */
2466 hdd_wmm_connect(pAdapter, pRoamInfo,
2467 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302468
2469 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2470
2471 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 pAdapter;
2473 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302474 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 &broadcastMacAddr,
2476 pRoamInfo->pBssDesc);
2477
2478 if (pRoamInfo->pBssDesc) {
2479 struct cfg80211_bss *bss;
2480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2481 struct ieee80211_channel *chan;
2482 int chan_no;
2483 unsigned int freq;
2484#endif
2485 /* we created the IBSS, notify supplicant */
2486 hddLog(LOG1,
2487 FL("%s: created ibss " MAC_ADDRESS_STR),
2488 pAdapter->dev->name,
2489 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2490
2491 /* we must first give cfg80211 the BSS information */
2492 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2493 pRoamInfo);
2494 if (NULL == bss) {
2495 hddLog(LOGE,
2496 FL("%s: unable to create IBSS entry"),
2497 pAdapter->dev->name);
2498 return;
2499 }
2500 hddLog(LOG1, FL("Enabling queues"));
2501 wlan_hdd_netif_queue_control(pAdapter,
2502 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2503 WLAN_CONTROL_PATH);
2504
2505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2506 chan_no = pRoamInfo->pBssDesc->channelId;
2507
2508 if (chan_no <= 14)
2509 freq = ieee80211_channel_to_frequency(chan_no,
2510 IEEE80211_BAND_2GHZ);
2511 else
2512 freq = ieee80211_channel_to_frequency(chan_no,
2513 IEEE80211_BAND_5GHZ);
2514
2515 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2516
2517 if (chan)
2518 cfg80211_ibss_joined(pAdapter->dev,
2519 bss->bssid, chan,
2520 GFP_KERNEL);
2521 else
2522 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2523 pAdapter->dev->name,
2524 (int)pRoamInfo->pBssDesc->channelId);
2525#else
2526 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2527 GFP_KERNEL);
2528#endif
2529 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531 bss);
2532 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002533 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002534 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002535 pAdapter->sessionId);
2536 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2537 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002538 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002539 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002540 break;
2541 }
2542
2543 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2544 {
2545 hddLog(LOGE,
2546 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2547 break;
2548 }
2549
2550 default:
2551 hddLog(LOGE, FL("%s: unexpected result %d"),
2552 pAdapter->dev->name, (int)roamResult);
2553 break;
2554 }
2555
2556 return;
2557}
2558
2559/**
2560 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2561 * @pHddStaCtx: pointer to global HDD station context
2562 * @staId: station id
2563 * @peerMacAddress: pointer to peer MAC address
2564 *
2565 * This information is passed to iwconfig later. The peer that joined
2566 * last is passed as information to iwconfig.
2567 *
2568 * Return:
2569 * true if we add MAX_IBSS_PEERS or less STA
2570 * false otherwise.
2571 */
2572static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302573 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574{
2575 bool fSuccess = false;
2576 int idx = 0;
2577
2578 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2579 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2580 pHddStaCtx->conn_info.staId[idx] = staId;
2581
Anurag Chouhanc5548422016-02-24 18:33:27 +05302582 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002583 peerMacAddress[idx], peerMacAddress);
2584
2585 fSuccess = true;
2586 break;
2587 }
2588 }
2589
2590 return fSuccess;
2591}
2592
2593/**
2594 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2595 * @pAdapter: pointer to adapter
2596 * @staId: station id
2597 *
2598 * Return:
2599 * true if we remove MAX_IBSS_PEERS or less STA
2600 * false otherwise.
2601 */
2602static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2603{
2604 bool fSuccess = false;
2605 int idx = 0;
2606 uint8_t valid_idx = 0;
2607 uint8_t del_idx = 0;
2608 uint8_t empty_slots = 0;
2609 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2610
2611 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2612 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2613 pHddStaCtx->conn_info.staId[idx] = 0;
2614
Anurag Chouhanc5548422016-02-24 18:33:27 +05302615 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 peerMacAddress[idx]);
2617
2618 fSuccess = true;
2619
2620 /*
2621 * Note the deleted Index, if its 0 we need special
2622 * handling.
2623 */
2624 del_idx = idx;
2625
2626 empty_slots++;
2627 } else {
2628 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2629 valid_idx = idx;
2630 } else {
2631 /* Found an empty slot */
2632 empty_slots++;
2633 }
2634 }
2635 }
2636
2637 if (MAX_IBSS_PEERS == empty_slots) {
2638 /* Last peer departed, set the IBSS state appropriately */
2639 pHddStaCtx->conn_info.connState =
2640 eConnectionState_IbssDisconnected;
2641 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2642 }
2643 /* Find next active staId, to have a valid sta trigger for TL. */
2644 if (fSuccess == true) {
2645 if (del_idx == 0) {
2646 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2647 pHddStaCtx->conn_info.staId[0] =
2648 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302649 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 peerMacAddress[0],
2651 &pHddStaCtx->conn_info.
2652 peerMacAddress[valid_idx]);
2653
2654 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302655 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656 peerMacAddress[valid_idx]);
2657 }
2658 }
2659 }
2660 return fSuccess;
2661}
2662
2663/**
2664 * roam_ibss_connect_handler() - IBSS connection handler
2665 * @pAdapter: pointer to adapter
2666 * @pRoamInfo: pointer to roam info
2667 *
2668 * We update the status of the IBSS to connected in this function.
2669 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302670 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302672static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673 tCsrRoamInfo *pRoamInfo)
2674{
2675 struct cfg80211_bss *bss;
2676 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2677 /*
2678 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2679 * a partner stations).
2680 */
2681 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2682
2683 /* Save the connection info from CSR... */
2684 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2685
2686 /* Send the bssid address to the wext. */
2687 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2688 /* add bss_id to cfg80211 data base */
2689 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2690 if (NULL == bss) {
2691 hddLog(LOGE,
2692 FL("%s: unable to create IBSS entry"),
2693 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302694 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 }
2696 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 bss);
2699
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302700 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701}
2702
2703/**
2704 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2705 * @pAdapter: pointer to adapter
2706 * @pRoamInfo: pointer to roam info
2707 * @roamId: roam id
2708 * @roamStatus: roam status
2709 * @roamResult: roam result
2710 *
2711 * This function indicates the Mic failure to the supplicant
2712 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302713 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002714 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302715static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002716hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2717 tCsrRoamInfo *pRoamInfo,
2718 uint32_t roamId,
2719 eRoamCmdStatus roamStatus,
2720 eCsrRoamResult roamResult)
2721{
2722 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2723
2724 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2725 TKIP_COUNTER_MEASURE_STOPED ==
2726 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2727 struct iw_michaelmicfailure msg;
2728 union iwreq_data wreq;
2729 memset(&msg, '\0', sizeof(msg));
2730 msg.src_addr.sa_family = ARPHRD_ETHER;
2731 memcpy(msg.src_addr.sa_data,
2732 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2733 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2734 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2735 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2736
2737 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2738 msg.flags = IW_MICFAILURE_GROUP;
2739 else
2740 msg.flags = IW_MICFAILURE_PAIRWISE;
2741 memset(&wreq, 0, sizeof(wreq));
2742 wreq.data.length = sizeof(msg);
2743 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2744 (char *)&msg);
2745 /* inform mic failure to nl80211 */
2746 cfg80211_michael_mic_failure(pAdapter->dev,
2747 pRoamInfo->u.pMICFailureInfo->
2748 taMacAddr,
2749 ((pRoamInfo->u.pMICFailureInfo->
2750 multicast ==
2751 eSIR_TRUE) ?
2752 NL80211_KEYTYPE_GROUP :
2753 NL80211_KEYTYPE_PAIRWISE),
2754 pRoamInfo->u.pMICFailureInfo->
2755 keyId,
2756 pRoamInfo->u.pMICFailureInfo->TSC,
2757 GFP_KERNEL);
2758
2759 }
2760
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302761 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762}
2763
2764/**
2765 * roam_roam_connect_status_update_handler() - IBSS connect status update
2766 * @pAdapter: pointer to adapter
2767 * @pRoamInfo: pointer to roam info
2768 * @roamId: roam id
2769 * @roamStatus: roam status
2770 * @roamResult: roam result
2771 *
2772 * The Ibss connection status is updated regularly here in this function.
2773 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302774 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302776static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002777roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2778 tCsrRoamInfo *pRoamInfo,
2779 uint32_t roamId,
2780 eRoamCmdStatus roamStatus,
2781 eCsrRoamResult roamResult)
2782{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302783 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002784
2785 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2786 switch (roamResult) {
2787 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2788 {
2789 hdd_station_ctx_t *pHddStaCtx =
2790 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2791 struct station_info staInfo;
2792
2793 pr_info("IBSS New Peer indication from SME "
2794 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2795 MAC_ADDRESS_STR " and stationID= %d",
2796 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2797 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2798 pRoamInfo->staId);
2799
2800 if (!roam_save_ibss_station
2801 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2802 pRoamInfo->staId,
2803 &pRoamInfo->peerMac)) {
2804 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2805 break;
2806 }
2807
2808 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2809
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302811 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002812 pRoamInfo,
2813 pRoamInfo->staId,
2814 &pRoamInfo->peerMac,
2815 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302816 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002817 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302818 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2819 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820 }
2821 pHddStaCtx->ibss_sta_generation++;
2822 memset(&staInfo, 0, sizeof(staInfo));
2823 staInfo.filled = 0;
2824 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2825
2826 cfg80211_new_sta(pAdapter->dev,
2827 (const u8 *)pRoamInfo->peerMac.bytes,
2828 &staInfo, GFP_KERNEL);
2829
2830 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2831 pHddStaCtx->ibss_enc_key.encType
2832 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2833 pHddStaCtx->ibss_enc_key.encType
2834 || eCSR_ENCRYPT_TYPE_TKIP ==
2835 pHddStaCtx->ibss_enc_key.encType
2836 || eCSR_ENCRYPT_TYPE_AES ==
2837 pHddStaCtx->ibss_enc_key.encType) {
2838 pHddStaCtx->ibss_enc_key.keyDirection =
2839 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302840 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841 &pRoamInfo->peerMac);
2842
2843 hddLog(LOG2, "New peer joined set PTK encType=%d",
2844 pHddStaCtx->ibss_enc_key.encType);
2845
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302846 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002847 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2848 (pAdapter),
2849 pAdapter->sessionId,
2850 &pHddStaCtx->ibss_enc_key,
2851 &roamId);
2852
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302853 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002854 hddLog(LOGE,
2855 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302856 qdf_status);
2857 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002858 }
2859 }
2860 hddLog(LOG1, FL("Enabling queues"));
2861 wlan_hdd_netif_queue_control(pAdapter,
2862 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2863 WLAN_CONTROL_PATH);
2864 break;
2865 }
2866
2867 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2868 {
2869
2870 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2871
2872 break;
2873 }
2874 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2875 {
2876 hdd_station_ctx_t *pHddStaCtx =
2877 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2878
2879 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2880 hddLog(LOGW,
2881 "IBSS peer departed by cannot find peer in our registration table with TL");
2882
2883 pr_info("IBSS Peer Departed from SME "
2884 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2885 MAC_ADDRESS_STR " and stationID= %d",
2886 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2887 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2888 pRoamInfo->staId);
2889
2890 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2891
2892 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2893 pHddStaCtx->ibss_sta_generation++;
2894
2895 cfg80211_del_sta(pAdapter->dev,
2896 (const u8 *)&pRoamInfo->peerMac.bytes,
2897 GFP_KERNEL);
2898 break;
2899 }
2900 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2901 {
2902 hddLog(LOG3,
2903 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2904 /* Stop only when we are inactive */
2905 hddLog(LOG1, FL("Disabling queues"));
2906 wlan_hdd_netif_queue_control(pAdapter,
2907 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2908 WLAN_CONTROL_PATH);
2909 hddLog(LOG1,
2910 FL("Set HDD connState to eConnectionState_NotConnected"));
2911 hdd_conn_set_connection_state(pAdapter,
2912 eConnectionState_NotConnected);
2913
2914 /* Send the bssid address to the wext. */
2915 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2916 break;
2917 }
2918 default:
2919 break;
2920
2921 }
2922
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302923 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002924}
2925
2926#ifdef FEATURE_WLAN_TDLS
2927/**
2928 * hdd_roam_register_tdlssta() - register new TDLS station
2929 * @pAdapter: pointer to adapter
2930 * @peerMac: pointer to peer MAC address
2931 * @staId: station identifier
2932 * @ucastSig: unicast signature
2933 *
2934 * Construct the staDesc and register with TL the new STA.
2935 * This is called as part of ADD_STA in the TDLS setup.
2936 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302937 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302939QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 const uint8_t *peerMac, uint16_t staId,
2941 uint8_t ucastSig)
2942{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302943 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002944 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002945 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002946
2947 /*
2948 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2949 * be peer MAC, here we are working on direct Link
2950 */
2951 staDesc.sta_id = staId;
2952
2953 /* set the QoS field appropriately .. */
2954 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2955 : (staDesc.is_qos_enabled = 0);
2956
Dhanashri Atre50141c52016-04-07 13:15:29 -07002957 /* Register the vdev transmit and receive functions */
2958 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2959 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2960 ol_txrx_vdev_register(
2961 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2962 pAdapter, &txrx_ops);
2963 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964
2965 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002966 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302967 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002968 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302969 qdf_status, qdf_status);
2970 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002971 }
2972
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302973 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002974}
2975
2976/**
2977 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2978 * @pAdapter: pointer to adapter
2979 * @staId: station identifier
2980 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302981 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002982 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302983static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002984 uint8_t staId)
2985{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302986 QDF_STATUS qdf_status;
2987 qdf_status = ol_txrx_clear_peer(staId);
2988 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302990 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002991 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302992 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002993}
2994
2995/**
2996 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2997 * @pAdapter: pointer to adapter
2998 * @pRoamInfo: pointer to roam info
2999 * @roamId: roam id
3000 * @roamStatus: roam status
3001 * @roamResult: roam result
3002 *
3003 * HDD interface between SME and TL to ensure TDLS client registration with
3004 * TL in case of new TDLS client is added and deregistration at the time
3005 * TDLS client is deleted.
3006 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303007 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003008 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303009static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003010hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3011 tCsrRoamInfo *pRoamInfo,
3012 uint32_t roamId,
3013 eRoamCmdStatus roamStatus,
3014 eCsrRoamResult roamResult)
3015{
3016 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3017 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3018 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303019 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003020 uint8_t staIdx;
3021 hddTdlsPeer_t *curr_peer;
3022 uint32_t reason;
3023
3024 hddLog(LOG2,
3025 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3026 roamResult ==
3027 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3028 ==
3029 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3030 roamResult ==
3031 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3032 : roamResult ==
3033 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3034 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3035 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3036 roamResult ==
3037 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3038 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3039 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3040 : roamResult ==
3041 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3042 : roamResult ==
3043 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3044 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3045 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3046
3047 if (!pHddTdlsCtx) {
3048 hddLog(LOG1,
3049 FL("TDLS ctx is null, ignore roamResult (%d)"),
3050 roamResult);
3051 return status;
3052 }
3053
3054 switch (roamResult) {
3055 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3056 {
3057 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3058 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3059 pRoamInfo->statusCode);
3060 } else {
3061 /*
3062 * Check if there is available index for this new TDLS
3063 * STA.
3064 */
3065 for (staIdx = 0;
3066 staIdx < pHddCtx->max_num_tdls_sta;
3067 staIdx++) {
3068 if (0 ==
3069 pHddCtx->tdlsConnInfo[staIdx].
3070 staId) {
3071 pHddCtx->tdlsConnInfo[staIdx].
3072 sessionId =
3073 pRoamInfo->sessionId;
3074 pHddCtx->tdlsConnInfo[staIdx].
3075 staId = pRoamInfo->staId;
3076
3077 hddLog(LOGW,
3078 ("TDLS: STA IDX at %d is %d "
3079 "of mac "
3080 MAC_ADDRESS_STR),
3081 staIdx,
3082 pHddCtx->
3083 tdlsConnInfo[staIdx].
3084 staId,
3085 MAC_ADDR_ARRAY
3086 (pRoamInfo->peerMac.bytes));
3087
Anurag Chouhanc5548422016-02-24 18:33:27 +05303088 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 tdlsConnInfo
3090 [staIdx].
3091 peerMac,
3092 &pRoamInfo->
3093 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303094 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 break;
3096 }
3097 }
3098 if (staIdx < pHddCtx->max_num_tdls_sta) {
3099 if (-1 ==
3100 wlan_hdd_tdls_set_sta_id(pAdapter,
3101 pRoamInfo->
3102 peerMac.bytes,
3103 pRoamInfo->
3104 staId)) {
3105 hddLog(LOGE,
3106 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303107 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108 }
3109
3110 (WLAN_HDD_GET_CTX(pAdapter))->
3111 sta_to_adapter[pRoamInfo->staId] =
3112 pAdapter;
3113 /*
3114 * store the ucast signature,
3115 * if required for further reference.
3116 */
3117
3118 wlan_hdd_tdls_set_signature(pAdapter,
3119 pRoamInfo->
3120 peerMac.bytes,
3121 pRoamInfo->
3122 ucastSig);
3123 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303124 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003125 hddLog(LOGE,
3126 FL("no available slot in conn_info. staId %d cannot be stored"),
3127 pRoamInfo->staId);
3128 }
3129 pAdapter->tdlsAddStaStatus = status;
3130 }
3131 complete(&pAdapter->tdls_add_station_comp);
3132 break;
3133 }
3134 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3135 {
3136 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3137 hddLog(LOGE,
3138 FL("Add Sta failed. status code(=%d)"),
3139 pRoamInfo->statusCode);
3140 }
3141 /* store the ucast signature which will be used later when
3142 * registering to TL
3143 */
3144 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3145 complete(&pAdapter->tdls_add_station_comp);
3146 break;
3147 }
3148 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3149 {
3150 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3151 hddLog(LOGE,
3152 FL("Link Establish Request failed. status(=%d)"),
3153 pRoamInfo->statusCode);
3154 }
3155 complete(&pAdapter->tdls_link_establish_req_comp);
3156 break;
3157 }
3158 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3159 {
3160 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3161 staIdx++) {
3162 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3163 pRoamInfo->sessionId)
3164 && pRoamInfo->staId ==
3165 pHddCtx->tdlsConnInfo[staIdx].staId) {
3166 hddLog(LOGW,
3167 ("HDD: del STA IDX = %x"),
3168 pRoamInfo->staId);
3169
3170 curr_peer =
3171 wlan_hdd_tdls_find_peer(pAdapter,
3172 pRoamInfo->
3173 peerMac.bytes,
3174 true);
3175 if (NULL != curr_peer
3176 && TDLS_IS_CONNECTED(curr_peer)) {
3177 hdd_roam_deregister_tdlssta
3178 (pAdapter,
3179 pRoamInfo->staId);
3180 wlan_hdd_tdls_decrement_peer_count
3181 (pAdapter);
3182 }
3183 wlan_hdd_tdls_reset_peer(pAdapter,
3184 pRoamInfo->
3185 peerMac.bytes);
3186
3187 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3188 pHddCtx->tdlsConnInfo[staIdx].
3189 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303190 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191 tdlsConnInfo[staIdx].
3192 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303193 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303194 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003195 break;
3196 }
3197 }
3198 complete(&pAdapter->tdls_del_station_comp);
3199 }
3200 break;
3201 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3202 {
3203 hddLog(LOGE,
3204 FL("Sending teardown to supplicant with reason code %u"),
3205 pRoamInfo->reasonCode);
3206
3207 curr_peer =
3208 wlan_hdd_tdls_find_peer(pAdapter,
3209 pRoamInfo->peerMac.bytes, true);
3210 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3211 pRoamInfo->reasonCode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303212 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003213 break;
3214 }
3215 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3216 {
3217 /* 0 staIdx is assigned to AP we dont want to touch that */
3218 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3219 staIdx++) {
3220 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3221 pRoamInfo->sessionId)
3222 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3223 hddLog(LOGW,
3224 ("hdd_tdlsStatusUpdate: staIdx %d "
3225 MAC_ADDRESS_STR),
3226 pHddCtx->tdlsConnInfo[staIdx].
3227 staId,
3228 MAC_ADDR_ARRAY(pHddCtx->
3229 tdlsConnInfo
3230 [staIdx].
3231 peerMac.
3232 bytes));
3233 wlan_hdd_tdls_reset_peer(pAdapter,
3234 pHddCtx->
3235 tdlsConnInfo
3236 [staIdx].
3237 peerMac.bytes);
3238 hdd_roam_deregister_tdlssta(pAdapter,
3239 pHddCtx->
3240 tdlsConnInfo
3241 [staIdx].
3242 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303243 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244 sizeof
3245 (smeTdlsPeerStateParams));
3246 smeTdlsPeerStateParams.vdevId =
3247 pHddCtx->tdlsConnInfo[staIdx].
3248 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303249 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003250 peerMacAddr,
3251 &pHddCtx->
3252 tdlsConnInfo[staIdx].
3253 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303254 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003255 smeTdlsPeerStateParams.peerState =
3256 eSME_TDLS_PEER_STATE_TEARDOWN;
3257
3258 hddLog(LOG1,
3259 FL("calling sme_update_tdls_peer_state for staIdx %d "
3260 MAC_ADDRESS_STR),
3261 pHddCtx->tdlsConnInfo[staIdx].
3262 staId,
3263 MAC_ADDR_ARRAY(pHddCtx->
3264 tdlsConnInfo
3265 [staIdx].
3266 peerMac.
3267 bytes));
3268 status =
3269 sme_update_tdls_peer_state(
3270 pHddCtx->hHal,
3271 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303272 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273 hddLog(LOGE,
3274 FL("sme_update_tdls_peer_state failed for "
3275 MAC_ADDRESS_STR),
3276 MAC_ADDR_ARRAY
3277 (pHddCtx->
3278 tdlsConnInfo[staIdx].
3279 peerMac.bytes));
3280 }
3281 wlan_hdd_tdls_decrement_peer_count
3282 (pAdapter);
3283
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303284 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003285 tdlsConnInfo[staIdx].
3286 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303287 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003288 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3289 pHddCtx->tdlsConnInfo[staIdx].
3290 sessionId = 255;
3291
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303292 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003293 }
3294 }
3295 break;
3296 }
3297 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3298 {
3299 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303300 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3301 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003302 hddLog(LOG2,
3303 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3304 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303305 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303306 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003307 break;
3308 }
3309
3310 curr_peer =
3311 wlan_hdd_tdls_get_peer(pAdapter,
3312 pRoamInfo->peerMac.bytes);
3313 if (!curr_peer) {
3314 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303315 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003316 } else {
3317 if (eTDLS_LINK_CONNECTED ==
3318 curr_peer->link_status) {
3319 hddLog(LOGE,
3320 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3321 } else {
3322 /*
3323 * If external control is enabled then initiate
3324 * TDLS only if forced peer is set otherwise
3325 * ignore should Discover trigger from fw.
3326 */
3327 if (pHddCtx->config->
3328 fTDLSExternalControl
3329 && (false ==
3330 curr_peer->isForcedPeer)) {
3331 hddLog(LOG2,
3332 FL
3333 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303334 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003335 break;
3336 } else {
3337 hddLog(LOG2,
3338 FL
3339 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3340 pHddCtx->config->
3341 fTDLSExternalControl,
3342 curr_peer->isForcedPeer,
3343 pRoamInfo->reasonCode);
3344 }
3345 wlan_hdd_tdls_pre_setup_init_work
3346 (pHddTdlsCtx, curr_peer);
3347 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303348 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003349 }
3350 break;
3351 }
3352
3353 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3354 {
3355 curr_peer =
3356 wlan_hdd_tdls_find_peer(pAdapter,
3357 pRoamInfo->peerMac.bytes, true);
3358 if (!curr_peer) {
3359 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303360 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 } else {
3362 if (eTDLS_LINK_CONNECTED ==
3363 curr_peer->link_status) {
3364 hddLog(LOGE,
3365 FL
3366 ("Received SHOULD_TEARDOWN for peer "
3367 MAC_ADDRESS_STR
3368 " staId: %d, reason: %d"),
3369 MAC_ADDR_ARRAY(pRoamInfo->
3370 peerMac.bytes),
3371 pRoamInfo->staId,
3372 pRoamInfo->reasonCode);
3373
3374 if (pRoamInfo->reasonCode ==
3375 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3376 pRoamInfo->reasonCode ==
3377 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3378 pRoamInfo->reasonCode ==
3379 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3380 pRoamInfo->reasonCode ==
3381 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3382 reason =
3383 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3384 } else
3385 reason =
3386 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3387
3388 wlan_hdd_tdls_indicate_teardown
3389 (pHddTdlsCtx->pAdapter, curr_peer,
3390 reason);
3391 } else {
3392 hddLog(LOGE,
3393 FL
3394 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3395 pRoamInfo->reasonCode);
3396 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303397 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003398 }
3399 break;
3400 }
3401
3402 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3403 {
3404 curr_peer =
3405 wlan_hdd_tdls_find_peer(pAdapter,
3406 pRoamInfo->peerMac.bytes, true);
3407 if (!curr_peer) {
3408 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303409 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 } else {
3411 if (eTDLS_LINK_CONNECTED ==
3412 curr_peer->link_status) {
3413 hddLog(LOGE,
3414 FL
3415 ("Received SHOULD_PEER_DISCONNECTED for peer "
3416 MAC_ADDRESS_STR
3417 " staId: %d, reason: %d"),
3418 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3419 pRoamInfo->staId,
3420 pRoamInfo->reasonCode);
3421
3422 if (pRoamInfo->reasonCode ==
3423 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3424 pRoamInfo->reasonCode ==
3425 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3426 pRoamInfo->reasonCode ==
3427 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3428 pRoamInfo->reasonCode ==
3429 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3430 reason =
3431 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3432 } else
3433 reason =
3434 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3435
3436 wlan_hdd_tdls_indicate_teardown
3437 (pHddTdlsCtx->pAdapter, curr_peer,
3438 reason);
3439 } else {
3440 hddLog(LOGE,
3441 FL
3442 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3443 pRoamInfo->reasonCode);
3444 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303445 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003446 }
3447 break;
3448 }
3449 default:
3450 {
3451 break;
3452 }
3453 }
3454
3455 return status;
3456}
3457#endif
3458
3459#ifdef WLAN_FEATURE_11W
3460/**
3461 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3462 * @pAdapter: pointer to the adapter
3463 * @nFrameLength: Length of the unprotected frame being passed
3464 * @pbFrames: Pointer to the frame buffer
3465 * @frameType: 802.11 frame type
3466 *
3467 * This function forwards the unprotected management frame to the supplicant.
3468 *
3469 * Return: nothing
3470 */
3471static void
3472hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3473 uint8_t *pbFrames, uint8_t frameType)
3474{
3475 uint8_t type = 0;
3476 uint8_t subType = 0;
3477
3478 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3479 frameType, nFrameLength);
3480
3481 /* Sanity Checks */
3482 if (NULL == pAdapter) {
3483 hddLog(LOGE, FL("pAdapter is NULL"));
3484 return;
3485 }
3486
3487 if (NULL == pAdapter->dev) {
3488 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3489 return;
3490 }
3491
3492 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3493 hddLog(LOGE, FL("pAdapter has invalid magic"));
3494 return;
3495 }
3496
3497 if (!nFrameLength) {
3498 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3499 return;
3500 }
3501
3502 if (NULL == pbFrames) {
3503 hddLog(LOGE, FL("pbFrames is NULL"));
3504 return;
3505 }
3506
3507 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3508 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3509
3510 /* Get pAdapter from Destination mac address of the frame */
3511 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3513 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3514 nFrameLength);
3515#else
3516 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3517 nFrameLength);
3518#endif
3519 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3520 } else if (type == SIR_MAC_MGMT_FRAME &&
3521 subType == SIR_MAC_MGMT_DEAUTH) {
3522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3523 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3524 nFrameLength);
3525#else
3526 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3527 nFrameLength);
3528#endif
3529 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3530 } else {
3531 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3532 type, subType);
3533 return;
3534 }
3535}
3536#endif
3537
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003538#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539/**
3540 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3541 * @pAdapter: pointer to adapter
3542 * @tid: traffic identifier
3543 * @state: state
3544 * @measInterval: measurement interval
3545 *
3546 * This function sends traffic stream metrics IE information to
3547 * the supplicant via wireless event.
3548 *
3549 * Return: none
3550 */
3551static void
3552hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3553 uint8_t state, uint16_t measInterval)
3554{
3555 union iwreq_data wrqu;
3556 char buf[IW_CUSTOM_MAX + 1];
3557 int nBytes = 0;
3558
3559 if (NULL == pAdapter)
3560 return;
3561
3562 /* create the event */
3563 memset(&wrqu, '\0', sizeof(wrqu));
3564 memset(buf, '\0', sizeof(buf));
3565
3566 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3567 tid, state, measInterval);
3568
3569 nBytes =
3570 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3571 measInterval);
3572
3573 wrqu.data.pointer = buf;
3574 wrqu.data.length = nBytes;
3575 /* send the event */
3576 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3577}
3578
3579/**
3580 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3581 * @pAdapter: pointer to adapter
3582 * @pRoamInfo: pointer to roam info
3583 *
3584 * This function sends cckm preauth indication to the supplicant
3585 * via wireless custom event.
3586 *
3587 * Return: none
3588 */
3589static void
3590hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3591{
3592 union iwreq_data wrqu;
3593 char buf[IW_CUSTOM_MAX + 1];
3594 char *pos = buf;
3595 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3596
3597 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3598 return;
3599
3600 /* create the event */
3601 memset(&wrqu, '\0', sizeof(wrqu));
3602 memset(buf, '\0', sizeof(buf));
3603
3604 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3605 hddLog(LOG1,
3606 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3607 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3608 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3609
3610 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3611 pos += nBytes;
3612 freeBytes -= nBytes;
3613
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303614 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303615 pos += QDF_MAC_ADDR_SIZE;
3616 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003617
3618 nBytes = snprintf(pos, freeBytes, " %u:%u",
3619 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3620 freeBytes -= nBytes;
3621
3622 wrqu.data.pointer = buf;
3623 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3624
3625 /* send the event */
3626 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3627}
3628
3629/**
3630 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3631 * @pAdapter: pointer to adapter
3632 * @pRoamInfo: pointer to roam info
3633 *
3634 * Return: none
3635 */
3636static void
3637hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3638 tCsrRoamInfo *pRoamInfo)
3639{
3640 union iwreq_data wrqu;
3641 char buf[IW_CUSTOM_MAX + 1];
3642 int nBytes = 0;
3643
3644 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3645 return;
3646
3647 /* create the event */
3648 memset(&wrqu, '\0', sizeof(wrqu));
3649 memset(buf, '\0', sizeof(buf));
3650
3651 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3652
3653 nBytes =
3654 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3655 pRoamInfo->tsmRoamDelay);
3656
3657 wrqu.data.pointer = buf;
3658 wrqu.data.length = nBytes;
3659
3660 /* send the event */
3661 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3662}
3663
3664/**
3665 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3666 * @pAdapter: pointer to adapter
3667 * @measurementToken: measurement token
3668 * @flag: flag
3669 * @numBss: number of bss
3670 *
3671 * If the measurement is none and no scan results found,
3672 * indicate the supplicant about measurement done.
3673 *
3674 * Return: none
3675 */
3676void
3677hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3678 const uint16_t measurementToken,
3679 const bool flag, const uint8_t numBss)
3680{
3681 union iwreq_data wrqu;
3682 char buf[IW_CUSTOM_MAX];
3683 char *pos = buf;
3684 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3685
3686 memset(&wrqu, '\0', sizeof(wrqu));
3687 memset(buf, '\0', sizeof(buf));
3688
3689 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3690 flag, numBss);
3691
3692 nBytes =
3693 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3694 flag, numBss);
3695
3696 wrqu.data.pointer = buf;
3697 wrqu.data.length = nBytes;
3698 /* send the event */
3699 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3700}
3701
3702/**
3703 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3704 * @pAdapter: pointer to adapter
3705 * @pRoamInfo: pointer to roam info
3706 *
3707 * If the measurement is none and no scan results found,
3708 * indicate the supplicant about measurement done.
3709 *
3710 * Return: none
3711 */
3712static void
3713hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3714 const tCsrRoamInfo *pRoamInfo)
3715{
3716 union iwreq_data wrqu;
3717 char buf[IW_CUSTOM_MAX];
3718 char *pos = buf;
3719 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3720 uint8_t i = 0, len = 0;
3721 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3722 uint8_t lastSent = 0, sendBss = 0;
3723 int bcnRepFieldSize =
3724 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3725 bcnReportFields);
3726 uint8_t ieLenByte = 1;
3727 /*
3728 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3729 */
3730#define ESEBCNREPHEADER_LEN (18)
3731
3732 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3733 return;
3734
3735 /*
3736 * Custom event can pass maximum of 256 bytes of data,
3737 * based on the IE len we need to identify how many BSS info can
3738 * be filled in to custom event data.
3739 */
3740 /*
3741 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3742 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3743 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3744 */
3745
3746 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3747 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3748 hddLog(LOG1,
3749 "Measurement Done but no scan results");
3750 /* If the measurement is none and no scan results found,
3751 indicate the supplicant about measurement done */
3752 hdd_indicate_ese_bcn_report_no_results(
3753 pAdapter,
3754 pRoamInfo->pEseBcnReportRsp->
3755 measurementToken,
3756 pRoamInfo->pEseBcnReportRsp->flag,
3757 pRoamInfo->pEseBcnReportRsp->numBss);
3758 } else {
3759 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3760 memset(&wrqu, '\0', sizeof(wrqu));
3761 memset(buf, '\0', sizeof(buf));
3762 tot_bcn_ieLen = 0;
3763 sendBss = 0;
3764 pos = buf;
3765 freeBytes = IW_CUSTOM_MAX;
3766
3767 for (i = lastSent;
3768 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3769 len =
3770 bcnRepFieldSize + ieLenByte +
3771 pRoamInfo->pEseBcnReportRsp->
3772 bcnRepBssInfo[i].ieLen;
3773 if ((len + tot_bcn_ieLen) >
3774 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3775 break;
3776 }
3777 tot_bcn_ieLen += len;
3778 sendBss++;
3779 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3780 i, bcnRepFieldSize, 1,
3781 pRoamInfo->pEseBcnReportRsp->
3782 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3783 }
3784
3785 hddLog(LOG1, "Sending %d BSS Info",
3786 sendBss);
3787 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3788 pRoamInfo->pEseBcnReportRsp->measurementToken,
3789 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3790 tot_bcn_ieLen);
3791
3792 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3793 pRoamInfo->pEseBcnReportRsp->
3794 measurementToken,
3795 pRoamInfo->pEseBcnReportRsp->flag,
3796 sendBss);
3797 pos += nBytes;
3798 freeBytes -= nBytes;
3799
3800 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303801 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003802 sizeof(tot_bcn_ieLen));
3803 pos += sizeof(tot_bcn_ieLen);
3804 freeBytes -= sizeof(tot_bcn_ieLen);
3805
3806 for (i = 0; i < sendBss; i++) {
3807 hddLog(LOG1,
3808 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3809 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3810 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3811 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3812 pRoamInfo->pEseBcnReportRsp->
3813 bcnRepBssInfo[i +
3814 lastSent].bcnReportFields.
3815 ChanNum,
3816 pRoamInfo->pEseBcnReportRsp->
3817 bcnRepBssInfo[i +
3818 lastSent].bcnReportFields.
3819 Spare,
3820 pRoamInfo->pEseBcnReportRsp->
3821 bcnRepBssInfo[i +
3822 lastSent].bcnReportFields.
3823 MeasDuration,
3824 pRoamInfo->pEseBcnReportRsp->
3825 bcnRepBssInfo[i +
3826 lastSent].bcnReportFields.
3827 PhyType,
3828 pRoamInfo->pEseBcnReportRsp->
3829 bcnRepBssInfo[i +
3830 lastSent].bcnReportFields.
3831 RecvSigPower,
3832 pRoamInfo->pEseBcnReportRsp->
3833 bcnRepBssInfo[i +
3834 lastSent].bcnReportFields.
3835 ParentTsf,
3836 pRoamInfo->pEseBcnReportRsp->
3837 bcnRepBssInfo[i +
3838 lastSent].bcnReportFields.
3839 TargetTsf[0],
3840 pRoamInfo->pEseBcnReportRsp->
3841 bcnRepBssInfo[i +
3842 lastSent].bcnReportFields.
3843 TargetTsf[1],
3844 pRoamInfo->pEseBcnReportRsp->
3845 bcnRepBssInfo[i +
3846 lastSent].bcnReportFields.
3847 BcnInterval,
3848 pRoamInfo->pEseBcnReportRsp->
3849 bcnRepBssInfo[i +
3850 lastSent].bcnReportFields.
3851 CapabilityInfo,
3852 pRoamInfo->pEseBcnReportRsp->
3853 bcnRepBssInfo[i +
3854 lastSent].bcnReportFields.
3855 Bssid[0],
3856 pRoamInfo->pEseBcnReportRsp->
3857 bcnRepBssInfo[i +
3858 lastSent].bcnReportFields.
3859 Bssid[1],
3860 pRoamInfo->pEseBcnReportRsp->
3861 bcnRepBssInfo[i +
3862 lastSent].bcnReportFields.
3863 Bssid[2],
3864 pRoamInfo->pEseBcnReportRsp->
3865 bcnRepBssInfo[i +
3866 lastSent].bcnReportFields.
3867 Bssid[3],
3868 pRoamInfo->pEseBcnReportRsp->
3869 bcnRepBssInfo[i +
3870 lastSent].bcnReportFields.
3871 Bssid[4],
3872 pRoamInfo->pEseBcnReportRsp->
3873 bcnRepBssInfo[i +
3874 lastSent].bcnReportFields.
3875 Bssid[5]);
3876
3877 /* bcn report fields are copied */
3878 len =
3879 sizeof(pRoamInfo->pEseBcnReportRsp->
3880 bcnRepBssInfo[i +
3881 lastSent].
3882 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303883 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003884 (char *)&pRoamInfo->
3885 pEseBcnReportRsp->bcnRepBssInfo[i +
3886 lastSent].
3887 bcnReportFields, len);
3888 pos += len;
3889 freeBytes -= len;
3890
3891 /* Add 1 byte of ie len */
3892 len =
3893 pRoamInfo->pEseBcnReportRsp->
3894 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303895 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896 pos += sizeof(len);
3897 freeBytes -= sizeof(len);
3898
3899 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303900 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003901 (char *)pRoamInfo->
3902 pEseBcnReportRsp->bcnRepBssInfo[i +
3903 lastSent].
3904 pBuf, len);
3905 pos += len;
3906 freeBytes -= len;
3907 }
3908
3909 wrqu.data.pointer = buf;
3910 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3911
3912 /* send the event */
3913 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3914 buf);
3915 lastSent += sendBss;
3916 }
3917 }
3918}
3919
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003920#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921
3922/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303923 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3924 * @pHddStaCtx: Station Context
3925 *
3926 * API to check if the connection authentication type is 8021x_sha256.
3927 *
3928 * Return: bool
3929 */
3930#ifdef WLAN_FEATURE_11W
3931static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3932{
3933 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3934 pHddStaCtx->conn_info.authType;
3935}
3936#else
3937static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3938{
3939 return false;
3940}
3941#endif
3942
3943/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 * hdd_sme_roam_callback() - hdd sme roam callback
3945 * @pContext: pointer to adapter context
3946 * @pRoamInfo: pointer to roam info
3947 * @roamId: roam id
3948 * @roamStatus: roam status
3949 * @roamResult: roam result
3950 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303951 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003952 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303953QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003954hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3955 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3956{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303957 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003958 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3959 hdd_wext_state_t *pWextState = NULL;
3960 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303961 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003962 hdd_context_t *pHddCtx = NULL;
3963
3964 hddLog(LOG2,
3965 "CSR Callback: status= %d result= %d roamID=%d",
3966 roamStatus, roamResult, roamId);
3967
3968 /* Sanity check */
3969 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3970 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303971 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972 }
3973
3974 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3976
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303977 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303978 pAdapter->sessionId, roamStatus));
3979
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003980 switch (roamStatus) {
3981 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303982 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3983 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003984 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003985 break;
3986
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003987 /*
3988 * We did pre-auth,then we attempted a 11r or ese reassoc.
3989 * reassoc failed due to failure, timeout, reject from ap
3990 * in any case tell the OS, our carrier is off and mark
3991 * interface down.
3992 */
3993 case eCSR_ROAM_FT_REASSOC_FAILED:
3994 hddLog(LOGE,
3995 FL
3996 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3997 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303998 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003999 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4000 roamStatus, roamResult);
4001 /*
4002 * Check if Mcast/Bcast Filters are set, if yes
4003 * clear the filters here.
4004 */
4005 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4006 true) {
4007 (WLAN_HDD_GET_CTX(pAdapter))->
4008 hdd_mcastbcast_filter_set = false;
4009 }
4010 pHddStaCtx->ft_carrier_on = false;
4011 pHddStaCtx->hdd_ReassocScenario = false;
4012 hddLog(LOG1,
4013 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4014 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4015 break;
4016
4017 case eCSR_ROAM_FT_START:
4018 /*
4019 * When we roam for ESE and 11r, we dont want the OS to be
4020 * informed that the link is down. So mark the link ready for
4021 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4022 * be received. Where in we will not mark the link down
4023 * Also we want to stop tx at this point when we will be
4024 * doing disassoc at this time. This saves 30-60 msec
4025 * after reassoc.
4026 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004027 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004028 wlan_hdd_netif_queue_control(pAdapter,
4029 WLAN_NETIF_TX_DISABLE,
4030 WLAN_CONTROL_PATH);
4031 status = hdd_roam_deregister_sta(pAdapter,
4032 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304033 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304034 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004035 pHddStaCtx->ft_carrier_on = true;
4036 pHddStaCtx->hdd_ReassocScenario = true;
4037 hddLog(LOG1,
4038 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4039 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4040 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004041
4042 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043 /* notify apps that we can't pass traffic anymore */
4044 hddLog(LOG1, FL("Disabling queues"));
4045 wlan_hdd_netif_queue_control(pAdapter,
4046 WLAN_NETIF_TX_DISABLE,
4047 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004048 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 wlan_hdd_netif_queue_control(pAdapter,
4050 WLAN_NETIF_CARRIER_OFF,
4051 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004052 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004053 break;
4054 case eCSR_ROAM_LOSTLINK:
4055 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4056 hddLog(LOG2, "Roaming started due to connection lost");
4057 hddLog(LOG1, FL("Disabling queues"));
4058 wlan_hdd_netif_queue_control(pAdapter,
4059 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4060 WLAN_CONTROL_PATH);
4061 break;
4062 }
4063 case eCSR_ROAM_DISASSOCIATED:
4064 {
4065 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304066 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004067 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4068 roamStatus, roamResult);
4069 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4071 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4072 hdd_conf_mcastbcast_filter(pHddCtx, false);
4073
4074 if (true ==
4075 pHddCtx->sus_res_mcastbcast_filter_valid) {
4076 pHddCtx->configuredMcastBcastFilter =
4077 pHddCtx->sus_res_mcastbcast_filter;
4078 pHddCtx->
4079 sus_res_mcastbcast_filter_valid =
4080 false;
4081 }
4082
4083 hddLog(LOG1,
4084 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4085 hddLog(LOG1,
4086 "McastBcastFilter = %d",
4087 pHddCtx->configuredMcastBcastFilter);
4088 hddLog(LOG1,
4089 "offload: already called mcastbcast filter");
4090 (WLAN_HDD_GET_CTX(pAdapter))->
4091 hdd_mcastbcast_filter_set = false;
4092 }
4093 /* Call to clear any MC Addr List filter applied after
4094 * successful connection.
4095 */
4096 wlan_hdd_set_mc_addr_list(pAdapter, false);
4097 }
4098 break;
4099 case eCSR_ROAM_IBSS_LEAVE:
4100 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304101 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004102 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4103 roamStatus, roamResult);
4104 break;
4105 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4106 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4107 /*
4108 * To Do - address probable memory leak with WEP encryption upon
4109 * successful association.
4110 */
4111 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4112 /* Clear saved connection information in HDD */
4113 hdd_conn_remove_connect_info(
4114 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4115 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304116 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004117 hdd_association_completion_handler(pAdapter, pRoamInfo,
4118 roamId, roamStatus,
4119 roamResult);
4120#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4121 if (pRoamInfo)
4122 pRoamInfo->roamSynchInProgress = false;
4123#endif
4124 break;
4125 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304126 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004127 pRoamInfo,
4128 roamId,
4129 roamStatus,
4130 roamResult);
4131 break;
4132 case eCSR_ROAM_IBSS_IND:
4133 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4134 roamStatus, roamResult);
4135 break;
4136
4137 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304138 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004139 roam_roam_connect_status_update_handler(pAdapter,
4140 pRoamInfo,
4141 roamId,
4142 roamStatus,
4143 roamResult);
4144 break;
4145
4146 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304147 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004148 hdd_roam_mic_error_indication_handler(pAdapter,
4149 pRoamInfo,
4150 roamId,
4151 roamStatus,
4152 roamResult);
4153 break;
4154
4155 case eCSR_ROAM_SET_KEY_COMPLETE:
4156 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304157 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004158 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4159 roamId, roamStatus,
4160 roamResult);
4161 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4162 pHddStaCtx->hdd_ReassocScenario = false;
4163 hddLog(LOG1,
4164 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4165 pHddStaCtx->hdd_ReassocScenario,
4166 pAdapter->sessionId);
4167 }
4168 }
4169#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4170 if (pRoamInfo != NULL)
4171 pRoamInfo->roamSynchInProgress = false;
4172#endif
4173 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004174
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004175 case eCSR_ROAM_FT_RESPONSE:
4176 hdd_send_ft_event(pAdapter);
4177 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004178
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004179 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304180 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4181 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004182 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304183 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 wlan_hdd_cfg80211_pmksa_candidate_notify(
4185 pAdapter, pRoamInfo, 1, false);
4186 }
4187 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004188
4189#ifdef FEATURE_WLAN_LFR_METRICS
4190 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4191 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304192 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004193 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4194 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304195 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004196 }
4197 break;
4198 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4199 /*
4200 * This event will notify pre-auth completion in case of success
4201 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304202 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004203 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4204 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304205 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004206 }
4207 break;
4208 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4209 /*
4210 * This event will notify pre-auth completion incase of failure.
4211 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304212 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4214 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304215 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004216 }
4217 break;
4218 case eCSR_ROAM_HANDOVER_SUCCESS:
4219 /* This event is to notify handover success.
4220 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304221 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4223 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304224 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004225 }
4226 break;
4227#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228 case eCSR_ROAM_REMAIN_CHAN_READY:
4229 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4230 break;
4231 case eCSR_ROAM_SEND_ACTION_CNF:
4232 hdd_send_action_cnf(pAdapter,
4233 (roamResult ==
4234 eCSR_ROAM_RESULT_NONE) ? true : false);
4235 break;
4236#ifdef FEATURE_WLAN_TDLS
4237 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304238 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004239 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4240 roamId,
4241 roamStatus,
4242 roamResult);
4243 break;
4244 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4245 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4246 pRoamInfo->reasonCode);
4247 break;
4248#endif
4249#ifdef WLAN_FEATURE_11W
4250 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4251 hdd_indicate_unprot_mgmt_frame(pAdapter,
4252 pRoamInfo->nFrameLength,
4253 pRoamInfo->pbFrames,
4254 pRoamInfo->frameType);
4255 break;
4256#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004257#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004258 case eCSR_ROAM_TSM_IE_IND:
4259 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4260 pRoamInfo->tsmIe.state,
4261 pRoamInfo->tsmIe.msmt_interval);
4262 break;
4263
4264 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4265 {
4266 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4267 pHddStaCtx->conn_info.authType
4268 || eCSR_AUTH_TYPE_CCKM_RSN ==
4269 pHddStaCtx->conn_info.authType) {
4270 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4271 }
4272 break;
4273 }
4274
4275 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4276 {
4277 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4278 break;
4279 }
4280
4281 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4282 {
4283 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4284 break;
4285 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004286#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004287 default:
4288 break;
4289 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304290 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004291}
4292
4293/**
4294 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4295 * @auth_suite: auth suite
4296 *
4297 * Return: eCsrAuthType enumeration
4298 */
4299eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4300{
4301 eCsrAuthType auth_type;
4302 /* is the auth type supported? */
4303 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4304 auth_type = eCSR_AUTH_TYPE_RSN;
4305 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4306 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004307 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004308 /* Check for 11r FT Authentication with PSK */
4309 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4310 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4311 /* Check for 11R FT Authentication with 802.1X */
4312 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4313 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004314#ifdef FEATURE_WLAN_ESE
4315 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4316 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4317 } else
4318#endif /* FEATURE_WLAN_ESE */
4319#ifdef WLAN_FEATURE_11W
4320 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4321 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4322 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4323 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4324 } else
4325#endif
4326 {
4327 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4328 }
4329 return auth_type;
4330}
4331
4332/**
4333 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4334 * @auth_suite: auth suite
4335 *
4336 * Return: eCsrAuthType enumeration
4337 */
4338eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4339{
4340 eCsrAuthType auth_type;
4341 /* is the auth type supported? */
4342 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4343 auth_type = eCSR_AUTH_TYPE_WPA;
4344 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4345 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4346 } else
4347#ifdef FEATURE_WLAN_ESE
4348 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4349 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4350 } else
4351#endif /* FEATURE_WLAN_ESE */
4352 {
4353 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4354 }
4355 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4356 return auth_type;
4357}
4358
4359/**
4360 * hdd_translate_rsn_to_csr_encryption_type() -
4361 * Translate RSN to CSR encryption type
4362 * @cipher_suite: cipher suite
4363 *
4364 * Return: eCsrEncryptionType enumeration
4365 */
4366eCsrEncryptionType
4367hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4368{
4369 eCsrEncryptionType cipher_type;
4370
4371 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4372 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4373 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4374 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4375 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4376 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4377 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4378 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4379 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4380 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4381 else
4382 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4383
4384 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4385 return cipher_type;
4386}
4387
4388/**
4389 * hdd_translate_wpa_to_csr_encryption_type() -
4390 * Translate WPA to CSR encryption type
4391 * @cipher_suite: cipher suite
4392 *
4393 * Return: eCsrEncryptionType enumeration
4394 */
4395eCsrEncryptionType
4396hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4397{
4398 eCsrEncryptionType cipher_type;
4399
4400 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4401 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4402 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4403 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4404 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4405 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4406 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4407 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4408 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4409 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4410 else
4411 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4412
4413 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4414 return cipher_type;
4415}
4416
4417/**
4418 * hdd_process_genie() - process gen ie
4419 * @pAdapter: pointer to adapter
4420 * @bssid: pointer to mac address
4421 * @pEncryptType: pointer to encryption type
4422 * @mcEncryptType: pointer to multicast encryption type
4423 * @pAuthType: pointer to auth type
4424 *
4425 * Return: 0 on success, error number otherwise
4426 */
4427static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4428 u8 *bssid,
4429 eCsrEncryptionType *pEncryptType,
4430 eCsrEncryptionType *mcEncryptType,
4431 eCsrAuthType *pAuthType,
4432#ifdef WLAN_FEATURE_11W
4433 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4434#endif
4435 uint16_t gen_ie_len, uint8_t *gen_ie)
4436{
4437 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304438 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004439 tDot11fIERSN dot11RSNIE;
4440 tDot11fIEWPA dot11WPAIE;
4441 uint32_t i;
4442 uint8_t *pRsnIe;
4443 uint16_t RSNIeLen;
4444 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4445 bool updatePMKCache = false;
4446
4447 /*
4448 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4449 * setting present flag to 0.
4450 */
4451 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4452 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4453
4454 /* Type check */
4455 if (gen_ie[0] == DOT11F_EID_RSN) {
4456 /* Validity checks */
4457 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4458 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4459 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4460 gen_ie_len);
4461 return -EINVAL;
4462 }
4463 /* Skip past the EID byte and length byte */
4464 pRsnIe = gen_ie + 2;
4465 RSNIeLen = gen_ie_len - 2;
4466 /* Unpack the RSN IE */
4467 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4468 pRsnIe, RSNIeLen, &dot11RSNIE);
4469 /* Copy out the encryption and authentication types */
4470 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4471 dot11RSNIE.pwise_cipher_suite_count);
4472 hddLog(LOG1, FL("authentication suite count: %d"),
4473 dot11RSNIE.akm_suite_count);
4474 /*Here we have followed the apple base code,
4475 but probably I suspect we can do something different */
4476 /* dot11RSNIE.akm_suite_count */
4477 /* Just translate the FIRST one */
4478 *pAuthType =
4479 hdd_translate_rsn_to_csr_auth_type(
4480 dot11RSNIE.akm_suites[0]);
4481 /* dot11RSNIE.pwise_cipher_suite_count */
4482 *pEncryptType =
4483 hdd_translate_rsn_to_csr_encryption_type(
4484 dot11RSNIE.pwise_cipher_suites[0]);
4485 /* dot11RSNIE.gp_cipher_suite_count */
4486 *mcEncryptType =
4487 hdd_translate_rsn_to_csr_encryption_type(
4488 dot11RSNIE.gp_cipher_suite);
4489#ifdef WLAN_FEATURE_11W
4490 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4491 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4492#endif
4493 /* Set the PMKSA ID Cache for this interface */
4494 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4495 if (is_zero_ether_addr(bssid)) {
4496 hddLog(LOGE, FL("MAC address is all zeroes"));
4497 break;
4498 }
4499 updatePMKCache = true;
4500 /*
4501 * For right now, I assume setASSOCIATE() has passed
4502 * in the bssid.
4503 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304504 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304505 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304506 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004507 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4508 }
4509
4510 if (updatePMKCache) {
4511 /*
4512 * Calling csr_roam_set_pmkid_cache to configure the
4513 * PMKIDs into the cache.
4514 */
4515 hddLog(LOG1,
4516 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4517 i);
4518 /* Finally set the PMKSA ID Cache in CSR */
4519 result =
4520 sme_roam_set_pmkid_cache(halHandle,
4521 pAdapter->sessionId,
4522 PMKIDCache,
4523 dot11RSNIE.pmkid_count,
4524 false);
4525 }
4526 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4527 /* Validity checks */
4528 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4529 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4530 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4531 gen_ie_len);
4532 return -EINVAL;
4533 }
4534 /* Skip past the EID and length byte - and four byte WiFi OUI */
4535 pRsnIe = gen_ie + 2 + 4;
4536 RSNIeLen = gen_ie_len - (2 + 4);
4537 /* Unpack the WPA IE */
4538 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4539 pRsnIe, RSNIeLen, &dot11WPAIE);
4540 /* Copy out the encryption and authentication types */
4541 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4542 dot11WPAIE.unicast_cipher_count);
4543 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4544 dot11WPAIE.auth_suite_count);
4545 /* dot11WPAIE.auth_suite_count */
4546 /* Just translate the FIRST one */
4547 *pAuthType =
4548 hdd_translate_wpa_to_csr_auth_type(
4549 dot11WPAIE.auth_suites[0]);
4550 /* dot11WPAIE.unicast_cipher_count */
4551 *pEncryptType =
4552 hdd_translate_wpa_to_csr_encryption_type(
4553 dot11WPAIE.unicast_ciphers[0]);
4554 /* dot11WPAIE.unicast_cipher_count */
4555 *mcEncryptType =
4556 hdd_translate_wpa_to_csr_encryption_type(
4557 dot11WPAIE.multicast_cipher);
4558 } else {
4559 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4560 return -EINVAL;
4561 }
4562 return 0;
4563}
4564
4565/**
4566 * hdd_set_genie_to_csr() - set genie to csr
4567 * @pAdapter: pointer to adapter
4568 * @RSNAuthType: pointer to auth type
4569 *
4570 * Return: 0 on success, error number otherwise
4571 */
4572int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4573{
4574 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4575 uint32_t status = 0;
4576 eCsrEncryptionType RSNEncryptType;
4577 eCsrEncryptionType mcRSNEncryptType;
4578#ifdef WLAN_FEATURE_11W
4579 uint8_t RSNMfpRequired = 0;
4580 uint8_t RSNMfpCapable = 0;
4581#endif
4582 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4583 /* MAC address of assoc peer */
4584 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304585 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004586 pWextState->roamProfile.BSSIDs.bssid,
4587 sizeof(bssid));
4588 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4589 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4590 /* continue */
4591 } else {
4592 return 0;
4593 }
4594 /* The actual processing may eventually be more extensive than this. */
4595 /* Right now, just consume any PMKIDs that are sent in by the app. */
4596 status = hdd_process_genie(pAdapter, bssid,
4597 &RSNEncryptType,
4598 &mcRSNEncryptType, RSNAuthType,
4599#ifdef WLAN_FEATURE_11W
4600 &RSNMfpRequired, &RSNMfpCapable,
4601#endif
4602 pWextState->WPARSNIE[1] + 2,
4603 pWextState->WPARSNIE);
4604 if (status == 0) {
4605 /*
4606 * Now copy over all the security attributes
4607 * you have parsed out.
4608 */
4609 pWextState->roamProfile.EncryptionType.numEntries = 1;
4610 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4611
4612 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4613 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4614 mcRSNEncryptType;
4615
Krunal Sonibe766b02016-03-10 13:00:44 -08004616 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004617 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4618 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4619 /*
4620 * For wpa none supplicant sends the WPA IE with unicast
4621 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4622 * multicast cipher as either AES/TKIP based on group
4623 * cipher configuration mentioned in the
4624 * wpa_supplicant.conf.
4625 */
4626
4627 /* Set the unicast cipher same as multicast cipher */
4628 pWextState->roamProfile.EncryptionType.encryptionType[0]
4629 = mcRSNEncryptType;
4630 }
4631#ifdef WLAN_FEATURE_11W
4632 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4633 RSNMfpRequired, RSNMfpCapable);
4634 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4635 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4636#endif
4637 hddLog(LOG1,
4638 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4639 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4640 }
4641 return 0;
4642}
4643
4644/**
4645 * hdd_set_csr_auth_type() - set csr auth type
4646 * @pAdapter: pointer to adapter
4647 * @RSNAuthType: auth type
4648 *
4649 * Return: 0 on success, error number otherwise
4650 */
4651int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4652{
4653 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4654 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4655 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4656 ENTER();
4657
4658 pRoamProfile->AuthType.numEntries = 1;
4659 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4660 pHddStaCtx->conn_info.authType);
4661
4662 switch (pHddStaCtx->conn_info.authType) {
4663 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4664#ifdef FEATURE_WLAN_ESE
4665 case eCSR_AUTH_TYPE_CCKM_WPA:
4666 case eCSR_AUTH_TYPE_CCKM_RSN:
4667#endif
4668 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4669
4670 pRoamProfile->AuthType.authType[0] =
4671 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4672 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4673
4674#ifdef FEATURE_WLAN_ESE
4675 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4676 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4677 == IW_AUTH_KEY_MGMT_802_1X)) {
4678 hddLog(LOG1,
4679 FL("set authType to CCKM WPA. AKM also 802.1X."));
4680 pRoamProfile->AuthType.authType[0] =
4681 eCSR_AUTH_TYPE_CCKM_WPA;
4682 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4683 hddLog(LOG1,
4684 FL("Last chance to set authType to CCKM WPA."));
4685 pRoamProfile->AuthType.authType[0] =
4686 eCSR_AUTH_TYPE_CCKM_WPA;
4687 } else
4688#endif
4689 if ((pWextState->
4690 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4691 == IW_AUTH_KEY_MGMT_802_1X) {
4692 pRoamProfile->AuthType.authType[0] =
4693 eCSR_AUTH_TYPE_WPA;
4694 } else
4695 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4696 == IW_AUTH_KEY_MGMT_PSK) {
4697 pRoamProfile->AuthType.authType[0] =
4698 eCSR_AUTH_TYPE_WPA_PSK;
4699 } else {
4700 pRoamProfile->AuthType.authType[0] =
4701 eCSR_AUTH_TYPE_WPA_NONE;
4702 }
4703 }
4704 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4705#ifdef FEATURE_WLAN_ESE
4706 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4707 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4708 == IW_AUTH_KEY_MGMT_802_1X)) {
4709 hddLog(LOG1,
4710 FL("set authType to CCKM RSN. AKM also 802.1X."));
4711 pRoamProfile->AuthType.authType[0] =
4712 eCSR_AUTH_TYPE_CCKM_RSN;
4713 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4714 hddLog(LOG1,
4715 FL("Last chance to set authType to CCKM RSN."));
4716 pRoamProfile->AuthType.authType[0] =
4717 eCSR_AUTH_TYPE_CCKM_RSN;
4718 } else
4719#endif
4720
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004721 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4722 ((pWextState->
4723 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4724 == IW_AUTH_KEY_MGMT_802_1X)) {
4725 pRoamProfile->AuthType.authType[0] =
4726 eCSR_AUTH_TYPE_FT_RSN;
4727 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4728 &&
4729 ((pWextState->
4730 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4731 == IW_AUTH_KEY_MGMT_PSK)) {
4732 pRoamProfile->AuthType.authType[0] =
4733 eCSR_AUTH_TYPE_FT_RSN_PSK;
4734 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004735
4736#ifdef WLAN_FEATURE_11W
4737 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4738 pRoamProfile->AuthType.authType[0] =
4739 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4740 } else if (RSNAuthType ==
4741 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4742 pRoamProfile->AuthType.authType[0] =
4743 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4744 } else
4745#endif
4746
4747 if ((pWextState->
4748 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4749 == IW_AUTH_KEY_MGMT_802_1X) {
4750 pRoamProfile->AuthType.authType[0] =
4751 eCSR_AUTH_TYPE_RSN;
4752 } else
4753 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4754 == IW_AUTH_KEY_MGMT_PSK) {
4755 pRoamProfile->AuthType.authType[0] =
4756 eCSR_AUTH_TYPE_RSN_PSK;
4757 } else {
4758 pRoamProfile->AuthType.authType[0] =
4759 eCSR_AUTH_TYPE_UNKNOWN;
4760 }
4761 }
4762 break;
4763
4764 case eCSR_AUTH_TYPE_SHARED_KEY:
4765
4766 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4767 break;
4768 default:
4769
4770#ifdef FEATURE_WLAN_ESE
4771 hddLog(LOG1, FL("In default, unknown auth type."));
4772#endif /* FEATURE_WLAN_ESE */
4773 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4774 break;
4775 }
4776
4777 hddLog(LOG1, FL("Set roam Authtype to %d"),
4778 pWextState->roamProfile.AuthType.authType[0]);
4779
4780 EXIT();
4781 return 0;
4782}
4783
4784/**
4785 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4786 * to the CSR roam profile.
4787 *
4788 * @dev: Pointer to the net device.
4789 * @info: Pointer to the iw_request_info.
4790 * @wrqu: Pointer to the iwreq_data.
4791 * @extra: Pointer to the data.
4792 *
4793 * Return: 0 for success, error number on failure
4794 */
4795static int __iw_set_essid(struct net_device *dev,
4796 struct iw_request_info *info,
4797 union iwreq_data *wrqu, char *extra)
4798{
4799 unsigned long rc;
4800 uint32_t status = 0;
4801 hdd_wext_state_t *pWextState;
4802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4803 hdd_context_t *hdd_ctx;
4804 uint32_t roamId;
4805 tCsrRoamProfile *pRoamProfile;
4806 eMib_dot11DesiredBssType connectedBssType;
4807 eCsrAuthType RSNAuthType;
4808 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4810 int ret;
4811
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004812 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004813
4814 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4815 ret = wlan_hdd_validate_context(hdd_ctx);
4816 if (0 != ret)
4817 return ret;
4818
Krunal Sonibe766b02016-03-10 13:00:44 -08004819 if (pAdapter->device_mode != QDF_STA_MODE &&
4820 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004821 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4822 hdd_device_mode_to_string(pAdapter->device_mode),
4823 pAdapter->device_mode);
4824 return -EINVAL;
4825 }
4826
4827 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4828
4829 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4830 hddLog(LOG2, FL("Counter measure is in progress"));
4831 return -EBUSY;
4832 }
4833 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4834 return -EINVAL;
4835
4836 pRoamProfile = &pWextState->roamProfile;
4837 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4838 (eMib_dot11DesiredBssType_independent ==
4839 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304840 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004841
4842 /* Need to issue a disconnect to CSR. */
4843 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304844 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4846
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304847 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848 rc = wait_for_completion_timeout(&pAdapter->
4849 disconnect_comp_var,
4850 msecs_to_jiffies
4851 (WLAN_WAIT_TIME_DISCONNECT));
4852 if (!rc)
4853 hddLog(LOGE, FL("Disconnect event timed out"));
4854 }
4855 }
4856
4857 /*
4858 * when cfg80211 defined, wpa_supplicant wext driver uses
4859 * zero-length, null-string ssid for force disconnection.
4860 * after disconnection (if previously connected) and cleaning ssid,
4861 * driver MUST return success.
4862 */
4863 if (0 == wrqu->essid.length)
4864 return 0;
4865
4866 status = hdd_wmm_get_uapsd_mask(pAdapter,
4867 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304868 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004869 pWextState->roamProfile.uapsd_mask = 0;
4870
4871 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4872
4873 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4874 wrqu->essid.length;
4875
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304876 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004877 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304878 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004879 ssId), extra, wrqu->essid.length);
4880 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4881 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4882
4883 /* set gen ie */
4884 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4885
4886 /* set auth */
4887 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4888 }
4889#ifdef FEATURE_WLAN_WAPI
4890 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4891 if (pAdapter->wapi_info.nWapiMode) {
4892 switch (pAdapter->wapi_info.wapiAuthMode) {
4893 case WAPI_AUTH_MODE_PSK:
4894 {
4895 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4896 pAdapter->wapi_info.wapiAuthMode);
4897 pRoamProfile->AuthType.numEntries = 1;
4898 pRoamProfile->AuthType.authType[0] =
4899 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4900 break;
4901 }
4902 case WAPI_AUTH_MODE_CERT:
4903 {
4904 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4905 pAdapter->wapi_info.wapiAuthMode);
4906 pRoamProfile->AuthType.numEntries = 1;
4907 pRoamProfile->AuthType.authType[0] =
4908 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4909 break;
4910 }
4911 } /* End of switch */
4912 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4913 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4914 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4915 pRoamProfile->EncryptionType.numEntries = 1;
4916 pRoamProfile->EncryptionType.encryptionType[0] =
4917 eCSR_ENCRYPT_TYPE_WPI;
4918 pRoamProfile->mcEncryptionType.numEntries = 1;
4919 pRoamProfile->mcEncryptionType.encryptionType[0] =
4920 eCSR_ENCRYPT_TYPE_WPI;
4921 }
4922 }
4923#endif /* FEATURE_WLAN_WAPI */
4924 /* if previous genIE is not NULL, update AssocIE */
4925 if (0 != pWextState->genIE.length) {
4926 memset(&pWextState->assocAddIE, 0,
4927 sizeof(pWextState->assocAddIE));
4928 memcpy(pWextState->assocAddIE.addIEdata,
4929 pWextState->genIE.addIEdata, pWextState->genIE.length);
4930 pWextState->assocAddIE.length = pWextState->genIE.length;
4931 pWextState->roamProfile.pAddIEAssoc =
4932 pWextState->assocAddIE.addIEdata;
4933 pWextState->roamProfile.nAddIEAssocLength =
4934 pWextState->assocAddIE.length;
4935
4936 /* clear previous genIE after use it */
4937 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4938 }
4939
4940 /*
4941 * Assumes it is not WPS Association by default, except when
4942 * pAddIEAssoc has WPS IE.
4943 */
4944 pWextState->roamProfile.bWPSAssociation = false;
4945
4946 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4947 pWextState->roamProfile.
4948 nAddIEAssocLength))
4949 pWextState->roamProfile.bWPSAssociation = true;
4950
4951 /* Disable auto BMPS entry by PMC until DHCP is done */
4952 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4953 true);
4954
4955 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4956
4957 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4958 hdd_select_cbmode(pAdapter,
4959 (WLAN_HDD_GET_CTX(pAdapter))->config->
4960 AdHocChannel5G);
4961 }
4962 status = sme_roam_connect(hHal, pAdapter->sessionId,
4963 &(pWextState->roamProfile), &roamId);
4964 pRoamProfile->ChannelInfo.ChannelList = NULL;
4965 pRoamProfile->ChannelInfo.numOfChannels = 0;
4966
4967 EXIT();
4968 return status;
4969}
4970
4971/**
4972 * iw_set_essid() - set essid handler function
4973 * @dev: Pointer to the net device.
4974 * @info: Pointer to the iw_request_info.
4975 * @wrqu: Pointer to the iwreq_data.
4976 * @extra: Pointer to the data.
4977 *
4978 * Return: 0 for success, error number on failure
4979 */
4980int iw_set_essid(struct net_device *dev,
4981 struct iw_request_info *info,
4982 union iwreq_data *wrqu, char *extra)
4983{
4984 int ret;
4985
4986 cds_ssr_protect(__func__);
4987 ret = __iw_set_essid(dev, info, wrqu, extra);
4988 cds_ssr_unprotect(__func__);
4989
4990 return ret;
4991}
4992
4993/**
4994 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4995 * @dev: pointer to the net device
4996 * @info: pointer to the iw request info
4997 * @dwrq: pointer to iw_point
4998 * @extra: pointer to the data
4999 *
5000 * Return: 0 on success, error number otherwise
5001 */
5002static int __iw_get_essid(struct net_device *dev,
5003 struct iw_request_info *info,
5004 struct iw_point *dwrq, char *extra)
5005{
5006 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5007 hdd_context_t *hdd_ctx;
5008 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5009 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5010 int ret;
5011
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005012 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005013
5014 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5015 ret = wlan_hdd_validate_context(hdd_ctx);
5016 if (0 != ret)
5017 return ret;
5018
5019 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5020 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5021 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5022 || pHddStaCtx->conn_info.connState ==
5023 eConnectionState_IbssDisconnected)
5024 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5025 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5026 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5027 dwrq->length);
5028 dwrq->flags = 1;
5029 } else {
5030 memset(extra, 0, dwrq->length);
5031 dwrq->length = 0;
5032 dwrq->flags = 0;
5033 }
5034 EXIT();
5035 return 0;
5036}
5037
5038/**
5039 * iw_get_essid() - get essid handler function
5040 * @dev: Pointer to the net device.
5041 * @info: Pointer to the iw_request_info.
5042 * @wrqu: Pointer to the iwreq_data.
5043 * @extra: Pointer to the data.
5044 *
5045 * Return: 0 for success, error number on failure
5046 */
5047int iw_get_essid(struct net_device *dev,
5048 struct iw_request_info *info,
5049 struct iw_point *wrqu, char *extra)
5050{
5051 int ret;
5052
5053 cds_ssr_protect(__func__);
5054 ret = __iw_get_essid(dev, info, wrqu, extra);
5055 cds_ssr_unprotect(__func__);
5056
5057 return ret;
5058}
5059
5060/**
5061 * __iw_set_auth() -
5062 * This function sets the auth type received from the wpa_supplicant
5063 * @dev: pointer to the net device
5064 * @info: pointer to the iw request info
5065 * @wrqu: pointer to iwreq_data
5066 * @extra: pointer to the data
5067 *
5068 * Return: 0 on success, error number otherwise
5069 */
5070static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5071 union iwreq_data *wrqu, char *extra)
5072{
5073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5074 hdd_context_t *hdd_ctx;
5075 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5076 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5077 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5078 eCsrEncryptionType mcEncryptionType;
5079 eCsrEncryptionType ucEncryptionType;
5080 int ret;
5081
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005082 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005083
5084 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5085 ret = wlan_hdd_validate_context(hdd_ctx);
5086 if (0 != ret)
5087 return ret;
5088
5089 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5090 case IW_AUTH_WPA_VERSION:
5091 pWextState->wpaVersion = wrqu->param.value;
5092 break;
5093
5094 case IW_AUTH_CIPHER_PAIRWISE:
5095 {
5096 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5097 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5098 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5099 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5100 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5101 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5102 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5103 if ((IW_AUTH_KEY_MGMT_802_1X
5104 ==
5105 (pWextState->
5106 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5107 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5108 pHddStaCtx->conn_info.authType))
5109 /*Dynamic WEP key */
5110 ucEncryptionType =
5111 eCSR_ENCRYPT_TYPE_WEP40;
5112 else
5113 /*Static WEP key */
5114 ucEncryptionType =
5115 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5116 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5117 if ((IW_AUTH_KEY_MGMT_802_1X
5118 ==
5119 (pWextState->
5120 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5121 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5122 pHddStaCtx->conn_info.authType))
5123 /*Dynamic WEP key */
5124 ucEncryptionType =
5125 eCSR_ENCRYPT_TYPE_WEP104;
5126 else
5127 /*Static WEP key */
5128 ucEncryptionType =
5129 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5130 } else {
5131 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5132 wrqu->param.value);
5133 return -EINVAL;
5134 }
5135
5136 pRoamProfile->EncryptionType.numEntries = 1;
5137 pRoamProfile->EncryptionType.encryptionType[0] =
5138 ucEncryptionType;
5139 }
5140 break;
5141 case IW_AUTH_CIPHER_GROUP:
5142 {
5143 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5144 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5145 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5146 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5147 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5148 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5149 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5150 if ((IW_AUTH_KEY_MGMT_802_1X
5151 ==
5152 (pWextState->
5153 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5154 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5155 pHddStaCtx->conn_info.authType))
5156 mcEncryptionType =
5157 eCSR_ENCRYPT_TYPE_WEP40;
5158 else
5159 mcEncryptionType =
5160 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5161 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5162 /* Dynamic WEP keys won't work with shared keys */
5163 if ((IW_AUTH_KEY_MGMT_802_1X
5164 ==
5165 (pWextState->
5166 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5167 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5168 pHddStaCtx->conn_info.authType)) {
5169 mcEncryptionType =
5170 eCSR_ENCRYPT_TYPE_WEP104;
5171 } else {
5172 mcEncryptionType =
5173 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5174 }
5175 } else {
5176 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5177 wrqu->param.value);
5178 return -EINVAL;
5179 }
5180
5181 pRoamProfile->mcEncryptionType.numEntries = 1;
5182 pRoamProfile->mcEncryptionType.encryptionType[0] =
5183 mcEncryptionType;
5184 }
5185 break;
5186
5187 case IW_AUTH_80211_AUTH_ALG:
5188 {
5189 /* Save the auth algo here and set auth type to SME Roam profile
5190 in the iw_set_ap_address */
5191 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5192 pHddStaCtx->conn_info.authType =
5193 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5194
5195 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5196 pHddStaCtx->conn_info.authType =
5197 eCSR_AUTH_TYPE_SHARED_KEY;
5198
5199 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5200 /*Not supported */
5201 pHddStaCtx->conn_info.authType =
5202 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5203 pWextState->roamProfile.AuthType.authType[0] =
5204 pHddStaCtx->conn_info.authType;
5205 }
5206 break;
5207
5208 case IW_AUTH_KEY_MGMT:
5209 {
5210#ifdef FEATURE_WLAN_ESE
5211#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5212 /*Check for CCKM AKM type */
5213 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5214 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5215 /* Set the CCKM bit in authKeyMgmt */
5216 /*
5217 * Right now, this breaks all ref to authKeyMgmt because
5218 * our code doesn't realize it is a "bitfield"
5219 */
5220 pWextState->authKeyMgmt |=
5221 IW_AUTH_KEY_MGMT_CCKM;
5222 /* Set the key management to 802.1X */
5223 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5224 pWextState->isESEConnection = true;
5225 /*
5226 * This is test code. I need to actually KNOW whether
5227 * this is an RSN Assoc or WPA.
5228 */
5229 pWextState->collectedAuthType =
5230 eCSR_AUTH_TYPE_CCKM_RSN;
5231 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5232 /* Save the key management */
5233 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5234 pWextState->collectedAuthType =
5235 eCSR_AUTH_TYPE_RSN;
5236 } else
5237 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5238 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5239 /* Save the key management anyway */
5240 pWextState->authKeyMgmt = wrqu->param.value;
5241 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5242 /* Save the key management */
5243 pWextState->authKeyMgmt |=
5244 IW_AUTH_KEY_MGMT_802_1X;
5245 pWextState->collectedAuthType =
5246 eCSR_AUTH_TYPE_RSN;
5247 }
5248#else
5249 /* Save the key management */
5250 pWextState->authKeyMgmt = wrqu->param.value;
5251#endif /* FEATURE_WLAN_ESE */
5252 }
5253 break;
5254
5255 case IW_AUTH_TKIP_COUNTERMEASURES:
5256 {
5257 if (wrqu->param.value) {
5258 hddLog(LOG2,
5259 "Counter Measure started %d",
5260 wrqu->param.value);
5261 pWextState->mTKIPCounterMeasures =
5262 TKIP_COUNTER_MEASURE_STARTED;
5263 } else {
5264 hddLog(LOG2,
5265 "Counter Measure stopped=%d",
5266 wrqu->param.value);
5267 pWextState->mTKIPCounterMeasures =
5268 TKIP_COUNTER_MEASURE_STOPED;
5269 }
5270 }
5271 break;
5272 case IW_AUTH_DROP_UNENCRYPTED:
5273 case IW_AUTH_WPA_ENABLED:
5274 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5275 case IW_AUTH_ROAMING_CONTROL:
5276 case IW_AUTH_PRIVACY_INVOKED:
5277
5278 default:
5279
5280 hddLog(LOGW, FL("called with unsupported auth type %d"),
5281 wrqu->param.flags & IW_AUTH_INDEX);
5282 break;
5283 }
5284
5285 EXIT();
5286 return 0;
5287}
5288
5289/**
5290 * iw_set_auth() - set auth callback function
5291 * @dev: Pointer to the net device.
5292 * @info: Pointer to the iw_request_info.
5293 * @wrqu: Pointer to the iwreq_data.
5294 * @extra: Pointer to the data.
5295 *
5296 * Return: 0 for success, error number on failure.
5297 */
5298int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5299 union iwreq_data *wrqu, char *extra)
5300{
5301 int ret;
5302
5303 cds_ssr_protect(__func__);
5304 ret = __iw_set_auth(dev, info, wrqu, extra);
5305 cds_ssr_unprotect(__func__);
5306
5307 return ret;
5308}
5309
5310/**
5311 * __iw_get_auth() -
5312 * This function returns the auth type to the wpa_supplicant
5313 * @dev: pointer to the net device
5314 * @info: pointer to the iw request info
5315 * @wrqu: pointer to iwreq_data
5316 * @extra: pointer to the data
5317 *
5318 * Return: 0 on success, error number otherwise
5319 */
5320static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5321 union iwreq_data *wrqu, char *extra)
5322{
5323 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5324 hdd_context_t *hdd_ctx;
5325 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5326 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5327 int ret;
5328
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005329 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005330
5331 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5332 ret = wlan_hdd_validate_context(hdd_ctx);
5333 if (0 != ret)
5334 return ret;
5335
5336 switch (pRoamProfile->negotiatedAuthType) {
5337 case eCSR_AUTH_TYPE_WPA_NONE:
5338 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5339 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5340 break;
5341 case eCSR_AUTH_TYPE_WPA:
5342 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5343 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5344 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005345
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005346 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005347 case eCSR_AUTH_TYPE_RSN:
5348 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5349 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5350 break;
5351 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5352 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5353 break;
5354 case eCSR_AUTH_TYPE_SHARED_KEY:
5355 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5356 break;
5357 case eCSR_AUTH_TYPE_UNKNOWN:
5358 hddLog(LOG1, FL("called with unknown auth type"));
5359 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5360 break;
5361 case eCSR_AUTH_TYPE_AUTOSWITCH:
5362 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5363 break;
5364 case eCSR_AUTH_TYPE_WPA_PSK:
5365 hddLog(LOG1, FL("called with WPA PSK auth type"));
5366 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5367 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005368
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005369 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005370 case eCSR_AUTH_TYPE_RSN_PSK:
5371#ifdef WLAN_FEATURE_11W
5372 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5373 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5374#endif
5375 hddLog(LOG1, FL("called with RSN PSK auth type"));
5376 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5377 return -EIO;
5378 default:
5379 hddLog(LOGE, FL("called with unknown auth type"));
5380 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5381 return -EIO;
5382 }
5383 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5384 switch (pRoamProfile->negotiatedUCEncryptionType) {
5385 case eCSR_ENCRYPT_TYPE_NONE:
5386 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5387 break;
5388 case eCSR_ENCRYPT_TYPE_WEP40:
5389 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5390 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5391 break;
5392 case eCSR_ENCRYPT_TYPE_TKIP:
5393 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5394 break;
5395 case eCSR_ENCRYPT_TYPE_WEP104:
5396 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5397 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5398 break;
5399 case eCSR_ENCRYPT_TYPE_AES:
5400 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5401 break;
5402 default:
5403 hddLog(LOG1, FL("called with unknown auth type %d"),
5404 pRoamProfile->negotiatedUCEncryptionType);
5405 return -EIO;
5406 }
5407 }
5408
5409 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5410 switch (pRoamProfile->negotiatedMCEncryptionType) {
5411 case eCSR_ENCRYPT_TYPE_NONE:
5412 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5413 break;
5414 case eCSR_ENCRYPT_TYPE_WEP40:
5415 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5416 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5417 break;
5418 case eCSR_ENCRYPT_TYPE_TKIP:
5419 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5420 break;
5421 case eCSR_ENCRYPT_TYPE_WEP104:
5422 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5423 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5424 break;
5425 case eCSR_ENCRYPT_TYPE_AES:
5426 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5427 break;
5428 default:
5429 hddLog(LOG1, FL("called with unknown auth type %d"),
5430 pRoamProfile->negotiatedMCEncryptionType);
5431 return -EIO;
5432 }
5433 }
5434
5435 hddLog(LOG1, FL("called with auth type %d"),
5436 pRoamProfile->AuthType.authType[0]);
5437 EXIT();
5438 return 0;
5439}
5440
5441/**
5442 * iw_get_auth() - get auth callback function
5443 * @dev: Pointer to the net device.
5444 * @info: Pointer to the iw_request_info.
5445 * @wrqu: Pointer to the iwreq_data.
5446 * @extra: Pointer to the data.
5447 *
5448 * Return: 0 for success, error number on failure.
5449 */
5450int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5451 union iwreq_data *wrqu, char *extra)
5452{
5453 int ret;
5454
5455 cds_ssr_protect(__func__);
5456 ret = __iw_get_auth(dev, info, wrqu, extra);
5457 cds_ssr_unprotect(__func__);
5458
5459 return ret;
5460}
5461
5462/**
5463 * __iw_set_ap_address() - set ap address
5464 * @dev: pointer to the net device
5465 * @info: pointer to the iw request info
5466 * @wrqu: pointer to iwreq_data
5467 * @extra: pointer to the data
5468 *
5469 * This function updates the HDD global station context connection info
5470 * BSSID with the MAC address received from the wpa_supplicant.
5471 *
5472 * Return: 0 on success, error number otherwise
5473 */
5474static int __iw_set_ap_address(struct net_device *dev,
5475 struct iw_request_info *info,
5476 union iwreq_data *wrqu, char *extra)
5477{
5478
5479 hdd_adapter_t *adapter;
5480 hdd_context_t *hdd_ctx;
5481 hdd_station_ctx_t *pHddStaCtx =
5482 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5483 uint8_t *pMacAddress = NULL;
5484 int ret;
5485
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005486 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005487
5488 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5489
5490 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5491 ret = wlan_hdd_validate_context(hdd_ctx);
5492 if (0 != ret)
5493 return ret;
5494
5495 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5496 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305497 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305498 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005499 EXIT();
5500
5501 return 0;
5502}
5503
5504/**
5505 * iw_set_ap_address() - set ap addresses callback function
5506 * @dev: Pointer to the net device.
5507 * @info: Pointer to the iw_request_info.
5508 * @wrqu: Pointer to the iwreq_data.
5509 * @extra: Pointer to the data.
5510 *
5511 * Return: 0 for success, error number on failure.
5512 */
5513int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5514 union iwreq_data *wrqu, char *extra)
5515{
5516 int ret;
5517
5518 cds_ssr_protect(__func__);
5519 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5520 cds_ssr_unprotect(__func__);
5521
5522 return ret;
5523}
5524
5525/**
5526 * __iw_get_ap_address() - get ap address
5527 * @dev: pointer to the net device
5528 * @info: pointer to the iw request info
5529 * @wrqu: pointer to iwreq_data
5530 * @extra: pointer to the data
5531 *
5532 * This function returns currently associated BSSID.
5533 *
5534 * Return: 0 on success, error number otherwise
5535 */
5536static int __iw_get_ap_address(struct net_device *dev,
5537 struct iw_request_info *info,
5538 union iwreq_data *wrqu, char *extra)
5539{
5540 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5541 hdd_context_t *hdd_ctx;
5542 hdd_station_ctx_t *pHddStaCtx =
5543 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5544 int ret;
5545
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005546 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005547
5548 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5549 ret = wlan_hdd_validate_context(hdd_ctx);
5550 if (0 != ret)
5551 return ret;
5552
5553 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5554 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305555 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005556 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305557 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005558 } else {
5559 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5560 }
5561 EXIT();
5562 return 0;
5563}
5564
5565/**
5566 * iw_get_ap_address() - get ap addresses callback function
5567 * @dev: Pointer to the net device.
5568 * @info: Pointer to the iw_request_info.
5569 * @wrqu: Pointer to the iwreq_data.
5570 * @extra: Pointer to the data.
5571 *
5572 * Return: 0 for success, error number on failure.
5573 */
5574int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5575 union iwreq_data *wrqu, char *extra)
5576{
5577 int ret;
5578
5579 cds_ssr_protect(__func__);
5580 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5581 cds_ssr_unprotect(__func__);
5582
5583 return ret;
5584}