blob: 39bb930d45806ab82bb7ad7df031d7ceb244e7a5 [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>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070053#include "wlan_hdd_lpass.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include <cds_sched.h>
55#include "cds_concurrency.h"
56#include "sme_power_save_api.h"
57#include "ol_txrx_ctrl_api.h"
58#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080059#include "ol_txrx.h"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053060#include "ol_rx_fwd.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080061#include "cdp_txrx_flow_ctrl_legacy.h"
62#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64/* These are needed to recognize WPA and RSN suite types */
65#define HDD_WPA_OUI_SIZE 4
66#define HDD_RSN_OUI_SIZE 4
67uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
68uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
69uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
70uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
71uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
72uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
73
74#ifdef FEATURE_WLAN_ESE
75/* CCKM */
76uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
77/* CCKM */
78uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
79#endif /* FEATURE_WLAN_ESE */
80
81/* group cipher */
82uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
83
84/* WEP-40 or RSN */
85uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
86
87/* TKIP or RSN-PSK */
88uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
89
90/* Reserved */
91uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
92
93/* AES-CCMP */
94uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
95
96/* WEP-104 */
97uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
98
99#ifdef WLAN_FEATURE_11W
100/* RSN-PSK-SHA256 */
101uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
102
103/* RSN-8021X-SHA256 */
104uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
105#endif
106
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107/* Offset where the EID-Len-IE, start. */
108#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
109#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110
111#define BEACON_FRAME_IES_OFFSET 12
112#define HDD_PEER_AUTHORIZE_WAIT 10
113
114/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700115 * beacon_filter_table - table of IEs used for beacon filtering
116 */
117static const int beacon_filter_table[] = {
118 SIR_MAC_DS_PARAM_SET_EID,
119 SIR_MAC_ERP_INFO_EID,
120 SIR_MAC_EDCA_PARAM_SET_EID,
121 SIR_MAC_QOS_CAPABILITY_EID,
122 SIR_MAC_HT_INFO_EID,
123 SIR_MAC_VHT_OPMODE_EID,
124 SIR_MAC_VHT_OPERATION_EID,
125};
126
127/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128 * hdd_conn_set_authenticated() - set authentication state
129 * @pAdapter: pointer to the adapter
130 * @authState: authentication state
131 *
132 * This function updates the global HDD station context
133 * authentication state.
134 *
135 * Return: none
136 */
137static void
138hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
139{
140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
142
143 /* save the new connection state */
144 hddLog(LOG1,
145 FL("Authenticated state Changed from oldState:%d to State:%d"),
146 pHddStaCtx->conn_info.uIsAuthenticated, authState);
147 pHddStaCtx->conn_info.uIsAuthenticated = authState;
148
149 /* Check is pending ROC request or not when auth state changed */
150 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
151}
152
153/**
154 * hdd_conn_set_connection_state() - set connection state
155 * @pAdapter: pointer to the adapter
156 * @connState: connection state
157 *
158 * This function updates the global HDD station context connection state.
159 *
160 * Return: none
161 */
162void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
163 eConnectionState connState)
164{
165 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
166 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
167
168 /* save the new connection state */
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530169 hdd_info("%pS Changed connectionState Changed from oldState:%d to State:%d",
170 (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
171 connState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 pHddStaCtx->conn_info.connState = connState;
173
174 /* Check is pending ROC request or not when connection state changed */
175 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
176}
177
178/**
179 * hdd_conn_get_connection_state() - get connection state
180 * @pAdapter: pointer to the adapter
181 * @pConnState: pointer to connection state
182 *
183 * This function updates the global HDD station context connection state.
184 *
185 * Return: true if (Infra Associated or IBSS Connected)
186 * and sets output parameter pConnState;
187 * false otherwise
188 */
189static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
190 eConnectionState *pConnState)
191{
192 bool fConnected = false;
193 eConnectionState connState;
194
195 /* get the connection state. */
196 connState = pHddStaCtx->conn_info.connState;
197
198 if (eConnectionState_Associated == connState ||
199 eConnectionState_IbssConnected == connState ||
200 eConnectionState_IbssDisconnected == connState) {
201 fConnected = true;
202 }
203
204 if (pConnState)
205 *pConnState = connState;
206
207 return fConnected;
208}
209
210/**
211 * hdd_is_connecting() - Function to check connection progress
212 * @hdd_sta_ctx: pointer to global HDD Station context
213 *
214 * Return: true if connecting, false otherwise
215 */
216bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
217{
218 return hdd_sta_ctx->conn_info.connState ==
219 eConnectionState_Connecting;
220}
221
222/**
223 * hdd_conn_is_connected() - Function to check connection status
224 * @pHddStaCtx: pointer to global HDD Station context
225 *
226 * Return: false if any errors encountered, true otherwise
227 */
228bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
229{
230 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
231}
232
233/**
234 * hdd_conn_get_connected_band() - get current connection radio band
235 * @pHddStaCtx: pointer to global HDD Station context
236 *
237 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
238 * eCSR_BAND_ALL if not connected
239 */
240eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
241{
242 uint8_t staChannel = 0;
243
244 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
245 staChannel = pHddStaCtx->conn_info.operationChannel;
246
247 if (staChannel > 0 && staChannel < 14)
248 return eCSR_BAND_24;
249 else if (staChannel >= 36 && staChannel <= 184)
250 return eCSR_BAND_5G;
251 else /* If station is not connected return as eCSR_BAND_ALL */
252 return eCSR_BAND_ALL;
253}
254
255/**
256 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
257 * @pHddStaCtx: pointer to global HDD Station context
258 * @pConnectedCipherAlgo: pointer to connected cipher algo
259 *
260 * Return: false if any errors encountered, true otherwise
261 */
262static inline bool
263hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
264 eCsrEncryptionType *pConnectedCipherAlgo)
265{
266 bool fConnected = false;
267
268 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
269
270 if (pConnectedCipherAlgo)
271 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
272
273 return fConnected;
274}
275
276/**
277 * hdd_conn_get_connected_bss_type() - get current bss type
278 * @pHddStaCtx: pointer to global HDD Station context
279 * @pConnectedBssType: pointer to connected bss type
280 *
281 * Return: false if any errors encountered, true otherwise
282 */
283inline bool
284hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
285 eMib_dot11DesiredBssType *pConnectedBssType)
286{
287 bool fConnected = false;
288
289 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
290
291 if (pConnectedBssType) {
292 *pConnectedBssType =
293 pHddStaCtx->conn_info.connDot11DesiredBssType;
294 }
295
296 return fConnected;
297}
298
299/**
300 * hdd_conn_save_connected_bss_type() - set connected bss type
301 * @pHddStaCtx: pointer to global HDD Station context
302 * @csr_roamBssType: bss type
303 *
304 * Return: none
305 */
306static inline void
307hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
308 eCsrRoamBssType csr_roamBssType)
309{
310 switch (csr_roamBssType) {
311 case eCSR_BSS_TYPE_INFRASTRUCTURE:
312 pHddStaCtx->conn_info.connDot11DesiredBssType =
313 eMib_dot11DesiredBssType_infrastructure;
314 break;
315
316 case eCSR_BSS_TYPE_IBSS:
317 case eCSR_BSS_TYPE_START_IBSS:
318 pHddStaCtx->conn_info.connDot11DesiredBssType =
319 eMib_dot11DesiredBssType_independent;
320 break;
321
322 /** We will never set the BssType to 'any' when attempting a connection
323 so CSR should never send this back to us.*/
324 case eCSR_BSS_TYPE_ANY:
325 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530326 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 break;
328 }
329}
330
331/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700332 * hdd_remove_beacon_filter() - remove beacon filter
333 * @adapter: Pointer to the hdd adapter
334 *
335 * Return: 0 on success and errno on failure
336 */
337static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
338{
339 QDF_STATUS status;
340 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
341
342 status = sme_remove_beacon_filter(hdd_ctx->hHal,
343 adapter->sessionId);
344 if (!QDF_IS_STATUS_SUCCESS(status)) {
345 hdd_err("sme_remove_beacon_filter() failed");
346 return -EFAULT;
347 }
348
349 return 0;
350}
351
352/**
353 * hdd_add_beacon_filter() - add beacon filter
354 * @adapter: Pointer to the hdd adapter
355 *
356 * Return: 0 on success and errno on failure
357 */
358static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
359{
360 int i;
361 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
362 QDF_STATUS status;
363 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
364
365 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
366 qdf_set_bit((beacon_filter_table[i] - 1),
367 (unsigned long int *)ie_map);
368
369 status = sme_add_beacon_filter(hdd_ctx->hHal,
370 adapter->sessionId, ie_map);
371 if (!QDF_IS_STATUS_SUCCESS(status)) {
372 hdd_err("sme_add_beacon_filter() failed");
373 return -EFAULT;
374 }
375 return 0;
376}
377
378/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 * hdd_conn_save_connect_info() - save current connection information
380 * @pAdapter: pointer to adapter
381 * @pRoamInfo: pointer to roam info
382 * @eBssType: bss type
383 *
384 * Return: none
385 */
386static void
387hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
388 eCsrRoamBssType eBssType)
389{
390 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
391 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
392
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530393 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394
395 if (pRoamInfo) {
396 /* Save the BSSID for the connection */
397 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530398 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530399 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 &pRoamInfo->bssid);
401
402 /*
403 * Save the Station ID for this station from
404 * the 'Roam Info'. For IBSS mode, staId is
405 * assigned in NEW_PEER_IND. For reassoc,
406 * the staID doesn't change and it may be invalid
407 * in this structure so no change here.
408 */
409 if (!pRoamInfo->fReassocReq) {
410 pHddStaCtx->conn_info.staId[0] =
411 pRoamInfo->staId;
412 }
413 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530414 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 &pRoamInfo->bssid);
416 } else {
417 /*
418 * can't happen. We need a valid IBSS or Infra setting
419 * in the BSSDescription or we can't function.
420 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530421 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 }
423
424 /* notify WMM */
425 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
426
427 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530428 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 } else {
430 /* Get Multicast Encryption Type */
431 encryptType =
432 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
433 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
434 /* Get Unicast Encryption Type */
435 encryptType =
436 pRoamInfo->u.pConnectedProfile->EncryptionType;
437 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
438
439 pHddStaCtx->conn_info.authType =
440 pRoamInfo->u.pConnectedProfile->AuthType;
441
442 pHddStaCtx->conn_info.operationChannel =
443 pRoamInfo->u.pConnectedProfile->operationChannel;
444
445 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530446 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 &pRoamInfo->u.pConnectedProfile->SSID,
448 sizeof(tSirMacSSid));
449
450 /* Save dot11mode in which STA associated to AP */
451 pHddStaCtx->conn_info.dot11Mode =
452 pRoamInfo->u.pConnectedProfile->dot11Mode;
453
454 pHddStaCtx->conn_info.proxyARPService =
455 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530456
457 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
458
459 pHddStaCtx->conn_info.rate_flags =
460 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 }
462 }
463 /* save the connected BssType */
464 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
465}
466
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467/**
468 * hdd_send_ft_assoc_response() - send fast transition assoc response
469 * @dev: pointer to net device
470 * @pAdapter: pointer to adapter
471 * @pCsrRoamInfo: pointer to roam info
472 *
473 * Send the 11R key information to the supplicant. Only then can the supplicant
474 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
475 * for the same purpose.)
476 *
477 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
478 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
479 * This is the Assoc Response.
480 *
481 * Return: none
482 */
483static void
484hdd_send_ft_assoc_response(struct net_device *dev,
485 hdd_adapter_t *pAdapter,
486 tCsrRoamInfo *pCsrRoamInfo)
487{
488 union iwreq_data wrqu;
489 char *buff;
490 unsigned int len = 0;
491 u8 *pFTAssocRsp = NULL;
492
493 if (pCsrRoamInfo->nAssocRspLength == 0) {
494 hddLog(LOGE,
495 FL("pCsrRoamInfo->nAssocRspLength=%d"),
496 (int)pCsrRoamInfo->nAssocRspLength);
497 return;
498 }
499
500 pFTAssocRsp =
501 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
502 pCsrRoamInfo->nAssocReqLength);
503 if (pFTAssocRsp == NULL) {
504 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
505 return;
506 }
507 /* pFTAssocRsp needs to point to the IEs */
508 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
509 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
510 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
511
512 /* We need to send the IEs to the supplicant. */
513 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
514 if (buff == NULL) {
515 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
516 return;
517 }
518 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
519 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
520 wrqu.data.length = len;
521 memset(buff, 0, IW_GENERIC_IE_MAX);
522 memcpy(buff, pFTAssocRsp, len);
523 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
524
525 kfree(buff);
526}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528/**
529 * hdd_send_ft_event() - send fast transition event
530 * @pAdapter: pointer to adapter
531 *
532 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
533 * FT events to the supplicant. At the reception of Auth2 we send the RIC
534 * followed by the auth response IEs to the supplicant.
535 * Once both are received in the supplicant, an FT event is generated
536 * to the supplicant.
537 *
538 * Return: none
539 */
540static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
541{
542 uint16_t auth_resp_len = 0;
543 uint32_t ric_ies_length = 0;
544 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
545
546#if defined(KERNEL_SUPPORT_11R_CFG80211)
547 struct cfg80211_ft_event_params ftEvent;
548 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
549 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
550 struct net_device *dev = pAdapter->dev;
551#else
552 char *buff;
553 union iwreq_data wrqu;
554 uint16_t str_len;
555#endif
556
557#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530558 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
559 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560
561 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
562 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
563 if (ric_ies_length == 0) {
564 hddLog(LOGW,
565 FL("RIC IEs is of length 0 not sending RIC Information for now"));
566 }
567
568 ftEvent.ric_ies = ricIe;
569 ftEvent.ric_ies_len = ric_ies_length;
570 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
571
572 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
573 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
574 &auth_resp_len);
575
576 if (auth_resp_len == 0) {
577 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
578 return;
579 }
580
581 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
582
583 ftEvent.target_ap = ftIe;
584
Anurag Chouhan6d760662016-02-20 16:05:43 +0530585 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
586 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587
588 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
589 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
590 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
591 ftEvent.target_ap[0], ftEvent.target_ap[1],
592 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
593 ftEvent.target_ap[5]);
594
595 (void)cfg80211_ft_event(dev, &ftEvent);
596
597#else
598 /* We need to send the IEs to the supplicant */
599 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
600 if (buff == NULL) {
601 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
602 return;
603 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530604 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605
606 /* Sme needs to send the RIC IEs first */
607 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
608 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
609 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
610 &ric_ies_length);
611 if (ric_ies_length == 0) {
612 hddLog(LOGW,
613 FL("RIC IEs is of length 0 not sending RIC Information for now"));
614 } else {
615 wrqu.data.length = str_len + ric_ies_length;
616 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
617 }
618
619 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530620 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
622 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
623 (u8 *) &buff[str_len],
624 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
625
626 if (auth_resp_len == 0) {
627 kfree(buff);
628 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
629 return;
630 }
631
632 wrqu.data.length = str_len + auth_resp_len;
633 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
634
635 kfree(buff);
636#endif
637}
638
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639#ifdef FEATURE_WLAN_ESE
640/**
641 * hdd_send_new_ap_channel_info() - send new ap channel info
642 * @dev: pointer to net device
643 * @pAdapter: pointer to adapter
644 * @pCsrRoamInfo: pointer to roam info
645 *
646 * Send the ESE required "new AP Channel info" to the supplicant.
647 * (This keeps the supplicant "up to date" on the current channel.)
648 *
649 * The current (new AP) channel information is passed in.
650 *
651 * Return: none
652 */
653static void
654hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
655 tCsrRoamInfo *pCsrRoamInfo)
656{
657 union iwreq_data wrqu;
658 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
659
660 if (descriptor == NULL) {
661 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
662 return;
663 }
664 /*
665 * Send the Channel event, the supplicant needs this to generate
666 * the Adjacent AP report.
667 */
668 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
669 descriptor->channelId);
670 memset(&wrqu, '\0', sizeof(wrqu));
671 wrqu.freq.m = descriptor->channelId;
672 wrqu.freq.e = 0;
673 wrqu.freq.i = 0;
674 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
675}
676
677#endif /* FEATURE_WLAN_ESE */
678
679/**
680 * hdd_send_update_beacon_ies_event() - send update beacons ie event
681 * @pAdapter: pointer to adapter
682 * @pCsrRoamInfo: pointer to roam info
683 *
684 * Return: none
685 */
686static void
687hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
688 tCsrRoamInfo *pCsrRoamInfo)
689{
690 union iwreq_data wrqu;
691 u8 *pBeaconIes;
692 u8 currentLen = 0;
693 char *buff;
694 int totalIeLen = 0, currentOffset = 0, strLen;
695
696 memset(&wrqu, '\0', sizeof(wrqu));
697
698 if (0 == pCsrRoamInfo->nBeaconLength) {
699 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
700 return;
701 }
702 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
703 if (pBeaconIes == NULL) {
704 hddLog(LOGW, FL("Beacon IEs is NULL"));
705 return;
706 }
707 /* pBeaconIes needs to point to the IEs */
708 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
709 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
710 hddLog(LOG1, FL("Beacon IEs length = %d"),
711 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
712
713 /* We need to send the IEs to the supplicant. */
714 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
715 if (buff == NULL) {
716 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
717 return;
718 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530719 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720
721 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
722 currentLen = strLen + 1;
723
724 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
725 do {
726 /*
727 * If the beacon size exceeds max CUSTOM event size, break it
728 * into chunks of CUSTOM event max size and send it to
729 * supplicant. Changes are done in supplicant to handle this.
730 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530731 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530733 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530734 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 currentLen);
736 currentOffset += currentLen;
737 totalIeLen -= currentLen;
738 wrqu.data.length = strLen + 1 + currentLen;
739 if (totalIeLen)
740 buff[strLen] = 1; /* more chunks pending */
741 else
742 buff[strLen] = 0; /* last chunk */
743
744 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
745 currentLen);
746 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
747 } while (totalIeLen > 0);
748
749 kfree(buff);
750}
751
752/**
753 * hdd_send_association_event() - send association event
754 * @dev: pointer to net device
755 * @pCsrRoamInfo: pointer to roam info
756 *
757 * Return: none
758 */
759static void hdd_send_association_event(struct net_device *dev,
760 tCsrRoamInfo *pCsrRoamInfo)
761{
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
764 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
765 union iwreq_data wrqu;
766 int we_event;
767 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530768 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 /* Added to find the auth type on the fly at run time */
771 /* rather than with cfg to see if FT is enabled */
772 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
773 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774
775 memset(&wrqu, '\0', sizeof(wrqu));
776 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
777 we_event = SIOCGIWAP;
778#ifdef WLAN_FEATURE_ROAM_OFFLOAD
779 if (NULL != pCsrRoamInfo)
780 if (pCsrRoamInfo->roamSynchInProgress)
781 /* change logging before release */
782 hddLog(LOG4, "LFR3:hdd_send_association_event");
783#endif
784 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
Abhishek Singh1c676222016-05-09 14:20:28 +0530785 tSirSmeChanInfo chan_info;
786
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 if (!pCsrRoamInfo) {
788 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
789 return;
790 }
791
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800792 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
793 cds_incr_active_session(pAdapter->device_mode,
794 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
796 sizeof(pCsrRoamInfo->pBssDesc->bssId));
797
798#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800799 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 if (global_p2p_connection_status ==
801 P2P_CLIENT_CONNECTING_STATE_1) {
802 global_p2p_connection_status =
803 P2P_CLIENT_CONNECTED_STATE_1;
804 hddLog(LOGE,
805 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
806 } else if (global_p2p_connection_status ==
807 P2P_CLIENT_CONNECTING_STATE_2) {
808 global_p2p_connection_status =
809 P2P_CLIENT_COMPLETED_STATE;
810 hddLog(LOGE,
811 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
812 }
813 }
814#endif
815 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
816 MAC_ADDRESS_STR "\n",
817 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
818 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
819 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
820
821 /*
822 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
823 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800824 * fFTEnable is true.
825 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 if ((pRoamProfile->AuthType.authType[0] ==
828 eCSR_AUTH_TYPE_FT_RSN_PSK)
829 || (pRoamProfile->AuthType.authType[0] ==
830 eCSR_AUTH_TYPE_FT_RSN)
831#ifdef FEATURE_WLAN_ESE
832 || (pRoamProfile->AuthType.authType[0] ==
833 eCSR_AUTH_TYPE_CCKM_RSN)
834 || (pRoamProfile->AuthType.authType[0] ==
835 eCSR_AUTH_TYPE_CCKM_WPA)
836#endif
837 ) {
838 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
839 }
Abhishek Singh1c676222016-05-09 14:20:28 +0530840 qdf_copy_macaddr(&peerMacAddr,
841 &pHddStaCtx->conn_info.bssId);
842 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
843 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
844 chan_info.info = pCsrRoamInfo->chan_info.info;
845 chan_info.band_center_freq1 =
846 pCsrRoamInfo->chan_info.band_center_freq1;
847 chan_info.band_center_freq2 =
848 pCsrRoamInfo->chan_info.band_center_freq2;
849 chan_info.reg_info_1 =
850 pCsrRoamInfo->chan_info.reg_info_1;
851 chan_info.reg_info_2 =
852 pCsrRoamInfo->chan_info.reg_info_2;
853 /* send peer status indication to oem app */
854 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
855 ePeerConnected,
856 pCsrRoamInfo->
857 timingMeasCap,
858 pAdapter->sessionId,
859 &chan_info,
860 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862#ifdef MSM_PLATFORM
863#ifdef CONFIG_CNSS
864 /* start timer in sta/p2p_cli */
865 spin_lock_bh(&pHddCtx->bus_bw_lock);
866 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
867 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530868 ol_get_intra_bss_fwd_pkts_count(pAdapter->sessionId,
869 &pAdapter->prev_fwd_tx_packets,
870 &pAdapter->prev_fwd_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871 spin_unlock_bh(&pHddCtx->bus_bw_lock);
872 hdd_start_bus_bw_compute_timer(pAdapter);
873#endif
874#endif
875 } else if (eConnectionState_IbssConnected == /* IBss Associated */
876 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800877 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
879 ETH_ALEN);
880 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
881 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
882 } else { /* Not Associated */
883
884 pr_info("wlan: disconnected\n");
885 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530886 cds_decr_session_set_pcl(pAdapter->device_mode,
887 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889
890#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
891 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
892#endif
893
Abhishek Singh1c676222016-05-09 14:20:28 +0530894 if ((pAdapter->device_mode == QDF_STA_MODE) ||
895 (pAdapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530896 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897 &pHddStaCtx->conn_info.bssId);
898
899 /* send peer status indication to oem app */
900 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
Abhishek Singh1c676222016-05-09 14:20:28 +0530901 ePeerDisconnected, 0,
902 pAdapter->sessionId,
903 NULL,
904 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 }
906#ifdef WLAN_FEATURE_LPSS
907 pAdapter->rssi_send = false;
908 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
909#endif
910#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800911 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 (pCsrRoamInfo)) {
913 hddLog(LOG4,
914 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
915 pCsrRoamInfo->tdls_prohibited,
916 pCsrRoamInfo->tdls_chan_swit_prohibited);
917
918 wlan_hdd_update_tdls_info(pAdapter,
919 pCsrRoamInfo->tdls_prohibited,
920 pCsrRoamInfo->tdls_chan_swit_prohibited);
921 }
922#endif
923#ifdef MSM_PLATFORM
924 /* stop timer in sta/p2p_cli */
925 spin_lock_bh(&pHddCtx->bus_bw_lock);
926 pAdapter->prev_tx_packets = 0;
927 pAdapter->prev_rx_packets = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530928 pAdapter->prev_fwd_tx_packets = 0;
929 pAdapter->prev_fwd_rx_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 spin_unlock_bh(&pHddCtx->bus_bw_lock);
931 hdd_stop_bus_bw_compute_timer(pAdapter);
932#endif
933 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800934 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 /* Send SCC/MCC Switching event to IPA */
936 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
937
938 msg = NULL;
939 /*During the WLAN uninitialization,supplicant is stopped before the
940 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800941 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942 wireless_send_event(dev, we_event, &wrqu, msg);
943#ifdef FEATURE_WLAN_ESE
944 if (eConnectionState_Associated ==
945 pHddStaCtx->conn_info.connState) {
946 if ((pRoamProfile->AuthType.authType[0] ==
947 eCSR_AUTH_TYPE_CCKM_RSN) ||
948 (pRoamProfile->AuthType.authType[0] ==
949 eCSR_AUTH_TYPE_CCKM_WPA))
950 hdd_send_new_ap_channel_info(dev, pAdapter,
951 pCsrRoamInfo);
952 }
953#endif
954 }
955}
956
957/**
958 * hdd_conn_remove_connect_info() - remove connection info
959 * @pHddStaCtx: pointer to global HDD station context
960 * @pCsrRoamInfo: pointer to roam info
961 *
962 * Return: none
963 */
964static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
965{
966 /* Remove staId, bssId and peerMacAddress */
967 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530968 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
969 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530970 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971
972 /* Clear all security settings */
973 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
974 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
975 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
976
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530977 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
978 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800979
980 /* Set not-connected state */
981 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
982 pHddStaCtx->conn_info.proxyARPService = 0;
983
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530984 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985}
986
987/**
988 * hdd_roam_deregister_sta() - deregister station
989 * @pAdapter: pointer to adapter
990 * @staId: station identifier
991 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530992 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800993 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530994static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
996{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530997 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800998 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
999
1000 if (eConnectionState_IbssDisconnected ==
1001 pHddStaCtx->conn_info.connState) {
1002 /*
1003 * Do not set the carrier off when the last peer leaves.
1004 * We will set the carrier off while stopping the IBSS.
1005 */
1006 }
1007
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301008 qdf_status = ol_txrx_clear_peer(staId);
1009 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 hddLog(LOGE,
1011 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301012 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301014 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015}
1016
1017/**
1018 * hdd_dis_connect_handler() - disconnect event handler
1019 * @pAdapter: pointer to adapter
1020 * @pRoamInfo: pointer to roam info
1021 * @roamId: roam identifier
1022 * @roamStatus: roam status
1023 * @roamResult: roam result
1024 *
1025 * This function handles disconnect event:
1026 * 1. Disable transmit queues;
1027 * 2. Clean up internal connection states and data structures;
1028 * 3. Send disconnect indication to supplicant.
1029 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301030 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001031 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301032static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033 tCsrRoamInfo *pRoamInfo,
1034 uint32_t roamId,
1035 eRoamCmdStatus roamStatus,
1036 eCsrRoamResult roamResult)
1037{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301038 QDF_STATUS status = QDF_STATUS_SUCCESS;
1039 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040 struct net_device *dev = pAdapter->dev;
1041 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1042 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1043 uint8_t sta_id;
1044 bool sendDisconInd = true;
1045
1046 if (dev == NULL) {
1047 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301048 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 }
1050 /* notify apps that we can't pass traffic anymore */
1051 hddLog(LOG1, FL("Disabling queues"));
1052 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1053 WLAN_CONTROL_PATH);
1054
1055 if (hdd_ipa_is_enabled(pHddCtx))
1056 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1057 WLAN_STA_DISCONNECT,
1058 pHddStaCtx->conn_info.bssId.bytes);
1059
1060#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1061 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1062#endif
1063
Nirav Shah1da77682016-05-03 20:16:39 +05301064 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1065 pAdapter->sessionId,
1066 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067
1068 /* HDD has initiated disconnect, do not send disconnect indication
1069 * to kernel. Sending disconnected event to kernel for userspace
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301070 * initiated disconnect will be handled by disconnect handler call
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001071 * to cfg80211_disconnected.
1072 */
1073 if ((eConnectionState_Disconnecting ==
1074 pHddStaCtx->conn_info.connState) ||
1075 (eConnectionState_NotConnected ==
1076 pHddStaCtx->conn_info.connState)) {
1077 hddLog(LOG1,
1078 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1079 sendDisconInd = false;
1080 }
1081
1082 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1083 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084 hdd_conn_set_connection_state(pAdapter,
1085 eConnectionState_Disconnecting);
1086 }
1087
1088 hdd_clear_roam_profile_ie(pAdapter);
1089 hdd_wmm_init(pAdapter);
1090
1091 /* indicate 'disconnect' status to wpa_supplicant... */
1092 hdd_send_association_event(dev, pRoamInfo);
1093 /* indicate disconnected event to nl80211 */
1094 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1095 /*
1096 * Only send indication to kernel if not initiated
1097 * by kernel
1098 */
1099 if (sendDisconInd) {
1100 /*
1101 * To avoid wpa_supplicant sending "HANGED" CMD
1102 * to ICS UI.
1103 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001104 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1105 if (pRoamInfo->reasonCode ==
1106 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1107 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301108 wlan_hdd_cfg80211_indicate_disconnect(
1109 dev, false,
1110 pRoamInfo->reasonCode);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001111 } else {
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301112 wlan_hdd_cfg80211_indicate_disconnect(
1113 dev, false,
1114 WLAN_REASON_UNSPECIFIED
1115 );
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001116 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117
1118 hdd_info("sent disconnected event to nl80211, rssi: %d",
1119 pAdapter->rssi);
1120 }
1121 /*
1122 * During the WLAN uninitialization,supplicant is stopped
1123 * before the driver so not sending the status of the
1124 * connection to supplicant.
1125 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001126 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001127#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001128 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001129 if (global_p2p_connection_status ==
1130 P2P_CLIENT_CONNECTED_STATE_1) {
1131 global_p2p_connection_status =
1132 P2P_CLIENT_DISCONNECTED_STATE;
1133 hddLog(LOGE,
1134 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1135 } else if (global_p2p_connection_status ==
1136 P2P_CLIENT_COMPLETED_STATE) {
1137 global_p2p_connection_status =
1138 P2P_NOT_ACTIVE;
1139 hddLog(LOGE,
1140 "[P2P State] P2P Client is removed and moved to inactive state");
1141 }
1142 }
1143#endif
1144
1145 }
1146 }
1147
1148 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001149 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001150 if (hdd_remove_beacon_filter(pAdapter) != 0)
1151 hdd_err("hdd_remove_beacon_filter() failed");
1152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001153 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301154 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301155 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301157 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301158 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1159 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301160 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 }
1162 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301163 /* Clear all the peer sta register with TL. */
1164 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1165 if (0 == pHddStaCtx->conn_info.staId[i])
1166 continue;
1167 sta_id = pHddStaCtx->conn_info.staId[i];
1168 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1169 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301170 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301171 hddLog(LOGE,
1172 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1173 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301175 }
1176 /* set the staid and peer mac as 0, all other
1177 * reset are done in hdd_connRemoveConnectInfo.
1178 */
1179 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301180 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301181 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301182 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1183 pHddCtx->sta_to_adapter[sta_id] = NULL;
1184 }
1185 } else {
1186 sta_id = pHddStaCtx->conn_info.staId[0];
1187 /* We should clear all sta register with TL,
1188 * for now, only one.
1189 */
1190 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301191 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301192 hddLog(LOGE,
1193 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1194 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301196 }
1197 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199 /* Clear saved connection information in HDD */
1200 hdd_conn_remove_connect_info(pHddStaCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 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_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001263
1264 if (!pdev) {
1265 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301266 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 }
1268
1269 if (sta_id >= WLAN_MAX_STA_COUNT) {
1270 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301271 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 }
1273
1274 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1275 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301276 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001278 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1279 if (peer_mac_addr == NULL) {
1280 hddLog(LOGE, "peer mac addr is NULL");
1281 return QDF_STATUS_E_FAULT;
1282 }
1283
1284 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301285 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301287 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 }
1289#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1290 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292#endif
1293
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001294 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1296 /* make sure event is reset */
1297 INIT_COMPLETION(pAdapter->sta_authorized_event);
1298#endif
1299
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001300 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001301 hdd_set_peer_authorized_event,
1302 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301303 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001304 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301305 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 }
1307
Krunal Sonibe766b02016-03-10 13:00:44 -08001308 if (pAdapter->device_mode == QDF_STA_MODE ||
1309 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Houston Hoffman52ec6692016-04-21 16:36:45 -07001311 ol_txrx_vdev_handle vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 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 */
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001341QDF_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 {
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001671 qdf_status = hdd_get_peer_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) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 hdd_conn_set_connection_state(pAdapter,
1835 eConnectionState_Associated);
1836 }
1837 /* Save the connection info from CSR... */
1838 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1839 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001840
1841 if (hdd_add_beacon_filter(pAdapter) != 0)
1842 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843#ifdef FEATURE_WLAN_WAPI
1844 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1845 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1846 || pRoamInfo->u.pConnectedProfile->AuthType ==
1847 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1848 pAdapter->wapi_info.fIsWapiSta = 1;
1849 } else {
1850 pAdapter->wapi_info.fIsWapiSta = 0;
1851 }
1852#endif /* FEATURE_WLAN_WAPI */
1853
1854 /* Indicate 'connect' status to user space */
1855 hdd_send_association_event(dev, pRoamInfo);
1856
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001857 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858 if (pHddCtx->miracast_value)
1859 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1860 }
1861
1862 /* Initialize the Linkup event completion variable */
1863 INIT_COMPLETION(pAdapter->linkup_event_var);
1864
1865 /*
1866 * Sometimes Switching ON the Carrier is taking time to activate
1867 * the device properly. Before allowing any packet to go up to
1868 * the application, device activation has to be ensured for
1869 * proper queue mapping by the kernel. we have registered net
1870 * device notifier for device change notification. With this we
1871 * will come to know that the device is getting
1872 * activated properly.
1873 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001874 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001875 /*
1876 * Enable Linkup Event Servicing which allows the net
1877 * device notifier to set the linkup event variable.
1878 */
1879 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001880
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001881 /* Switch on the Carrier to activate the device */
1882 wlan_hdd_netif_queue_control(pAdapter,
1883 WLAN_NETIF_CARRIER_ON,
1884 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001885
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001886 /*
1887 * Wait for the Link to up to ensure all the queues
1888 * are set properly by the kernel.
1889 */
1890 rc = wait_for_completion_timeout(
1891 &pAdapter->linkup_event_var,
1892 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1893 );
1894 if (!rc)
1895 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001897 /*
1898 * Disable Linkup Event Servicing - no more service
1899 * required from the net device notifier call.
1900 */
1901 pAdapter->isLinkUpSvcNeeded = false;
1902 } else {
1903 pHddStaCtx->ft_carrier_on = false;
1904 ft_carrier_on = true;
1905 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1907 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1908 else
1909 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1910 pRoamInfo->staId);
1911
1912 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1913
1914 if (hdd_ipa_is_enabled(pHddCtx))
1915 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1916 WLAN_STA_CONNECT,
1917 pRoamInfo->bssid.bytes);
1918
1919#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1920 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1921#endif
1922
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301923 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001924 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925 pAdapter);
1926
1927#ifdef FEATURE_WLAN_TDLS
1928 wlan_hdd_tdls_connection_callback(pAdapter);
1929#endif
1930
Nirav Shah1da77682016-05-03 20:16:39 +05301931 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1932 pAdapter->sessionId,
1933 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
1934
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 /*
1936 * For reassoc, the station is already registered, all we need
1937 * is to change the state of the STA in TL.
1938 * If authentication is required (WPA/WPA2/DWEP), change TL to
1939 * CONNECTED instead of AUTHENTICATED.
1940 */
1941 if (!pRoamInfo->fReassocReq) {
1942 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 u8 *pFTAssocRsp = NULL;
1944 unsigned int assocRsplen = 0;
1945 u8 *pFTAssocReq = NULL;
1946 unsigned int assocReqlen = 0;
1947 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1949 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1950
1951 /* add bss_id to cfg80211 data base */
1952 bss =
1953 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1954 pRoamInfo);
1955 if (NULL == bss) {
1956 pr_err("wlan: Not able to create BSS entry\n");
1957 wlan_hdd_netif_queue_control(pAdapter,
1958 WLAN_NETIF_CARRIER_OFF,
1959 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301960 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1963 eCSR_AUTH_TYPE_FT_RSN
1964 || pRoamInfo->u.pConnectedProfile->AuthType ==
1965 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1966
1967 /* Association Response */
1968 pFTAssocRsp =
1969 (u8 *) (pRoamInfo->pbFrames +
1970 pRoamInfo->nBeaconLength +
1971 pRoamInfo->nAssocReqLength);
1972 if (pFTAssocRsp != NULL) {
1973 /*
1974 * pFTAssocRsp needs to point to the IEs
1975 */
1976 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1977 hddLog(LOG1,
1978 FL("AssocRsp is now at %02x%02x"),
1979 (unsigned int)pFTAssocRsp[0],
1980 (unsigned int)pFTAssocRsp[1]);
1981 assocRsplen =
1982 pRoamInfo->nAssocRspLength -
1983 FT_ASSOC_RSP_IES_OFFSET;
1984 } else {
1985 hddLog(LOGE, FL("AssocRsp is NULL"));
1986 assocRsplen = 0;
1987 }
1988
1989 /* Association Request */
1990 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1991 pRoamInfo->nBeaconLength);
1992 if (pFTAssocReq != NULL) {
1993 if (!ft_carrier_on) {
1994 /*
1995 * pFTAssocReq needs to point to
1996 * the IEs
1997 */
1998 pFTAssocReq +=
1999 FT_ASSOC_REQ_IES_OFFSET;
2000 hddLog(LOG1,
2001 FL("pFTAssocReq is now at %02x%02x"),
2002 (unsigned int)
2003 pFTAssocReq[0],
2004 (unsigned int)
2005 pFTAssocReq[1]);
2006 assocReqlen =
2007 pRoamInfo->nAssocReqLength -
2008 FT_ASSOC_REQ_IES_OFFSET;
2009 } else {
2010 /*
2011 * This should contain only the
2012 * FTIEs
2013 */
2014 assocReqlen =
2015 pRoamInfo->nAssocReqLength;
2016 }
2017 } else {
2018 hddLog(LOGE, FL("AssocReq is NULL"));
2019 assocReqlen = 0;
2020 }
2021
2022 if (ft_carrier_on) {
2023 if (!hddDisconInProgress) {
2024 /*
2025 * After roaming is completed,
2026 * active session count is
2027 * incremented as a part of
2028 * connect indication but
2029 * effectively the active
2030 * session count should still
2031 * be the same and hence upon
2032 * successful reassoc
2033 * decrement the active session
2034 * count here.
2035 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002036 if (!hdd_is_roam_sync_in_progress
2037 (pRoamInfo))
2038 cds_decr_session_set_pcl
2039 (pAdapter->device_mode,
2040 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002041 hddLog(LOG1,
2042 FL("ft_carrier_on is %d, sending roamed indication"),
2043 ft_carrier_on);
2044 chan =
2045 ieee80211_get_channel
2046 (pAdapter->wdev.wiphy,
2047 (int)pRoamInfo->pBssDesc->
2048 channelId);
2049 hddLog(LOG1,
2050 "assocReqlen %d assocRsplen %d",
2051 assocReqlen,
2052 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002053
2054 hdd_notice(
2055 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302056 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302057 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302058 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002059 pFTAssocReq,
2060 assocReqlen);
2061
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002062 cfg80211_roamed(dev, chan,
2063 pRoamInfo->
2064 bssid.bytes,
2065 pFTAssocReq,
2066 assocReqlen,
2067 pFTAssocRsp,
2068 assocRsplen,
2069 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002070 wlan_hdd_send_roam_auth_event(
2071 pHddCtx,
2072 pRoamInfo->bssid.bytes,
2073 pFTAssocReq,
2074 assocReqlen,
2075 pFTAssocRsp,
2076 assocRsplen,
2077 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002078 }
2079 if (sme_get_ftptk_state
2080 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2081 pAdapter->sessionId)) {
2082 sme_set_ftptk_state
2083 (WLAN_HDD_GET_HAL_CTX
2084 (pAdapter),
2085 pAdapter->sessionId,
2086 false);
2087 pRoamInfo->fAuthRequired =
2088 false;
2089
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302090 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091 roam_info.bssid,
2092 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302093 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302094 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 roam_info.peerMac,
2096 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302097 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002098 pHddStaCtx->roam_info.roamId =
2099 roamId;
2100 pHddStaCtx->roam_info.
2101 roamStatus = roamStatus;
2102 pHddStaCtx->roam_info.
2103 deferKeyComplete = true;
2104 }
2105 } else if (!hddDisconInProgress) {
2106 hddLog(LOG1,
2107 FL("ft_carrier_on is %d, sending connect indication"),
2108 ft_carrier_on);
2109 cfg80211_connect_result(dev,
2110 pRoamInfo->
2111 bssid.bytes,
2112 pFTAssocReq,
2113 assocReqlen,
2114 pFTAssocRsp,
2115 assocRsplen,
2116 WLAN_STATUS_SUCCESS,
2117 GFP_KERNEL);
2118 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002119 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002120 /*
2121 * wpa supplicant expecting WPA/RSN IE in
2122 * connect result.
2123 */
2124 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2125 (pAdapter),
2126 pAdapter->sessionId,
2127 &reqRsnLength,
2128 reqRsnIe);
2129
2130 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2131 (pAdapter),
2132 pAdapter->sessionId,
2133 &rspRsnLength,
2134 rspRsnIe);
2135 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 if (ft_carrier_on)
2137 hdd_send_re_assoc_event(dev,
2138 pAdapter,
2139 pRoamInfo,
2140 reqRsnIe,
2141 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002142 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143 hddLog(LOG1,
2144 FL("sending connect indication to nl80211:for bssid "
2145 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302146 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 MAC_ADDR_ARRAY
2148 (pRoamInfo->bssid.bytes),
2149 roamResult, roamStatus);
2150
2151 /* inform connect result to nl80211 */
2152 cfg80211_connect_result(dev,
2153 pRoamInfo->
2154 bssid.bytes,
2155 reqRsnIe,
2156 reqRsnLength,
2157 rspRsnIe,
2158 rspRsnLength,
2159 WLAN_STATUS_SUCCESS,
2160 GFP_KERNEL);
2161 }
2162 }
2163 }
2164 if (!hddDisconInProgress) {
2165 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002166 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167 bss);
2168
2169 /*
2170 * Perform any WMM-related association
2171 * processing.
2172 */
2173 hdd_wmm_assoc(pAdapter, pRoamInfo,
2174 eCSR_BSS_TYPE_INFRASTRUCTURE);
2175
2176 /*
2177 * Start the Queue - Start tx queues before
2178 * hdd_roam_register_sta, since
2179 * hdd_roam_register_sta will flush any cached
2180 * data frames immediately.
2181 */
2182 hddLog(LOG1, FL("Enabling queues"));
2183 wlan_hdd_netif_queue_control(pAdapter,
2184 WLAN_WAKE_ALL_NETIF_QUEUE,
2185 WLAN_CONTROL_PATH);
2186
2187 /*
2188 * Register the Station with TL after associated
2189 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302190 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 pRoamInfo,
2192 pHddStaCtx->
2193 conn_info.
2194 staId[0],
2195 NULL,
2196 pRoamInfo->
2197 pBssDesc);
2198 }
2199 } else {
2200 /*
2201 * wpa supplicant expecting WPA/RSN IE in connect result
2202 * in case of reassociation also need to indicate it to
2203 * supplicant.
2204 */
2205 csr_roam_get_wpa_rsn_req_ie(
2206 WLAN_HDD_GET_HAL_CTX(pAdapter),
2207 pAdapter->sessionId,
2208 &reqRsnLength, reqRsnIe);
2209
2210 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2211 reqRsnIe, reqRsnLength);
2212 /* Reassoc successfully */
2213 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302214 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 hdd_change_peer_state(pAdapter,
2216 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002217 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2219 pRoamInfo->roamSynchInProgress
2220#else
2221 false
2222#endif
2223 );
2224 hdd_conn_set_authenticated(pAdapter, false);
2225 } else {
2226 hddLog(LOG2,
2227 FL("staId: %d Changing TL state to AUTHENTICATED"),
2228 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302229 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 hdd_change_peer_state(pAdapter,
2231 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002232 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2234 pRoamInfo->roamSynchInProgress
2235#else
2236 false
2237#endif
2238 );
2239 hdd_conn_set_authenticated(pAdapter, true);
2240 }
2241
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302242 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002243 /*
2244 * Perform any WMM-related association
2245 * processing
2246 */
2247 hdd_wmm_assoc(pAdapter, pRoamInfo,
2248 eCSR_BSS_TYPE_INFRASTRUCTURE);
2249 }
2250
2251 /* Start the tx queues */
2252#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2253 if (pRoamInfo->roamSynchInProgress)
2254 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2255#endif
2256 hddLog(LOG1, FL("Enabling queues"));
2257 wlan_hdd_netif_queue_control(pAdapter,
2258 WLAN_WAKE_ALL_NETIF_QUEUE,
2259 WLAN_CONTROL_PATH);
2260 }
2261
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302262 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 hddLog(LOGE,
2264 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302265 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002266 }
2267#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302268 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 sizeof(pAdapter->hdd_stats.hddPmfStats));
2270#endif
2271 } else {
2272 hdd_wext_state_t *pWextState =
2273 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2274 if (pRoamInfo)
2275 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302276 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2278 roamResult, roamStatus);
2279 else
2280 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302281 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2283 roamResult, roamStatus);
2284
2285 /*
2286 * CR465478: Only send up a connection failure result when CSR
2287 * has completed operation - with a ASSOCIATION_FAILURE status.
2288 */
2289 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2290 && !hddDisconInProgress) {
2291 if (pRoamInfo)
2292 hddLog(LOGE,
2293 FL("send connect failure to nl80211: for bssid "
2294 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302295 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302297 roamResult, roamStatus,
2298 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 else
2300 hddLog(LOGE,
2301 FL("connect failed: for bssid "
2302 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302303 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2305 roamResult, roamStatus);
2306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 /* inform association failure event to nl80211 */
2308 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2309 roamResult) {
2310 if (pRoamInfo)
2311 cfg80211_connect_result(dev,
2312 pRoamInfo->bssid.bytes,
2313 NULL, 0, NULL, 0,
2314 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2315 GFP_KERNEL);
2316 else
2317 cfg80211_connect_result(dev,
2318 pWextState->req_bssId.bytes,
2319 NULL, 0, NULL, 0,
2320 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2321 GFP_KERNEL);
2322 } else {
2323 if (pRoamInfo) {
2324 eCsrAuthType authType =
2325 pWextState->roamProfile.AuthType.
2326 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302327 eCsrEncryptionType encryption_type =
2328 pWextState->roamProfile.
2329 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302331 (((authType ==
2332 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302334 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2335 ((encryption_type ==
2336 eCSR_ENCRYPT_TYPE_WEP40) ||
2337 (encryption_type ==
2338 eCSR_ENCRYPT_TYPE_WEP104) ||
2339 (encryption_type ==
2340 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2341 (encryption_type ==
2342 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 /*
2344 * In case of OPEN-WEP or SHARED-WEP
2345 * authentication, send exact protocol
2346 * reason code. This enables user
2347 * applications to reconnect the station
2348 * with correct configuration.
2349 */
2350 cfg80211_connect_result(dev,
2351 pRoamInfo->bssid.bytes, NULL, 0,
2352 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302353 (isWep &&
2354 pRoamInfo->reasonCode) ?
2355 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002356 WLAN_STATUS_UNSPECIFIED_FAILURE,
2357 GFP_KERNEL);
2358 } else
2359 cfg80211_connect_result(dev,
2360 pWextState->req_bssId.bytes,
2361 NULL, 0, NULL, 0,
2362 WLAN_STATUS_UNSPECIFIED_FAILURE,
2363 GFP_KERNEL);
2364 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302365 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002366 }
2367
2368 if (pRoamInfo) {
2369 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2370 pRoamInfo->statusCode)
2371 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2372 pRoamInfo->statusCode)
2373 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2374 pRoamInfo->statusCode)) {
2375 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2376 pRoamInfo);
2377 }
2378 }
2379
2380 /*
2381 * Set connection state to eConnectionState_NotConnected only
2382 * when CSR has completed operation - with a
2383 * ASSOCIATION_FAILURE status.
2384 */
2385 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2386 && !hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 hdd_conn_set_connection_state(pAdapter,
2388 eConnectionState_NotConnected);
2389 }
2390 hdd_wmm_init(pAdapter);
2391
2392 hddLog(LOG1, FL("Disabling queues"));
2393 wlan_hdd_netif_queue_control(pAdapter,
2394 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2395 WLAN_CONTROL_PATH);
2396 }
2397
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302398 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302400 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401
Govind Singh24db1ed2015-12-18 15:54:59 +05302402 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2403 cds_force_sap_on_scc(roamResult,
2404 pRoamInfo->pBssDesc->channelId);
2405 } else {
2406 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302407 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302408 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302410 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411}
2412
2413/**
2414 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2415 * @pAdapter: pointer to adapter
2416 * @pRoamInfo: pointer to roam info
2417 * @roamId: roam id
2418 * @roamStatus: roam status
2419 * @roamResult: roam result
2420 *
2421 * Here we update the status of the Ibss when we receive information that we
2422 * have started/joined an ibss session.
2423 *
2424 * Return: none
2425 */
2426static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2427 tCsrRoamInfo *pRoamInfo,
2428 uint32_t roamId,
2429 eRoamCmdStatus roamStatus,
2430 eCsrRoamResult roamResult)
2431{
2432 hddLog(LOG1, "%s: id %d, status %d, result %d",
2433 pAdapter->dev->name, roamId, roamStatus, roamResult);
2434
2435 switch (roamResult) {
2436 /* both IBSS Started and IBSS Join should come in here. */
2437 case eCSR_ROAM_RESULT_IBSS_STARTED:
2438 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2439 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2440 {
2441 hdd_context_t *pHddCtx =
2442 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302443 hdd_station_ctx_t *hdd_sta_ctx =
2444 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302445 struct qdf_mac_addr broadcastMacAddr =
2446 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447
2448 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302449 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450 return;
2451 }
2452
2453 /* When IBSS Started comes from CSR, we need to move
2454 * connection state to IBSS Disconnected (meaning no peers
2455 * are in the IBSS).
2456 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 hdd_conn_set_connection_state(pAdapter,
2458 eConnectionState_IbssDisconnected);
2459 /* notify wmm */
2460 hdd_wmm_connect(pAdapter, pRoamInfo,
2461 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302462
2463 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2464
2465 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466 pAdapter;
2467 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302468 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 &broadcastMacAddr,
2470 pRoamInfo->pBssDesc);
2471
2472 if (pRoamInfo->pBssDesc) {
2473 struct cfg80211_bss *bss;
2474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2475 struct ieee80211_channel *chan;
2476 int chan_no;
2477 unsigned int freq;
2478#endif
2479 /* we created the IBSS, notify supplicant */
2480 hddLog(LOG1,
2481 FL("%s: created ibss " MAC_ADDRESS_STR),
2482 pAdapter->dev->name,
2483 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2484
2485 /* we must first give cfg80211 the BSS information */
2486 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2487 pRoamInfo);
2488 if (NULL == bss) {
2489 hddLog(LOGE,
2490 FL("%s: unable to create IBSS entry"),
2491 pAdapter->dev->name);
2492 return;
2493 }
2494 hddLog(LOG1, FL("Enabling queues"));
2495 wlan_hdd_netif_queue_control(pAdapter,
2496 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2497 WLAN_CONTROL_PATH);
2498
2499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2500 chan_no = pRoamInfo->pBssDesc->channelId;
2501
2502 if (chan_no <= 14)
2503 freq = ieee80211_channel_to_frequency(chan_no,
2504 IEEE80211_BAND_2GHZ);
2505 else
2506 freq = ieee80211_channel_to_frequency(chan_no,
2507 IEEE80211_BAND_5GHZ);
2508
2509 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2510
2511 if (chan)
2512 cfg80211_ibss_joined(pAdapter->dev,
2513 bss->bssid, chan,
2514 GFP_KERNEL);
2515 else
2516 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2517 pAdapter->dev->name,
2518 (int)pRoamInfo->pBssDesc->channelId);
2519#else
2520 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2521 GFP_KERNEL);
2522#endif
2523 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525 bss);
2526 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002527 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002528 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002529 pAdapter->sessionId);
2530 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2531 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002532 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002533 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 break;
2535 }
2536
2537 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2538 {
2539 hddLog(LOGE,
2540 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2541 break;
2542 }
2543
2544 default:
2545 hddLog(LOGE, FL("%s: unexpected result %d"),
2546 pAdapter->dev->name, (int)roamResult);
2547 break;
2548 }
2549
2550 return;
2551}
2552
2553/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002554 * hdd_save_peer() - Save peer MAC address in adapter peer table.
2555 * @sta_ctx: pointer to hdd station context
2556 * @sta_id: station ID
2557 * @peer_mac_addr: mac address of new peer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558 *
2559 * This information is passed to iwconfig later. The peer that joined
2560 * last is passed as information to iwconfig.
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002561
2562 * Return: true if success, false otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002563 */
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002564bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
2565 struct qdf_mac_addr *peer_mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002567 int idx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002569 for (idx = 0; idx < SIR_MAX_NUM_STA_IN_IBSS; idx++) {
2570 if (0 == sta_ctx->conn_info.staId[idx]) {
2571 sta_ctx->conn_info.staId[idx] = sta_id;
2572 qdf_copy_macaddr(
2573 &sta_ctx->conn_info.peerMacAddress[idx],
2574 peer_mac_addr);
2575 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576 }
2577 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002578 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579}
2580
2581/**
2582 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2583 * @pAdapter: pointer to adapter
2584 * @staId: station id
2585 *
2586 * Return:
2587 * true if we remove MAX_IBSS_PEERS or less STA
2588 * false otherwise.
2589 */
2590static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2591{
2592 bool fSuccess = false;
2593 int idx = 0;
2594 uint8_t valid_idx = 0;
2595 uint8_t del_idx = 0;
2596 uint8_t empty_slots = 0;
2597 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2598
2599 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2600 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2601 pHddStaCtx->conn_info.staId[idx] = 0;
2602
Anurag Chouhanc5548422016-02-24 18:33:27 +05302603 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002604 peerMacAddress[idx]);
2605
2606 fSuccess = true;
2607
2608 /*
2609 * Note the deleted Index, if its 0 we need special
2610 * handling.
2611 */
2612 del_idx = idx;
2613
2614 empty_slots++;
2615 } else {
2616 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2617 valid_idx = idx;
2618 } else {
2619 /* Found an empty slot */
2620 empty_slots++;
2621 }
2622 }
2623 }
2624
2625 if (MAX_IBSS_PEERS == empty_slots) {
2626 /* Last peer departed, set the IBSS state appropriately */
2627 pHddStaCtx->conn_info.connState =
2628 eConnectionState_IbssDisconnected;
2629 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2630 }
2631 /* Find next active staId, to have a valid sta trigger for TL. */
2632 if (fSuccess == true) {
2633 if (del_idx == 0) {
2634 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2635 pHddStaCtx->conn_info.staId[0] =
2636 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302637 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002638 peerMacAddress[0],
2639 &pHddStaCtx->conn_info.
2640 peerMacAddress[valid_idx]);
2641
2642 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302643 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002644 peerMacAddress[valid_idx]);
2645 }
2646 }
2647 }
2648 return fSuccess;
2649}
2650
2651/**
2652 * roam_ibss_connect_handler() - IBSS connection handler
2653 * @pAdapter: pointer to adapter
2654 * @pRoamInfo: pointer to roam info
2655 *
2656 * We update the status of the IBSS to connected in this function.
2657 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302658 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002659 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302660static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661 tCsrRoamInfo *pRoamInfo)
2662{
2663 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002664 /*
2665 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2666 * a partner stations).
2667 */
2668 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2669
2670 /* Save the connection info from CSR... */
2671 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2672
2673 /* Send the bssid address to the wext. */
2674 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2675 /* add bss_id to cfg80211 data base */
2676 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2677 if (NULL == bss) {
2678 hddLog(LOGE,
2679 FL("%s: unable to create IBSS entry"),
2680 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302681 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002682 }
2683 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002684 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002685 bss);
2686
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302687 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002688}
2689
2690/**
2691 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2692 * @pAdapter: pointer to adapter
2693 * @pRoamInfo: pointer to roam info
2694 * @roamId: roam id
2695 * @roamStatus: roam status
2696 * @roamResult: roam result
2697 *
2698 * This function indicates the Mic failure to the supplicant
2699 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302700 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302702static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002703hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2704 tCsrRoamInfo *pRoamInfo,
2705 uint32_t roamId,
2706 eRoamCmdStatus roamStatus,
2707 eCsrRoamResult roamResult)
2708{
2709 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2710
2711 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2712 TKIP_COUNTER_MEASURE_STOPED ==
2713 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2714 struct iw_michaelmicfailure msg;
2715 union iwreq_data wreq;
2716 memset(&msg, '\0', sizeof(msg));
2717 msg.src_addr.sa_family = ARPHRD_ETHER;
2718 memcpy(msg.src_addr.sa_data,
2719 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2720 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2721 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2722 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2723
2724 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2725 msg.flags = IW_MICFAILURE_GROUP;
2726 else
2727 msg.flags = IW_MICFAILURE_PAIRWISE;
2728 memset(&wreq, 0, sizeof(wreq));
2729 wreq.data.length = sizeof(msg);
2730 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2731 (char *)&msg);
2732 /* inform mic failure to nl80211 */
2733 cfg80211_michael_mic_failure(pAdapter->dev,
2734 pRoamInfo->u.pMICFailureInfo->
2735 taMacAddr,
2736 ((pRoamInfo->u.pMICFailureInfo->
2737 multicast ==
2738 eSIR_TRUE) ?
2739 NL80211_KEYTYPE_GROUP :
2740 NL80211_KEYTYPE_PAIRWISE),
2741 pRoamInfo->u.pMICFailureInfo->
2742 keyId,
2743 pRoamInfo->u.pMICFailureInfo->TSC,
2744 GFP_KERNEL);
2745
2746 }
2747
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302748 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002749}
2750
2751/**
2752 * roam_roam_connect_status_update_handler() - IBSS connect status update
2753 * @pAdapter: pointer to adapter
2754 * @pRoamInfo: pointer to roam info
2755 * @roamId: roam id
2756 * @roamStatus: roam status
2757 * @roamResult: roam result
2758 *
2759 * The Ibss connection status is updated regularly here in this function.
2760 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302761 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302763static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002764roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2765 tCsrRoamInfo *pRoamInfo,
2766 uint32_t roamId,
2767 eRoamCmdStatus roamStatus,
2768 eCsrRoamResult roamResult)
2769{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302770 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771
2772 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2773 switch (roamResult) {
2774 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2775 {
2776 hdd_station_ctx_t *pHddStaCtx =
2777 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2778 struct station_info staInfo;
2779
2780 pr_info("IBSS New Peer indication from SME "
2781 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2782 MAC_ADDRESS_STR " and stationID= %d",
2783 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2784 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2785 pRoamInfo->staId);
2786
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002787 if (!hdd_save_peer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002788 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2789 pRoamInfo->staId,
2790 &pRoamInfo->peerMac)) {
2791 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2792 break;
2793 }
2794
2795 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2796
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002797 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302798 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799 pRoamInfo,
2800 pRoamInfo->staId,
2801 &pRoamInfo->peerMac,
2802 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302803 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002804 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302805 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2806 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 }
2808 pHddStaCtx->ibss_sta_generation++;
2809 memset(&staInfo, 0, sizeof(staInfo));
2810 staInfo.filled = 0;
2811 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2812
2813 cfg80211_new_sta(pAdapter->dev,
2814 (const u8 *)pRoamInfo->peerMac.bytes,
2815 &staInfo, GFP_KERNEL);
2816
2817 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2818 pHddStaCtx->ibss_enc_key.encType
2819 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2820 pHddStaCtx->ibss_enc_key.encType
2821 || eCSR_ENCRYPT_TYPE_TKIP ==
2822 pHddStaCtx->ibss_enc_key.encType
2823 || eCSR_ENCRYPT_TYPE_AES ==
2824 pHddStaCtx->ibss_enc_key.encType) {
2825 pHddStaCtx->ibss_enc_key.keyDirection =
2826 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302827 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002828 &pRoamInfo->peerMac);
2829
2830 hddLog(LOG2, "New peer joined set PTK encType=%d",
2831 pHddStaCtx->ibss_enc_key.encType);
2832
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302833 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002834 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2835 (pAdapter),
2836 pAdapter->sessionId,
2837 &pHddStaCtx->ibss_enc_key,
2838 &roamId);
2839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302840 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841 hddLog(LOGE,
2842 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302843 qdf_status);
2844 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845 }
2846 }
2847 hddLog(LOG1, FL("Enabling queues"));
2848 wlan_hdd_netif_queue_control(pAdapter,
2849 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2850 WLAN_CONTROL_PATH);
2851 break;
2852 }
2853
2854 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2855 {
2856
2857 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2858
2859 break;
2860 }
2861 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2862 {
2863 hdd_station_ctx_t *pHddStaCtx =
2864 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2865
2866 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2867 hddLog(LOGW,
2868 "IBSS peer departed by cannot find peer in our registration table with TL");
2869
2870 pr_info("IBSS Peer Departed from SME "
2871 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2872 MAC_ADDRESS_STR " and stationID= %d",
2873 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2874 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2875 pRoamInfo->staId);
2876
2877 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2878
2879 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2880 pHddStaCtx->ibss_sta_generation++;
2881
2882 cfg80211_del_sta(pAdapter->dev,
2883 (const u8 *)&pRoamInfo->peerMac.bytes,
2884 GFP_KERNEL);
2885 break;
2886 }
2887 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2888 {
2889 hddLog(LOG3,
2890 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2891 /* Stop only when we are inactive */
2892 hddLog(LOG1, FL("Disabling queues"));
2893 wlan_hdd_netif_queue_control(pAdapter,
2894 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2895 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 hdd_conn_set_connection_state(pAdapter,
2897 eConnectionState_NotConnected);
2898
2899 /* Send the bssid address to the wext. */
2900 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2901 break;
2902 }
2903 default:
2904 break;
2905
2906 }
2907
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302908 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002909}
2910
2911#ifdef FEATURE_WLAN_TDLS
2912/**
2913 * hdd_roam_register_tdlssta() - register new TDLS station
2914 * @pAdapter: pointer to adapter
2915 * @peerMac: pointer to peer MAC address
2916 * @staId: station identifier
2917 * @ucastSig: unicast signature
2918 *
2919 * Construct the staDesc and register with TL the new STA.
2920 * This is called as part of ADD_STA in the TDLS setup.
2921 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302922 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002923 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302924QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 const uint8_t *peerMac, uint16_t staId,
2926 uint8_t ucastSig)
2927{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302928 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002929 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002930 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002931
2932 /*
2933 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2934 * be peer MAC, here we are working on direct Link
2935 */
2936 staDesc.sta_id = staId;
2937
2938 /* set the QoS field appropriately .. */
2939 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2940 : (staDesc.is_qos_enabled = 0);
2941
Dhanashri Atre50141c52016-04-07 13:15:29 -07002942 /* Register the vdev transmit and receive functions */
2943 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2944 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2945 ol_txrx_vdev_register(
2946 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2947 pAdapter, &txrx_ops);
2948 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002949
2950 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002951 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302952 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002953 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302954 qdf_status, qdf_status);
2955 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002956 }
2957
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302958 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002959}
2960
2961/**
2962 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2963 * @pAdapter: pointer to adapter
2964 * @staId: station identifier
2965 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302966 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002967 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302968static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002969 uint8_t staId)
2970{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302971 QDF_STATUS qdf_status;
2972 qdf_status = ol_txrx_clear_peer(staId);
2973 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002974 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302975 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002976 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302977 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978}
2979
2980/**
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07002981 * hdd_tdls_connection_tracker_update() - update connection tracker state
2982 * @adapter: pointer to adapter
2983 * @roam_info: pointer to roam info
2984 * @hdd_tdls_ctx: tdls context
2985 *
2986 * Return: QDF_STATUS enumeration
2987 */
2988static QDF_STATUS hdd_tdls_connection_tracker_update(hdd_adapter_t *adapter,
2989 tCsrRoamInfo *roam_info,
2990 tdlsCtx_t *hdd_tdls_ctx)
2991{
2992 hddTdlsPeer_t *curr_peer;
2993 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2994
2995 curr_peer = wlan_hdd_tdls_find_peer(adapter,
2996 roam_info->peerMac.bytes, true);
2997
2998 if (!curr_peer) {
2999 hdd_err("curr_peer is null");
3000 return QDF_STATUS_E_FAILURE;
3001 }
3002
3003 mutex_lock(&hdd_ctx->tdls_lock);
3004
3005 if (eTDLS_LINK_CONNECTED ==
3006 curr_peer->link_status) {
3007 hdd_err("Received CONNECTION_TRACKER_NOTIFICATION "
3008 MAC_ADDRESS_STR
3009 " staId: %d, reason: %d",
3010 MAC_ADDR_ARRAY(roam_info->peerMac.bytes),
3011 roam_info->staId,
3012 roam_info->reasonCode);
3013
3014 if (roam_info->reasonCode ==
3015 eWNI_TDLS_PEER_ENTER_BUF_STA ||
3016 roam_info->reasonCode ==
3017 eWNI_TDLS_ENTER_BT_BUSY_MODE)
3018 hdd_ctx->enable_tdls_connection_tracker = true;
3019 else if (roam_info->reasonCode ==
3020 eWNI_TDLS_PEER_EXIT_BUF_STA ||
3021 roam_info->reasonCode ==
3022 eWNI_TDLS_EXIT_BT_BUSY_MODE)
3023 hdd_ctx->enable_tdls_connection_tracker = false;
3024
3025 } else {
3026 hdd_err("TDLS not connected, ignore notification, reason: %d",
3027 roam_info->reasonCode);
3028 }
3029
3030 mutex_unlock(&hdd_ctx->tdls_lock);
3031
3032 return QDF_STATUS_SUCCESS;
3033}
3034
3035
3036
3037
3038/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003039 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
3040 * @pAdapter: pointer to adapter
3041 * @pRoamInfo: pointer to roam info
3042 * @roamId: roam id
3043 * @roamStatus: roam status
3044 * @roamResult: roam result
3045 *
3046 * HDD interface between SME and TL to ensure TDLS client registration with
3047 * TL in case of new TDLS client is added and deregistration at the time
3048 * TDLS client is deleted.
3049 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303050 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003051 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303052static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3054 tCsrRoamInfo *pRoamInfo,
3055 uint32_t roamId,
3056 eRoamCmdStatus roamStatus,
3057 eCsrRoamResult roamResult)
3058{
3059 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3060 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3061 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303062 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063 uint8_t staIdx;
3064 hddTdlsPeer_t *curr_peer;
3065 uint32_t reason;
3066
3067 hddLog(LOG2,
3068 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3069 roamResult ==
3070 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3071 ==
3072 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3073 roamResult ==
3074 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3075 : roamResult ==
3076 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3077 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3078 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3079 roamResult ==
3080 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3081 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3082 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3083 : roamResult ==
3084 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3085 : roamResult ==
3086 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3087 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3088 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3089
3090 if (!pHddTdlsCtx) {
3091 hddLog(LOG1,
3092 FL("TDLS ctx is null, ignore roamResult (%d)"),
3093 roamResult);
3094 return status;
3095 }
3096
3097 switch (roamResult) {
3098 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3099 {
3100 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3101 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3102 pRoamInfo->statusCode);
3103 } else {
3104 /*
3105 * Check if there is available index for this new TDLS
3106 * STA.
3107 */
3108 for (staIdx = 0;
3109 staIdx < pHddCtx->max_num_tdls_sta;
3110 staIdx++) {
3111 if (0 ==
3112 pHddCtx->tdlsConnInfo[staIdx].
3113 staId) {
3114 pHddCtx->tdlsConnInfo[staIdx].
3115 sessionId =
3116 pRoamInfo->sessionId;
3117 pHddCtx->tdlsConnInfo[staIdx].
3118 staId = pRoamInfo->staId;
3119
3120 hddLog(LOGW,
3121 ("TDLS: STA IDX at %d is %d "
3122 "of mac "
3123 MAC_ADDRESS_STR),
3124 staIdx,
3125 pHddCtx->
3126 tdlsConnInfo[staIdx].
3127 staId,
3128 MAC_ADDR_ARRAY
3129 (pRoamInfo->peerMac.bytes));
3130
Anurag Chouhanc5548422016-02-24 18:33:27 +05303131 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003132 tdlsConnInfo
3133 [staIdx].
3134 peerMac,
3135 &pRoamInfo->
3136 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303137 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138 break;
3139 }
3140 }
3141 if (staIdx < pHddCtx->max_num_tdls_sta) {
3142 if (-1 ==
3143 wlan_hdd_tdls_set_sta_id(pAdapter,
3144 pRoamInfo->
3145 peerMac.bytes,
3146 pRoamInfo->
3147 staId)) {
3148 hddLog(LOGE,
3149 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303150 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003151 }
3152
3153 (WLAN_HDD_GET_CTX(pAdapter))->
3154 sta_to_adapter[pRoamInfo->staId] =
3155 pAdapter;
3156 /*
3157 * store the ucast signature,
3158 * if required for further reference.
3159 */
3160
3161 wlan_hdd_tdls_set_signature(pAdapter,
3162 pRoamInfo->
3163 peerMac.bytes,
3164 pRoamInfo->
3165 ucastSig);
3166 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303167 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003168 hddLog(LOGE,
3169 FL("no available slot in conn_info. staId %d cannot be stored"),
3170 pRoamInfo->staId);
3171 }
3172 pAdapter->tdlsAddStaStatus = status;
3173 }
3174 complete(&pAdapter->tdls_add_station_comp);
3175 break;
3176 }
3177 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3178 {
3179 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3180 hddLog(LOGE,
3181 FL("Add Sta failed. status code(=%d)"),
3182 pRoamInfo->statusCode);
3183 }
3184 /* store the ucast signature which will be used later when
3185 * registering to TL
3186 */
3187 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3188 complete(&pAdapter->tdls_add_station_comp);
3189 break;
3190 }
3191 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3192 {
3193 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3194 hddLog(LOGE,
3195 FL("Link Establish Request failed. status(=%d)"),
3196 pRoamInfo->statusCode);
3197 }
3198 complete(&pAdapter->tdls_link_establish_req_comp);
3199 break;
3200 }
3201 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3202 {
3203 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3204 staIdx++) {
3205 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3206 pRoamInfo->sessionId)
3207 && pRoamInfo->staId ==
3208 pHddCtx->tdlsConnInfo[staIdx].staId) {
3209 hddLog(LOGW,
3210 ("HDD: del STA IDX = %x"),
3211 pRoamInfo->staId);
3212
3213 curr_peer =
3214 wlan_hdd_tdls_find_peer(pAdapter,
3215 pRoamInfo->
3216 peerMac.bytes,
3217 true);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303218 if (NULL != curr_peer) {
3219 hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
3220 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3221 curr_peer->link_status);
3222 if (TDLS_IS_CONNECTED(curr_peer)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003223 hdd_roam_deregister_tdlssta
3224 (pAdapter,
3225 pRoamInfo->staId);
3226 wlan_hdd_tdls_decrement_peer_count
3227 (pAdapter);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303228 } else if (eTDLS_LINK_CONNECTING ==
3229 curr_peer->link_status) {
3230 hdd_roam_deregister_tdlssta
3231 (pAdapter,
3232 pRoamInfo->staId);
3233 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003234 }
3235 wlan_hdd_tdls_reset_peer(pAdapter,
3236 pRoamInfo->
3237 peerMac.bytes);
3238
3239 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3240 pHddCtx->tdlsConnInfo[staIdx].
3241 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303242 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003243 tdlsConnInfo[staIdx].
3244 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303245 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303246 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003247 break;
3248 }
3249 }
3250 complete(&pAdapter->tdls_del_station_comp);
3251 }
3252 break;
3253 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3254 {
3255 hddLog(LOGE,
3256 FL("Sending teardown to supplicant with reason code %u"),
3257 pRoamInfo->reasonCode);
3258
3259 curr_peer =
3260 wlan_hdd_tdls_find_peer(pAdapter,
3261 pRoamInfo->peerMac.bytes, true);
3262 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3263 pRoamInfo->reasonCode);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303264 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
3265 curr_peer->peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303266 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267 break;
3268 }
3269 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3270 {
3271 /* 0 staIdx is assigned to AP we dont want to touch that */
3272 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3273 staIdx++) {
3274 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3275 pRoamInfo->sessionId)
3276 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3277 hddLog(LOGW,
3278 ("hdd_tdlsStatusUpdate: staIdx %d "
3279 MAC_ADDRESS_STR),
3280 pHddCtx->tdlsConnInfo[staIdx].
3281 staId,
3282 MAC_ADDR_ARRAY(pHddCtx->
3283 tdlsConnInfo
3284 [staIdx].
3285 peerMac.
3286 bytes));
3287 wlan_hdd_tdls_reset_peer(pAdapter,
3288 pHddCtx->
3289 tdlsConnInfo
3290 [staIdx].
3291 peerMac.bytes);
3292 hdd_roam_deregister_tdlssta(pAdapter,
3293 pHddCtx->
3294 tdlsConnInfo
3295 [staIdx].
3296 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303297 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003298 sizeof
3299 (smeTdlsPeerStateParams));
3300 smeTdlsPeerStateParams.vdevId =
3301 pHddCtx->tdlsConnInfo[staIdx].
3302 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303303 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003304 peerMacAddr,
3305 &pHddCtx->
3306 tdlsConnInfo[staIdx].
3307 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303308 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003309 smeTdlsPeerStateParams.peerState =
3310 eSME_TDLS_PEER_STATE_TEARDOWN;
3311
3312 hddLog(LOG1,
3313 FL("calling sme_update_tdls_peer_state for staIdx %d "
3314 MAC_ADDRESS_STR),
3315 pHddCtx->tdlsConnInfo[staIdx].
3316 staId,
3317 MAC_ADDR_ARRAY(pHddCtx->
3318 tdlsConnInfo
3319 [staIdx].
3320 peerMac.
3321 bytes));
3322 status =
3323 sme_update_tdls_peer_state(
3324 pHddCtx->hHal,
3325 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303326 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003327 hddLog(LOGE,
3328 FL("sme_update_tdls_peer_state failed for "
3329 MAC_ADDRESS_STR),
3330 MAC_ADDR_ARRAY
3331 (pHddCtx->
3332 tdlsConnInfo[staIdx].
3333 peerMac.bytes));
3334 }
3335 wlan_hdd_tdls_decrement_peer_count
3336 (pAdapter);
3337
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303338 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003339 tdlsConnInfo[staIdx].
3340 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303341 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003342 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3343 pHddCtx->tdlsConnInfo[staIdx].
3344 sessionId = 255;
3345
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303346 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003347 }
3348 }
3349 break;
3350 }
3351 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3352 {
3353 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303354 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3355 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356 hddLog(LOG2,
3357 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3358 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303359 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303360 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 break;
3362 }
3363
Archana Ramachandran7ba24ff2016-04-26 12:29:04 -07003364 if (pHddCtx->tdls_nss_switch_in_progress) {
3365 hdd_err("TDLS antenna switch is in progress, ignore SHOULD_DISCOVER");
3366 status = QDF_STATUS_SUCCESS;
3367 break;
3368 }
3369
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370 curr_peer =
3371 wlan_hdd_tdls_get_peer(pAdapter,
Kabilan Kannan36090ce2016-05-03 19:28:44 -07003372 pRoamInfo->peerMac.bytes,
3373 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003374 if (!curr_peer) {
3375 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303376 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003377 } else {
3378 if (eTDLS_LINK_CONNECTED ==
3379 curr_peer->link_status) {
3380 hddLog(LOGE,
3381 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3382 } else {
3383 /*
3384 * If external control is enabled then initiate
3385 * TDLS only if forced peer is set otherwise
3386 * ignore should Discover trigger from fw.
3387 */
3388 if (pHddCtx->config->
3389 fTDLSExternalControl
3390 && (false ==
3391 curr_peer->isForcedPeer)) {
3392 hddLog(LOG2,
3393 FL
3394 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303395 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396 break;
3397 } else {
3398 hddLog(LOG2,
3399 FL
3400 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3401 pHddCtx->config->
3402 fTDLSExternalControl,
3403 curr_peer->isForcedPeer,
3404 pRoamInfo->reasonCode);
3405 }
3406 wlan_hdd_tdls_pre_setup_init_work
3407 (pHddTdlsCtx, curr_peer);
3408 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303409 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 }
3411 break;
3412 }
3413
3414 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3415 {
3416 curr_peer =
3417 wlan_hdd_tdls_find_peer(pAdapter,
3418 pRoamInfo->peerMac.bytes, true);
3419 if (!curr_peer) {
3420 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303421 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003422 } else {
3423 if (eTDLS_LINK_CONNECTED ==
3424 curr_peer->link_status) {
3425 hddLog(LOGE,
3426 FL
3427 ("Received SHOULD_TEARDOWN for peer "
3428 MAC_ADDRESS_STR
3429 " staId: %d, reason: %d"),
3430 MAC_ADDR_ARRAY(pRoamInfo->
3431 peerMac.bytes),
3432 pRoamInfo->staId,
3433 pRoamInfo->reasonCode);
3434
3435 if (pRoamInfo->reasonCode ==
3436 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3437 pRoamInfo->reasonCode ==
3438 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3439 pRoamInfo->reasonCode ==
3440 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3441 pRoamInfo->reasonCode ==
3442 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3443 reason =
3444 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3445 } else
3446 reason =
3447 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3448
3449 wlan_hdd_tdls_indicate_teardown
3450 (pHddTdlsCtx->pAdapter, curr_peer,
3451 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303452 hdd_send_wlan_tdls_teardown_event(
3453 eTDLS_TEARDOWN_BSS_DISCONNECT,
3454 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003455 } else {
3456 hddLog(LOGE,
3457 FL
3458 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3459 pRoamInfo->reasonCode);
3460 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303461 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003462 }
3463 break;
3464 }
3465
3466 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3467 {
3468 curr_peer =
3469 wlan_hdd_tdls_find_peer(pAdapter,
3470 pRoamInfo->peerMac.bytes, true);
3471 if (!curr_peer) {
3472 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303473 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 } else {
3475 if (eTDLS_LINK_CONNECTED ==
3476 curr_peer->link_status) {
3477 hddLog(LOGE,
3478 FL
3479 ("Received SHOULD_PEER_DISCONNECTED for peer "
3480 MAC_ADDRESS_STR
3481 " staId: %d, reason: %d"),
3482 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3483 pRoamInfo->staId,
3484 pRoamInfo->reasonCode);
3485
3486 if (pRoamInfo->reasonCode ==
3487 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3488 pRoamInfo->reasonCode ==
3489 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3490 pRoamInfo->reasonCode ==
3491 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3492 pRoamInfo->reasonCode ==
3493 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3494 reason =
3495 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3496 } else
3497 reason =
3498 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3499
3500 wlan_hdd_tdls_indicate_teardown
3501 (pHddTdlsCtx->pAdapter, curr_peer,
3502 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303503 hdd_send_wlan_tdls_teardown_event(
3504 eTDLS_TEARDOWN_BSS_DISCONNECT,
3505 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506 } else {
3507 hddLog(LOGE,
3508 FL
3509 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3510 pRoamInfo->reasonCode);
3511 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303512 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003513 }
3514 break;
3515 }
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07003516
3517 case eCSR_ROAM_RESULT_TDLS_CONNECTION_TRACKER_NOTIFICATION:
3518 status = hdd_tdls_connection_tracker_update(pAdapter,
3519 pRoamInfo,
3520 pHddTdlsCtx);
3521 break;
3522
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003523 default:
3524 {
3525 break;
3526 }
3527 }
3528
3529 return status;
3530}
3531#endif
3532
3533#ifdef WLAN_FEATURE_11W
3534/**
3535 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3536 * @pAdapter: pointer to the adapter
3537 * @nFrameLength: Length of the unprotected frame being passed
3538 * @pbFrames: Pointer to the frame buffer
3539 * @frameType: 802.11 frame type
3540 *
3541 * This function forwards the unprotected management frame to the supplicant.
3542 *
3543 * Return: nothing
3544 */
3545static void
3546hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3547 uint8_t *pbFrames, uint8_t frameType)
3548{
3549 uint8_t type = 0;
3550 uint8_t subType = 0;
3551
3552 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3553 frameType, nFrameLength);
3554
3555 /* Sanity Checks */
3556 if (NULL == pAdapter) {
3557 hddLog(LOGE, FL("pAdapter is NULL"));
3558 return;
3559 }
3560
3561 if (NULL == pAdapter->dev) {
3562 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3563 return;
3564 }
3565
3566 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3567 hddLog(LOGE, FL("pAdapter has invalid magic"));
3568 return;
3569 }
3570
3571 if (!nFrameLength) {
3572 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3573 return;
3574 }
3575
3576 if (NULL == pbFrames) {
3577 hddLog(LOGE, FL("pbFrames is NULL"));
3578 return;
3579 }
3580
3581 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3582 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3583
3584 /* Get pAdapter from Destination mac address of the frame */
3585 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3587 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3588 nFrameLength);
3589#else
3590 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3591 nFrameLength);
3592#endif
3593 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3594 } else if (type == SIR_MAC_MGMT_FRAME &&
3595 subType == SIR_MAC_MGMT_DEAUTH) {
3596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3597 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3598 nFrameLength);
3599#else
3600 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3601 nFrameLength);
3602#endif
3603 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3604 } else {
3605 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3606 type, subType);
3607 return;
3608 }
3609}
3610#endif
3611
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003612#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003613/**
3614 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3615 * @pAdapter: pointer to adapter
3616 * @tid: traffic identifier
3617 * @state: state
3618 * @measInterval: measurement interval
3619 *
3620 * This function sends traffic stream metrics IE information to
3621 * the supplicant via wireless event.
3622 *
3623 * Return: none
3624 */
3625static void
3626hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3627 uint8_t state, uint16_t measInterval)
3628{
3629 union iwreq_data wrqu;
3630 char buf[IW_CUSTOM_MAX + 1];
3631 int nBytes = 0;
3632
3633 if (NULL == pAdapter)
3634 return;
3635
3636 /* create the event */
3637 memset(&wrqu, '\0', sizeof(wrqu));
3638 memset(buf, '\0', sizeof(buf));
3639
3640 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3641 tid, state, measInterval);
3642
3643 nBytes =
3644 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3645 measInterval);
3646
3647 wrqu.data.pointer = buf;
3648 wrqu.data.length = nBytes;
3649 /* send the event */
3650 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3651}
3652
3653/**
3654 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3655 * @pAdapter: pointer to adapter
3656 * @pRoamInfo: pointer to roam info
3657 *
3658 * This function sends cckm preauth indication to the supplicant
3659 * via wireless custom event.
3660 *
3661 * Return: none
3662 */
3663static void
3664hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3665{
3666 union iwreq_data wrqu;
3667 char buf[IW_CUSTOM_MAX + 1];
3668 char *pos = buf;
3669 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3670
3671 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3672 return;
3673
3674 /* create the event */
3675 memset(&wrqu, '\0', sizeof(wrqu));
3676 memset(buf, '\0', sizeof(buf));
3677
3678 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3679 hddLog(LOG1,
3680 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3681 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3682 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3683
3684 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3685 pos += nBytes;
3686 freeBytes -= nBytes;
3687
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303688 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303689 pos += QDF_MAC_ADDR_SIZE;
3690 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003691
3692 nBytes = snprintf(pos, freeBytes, " %u:%u",
3693 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3694 freeBytes -= nBytes;
3695
3696 wrqu.data.pointer = buf;
3697 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3698
3699 /* send the event */
3700 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3701}
3702
3703/**
3704 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3705 * @pAdapter: pointer to adapter
3706 * @pRoamInfo: pointer to roam info
3707 *
3708 * Return: none
3709 */
3710static void
3711hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3712 tCsrRoamInfo *pRoamInfo)
3713{
3714 union iwreq_data wrqu;
3715 char buf[IW_CUSTOM_MAX + 1];
3716 int nBytes = 0;
3717
3718 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3719 return;
3720
3721 /* create the event */
3722 memset(&wrqu, '\0', sizeof(wrqu));
3723 memset(buf, '\0', sizeof(buf));
3724
3725 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3726
3727 nBytes =
3728 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3729 pRoamInfo->tsmRoamDelay);
3730
3731 wrqu.data.pointer = buf;
3732 wrqu.data.length = nBytes;
3733
3734 /* send the event */
3735 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3736}
3737
3738/**
3739 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3740 * @pAdapter: pointer to adapter
3741 * @measurementToken: measurement token
3742 * @flag: flag
3743 * @numBss: number of bss
3744 *
3745 * If the measurement is none and no scan results found,
3746 * indicate the supplicant about measurement done.
3747 *
3748 * Return: none
3749 */
3750void
3751hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3752 const uint16_t measurementToken,
3753 const bool flag, const uint8_t numBss)
3754{
3755 union iwreq_data wrqu;
3756 char buf[IW_CUSTOM_MAX];
3757 char *pos = buf;
3758 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3759
3760 memset(&wrqu, '\0', sizeof(wrqu));
3761 memset(buf, '\0', sizeof(buf));
3762
3763 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3764 flag, numBss);
3765
3766 nBytes =
3767 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3768 flag, numBss);
3769
3770 wrqu.data.pointer = buf;
3771 wrqu.data.length = nBytes;
3772 /* send the event */
3773 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3774}
3775
3776/**
3777 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3778 * @pAdapter: pointer to adapter
3779 * @pRoamInfo: pointer to roam info
3780 *
3781 * If the measurement is none and no scan results found,
3782 * indicate the supplicant about measurement done.
3783 *
3784 * Return: none
3785 */
3786static void
3787hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3788 const tCsrRoamInfo *pRoamInfo)
3789{
3790 union iwreq_data wrqu;
3791 char buf[IW_CUSTOM_MAX];
3792 char *pos = buf;
3793 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3794 uint8_t i = 0, len = 0;
3795 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3796 uint8_t lastSent = 0, sendBss = 0;
3797 int bcnRepFieldSize =
3798 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3799 bcnReportFields);
3800 uint8_t ieLenByte = 1;
3801 /*
3802 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3803 */
3804#define ESEBCNREPHEADER_LEN (18)
3805
3806 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3807 return;
3808
3809 /*
3810 * Custom event can pass maximum of 256 bytes of data,
3811 * based on the IE len we need to identify how many BSS info can
3812 * be filled in to custom event data.
3813 */
3814 /*
3815 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3816 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3817 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3818 */
3819
3820 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3821 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3822 hddLog(LOG1,
3823 "Measurement Done but no scan results");
3824 /* If the measurement is none and no scan results found,
3825 indicate the supplicant about measurement done */
3826 hdd_indicate_ese_bcn_report_no_results(
3827 pAdapter,
3828 pRoamInfo->pEseBcnReportRsp->
3829 measurementToken,
3830 pRoamInfo->pEseBcnReportRsp->flag,
3831 pRoamInfo->pEseBcnReportRsp->numBss);
3832 } else {
3833 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3834 memset(&wrqu, '\0', sizeof(wrqu));
3835 memset(buf, '\0', sizeof(buf));
3836 tot_bcn_ieLen = 0;
3837 sendBss = 0;
3838 pos = buf;
3839 freeBytes = IW_CUSTOM_MAX;
3840
3841 for (i = lastSent;
3842 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3843 len =
3844 bcnRepFieldSize + ieLenByte +
3845 pRoamInfo->pEseBcnReportRsp->
3846 bcnRepBssInfo[i].ieLen;
3847 if ((len + tot_bcn_ieLen) >
3848 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3849 break;
3850 }
3851 tot_bcn_ieLen += len;
3852 sendBss++;
3853 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3854 i, bcnRepFieldSize, 1,
3855 pRoamInfo->pEseBcnReportRsp->
3856 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3857 }
3858
3859 hddLog(LOG1, "Sending %d BSS Info",
3860 sendBss);
3861 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3862 pRoamInfo->pEseBcnReportRsp->measurementToken,
3863 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3864 tot_bcn_ieLen);
3865
3866 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3867 pRoamInfo->pEseBcnReportRsp->
3868 measurementToken,
3869 pRoamInfo->pEseBcnReportRsp->flag,
3870 sendBss);
3871 pos += nBytes;
3872 freeBytes -= nBytes;
3873
3874 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303875 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876 sizeof(tot_bcn_ieLen));
3877 pos += sizeof(tot_bcn_ieLen);
3878 freeBytes -= sizeof(tot_bcn_ieLen);
3879
3880 for (i = 0; i < sendBss; i++) {
3881 hddLog(LOG1,
3882 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3883 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3884 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3885 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3886 pRoamInfo->pEseBcnReportRsp->
3887 bcnRepBssInfo[i +
3888 lastSent].bcnReportFields.
3889 ChanNum,
3890 pRoamInfo->pEseBcnReportRsp->
3891 bcnRepBssInfo[i +
3892 lastSent].bcnReportFields.
3893 Spare,
3894 pRoamInfo->pEseBcnReportRsp->
3895 bcnRepBssInfo[i +
3896 lastSent].bcnReportFields.
3897 MeasDuration,
3898 pRoamInfo->pEseBcnReportRsp->
3899 bcnRepBssInfo[i +
3900 lastSent].bcnReportFields.
3901 PhyType,
3902 pRoamInfo->pEseBcnReportRsp->
3903 bcnRepBssInfo[i +
3904 lastSent].bcnReportFields.
3905 RecvSigPower,
3906 pRoamInfo->pEseBcnReportRsp->
3907 bcnRepBssInfo[i +
3908 lastSent].bcnReportFields.
3909 ParentTsf,
3910 pRoamInfo->pEseBcnReportRsp->
3911 bcnRepBssInfo[i +
3912 lastSent].bcnReportFields.
3913 TargetTsf[0],
3914 pRoamInfo->pEseBcnReportRsp->
3915 bcnRepBssInfo[i +
3916 lastSent].bcnReportFields.
3917 TargetTsf[1],
3918 pRoamInfo->pEseBcnReportRsp->
3919 bcnRepBssInfo[i +
3920 lastSent].bcnReportFields.
3921 BcnInterval,
3922 pRoamInfo->pEseBcnReportRsp->
3923 bcnRepBssInfo[i +
3924 lastSent].bcnReportFields.
3925 CapabilityInfo,
3926 pRoamInfo->pEseBcnReportRsp->
3927 bcnRepBssInfo[i +
3928 lastSent].bcnReportFields.
3929 Bssid[0],
3930 pRoamInfo->pEseBcnReportRsp->
3931 bcnRepBssInfo[i +
3932 lastSent].bcnReportFields.
3933 Bssid[1],
3934 pRoamInfo->pEseBcnReportRsp->
3935 bcnRepBssInfo[i +
3936 lastSent].bcnReportFields.
3937 Bssid[2],
3938 pRoamInfo->pEseBcnReportRsp->
3939 bcnRepBssInfo[i +
3940 lastSent].bcnReportFields.
3941 Bssid[3],
3942 pRoamInfo->pEseBcnReportRsp->
3943 bcnRepBssInfo[i +
3944 lastSent].bcnReportFields.
3945 Bssid[4],
3946 pRoamInfo->pEseBcnReportRsp->
3947 bcnRepBssInfo[i +
3948 lastSent].bcnReportFields.
3949 Bssid[5]);
3950
3951 /* bcn report fields are copied */
3952 len =
3953 sizeof(pRoamInfo->pEseBcnReportRsp->
3954 bcnRepBssInfo[i +
3955 lastSent].
3956 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303957 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003958 (char *)&pRoamInfo->
3959 pEseBcnReportRsp->bcnRepBssInfo[i +
3960 lastSent].
3961 bcnReportFields, len);
3962 pos += len;
3963 freeBytes -= len;
3964
3965 /* Add 1 byte of ie len */
3966 len =
3967 pRoamInfo->pEseBcnReportRsp->
3968 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303969 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003970 pos += sizeof(len);
3971 freeBytes -= sizeof(len);
3972
3973 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303974 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003975 (char *)pRoamInfo->
3976 pEseBcnReportRsp->bcnRepBssInfo[i +
3977 lastSent].
3978 pBuf, len);
3979 pos += len;
3980 freeBytes -= len;
3981 }
3982
3983 wrqu.data.pointer = buf;
3984 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3985
3986 /* send the event */
3987 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3988 buf);
3989 lastSent += sendBss;
3990 }
3991 }
3992}
3993
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003994#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003995
3996/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303997 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3998 * @pHddStaCtx: Station Context
3999 *
4000 * API to check if the connection authentication type is 8021x_sha256.
4001 *
4002 * Return: bool
4003 */
4004#ifdef WLAN_FEATURE_11W
4005static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
4006{
4007 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
4008 pHddStaCtx->conn_info.authType;
4009}
4010#else
4011static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
4012{
4013 return false;
4014}
4015#endif
4016
4017/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004018 * hdd_sme_roam_callback() - hdd sme roam callback
4019 * @pContext: pointer to adapter context
4020 * @pRoamInfo: pointer to roam info
4021 * @roamId: roam id
4022 * @roamStatus: roam status
4023 * @roamResult: roam result
4024 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304025 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004026 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304027QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004028hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
4029 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
4030{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304031 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004032 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
4033 hdd_wext_state_t *pWextState = NULL;
4034 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304035 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004036 hdd_context_t *pHddCtx = NULL;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304037 struct hdd_chan_change_params chan_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038
4039 hddLog(LOG2,
4040 "CSR Callback: status= %d result= %d roamID=%d",
4041 roamStatus, roamResult, roamId);
4042
4043 /* Sanity check */
4044 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
4045 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304046 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004047 }
4048
4049 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4050 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4051
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304052 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05304053 pAdapter->sessionId, roamStatus));
4054
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004055 switch (roamStatus) {
4056 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05304057 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
4058 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08004059 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004060 break;
4061
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004062 /*
4063 * We did pre-auth,then we attempted a 11r or ese reassoc.
4064 * reassoc failed due to failure, timeout, reject from ap
4065 * in any case tell the OS, our carrier is off and mark
4066 * interface down.
4067 */
4068 case eCSR_ROAM_FT_REASSOC_FAILED:
4069 hddLog(LOGE,
4070 FL
4071 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
4072 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304073 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004074 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4075 roamStatus, roamResult);
4076 /*
4077 * Check if Mcast/Bcast Filters are set, if yes
4078 * clear the filters here.
4079 */
4080 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4081 true) {
4082 (WLAN_HDD_GET_CTX(pAdapter))->
4083 hdd_mcastbcast_filter_set = false;
4084 }
4085 pHddStaCtx->ft_carrier_on = false;
4086 pHddStaCtx->hdd_ReassocScenario = false;
4087 hddLog(LOG1,
4088 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4089 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4090 break;
4091
4092 case eCSR_ROAM_FT_START:
4093 /*
4094 * When we roam for ESE and 11r, we dont want the OS to be
4095 * informed that the link is down. So mark the link ready for
4096 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4097 * be received. Where in we will not mark the link down
4098 * Also we want to stop tx at this point when we will be
4099 * doing disassoc at this time. This saves 30-60 msec
4100 * after reassoc.
4101 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004102 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004103 wlan_hdd_netif_queue_control(pAdapter,
4104 WLAN_NETIF_TX_DISABLE,
4105 WLAN_CONTROL_PATH);
4106 status = hdd_roam_deregister_sta(pAdapter,
4107 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304108 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304109 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004110 pHddStaCtx->ft_carrier_on = true;
4111 pHddStaCtx->hdd_ReassocScenario = true;
4112 hddLog(LOG1,
4113 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4114 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4115 break;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004116 case eCSR_ROAM_DISABLE_QUEUES:
4117 hdd_info("Disabling queues");
4118 wlan_hdd_netif_queue_control(pAdapter,
4119 WLAN_NETIF_TX_DISABLE,
4120 WLAN_CONTROL_PATH);
4121 break;
4122 case eCSR_ROAM_ENABLE_QUEUES:
4123 hdd_info("Enabling queues");
4124 wlan_hdd_netif_queue_control(pAdapter,
4125 WLAN_WAKE_ALL_NETIF_QUEUE,
4126 WLAN_CONTROL_PATH);
4127 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004128
4129 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130 /* notify apps that we can't pass traffic anymore */
4131 hddLog(LOG1, FL("Disabling queues"));
4132 wlan_hdd_netif_queue_control(pAdapter,
4133 WLAN_NETIF_TX_DISABLE,
4134 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004135 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004136 wlan_hdd_netif_queue_control(pAdapter,
4137 WLAN_NETIF_CARRIER_OFF,
4138 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004139 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140 break;
4141 case eCSR_ROAM_LOSTLINK:
4142 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4143 hddLog(LOG2, "Roaming started due to connection lost");
4144 hddLog(LOG1, FL("Disabling queues"));
4145 wlan_hdd_netif_queue_control(pAdapter,
4146 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4147 WLAN_CONTROL_PATH);
4148 break;
4149 }
4150 case eCSR_ROAM_DISASSOCIATED:
4151 {
4152 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304153 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004154 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4155 roamStatus, roamResult);
4156 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4158 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4159 hdd_conf_mcastbcast_filter(pHddCtx, false);
4160
4161 if (true ==
4162 pHddCtx->sus_res_mcastbcast_filter_valid) {
4163 pHddCtx->configuredMcastBcastFilter =
4164 pHddCtx->sus_res_mcastbcast_filter;
4165 pHddCtx->
4166 sus_res_mcastbcast_filter_valid =
4167 false;
4168 }
4169
4170 hddLog(LOG1,
4171 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4172 hddLog(LOG1,
4173 "McastBcastFilter = %d",
4174 pHddCtx->configuredMcastBcastFilter);
4175 hddLog(LOG1,
4176 "offload: already called mcastbcast filter");
4177 (WLAN_HDD_GET_CTX(pAdapter))->
4178 hdd_mcastbcast_filter_set = false;
4179 }
4180 /* Call to clear any MC Addr List filter applied after
4181 * successful connection.
4182 */
4183 wlan_hdd_set_mc_addr_list(pAdapter, false);
4184 }
4185 break;
4186 case eCSR_ROAM_IBSS_LEAVE:
4187 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304188 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004189 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4190 roamStatus, roamResult);
4191 break;
4192 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4193 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4194 /*
4195 * To Do - address probable memory leak with WEP encryption upon
4196 * successful association.
4197 */
4198 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4199 /* Clear saved connection information in HDD */
4200 hdd_conn_remove_connect_info(
4201 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4202 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304203 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 hdd_association_completion_handler(pAdapter, pRoamInfo,
4205 roamId, roamStatus,
4206 roamResult);
4207#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4208 if (pRoamInfo)
4209 pRoamInfo->roamSynchInProgress = false;
4210#endif
4211 break;
4212 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304213 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004214 pRoamInfo,
4215 roamId,
4216 roamStatus,
4217 roamResult);
4218 break;
4219 case eCSR_ROAM_IBSS_IND:
4220 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4221 roamStatus, roamResult);
4222 break;
4223
4224 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304225 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 roam_roam_connect_status_update_handler(pAdapter,
4227 pRoamInfo,
4228 roamId,
4229 roamStatus,
4230 roamResult);
4231 break;
4232
4233 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304234 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235 hdd_roam_mic_error_indication_handler(pAdapter,
4236 pRoamInfo,
4237 roamId,
4238 roamStatus,
4239 roamResult);
4240 break;
4241
4242 case eCSR_ROAM_SET_KEY_COMPLETE:
4243 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304244 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4246 roamId, roamStatus,
4247 roamResult);
4248 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4249 pHddStaCtx->hdd_ReassocScenario = false;
4250 hddLog(LOG1,
4251 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4252 pHddStaCtx->hdd_ReassocScenario,
4253 pAdapter->sessionId);
4254 }
4255 }
4256#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4257 if (pRoamInfo != NULL)
4258 pRoamInfo->roamSynchInProgress = false;
4259#endif
4260 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004261
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004262 case eCSR_ROAM_FT_RESPONSE:
4263 hdd_send_ft_event(pAdapter);
4264 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004265
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304267 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4268 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004269 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304270 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004271 wlan_hdd_cfg80211_pmksa_candidate_notify(
4272 pAdapter, pRoamInfo, 1, false);
4273 }
4274 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275
4276#ifdef FEATURE_WLAN_LFR_METRICS
4277 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4278 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304279 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004280 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4281 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304282 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004283 }
4284 break;
4285 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4286 /*
4287 * This event will notify pre-auth completion in case of success
4288 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304289 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004290 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4291 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304292 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004293 }
4294 break;
4295 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4296 /*
4297 * This event will notify pre-auth completion incase of failure.
4298 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304299 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004300 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4301 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304302 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004303 }
4304 break;
4305 case eCSR_ROAM_HANDOVER_SUCCESS:
4306 /* This event is to notify handover success.
4307 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304308 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004309 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4310 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304311 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004312 }
4313 break;
4314#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004315 case eCSR_ROAM_REMAIN_CHAN_READY:
4316 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4317 break;
4318 case eCSR_ROAM_SEND_ACTION_CNF:
4319 hdd_send_action_cnf(pAdapter,
4320 (roamResult ==
4321 eCSR_ROAM_RESULT_NONE) ? true : false);
4322 break;
4323#ifdef FEATURE_WLAN_TDLS
4324 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304325 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004326 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4327 roamId,
4328 roamStatus,
4329 roamResult);
4330 break;
4331 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4332 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4333 pRoamInfo->reasonCode);
4334 break;
4335#endif
4336#ifdef WLAN_FEATURE_11W
4337 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4338 hdd_indicate_unprot_mgmt_frame(pAdapter,
4339 pRoamInfo->nFrameLength,
4340 pRoamInfo->pbFrames,
4341 pRoamInfo->frameType);
4342 break;
4343#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004344#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345 case eCSR_ROAM_TSM_IE_IND:
4346 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4347 pRoamInfo->tsmIe.state,
4348 pRoamInfo->tsmIe.msmt_interval);
4349 break;
4350
4351 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4352 {
4353 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4354 pHddStaCtx->conn_info.authType
4355 || eCSR_AUTH_TYPE_CCKM_RSN ==
4356 pHddStaCtx->conn_info.authType) {
4357 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4358 }
4359 break;
4360 }
4361
4362 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4363 {
4364 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4365 break;
4366 }
4367
4368 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4369 {
4370 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4371 break;
4372 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004373#endif /* FEATURE_WLAN_ESE */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304374 case eCSR_ROAM_STA_CHANNEL_SWITCH:
4375 hdd_info("channel switch for session:%d to channel:%d",
4376 pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
4377
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304378 chan_change.chan = pRoamInfo->chan_info.chan_id;
4379 chan_change.chan_params.ch_width =
4380 pRoamInfo->chan_info.ch_width;
4381 chan_change.chan_params.sec_ch_offset =
4382 pRoamInfo->chan_info.sec_ch_offset;
4383 chan_change.chan_params.center_freq_seg0 =
4384 pRoamInfo->chan_info.band_center_freq1;
4385 chan_change.chan_params.center_freq_seg1 =
4386 pRoamInfo->chan_info.band_center_freq2;
4387
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304388 status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304389 chan_change);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304390 if (QDF_IS_STATUS_ERROR(status))
4391 hdd_err("channel change notification failed");
4392
4393 status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
4394 if (QDF_IS_STATUS_ERROR(status))
4395 hdd_info("set hw mode change not done");
4396 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07004397 case eCSR_ROAM_NDP_STATUS_UPDATE:
4398 hdd_ndp_event_handler(pAdapter, pRoamInfo, roamId, roamStatus,
4399 roamResult);
4400 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004401 default:
4402 break;
4403 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304404 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004405}
4406
4407/**
4408 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4409 * @auth_suite: auth suite
4410 *
4411 * Return: eCsrAuthType enumeration
4412 */
4413eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4414{
4415 eCsrAuthType auth_type;
4416 /* is the auth type supported? */
4417 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4418 auth_type = eCSR_AUTH_TYPE_RSN;
4419 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4420 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004421 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004422 /* Check for 11r FT Authentication with PSK */
4423 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4424 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4425 /* Check for 11R FT Authentication with 802.1X */
4426 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4427 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004428#ifdef FEATURE_WLAN_ESE
4429 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4430 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4431 } else
4432#endif /* FEATURE_WLAN_ESE */
4433#ifdef WLAN_FEATURE_11W
4434 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4435 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4436 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4437 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4438 } else
4439#endif
4440 {
4441 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4442 }
4443 return auth_type;
4444}
4445
4446/**
4447 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4448 * @auth_suite: auth suite
4449 *
4450 * Return: eCsrAuthType enumeration
4451 */
4452eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4453{
4454 eCsrAuthType auth_type;
4455 /* is the auth type supported? */
4456 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4457 auth_type = eCSR_AUTH_TYPE_WPA;
4458 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4459 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4460 } else
4461#ifdef FEATURE_WLAN_ESE
4462 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4463 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4464 } else
4465#endif /* FEATURE_WLAN_ESE */
4466 {
4467 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4468 }
4469 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4470 return auth_type;
4471}
4472
4473/**
4474 * hdd_translate_rsn_to_csr_encryption_type() -
4475 * Translate RSN to CSR encryption type
4476 * @cipher_suite: cipher suite
4477 *
4478 * Return: eCsrEncryptionType enumeration
4479 */
4480eCsrEncryptionType
4481hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4482{
4483 eCsrEncryptionType cipher_type;
4484
4485 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4486 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4487 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4488 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4489 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4490 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4491 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4492 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4493 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4494 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4495 else
4496 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4497
4498 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4499 return cipher_type;
4500}
4501
4502/**
4503 * hdd_translate_wpa_to_csr_encryption_type() -
4504 * Translate WPA to CSR encryption type
4505 * @cipher_suite: cipher suite
4506 *
4507 * Return: eCsrEncryptionType enumeration
4508 */
4509eCsrEncryptionType
4510hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4511{
4512 eCsrEncryptionType cipher_type;
4513
4514 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4515 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4516 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4517 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4518 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4519 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4520 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4521 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4522 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4523 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4524 else
4525 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4526
4527 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4528 return cipher_type;
4529}
4530
4531/**
4532 * hdd_process_genie() - process gen ie
4533 * @pAdapter: pointer to adapter
4534 * @bssid: pointer to mac address
4535 * @pEncryptType: pointer to encryption type
4536 * @mcEncryptType: pointer to multicast encryption type
4537 * @pAuthType: pointer to auth type
4538 *
4539 * Return: 0 on success, error number otherwise
4540 */
4541static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4542 u8 *bssid,
4543 eCsrEncryptionType *pEncryptType,
4544 eCsrEncryptionType *mcEncryptType,
4545 eCsrAuthType *pAuthType,
4546#ifdef WLAN_FEATURE_11W
4547 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4548#endif
4549 uint16_t gen_ie_len, uint8_t *gen_ie)
4550{
4551 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304552 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004553 tDot11fIERSN dot11RSNIE;
4554 tDot11fIEWPA dot11WPAIE;
4555 uint32_t i;
4556 uint8_t *pRsnIe;
4557 uint16_t RSNIeLen;
4558 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4559 bool updatePMKCache = false;
4560
4561 /*
4562 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4563 * setting present flag to 0.
4564 */
4565 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4566 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4567
4568 /* Type check */
4569 if (gen_ie[0] == DOT11F_EID_RSN) {
4570 /* Validity checks */
4571 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4572 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4573 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4574 gen_ie_len);
4575 return -EINVAL;
4576 }
4577 /* Skip past the EID byte and length byte */
4578 pRsnIe = gen_ie + 2;
4579 RSNIeLen = gen_ie_len - 2;
4580 /* Unpack the RSN IE */
4581 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4582 pRsnIe, RSNIeLen, &dot11RSNIE);
4583 /* Copy out the encryption and authentication types */
4584 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4585 dot11RSNIE.pwise_cipher_suite_count);
4586 hddLog(LOG1, FL("authentication suite count: %d"),
4587 dot11RSNIE.akm_suite_count);
4588 /*Here we have followed the apple base code,
4589 but probably I suspect we can do something different */
4590 /* dot11RSNIE.akm_suite_count */
4591 /* Just translate the FIRST one */
4592 *pAuthType =
4593 hdd_translate_rsn_to_csr_auth_type(
4594 dot11RSNIE.akm_suites[0]);
4595 /* dot11RSNIE.pwise_cipher_suite_count */
4596 *pEncryptType =
4597 hdd_translate_rsn_to_csr_encryption_type(
4598 dot11RSNIE.pwise_cipher_suites[0]);
4599 /* dot11RSNIE.gp_cipher_suite_count */
4600 *mcEncryptType =
4601 hdd_translate_rsn_to_csr_encryption_type(
4602 dot11RSNIE.gp_cipher_suite);
4603#ifdef WLAN_FEATURE_11W
4604 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4605 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4606#endif
4607 /* Set the PMKSA ID Cache for this interface */
4608 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4609 if (is_zero_ether_addr(bssid)) {
4610 hddLog(LOGE, FL("MAC address is all zeroes"));
4611 break;
4612 }
4613 updatePMKCache = true;
4614 /*
4615 * For right now, I assume setASSOCIATE() has passed
4616 * in the bssid.
4617 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304618 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304619 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304620 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004621 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4622 }
4623
4624 if (updatePMKCache) {
4625 /*
4626 * Calling csr_roam_set_pmkid_cache to configure the
4627 * PMKIDs into the cache.
4628 */
4629 hddLog(LOG1,
4630 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4631 i);
4632 /* Finally set the PMKSA ID Cache in CSR */
4633 result =
4634 sme_roam_set_pmkid_cache(halHandle,
4635 pAdapter->sessionId,
4636 PMKIDCache,
4637 dot11RSNIE.pmkid_count,
4638 false);
4639 }
4640 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4641 /* Validity checks */
4642 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4643 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4644 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4645 gen_ie_len);
4646 return -EINVAL;
4647 }
4648 /* Skip past the EID and length byte - and four byte WiFi OUI */
4649 pRsnIe = gen_ie + 2 + 4;
4650 RSNIeLen = gen_ie_len - (2 + 4);
4651 /* Unpack the WPA IE */
4652 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4653 pRsnIe, RSNIeLen, &dot11WPAIE);
4654 /* Copy out the encryption and authentication types */
4655 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4656 dot11WPAIE.unicast_cipher_count);
4657 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4658 dot11WPAIE.auth_suite_count);
4659 /* dot11WPAIE.auth_suite_count */
4660 /* Just translate the FIRST one */
4661 *pAuthType =
4662 hdd_translate_wpa_to_csr_auth_type(
4663 dot11WPAIE.auth_suites[0]);
4664 /* dot11WPAIE.unicast_cipher_count */
4665 *pEncryptType =
4666 hdd_translate_wpa_to_csr_encryption_type(
4667 dot11WPAIE.unicast_ciphers[0]);
4668 /* dot11WPAIE.unicast_cipher_count */
4669 *mcEncryptType =
4670 hdd_translate_wpa_to_csr_encryption_type(
4671 dot11WPAIE.multicast_cipher);
4672 } else {
4673 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4674 return -EINVAL;
4675 }
4676 return 0;
4677}
4678
4679/**
4680 * hdd_set_genie_to_csr() - set genie to csr
4681 * @pAdapter: pointer to adapter
4682 * @RSNAuthType: pointer to auth type
4683 *
4684 * Return: 0 on success, error number otherwise
4685 */
4686int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4687{
4688 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4689 uint32_t status = 0;
4690 eCsrEncryptionType RSNEncryptType;
4691 eCsrEncryptionType mcRSNEncryptType;
4692#ifdef WLAN_FEATURE_11W
4693 uint8_t RSNMfpRequired = 0;
4694 uint8_t RSNMfpCapable = 0;
4695#endif
4696 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4697 /* MAC address of assoc peer */
4698 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304699 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004700 pWextState->roamProfile.BSSIDs.bssid,
4701 sizeof(bssid));
4702 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4703 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4704 /* continue */
4705 } else {
4706 return 0;
4707 }
4708 /* The actual processing may eventually be more extensive than this. */
4709 /* Right now, just consume any PMKIDs that are sent in by the app. */
4710 status = hdd_process_genie(pAdapter, bssid,
4711 &RSNEncryptType,
4712 &mcRSNEncryptType, RSNAuthType,
4713#ifdef WLAN_FEATURE_11W
4714 &RSNMfpRequired, &RSNMfpCapable,
4715#endif
4716 pWextState->WPARSNIE[1] + 2,
4717 pWextState->WPARSNIE);
4718 if (status == 0) {
4719 /*
4720 * Now copy over all the security attributes
4721 * you have parsed out.
4722 */
4723 pWextState->roamProfile.EncryptionType.numEntries = 1;
4724 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4725
4726 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4727 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4728 mcRSNEncryptType;
4729
Krunal Sonibe766b02016-03-10 13:00:44 -08004730 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004731 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4732 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4733 /*
4734 * For wpa none supplicant sends the WPA IE with unicast
4735 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4736 * multicast cipher as either AES/TKIP based on group
4737 * cipher configuration mentioned in the
4738 * wpa_supplicant.conf.
4739 */
4740
4741 /* Set the unicast cipher same as multicast cipher */
4742 pWextState->roamProfile.EncryptionType.encryptionType[0]
4743 = mcRSNEncryptType;
4744 }
4745#ifdef WLAN_FEATURE_11W
4746 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4747 RSNMfpRequired, RSNMfpCapable);
4748 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4749 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4750#endif
4751 hddLog(LOG1,
4752 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4753 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4754 }
4755 return 0;
4756}
4757
4758/**
4759 * hdd_set_csr_auth_type() - set csr auth type
4760 * @pAdapter: pointer to adapter
4761 * @RSNAuthType: auth type
4762 *
4763 * Return: 0 on success, error number otherwise
4764 */
4765int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4766{
4767 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4768 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004770
4771 pRoamProfile->AuthType.numEntries = 1;
4772 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4773 pHddStaCtx->conn_info.authType);
4774
4775 switch (pHddStaCtx->conn_info.authType) {
4776 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4777#ifdef FEATURE_WLAN_ESE
4778 case eCSR_AUTH_TYPE_CCKM_WPA:
4779 case eCSR_AUTH_TYPE_CCKM_RSN:
4780#endif
4781 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4782
4783 pRoamProfile->AuthType.authType[0] =
4784 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4785 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4786
4787#ifdef FEATURE_WLAN_ESE
4788 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4789 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4790 == IW_AUTH_KEY_MGMT_802_1X)) {
4791 hddLog(LOG1,
4792 FL("set authType to CCKM WPA. AKM also 802.1X."));
4793 pRoamProfile->AuthType.authType[0] =
4794 eCSR_AUTH_TYPE_CCKM_WPA;
4795 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4796 hddLog(LOG1,
4797 FL("Last chance to set authType to CCKM WPA."));
4798 pRoamProfile->AuthType.authType[0] =
4799 eCSR_AUTH_TYPE_CCKM_WPA;
4800 } else
4801#endif
4802 if ((pWextState->
4803 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4804 == IW_AUTH_KEY_MGMT_802_1X) {
4805 pRoamProfile->AuthType.authType[0] =
4806 eCSR_AUTH_TYPE_WPA;
4807 } else
4808 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4809 == IW_AUTH_KEY_MGMT_PSK) {
4810 pRoamProfile->AuthType.authType[0] =
4811 eCSR_AUTH_TYPE_WPA_PSK;
4812 } else {
4813 pRoamProfile->AuthType.authType[0] =
4814 eCSR_AUTH_TYPE_WPA_NONE;
4815 }
4816 }
4817 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4818#ifdef FEATURE_WLAN_ESE
4819 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4820 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4821 == IW_AUTH_KEY_MGMT_802_1X)) {
4822 hddLog(LOG1,
4823 FL("set authType to CCKM RSN. AKM also 802.1X."));
4824 pRoamProfile->AuthType.authType[0] =
4825 eCSR_AUTH_TYPE_CCKM_RSN;
4826 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4827 hddLog(LOG1,
4828 FL("Last chance to set authType to CCKM RSN."));
4829 pRoamProfile->AuthType.authType[0] =
4830 eCSR_AUTH_TYPE_CCKM_RSN;
4831 } else
4832#endif
4833
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004834 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4835 ((pWextState->
4836 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4837 == IW_AUTH_KEY_MGMT_802_1X)) {
4838 pRoamProfile->AuthType.authType[0] =
4839 eCSR_AUTH_TYPE_FT_RSN;
4840 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4841 &&
4842 ((pWextState->
4843 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4844 == IW_AUTH_KEY_MGMT_PSK)) {
4845 pRoamProfile->AuthType.authType[0] =
4846 eCSR_AUTH_TYPE_FT_RSN_PSK;
4847 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848
4849#ifdef WLAN_FEATURE_11W
4850 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4851 pRoamProfile->AuthType.authType[0] =
4852 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4853 } else if (RSNAuthType ==
4854 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4855 pRoamProfile->AuthType.authType[0] =
4856 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4857 } else
4858#endif
4859
4860 if ((pWextState->
4861 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4862 == IW_AUTH_KEY_MGMT_802_1X) {
4863 pRoamProfile->AuthType.authType[0] =
4864 eCSR_AUTH_TYPE_RSN;
4865 } else
4866 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4867 == IW_AUTH_KEY_MGMT_PSK) {
4868 pRoamProfile->AuthType.authType[0] =
4869 eCSR_AUTH_TYPE_RSN_PSK;
4870 } else {
4871 pRoamProfile->AuthType.authType[0] =
4872 eCSR_AUTH_TYPE_UNKNOWN;
4873 }
4874 }
4875 break;
4876
4877 case eCSR_AUTH_TYPE_SHARED_KEY:
4878
4879 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4880 break;
4881 default:
4882
4883#ifdef FEATURE_WLAN_ESE
4884 hddLog(LOG1, FL("In default, unknown auth type."));
4885#endif /* FEATURE_WLAN_ESE */
4886 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4887 break;
4888 }
4889
4890 hddLog(LOG1, FL("Set roam Authtype to %d"),
4891 pWextState->roamProfile.AuthType.authType[0]);
4892
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004893 return 0;
4894}
4895
4896/**
4897 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4898 * to the CSR roam profile.
4899 *
4900 * @dev: Pointer to the net device.
4901 * @info: Pointer to the iw_request_info.
4902 * @wrqu: Pointer to the iwreq_data.
4903 * @extra: Pointer to the data.
4904 *
4905 * Return: 0 for success, error number on failure
4906 */
4907static int __iw_set_essid(struct net_device *dev,
4908 struct iw_request_info *info,
4909 union iwreq_data *wrqu, char *extra)
4910{
4911 unsigned long rc;
4912 uint32_t status = 0;
4913 hdd_wext_state_t *pWextState;
4914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4915 hdd_context_t *hdd_ctx;
4916 uint32_t roamId;
4917 tCsrRoamProfile *pRoamProfile;
4918 eMib_dot11DesiredBssType connectedBssType;
4919 eCsrAuthType RSNAuthType;
4920 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4922 int ret;
4923
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004924 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004925
4926 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4927 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304928 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004929 return ret;
4930
Krunal Sonibe766b02016-03-10 13:00:44 -08004931 if (pAdapter->device_mode != QDF_STA_MODE &&
4932 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004933 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4934 hdd_device_mode_to_string(pAdapter->device_mode),
4935 pAdapter->device_mode);
4936 return -EINVAL;
4937 }
4938
4939 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4940
4941 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4942 hddLog(LOG2, FL("Counter measure is in progress"));
4943 return -EBUSY;
4944 }
4945 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4946 return -EINVAL;
4947
4948 pRoamProfile = &pWextState->roamProfile;
4949 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4950 (eMib_dot11DesiredBssType_independent ==
4951 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304952 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004953
4954 /* Need to issue a disconnect to CSR. */
4955 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304956 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004957 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4958
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304959 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004960 rc = wait_for_completion_timeout(&pAdapter->
4961 disconnect_comp_var,
4962 msecs_to_jiffies
4963 (WLAN_WAIT_TIME_DISCONNECT));
4964 if (!rc)
4965 hddLog(LOGE, FL("Disconnect event timed out"));
4966 }
4967 }
4968
4969 /*
4970 * when cfg80211 defined, wpa_supplicant wext driver uses
4971 * zero-length, null-string ssid for force disconnection.
4972 * after disconnection (if previously connected) and cleaning ssid,
4973 * driver MUST return success.
4974 */
4975 if (0 == wrqu->essid.length)
4976 return 0;
4977
4978 status = hdd_wmm_get_uapsd_mask(pAdapter,
4979 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304980 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004981 pWextState->roamProfile.uapsd_mask = 0;
4982
4983 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4984
4985 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4986 wrqu->essid.length;
4987
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304988 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004989 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304990 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004991 ssId), extra, wrqu->essid.length);
4992 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4993 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4994
4995 /* set gen ie */
4996 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4997
4998 /* set auth */
4999 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5000 }
5001#ifdef FEATURE_WLAN_WAPI
5002 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
5003 if (pAdapter->wapi_info.nWapiMode) {
5004 switch (pAdapter->wapi_info.wapiAuthMode) {
5005 case WAPI_AUTH_MODE_PSK:
5006 {
5007 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
5008 pAdapter->wapi_info.wapiAuthMode);
5009 pRoamProfile->AuthType.numEntries = 1;
5010 pRoamProfile->AuthType.authType[0] =
5011 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5012 break;
5013 }
5014 case WAPI_AUTH_MODE_CERT:
5015 {
5016 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
5017 pAdapter->wapi_info.wapiAuthMode);
5018 pRoamProfile->AuthType.numEntries = 1;
5019 pRoamProfile->AuthType.authType[0] =
5020 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5021 break;
5022 }
5023 } /* End of switch */
5024 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5025 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
5026 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
5027 pRoamProfile->EncryptionType.numEntries = 1;
5028 pRoamProfile->EncryptionType.encryptionType[0] =
5029 eCSR_ENCRYPT_TYPE_WPI;
5030 pRoamProfile->mcEncryptionType.numEntries = 1;
5031 pRoamProfile->mcEncryptionType.encryptionType[0] =
5032 eCSR_ENCRYPT_TYPE_WPI;
5033 }
5034 }
5035#endif /* FEATURE_WLAN_WAPI */
5036 /* if previous genIE is not NULL, update AssocIE */
5037 if (0 != pWextState->genIE.length) {
5038 memset(&pWextState->assocAddIE, 0,
5039 sizeof(pWextState->assocAddIE));
5040 memcpy(pWextState->assocAddIE.addIEdata,
5041 pWextState->genIE.addIEdata, pWextState->genIE.length);
5042 pWextState->assocAddIE.length = pWextState->genIE.length;
5043 pWextState->roamProfile.pAddIEAssoc =
5044 pWextState->assocAddIE.addIEdata;
5045 pWextState->roamProfile.nAddIEAssocLength =
5046 pWextState->assocAddIE.length;
5047
5048 /* clear previous genIE after use it */
5049 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
5050 }
5051
5052 /*
5053 * Assumes it is not WPS Association by default, except when
5054 * pAddIEAssoc has WPS IE.
5055 */
5056 pWextState->roamProfile.bWPSAssociation = false;
5057
5058 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
5059 pWextState->roamProfile.
5060 nAddIEAssocLength))
5061 pWextState->roamProfile.bWPSAssociation = true;
5062
5063 /* Disable auto BMPS entry by PMC until DHCP is done */
5064 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
5065 true);
5066
5067 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
5068
5069 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
5070 hdd_select_cbmode(pAdapter,
5071 (WLAN_HDD_GET_CTX(pAdapter))->config->
5072 AdHocChannel5G);
5073 }
Agrawal Ashish6b015762016-05-05 11:22:18 +05305074 /*
5075 * Change conn_state to connecting before sme_roam_connect(),
5076 * because sme_roam_connect() has a direct path to call
5077 * hdd_sme_roam_callback(), which will change the conn_state
5078 * If direct path, conn_state will be accordingly changed to
5079 * NotConnected or Associated by either
5080 * hdd_association_completion_handler() or hdd_dis_connect_handler()
5081 * in sme_RoamCallback()if sme_RomConnect is to be queued,
5082 * Connecting state will remain until it is completed.
5083 *
5084 * If connection state is not changed,
5085 * connection state will remain in eConnectionState_NotConnected state.
5086 * In hdd_association_completion_handler, "hddDisconInProgress" is
5087 * set to true if conn state is eConnectionState_NotConnected.
5088 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
5089 * informed of connect result indication which is an issue.
5090 */
5091 if (QDF_STA_MODE == pAdapter->device_mode ||
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305092 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)
Agrawal Ashish6b015762016-05-05 11:22:18 +05305093 hdd_conn_set_connection_state(pAdapter,
5094 eConnectionState_Connecting);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305095
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005096 status = sme_roam_connect(hHal, pAdapter->sessionId,
5097 &(pWextState->roamProfile), &roamId);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305098 if ((QDF_STATUS_SUCCESS != status) &&
5099 (QDF_STA_MODE == pAdapter->device_mode ||
5100 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
5101 hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
5102 pAdapter->sessionId, status);
5103 /* change back to NotAssociated */
5104 hdd_conn_set_connection_state(pAdapter,
5105 eConnectionState_NotConnected);
5106 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005107 pRoamProfile->ChannelInfo.ChannelList = NULL;
5108 pRoamProfile->ChannelInfo.numOfChannels = 0;
5109
5110 EXIT();
5111 return status;
5112}
5113
5114/**
5115 * iw_set_essid() - set essid handler function
5116 * @dev: Pointer to the net device.
5117 * @info: Pointer to the iw_request_info.
5118 * @wrqu: Pointer to the iwreq_data.
5119 * @extra: Pointer to the data.
5120 *
5121 * Return: 0 for success, error number on failure
5122 */
5123int iw_set_essid(struct net_device *dev,
5124 struct iw_request_info *info,
5125 union iwreq_data *wrqu, char *extra)
5126{
5127 int ret;
5128
5129 cds_ssr_protect(__func__);
5130 ret = __iw_set_essid(dev, info, wrqu, extra);
5131 cds_ssr_unprotect(__func__);
5132
5133 return ret;
5134}
5135
5136/**
5137 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
5138 * @dev: pointer to the net device
5139 * @info: pointer to the iw request info
5140 * @dwrq: pointer to iw_point
5141 * @extra: pointer to the data
5142 *
5143 * Return: 0 on success, error number otherwise
5144 */
5145static int __iw_get_essid(struct net_device *dev,
5146 struct iw_request_info *info,
5147 struct iw_point *dwrq, char *extra)
5148{
5149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5150 hdd_context_t *hdd_ctx;
5151 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5153 int ret;
5154
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005155 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005156
5157 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5158 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305159 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005160 return ret;
5161
5162 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5163 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5164 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5165 || pHddStaCtx->conn_info.connState ==
5166 eConnectionState_IbssDisconnected)
5167 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5168 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5169 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5170 dwrq->length);
5171 dwrq->flags = 1;
5172 } else {
5173 memset(extra, 0, dwrq->length);
5174 dwrq->length = 0;
5175 dwrq->flags = 0;
5176 }
5177 EXIT();
5178 return 0;
5179}
5180
5181/**
5182 * iw_get_essid() - get essid handler function
5183 * @dev: Pointer to the net device.
5184 * @info: Pointer to the iw_request_info.
5185 * @wrqu: Pointer to the iwreq_data.
5186 * @extra: Pointer to the data.
5187 *
5188 * Return: 0 for success, error number on failure
5189 */
5190int iw_get_essid(struct net_device *dev,
5191 struct iw_request_info *info,
5192 struct iw_point *wrqu, char *extra)
5193{
5194 int ret;
5195
5196 cds_ssr_protect(__func__);
5197 ret = __iw_get_essid(dev, info, wrqu, extra);
5198 cds_ssr_unprotect(__func__);
5199
5200 return ret;
5201}
5202
5203/**
5204 * __iw_set_auth() -
5205 * This function sets the auth type received from the wpa_supplicant
5206 * @dev: pointer to the net device
5207 * @info: pointer to the iw request info
5208 * @wrqu: pointer to iwreq_data
5209 * @extra: pointer to the data
5210 *
5211 * Return: 0 on success, error number otherwise
5212 */
5213static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5214 union iwreq_data *wrqu, char *extra)
5215{
5216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5217 hdd_context_t *hdd_ctx;
5218 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5219 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5220 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5221 eCsrEncryptionType mcEncryptionType;
5222 eCsrEncryptionType ucEncryptionType;
5223 int ret;
5224
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005225 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005226
5227 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5228 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305229 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005230 return ret;
5231
5232 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5233 case IW_AUTH_WPA_VERSION:
5234 pWextState->wpaVersion = wrqu->param.value;
5235 break;
5236
5237 case IW_AUTH_CIPHER_PAIRWISE:
5238 {
5239 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5240 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5241 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5242 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5243 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5244 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5245 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5246 if ((IW_AUTH_KEY_MGMT_802_1X
5247 ==
5248 (pWextState->
5249 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5250 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5251 pHddStaCtx->conn_info.authType))
5252 /*Dynamic WEP key */
5253 ucEncryptionType =
5254 eCSR_ENCRYPT_TYPE_WEP40;
5255 else
5256 /*Static WEP key */
5257 ucEncryptionType =
5258 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5259 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5260 if ((IW_AUTH_KEY_MGMT_802_1X
5261 ==
5262 (pWextState->
5263 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5264 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5265 pHddStaCtx->conn_info.authType))
5266 /*Dynamic WEP key */
5267 ucEncryptionType =
5268 eCSR_ENCRYPT_TYPE_WEP104;
5269 else
5270 /*Static WEP key */
5271 ucEncryptionType =
5272 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5273 } else {
5274 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5275 wrqu->param.value);
5276 return -EINVAL;
5277 }
5278
5279 pRoamProfile->EncryptionType.numEntries = 1;
5280 pRoamProfile->EncryptionType.encryptionType[0] =
5281 ucEncryptionType;
5282 }
5283 break;
5284 case IW_AUTH_CIPHER_GROUP:
5285 {
5286 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5287 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5288 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5289 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5290 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5291 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5292 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5293 if ((IW_AUTH_KEY_MGMT_802_1X
5294 ==
5295 (pWextState->
5296 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5297 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5298 pHddStaCtx->conn_info.authType))
5299 mcEncryptionType =
5300 eCSR_ENCRYPT_TYPE_WEP40;
5301 else
5302 mcEncryptionType =
5303 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5304 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5305 /* Dynamic WEP keys won't work with shared keys */
5306 if ((IW_AUTH_KEY_MGMT_802_1X
5307 ==
5308 (pWextState->
5309 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5310 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5311 pHddStaCtx->conn_info.authType)) {
5312 mcEncryptionType =
5313 eCSR_ENCRYPT_TYPE_WEP104;
5314 } else {
5315 mcEncryptionType =
5316 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5317 }
5318 } else {
5319 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5320 wrqu->param.value);
5321 return -EINVAL;
5322 }
5323
5324 pRoamProfile->mcEncryptionType.numEntries = 1;
5325 pRoamProfile->mcEncryptionType.encryptionType[0] =
5326 mcEncryptionType;
5327 }
5328 break;
5329
5330 case IW_AUTH_80211_AUTH_ALG:
5331 {
5332 /* Save the auth algo here and set auth type to SME Roam profile
5333 in the iw_set_ap_address */
5334 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5335 pHddStaCtx->conn_info.authType =
5336 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5337
5338 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5339 pHddStaCtx->conn_info.authType =
5340 eCSR_AUTH_TYPE_SHARED_KEY;
5341
5342 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5343 /*Not supported */
5344 pHddStaCtx->conn_info.authType =
5345 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5346 pWextState->roamProfile.AuthType.authType[0] =
5347 pHddStaCtx->conn_info.authType;
5348 }
5349 break;
5350
5351 case IW_AUTH_KEY_MGMT:
5352 {
5353#ifdef FEATURE_WLAN_ESE
5354#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5355 /*Check for CCKM AKM type */
5356 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5357 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5358 /* Set the CCKM bit in authKeyMgmt */
5359 /*
5360 * Right now, this breaks all ref to authKeyMgmt because
5361 * our code doesn't realize it is a "bitfield"
5362 */
5363 pWextState->authKeyMgmt |=
5364 IW_AUTH_KEY_MGMT_CCKM;
5365 /* Set the key management to 802.1X */
5366 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5367 pWextState->isESEConnection = true;
5368 /*
5369 * This is test code. I need to actually KNOW whether
5370 * this is an RSN Assoc or WPA.
5371 */
5372 pWextState->collectedAuthType =
5373 eCSR_AUTH_TYPE_CCKM_RSN;
5374 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5375 /* Save the key management */
5376 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5377 pWextState->collectedAuthType =
5378 eCSR_AUTH_TYPE_RSN;
5379 } else
5380 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5381 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5382 /* Save the key management anyway */
5383 pWextState->authKeyMgmt = wrqu->param.value;
5384 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5385 /* Save the key management */
5386 pWextState->authKeyMgmt |=
5387 IW_AUTH_KEY_MGMT_802_1X;
5388 pWextState->collectedAuthType =
5389 eCSR_AUTH_TYPE_RSN;
5390 }
5391#else
5392 /* Save the key management */
5393 pWextState->authKeyMgmt = wrqu->param.value;
5394#endif /* FEATURE_WLAN_ESE */
5395 }
5396 break;
5397
5398 case IW_AUTH_TKIP_COUNTERMEASURES:
5399 {
5400 if (wrqu->param.value) {
5401 hddLog(LOG2,
5402 "Counter Measure started %d",
5403 wrqu->param.value);
5404 pWextState->mTKIPCounterMeasures =
5405 TKIP_COUNTER_MEASURE_STARTED;
5406 } else {
5407 hddLog(LOG2,
5408 "Counter Measure stopped=%d",
5409 wrqu->param.value);
5410 pWextState->mTKIPCounterMeasures =
5411 TKIP_COUNTER_MEASURE_STOPED;
5412 }
5413 }
5414 break;
5415 case IW_AUTH_DROP_UNENCRYPTED:
5416 case IW_AUTH_WPA_ENABLED:
5417 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5418 case IW_AUTH_ROAMING_CONTROL:
5419 case IW_AUTH_PRIVACY_INVOKED:
5420
5421 default:
5422
5423 hddLog(LOGW, FL("called with unsupported auth type %d"),
5424 wrqu->param.flags & IW_AUTH_INDEX);
5425 break;
5426 }
5427
5428 EXIT();
5429 return 0;
5430}
5431
5432/**
5433 * iw_set_auth() - set auth callback function
5434 * @dev: Pointer to the net device.
5435 * @info: Pointer to the iw_request_info.
5436 * @wrqu: Pointer to the iwreq_data.
5437 * @extra: Pointer to the data.
5438 *
5439 * Return: 0 for success, error number on failure.
5440 */
5441int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5442 union iwreq_data *wrqu, char *extra)
5443{
5444 int ret;
5445
5446 cds_ssr_protect(__func__);
5447 ret = __iw_set_auth(dev, info, wrqu, extra);
5448 cds_ssr_unprotect(__func__);
5449
5450 return ret;
5451}
5452
5453/**
5454 * __iw_get_auth() -
5455 * This function returns the auth type to the wpa_supplicant
5456 * @dev: pointer to the net device
5457 * @info: pointer to the iw request info
5458 * @wrqu: pointer to iwreq_data
5459 * @extra: pointer to the data
5460 *
5461 * Return: 0 on success, error number otherwise
5462 */
5463static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5464 union iwreq_data *wrqu, char *extra)
5465{
5466 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5467 hdd_context_t *hdd_ctx;
5468 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5469 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5470 int ret;
5471
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005472 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005473
5474 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5475 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305476 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005477 return ret;
5478
5479 switch (pRoamProfile->negotiatedAuthType) {
5480 case eCSR_AUTH_TYPE_WPA_NONE:
5481 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5482 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5483 break;
5484 case eCSR_AUTH_TYPE_WPA:
5485 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5486 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5487 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005488
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005489 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005490 case eCSR_AUTH_TYPE_RSN:
5491 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5492 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5493 break;
5494 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5495 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5496 break;
5497 case eCSR_AUTH_TYPE_SHARED_KEY:
5498 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5499 break;
5500 case eCSR_AUTH_TYPE_UNKNOWN:
5501 hddLog(LOG1, FL("called with unknown auth type"));
5502 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5503 break;
5504 case eCSR_AUTH_TYPE_AUTOSWITCH:
5505 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5506 break;
5507 case eCSR_AUTH_TYPE_WPA_PSK:
5508 hddLog(LOG1, FL("called with WPA PSK auth type"));
5509 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5510 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005511
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005512 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005513 case eCSR_AUTH_TYPE_RSN_PSK:
5514#ifdef WLAN_FEATURE_11W
5515 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5516 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5517#endif
5518 hddLog(LOG1, FL("called with RSN PSK auth type"));
5519 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5520 return -EIO;
5521 default:
5522 hddLog(LOGE, FL("called with unknown auth type"));
5523 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5524 return -EIO;
5525 }
5526 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5527 switch (pRoamProfile->negotiatedUCEncryptionType) {
5528 case eCSR_ENCRYPT_TYPE_NONE:
5529 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5530 break;
5531 case eCSR_ENCRYPT_TYPE_WEP40:
5532 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5533 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5534 break;
5535 case eCSR_ENCRYPT_TYPE_TKIP:
5536 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5537 break;
5538 case eCSR_ENCRYPT_TYPE_WEP104:
5539 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5540 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5541 break;
5542 case eCSR_ENCRYPT_TYPE_AES:
5543 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5544 break;
5545 default:
5546 hddLog(LOG1, FL("called with unknown auth type %d"),
5547 pRoamProfile->negotiatedUCEncryptionType);
5548 return -EIO;
5549 }
5550 }
5551
5552 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5553 switch (pRoamProfile->negotiatedMCEncryptionType) {
5554 case eCSR_ENCRYPT_TYPE_NONE:
5555 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5556 break;
5557 case eCSR_ENCRYPT_TYPE_WEP40:
5558 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5559 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5560 break;
5561 case eCSR_ENCRYPT_TYPE_TKIP:
5562 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5563 break;
5564 case eCSR_ENCRYPT_TYPE_WEP104:
5565 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5566 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5567 break;
5568 case eCSR_ENCRYPT_TYPE_AES:
5569 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5570 break;
5571 default:
5572 hddLog(LOG1, FL("called with unknown auth type %d"),
5573 pRoamProfile->negotiatedMCEncryptionType);
5574 return -EIO;
5575 }
5576 }
5577
5578 hddLog(LOG1, FL("called with auth type %d"),
5579 pRoamProfile->AuthType.authType[0]);
5580 EXIT();
5581 return 0;
5582}
5583
5584/**
5585 * iw_get_auth() - get auth callback function
5586 * @dev: Pointer to the net device.
5587 * @info: Pointer to the iw_request_info.
5588 * @wrqu: Pointer to the iwreq_data.
5589 * @extra: Pointer to the data.
5590 *
5591 * Return: 0 for success, error number on failure.
5592 */
5593int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5594 union iwreq_data *wrqu, char *extra)
5595{
5596 int ret;
5597
5598 cds_ssr_protect(__func__);
5599 ret = __iw_get_auth(dev, info, wrqu, extra);
5600 cds_ssr_unprotect(__func__);
5601
5602 return ret;
5603}
5604
5605/**
5606 * __iw_set_ap_address() - set ap address
5607 * @dev: pointer to the net device
5608 * @info: pointer to the iw request info
5609 * @wrqu: pointer to iwreq_data
5610 * @extra: pointer to the data
5611 *
5612 * This function updates the HDD global station context connection info
5613 * BSSID with the MAC address received from the wpa_supplicant.
5614 *
5615 * Return: 0 on success, error number otherwise
5616 */
5617static int __iw_set_ap_address(struct net_device *dev,
5618 struct iw_request_info *info,
5619 union iwreq_data *wrqu, char *extra)
5620{
5621
5622 hdd_adapter_t *adapter;
5623 hdd_context_t *hdd_ctx;
5624 hdd_station_ctx_t *pHddStaCtx =
5625 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5626 uint8_t *pMacAddress = NULL;
5627 int ret;
5628
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005629 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005630
5631 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5632
5633 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5634 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305635 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636 return ret;
5637
5638 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5639 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305640 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305641 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005642 EXIT();
5643
5644 return 0;
5645}
5646
5647/**
5648 * iw_set_ap_address() - set ap addresses callback function
5649 * @dev: Pointer to the net device.
5650 * @info: Pointer to the iw_request_info.
5651 * @wrqu: Pointer to the iwreq_data.
5652 * @extra: Pointer to the data.
5653 *
5654 * Return: 0 for success, error number on failure.
5655 */
5656int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5657 union iwreq_data *wrqu, char *extra)
5658{
5659 int ret;
5660
5661 cds_ssr_protect(__func__);
5662 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5663 cds_ssr_unprotect(__func__);
5664
5665 return ret;
5666}
5667
5668/**
5669 * __iw_get_ap_address() - get ap address
5670 * @dev: pointer to the net device
5671 * @info: pointer to the iw request info
5672 * @wrqu: pointer to iwreq_data
5673 * @extra: pointer to the data
5674 *
5675 * This function returns currently associated BSSID.
5676 *
5677 * Return: 0 on success, error number otherwise
5678 */
5679static int __iw_get_ap_address(struct net_device *dev,
5680 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra)
5682{
5683 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5684 hdd_context_t *hdd_ctx;
5685 hdd_station_ctx_t *pHddStaCtx =
5686 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5687 int ret;
5688
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005689 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005690
5691 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5692 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305693 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005694 return ret;
5695
5696 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5697 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305698 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005699 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305700 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005701 } else {
5702 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5703 }
5704 EXIT();
5705 return 0;
5706}
5707
5708/**
5709 * iw_get_ap_address() - get ap addresses callback function
5710 * @dev: Pointer to the net device.
5711 * @info: Pointer to the iw_request_info.
5712 * @wrqu: Pointer to the iwreq_data.
5713 * @extra: Pointer to the data.
5714 *
5715 * Return: 0 for success, error number on failure.
5716 */
5717int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5718 union iwreq_data *wrqu, char *extra)
5719{
5720 int ret;
5721
5722 cds_ssr_protect(__func__);
5723 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5724 cds_ssr_unprotect(__func__);
5725
5726 return ret;
5727}