blob: e2c43c5eab1da7b4fca49be69c98a2afc13a2c4a [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_assoc.c
30 *
31 * WLAN Host Device Driver implementation
32 *
33 */
34
35#include "wlan_hdd_includes.h"
36#include <ani_global.h>
37#include "dot11f.h"
38#include "wlan_hdd_power.h"
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +053039#include "wlan_hdd_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include <linux/ieee80211.h>
41#include <linux/wireless.h>
42#include <linux/etherdevice.h>
43#include <net/cfg80211.h>
44#include "wlan_hdd_cfg80211.h"
45#include "csr_inside_api.h"
46#include "wlan_hdd_p2p.h"
47#ifdef FEATURE_WLAN_TDLS
48#include "wlan_hdd_tdls.h"
49#endif
50#include "sme_api.h"
51#include "wlan_hdd_hostapd.h"
52#include <wlan_hdd_ipa.h>
53#include <cds_sched.h>
54#include "cds_concurrency.h"
55#include "sme_power_save_api.h"
56#include "ol_txrx_ctrl_api.h"
57#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080058#include "ol_txrx.h"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053059#include "ol_rx_fwd.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080060#include "cdp_txrx_flow_ctrl_legacy.h"
61#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63/* These are needed to recognize WPA and RSN suite types */
64#define HDD_WPA_OUI_SIZE 4
65#define HDD_RSN_OUI_SIZE 4
66uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
67uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
68uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
69uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
70uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
71uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
72
73#ifdef FEATURE_WLAN_ESE
74/* CCKM */
75uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
76/* CCKM */
77uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
78#endif /* FEATURE_WLAN_ESE */
79
80/* group cipher */
81uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
82
83/* WEP-40 or RSN */
84uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
85
86/* TKIP or RSN-PSK */
87uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
88
89/* Reserved */
90uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
91
92/* AES-CCMP */
93uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
94
95/* WEP-104 */
96uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
97
98#ifdef WLAN_FEATURE_11W
99/* RSN-PSK-SHA256 */
100uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
101
102/* RSN-8021X-SHA256 */
103uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
104#endif
105
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106/* Offset where the EID-Len-IE, start. */
107#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
108#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109
110#define BEACON_FRAME_IES_OFFSET 12
111#define HDD_PEER_AUTHORIZE_WAIT 10
112
113/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700114 * beacon_filter_table - table of IEs used for beacon filtering
115 */
116static const int beacon_filter_table[] = {
117 SIR_MAC_DS_PARAM_SET_EID,
118 SIR_MAC_ERP_INFO_EID,
119 SIR_MAC_EDCA_PARAM_SET_EID,
120 SIR_MAC_QOS_CAPABILITY_EID,
121 SIR_MAC_HT_INFO_EID,
122 SIR_MAC_VHT_OPMODE_EID,
123 SIR_MAC_VHT_OPERATION_EID,
124};
125
126/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 * hdd_conn_set_authenticated() - set authentication state
128 * @pAdapter: pointer to the adapter
129 * @authState: authentication state
130 *
131 * This function updates the global HDD station context
132 * authentication state.
133 *
134 * Return: none
135 */
136static void
137hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
138{
139 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
140 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
141
142 /* save the new connection state */
143 hddLog(LOG1,
144 FL("Authenticated state Changed from oldState:%d to State:%d"),
145 pHddStaCtx->conn_info.uIsAuthenticated, authState);
146 pHddStaCtx->conn_info.uIsAuthenticated = authState;
147
148 /* Check is pending ROC request or not when auth state changed */
149 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
150}
151
152/**
153 * hdd_conn_set_connection_state() - set connection state
154 * @pAdapter: pointer to the adapter
155 * @connState: connection state
156 *
157 * This function updates the global HDD station context connection state.
158 *
159 * Return: none
160 */
161void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
162 eConnectionState connState)
163{
164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
165 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
166
167 /* save the new connection state */
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530168 hdd_info("%pS Changed connectionState Changed from oldState:%d to State:%d",
169 (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
170 connState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 pHddStaCtx->conn_info.connState = connState;
172
173 /* Check is pending ROC request or not when connection state changed */
174 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
175}
176
177/**
178 * hdd_conn_get_connection_state() - get connection state
179 * @pAdapter: pointer to the adapter
180 * @pConnState: pointer to connection state
181 *
182 * This function updates the global HDD station context connection state.
183 *
184 * Return: true if (Infra Associated or IBSS Connected)
185 * and sets output parameter pConnState;
186 * false otherwise
187 */
188static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
189 eConnectionState *pConnState)
190{
191 bool fConnected = false;
192 eConnectionState connState;
193
194 /* get the connection state. */
195 connState = pHddStaCtx->conn_info.connState;
196
197 if (eConnectionState_Associated == connState ||
198 eConnectionState_IbssConnected == connState ||
199 eConnectionState_IbssDisconnected == connState) {
200 fConnected = true;
201 }
202
203 if (pConnState)
204 *pConnState = connState;
205
206 return fConnected;
207}
208
209/**
210 * hdd_is_connecting() - Function to check connection progress
211 * @hdd_sta_ctx: pointer to global HDD Station context
212 *
213 * Return: true if connecting, false otherwise
214 */
215bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
216{
217 return hdd_sta_ctx->conn_info.connState ==
218 eConnectionState_Connecting;
219}
220
221/**
222 * hdd_conn_is_connected() - Function to check connection status
223 * @pHddStaCtx: pointer to global HDD Station context
224 *
225 * Return: false if any errors encountered, true otherwise
226 */
227bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
228{
229 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
230}
231
232/**
233 * hdd_conn_get_connected_band() - get current connection radio band
234 * @pHddStaCtx: pointer to global HDD Station context
235 *
236 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
237 * eCSR_BAND_ALL if not connected
238 */
239eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
240{
241 uint8_t staChannel = 0;
242
243 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
244 staChannel = pHddStaCtx->conn_info.operationChannel;
245
246 if (staChannel > 0 && staChannel < 14)
247 return eCSR_BAND_24;
248 else if (staChannel >= 36 && staChannel <= 184)
249 return eCSR_BAND_5G;
250 else /* If station is not connected return as eCSR_BAND_ALL */
251 return eCSR_BAND_ALL;
252}
253
254/**
255 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
256 * @pHddStaCtx: pointer to global HDD Station context
257 * @pConnectedCipherAlgo: pointer to connected cipher algo
258 *
259 * Return: false if any errors encountered, true otherwise
260 */
261static inline bool
262hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
263 eCsrEncryptionType *pConnectedCipherAlgo)
264{
265 bool fConnected = false;
266
267 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
268
269 if (pConnectedCipherAlgo)
270 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
271
272 return fConnected;
273}
274
275/**
276 * hdd_conn_get_connected_bss_type() - get current bss type
277 * @pHddStaCtx: pointer to global HDD Station context
278 * @pConnectedBssType: pointer to connected bss type
279 *
280 * Return: false if any errors encountered, true otherwise
281 */
282inline bool
283hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
284 eMib_dot11DesiredBssType *pConnectedBssType)
285{
286 bool fConnected = false;
287
288 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
289
290 if (pConnectedBssType) {
291 *pConnectedBssType =
292 pHddStaCtx->conn_info.connDot11DesiredBssType;
293 }
294
295 return fConnected;
296}
297
298/**
299 * hdd_conn_save_connected_bss_type() - set connected bss type
300 * @pHddStaCtx: pointer to global HDD Station context
301 * @csr_roamBssType: bss type
302 *
303 * Return: none
304 */
305static inline void
306hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
307 eCsrRoamBssType csr_roamBssType)
308{
309 switch (csr_roamBssType) {
310 case eCSR_BSS_TYPE_INFRASTRUCTURE:
311 pHddStaCtx->conn_info.connDot11DesiredBssType =
312 eMib_dot11DesiredBssType_infrastructure;
313 break;
314
315 case eCSR_BSS_TYPE_IBSS:
316 case eCSR_BSS_TYPE_START_IBSS:
317 pHddStaCtx->conn_info.connDot11DesiredBssType =
318 eMib_dot11DesiredBssType_independent;
319 break;
320
321 /** We will never set the BssType to 'any' when attempting a connection
322 so CSR should never send this back to us.*/
323 case eCSR_BSS_TYPE_ANY:
324 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530325 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 break;
327 }
328}
329
330/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700331 * hdd_remove_beacon_filter() - remove beacon filter
332 * @adapter: Pointer to the hdd adapter
333 *
334 * Return: 0 on success and errno on failure
335 */
336static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
337{
338 QDF_STATUS status;
339 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
340
341 status = sme_remove_beacon_filter(hdd_ctx->hHal,
342 adapter->sessionId);
343 if (!QDF_IS_STATUS_SUCCESS(status)) {
344 hdd_err("sme_remove_beacon_filter() failed");
345 return -EFAULT;
346 }
347
348 return 0;
349}
350
351/**
352 * hdd_add_beacon_filter() - add beacon filter
353 * @adapter: Pointer to the hdd adapter
354 *
355 * Return: 0 on success and errno on failure
356 */
357static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
358{
359 int i;
360 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
361 QDF_STATUS status;
362 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
363
364 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
365 qdf_set_bit((beacon_filter_table[i] - 1),
366 (unsigned long int *)ie_map);
367
368 status = sme_add_beacon_filter(hdd_ctx->hHal,
369 adapter->sessionId, ie_map);
370 if (!QDF_IS_STATUS_SUCCESS(status)) {
371 hdd_err("sme_add_beacon_filter() failed");
372 return -EFAULT;
373 }
374 return 0;
375}
376
377/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800378 * hdd_conn_save_connect_info() - save current connection information
379 * @pAdapter: pointer to adapter
380 * @pRoamInfo: pointer to roam info
381 * @eBssType: bss type
382 *
383 * Return: none
384 */
385static void
386hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
387 eCsrRoamBssType eBssType)
388{
389 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
390 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
391
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530392 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393
394 if (pRoamInfo) {
395 /* Save the BSSID for the connection */
396 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530397 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530398 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 &pRoamInfo->bssid);
400
401 /*
402 * Save the Station ID for this station from
403 * the 'Roam Info'. For IBSS mode, staId is
404 * assigned in NEW_PEER_IND. For reassoc,
405 * the staID doesn't change and it may be invalid
406 * in this structure so no change here.
407 */
408 if (!pRoamInfo->fReassocReq) {
409 pHddStaCtx->conn_info.staId[0] =
410 pRoamInfo->staId;
411 }
412 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530413 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 &pRoamInfo->bssid);
415 } else {
416 /*
417 * can't happen. We need a valid IBSS or Infra setting
418 * in the BSSDescription or we can't function.
419 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530420 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 }
422
423 /* notify WMM */
424 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
425
426 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530427 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 } else {
429 /* Get Multicast Encryption Type */
430 encryptType =
431 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
432 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
433 /* Get Unicast Encryption Type */
434 encryptType =
435 pRoamInfo->u.pConnectedProfile->EncryptionType;
436 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
437
438 pHddStaCtx->conn_info.authType =
439 pRoamInfo->u.pConnectedProfile->AuthType;
440
441 pHddStaCtx->conn_info.operationChannel =
442 pRoamInfo->u.pConnectedProfile->operationChannel;
443
444 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530445 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446 &pRoamInfo->u.pConnectedProfile->SSID,
447 sizeof(tSirMacSSid));
448
449 /* Save dot11mode in which STA associated to AP */
450 pHddStaCtx->conn_info.dot11Mode =
451 pRoamInfo->u.pConnectedProfile->dot11Mode;
452
453 pHddStaCtx->conn_info.proxyARPService =
454 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530455
456 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
457
458 pHddStaCtx->conn_info.rate_flags =
459 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 }
461 }
462 /* save the connected BssType */
463 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
464}
465
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466/**
467 * hdd_send_ft_assoc_response() - send fast transition assoc response
468 * @dev: pointer to net device
469 * @pAdapter: pointer to adapter
470 * @pCsrRoamInfo: pointer to roam info
471 *
472 * Send the 11R key information to the supplicant. Only then can the supplicant
473 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
474 * for the same purpose.)
475 *
476 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
477 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
478 * This is the Assoc Response.
479 *
480 * Return: none
481 */
482static void
483hdd_send_ft_assoc_response(struct net_device *dev,
484 hdd_adapter_t *pAdapter,
485 tCsrRoamInfo *pCsrRoamInfo)
486{
487 union iwreq_data wrqu;
488 char *buff;
489 unsigned int len = 0;
490 u8 *pFTAssocRsp = NULL;
491
492 if (pCsrRoamInfo->nAssocRspLength == 0) {
493 hddLog(LOGE,
494 FL("pCsrRoamInfo->nAssocRspLength=%d"),
495 (int)pCsrRoamInfo->nAssocRspLength);
496 return;
497 }
498
499 pFTAssocRsp =
500 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
501 pCsrRoamInfo->nAssocReqLength);
502 if (pFTAssocRsp == NULL) {
503 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
504 return;
505 }
506 /* pFTAssocRsp needs to point to the IEs */
507 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
508 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
509 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
510
511 /* We need to send the IEs to the supplicant. */
512 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
513 if (buff == NULL) {
514 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
515 return;
516 }
517 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
518 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
519 wrqu.data.length = len;
520 memset(buff, 0, IW_GENERIC_IE_MAX);
521 memcpy(buff, pFTAssocRsp, len);
522 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
523
524 kfree(buff);
525}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527/**
528 * hdd_send_ft_event() - send fast transition event
529 * @pAdapter: pointer to adapter
530 *
531 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
532 * FT events to the supplicant. At the reception of Auth2 we send the RIC
533 * followed by the auth response IEs to the supplicant.
534 * Once both are received in the supplicant, an FT event is generated
535 * to the supplicant.
536 *
537 * Return: none
538 */
539static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
540{
541 uint16_t auth_resp_len = 0;
542 uint32_t ric_ies_length = 0;
543 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
544
545#if defined(KERNEL_SUPPORT_11R_CFG80211)
546 struct cfg80211_ft_event_params ftEvent;
547 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
548 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
549 struct net_device *dev = pAdapter->dev;
550#else
551 char *buff;
552 union iwreq_data wrqu;
553 uint16_t str_len;
554#endif
555
556#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530557 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
558 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559
560 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
561 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
562 if (ric_ies_length == 0) {
563 hddLog(LOGW,
564 FL("RIC IEs is of length 0 not sending RIC Information for now"));
565 }
566
567 ftEvent.ric_ies = ricIe;
568 ftEvent.ric_ies_len = ric_ies_length;
569 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
570
571 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
572 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
573 &auth_resp_len);
574
575 if (auth_resp_len == 0) {
576 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
577 return;
578 }
579
580 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
581
582 ftEvent.target_ap = ftIe;
583
Anurag Chouhan6d760662016-02-20 16:05:43 +0530584 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
585 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586
587 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
588 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
589 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
590 ftEvent.target_ap[0], ftEvent.target_ap[1],
591 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
592 ftEvent.target_ap[5]);
593
594 (void)cfg80211_ft_event(dev, &ftEvent);
595
596#else
597 /* We need to send the IEs to the supplicant */
598 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
599 if (buff == NULL) {
600 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
601 return;
602 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530603 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604
605 /* Sme needs to send the RIC IEs first */
606 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
607 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
608 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
609 &ric_ies_length);
610 if (ric_ies_length == 0) {
611 hddLog(LOGW,
612 FL("RIC IEs is of length 0 not sending RIC Information for now"));
613 } else {
614 wrqu.data.length = str_len + ric_ies_length;
615 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
616 }
617
618 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530619 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
621 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
622 (u8 *) &buff[str_len],
623 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
624
625 if (auth_resp_len == 0) {
626 kfree(buff);
627 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
628 return;
629 }
630
631 wrqu.data.length = str_len + auth_resp_len;
632 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
633
634 kfree(buff);
635#endif
636}
637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638#ifdef FEATURE_WLAN_ESE
639/**
640 * hdd_send_new_ap_channel_info() - send new ap channel info
641 * @dev: pointer to net device
642 * @pAdapter: pointer to adapter
643 * @pCsrRoamInfo: pointer to roam info
644 *
645 * Send the ESE required "new AP Channel info" to the supplicant.
646 * (This keeps the supplicant "up to date" on the current channel.)
647 *
648 * The current (new AP) channel information is passed in.
649 *
650 * Return: none
651 */
652static void
653hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
654 tCsrRoamInfo *pCsrRoamInfo)
655{
656 union iwreq_data wrqu;
657 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
658
659 if (descriptor == NULL) {
660 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
661 return;
662 }
663 /*
664 * Send the Channel event, the supplicant needs this to generate
665 * the Adjacent AP report.
666 */
667 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
668 descriptor->channelId);
669 memset(&wrqu, '\0', sizeof(wrqu));
670 wrqu.freq.m = descriptor->channelId;
671 wrqu.freq.e = 0;
672 wrqu.freq.i = 0;
673 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
674}
675
676#endif /* FEATURE_WLAN_ESE */
677
678/**
679 * hdd_send_update_beacon_ies_event() - send update beacons ie event
680 * @pAdapter: pointer to adapter
681 * @pCsrRoamInfo: pointer to roam info
682 *
683 * Return: none
684 */
685static void
686hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
687 tCsrRoamInfo *pCsrRoamInfo)
688{
689 union iwreq_data wrqu;
690 u8 *pBeaconIes;
691 u8 currentLen = 0;
692 char *buff;
693 int totalIeLen = 0, currentOffset = 0, strLen;
694
695 memset(&wrqu, '\0', sizeof(wrqu));
696
697 if (0 == pCsrRoamInfo->nBeaconLength) {
698 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
699 return;
700 }
701 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
702 if (pBeaconIes == NULL) {
703 hddLog(LOGW, FL("Beacon IEs is NULL"));
704 return;
705 }
706 /* pBeaconIes needs to point to the IEs */
707 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
708 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
709 hddLog(LOG1, FL("Beacon IEs length = %d"),
710 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
711
712 /* We need to send the IEs to the supplicant. */
713 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
714 if (buff == NULL) {
715 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
716 return;
717 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530718 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719
720 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
721 currentLen = strLen + 1;
722
723 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
724 do {
725 /*
726 * If the beacon size exceeds max CUSTOM event size, break it
727 * into chunks of CUSTOM event max size and send it to
728 * supplicant. Changes are done in supplicant to handle this.
729 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530730 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530732 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530733 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 currentLen);
735 currentOffset += currentLen;
736 totalIeLen -= currentLen;
737 wrqu.data.length = strLen + 1 + currentLen;
738 if (totalIeLen)
739 buff[strLen] = 1; /* more chunks pending */
740 else
741 buff[strLen] = 0; /* last chunk */
742
743 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
744 currentLen);
745 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
746 } while (totalIeLen > 0);
747
748 kfree(buff);
749}
750
751/**
752 * hdd_send_association_event() - send association event
753 * @dev: pointer to net device
754 * @pCsrRoamInfo: pointer to roam info
755 *
756 * Return: none
757 */
758static void hdd_send_association_event(struct net_device *dev,
759 tCsrRoamInfo *pCsrRoamInfo)
760{
761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
762 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
763 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
764 union iwreq_data wrqu;
765 int we_event;
766 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530767 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800768
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 /* Added to find the auth type on the fly at run time */
770 /* rather than with cfg to see if FT is enabled */
771 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
772 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773
774 memset(&wrqu, '\0', sizeof(wrqu));
775 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
776 we_event = SIOCGIWAP;
777#ifdef WLAN_FEATURE_ROAM_OFFLOAD
778 if (NULL != pCsrRoamInfo)
779 if (pCsrRoamInfo->roamSynchInProgress)
780 /* change logging before release */
781 hddLog(LOG4, "LFR3:hdd_send_association_event");
782#endif
783 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
784 if (!pCsrRoamInfo) {
785 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
786 return;
787 }
788
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800789 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
790 cds_incr_active_session(pAdapter->device_mode,
791 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
793 sizeof(pCsrRoamInfo->pBssDesc->bssId));
794
795#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800796 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797 if (global_p2p_connection_status ==
798 P2P_CLIENT_CONNECTING_STATE_1) {
799 global_p2p_connection_status =
800 P2P_CLIENT_CONNECTED_STATE_1;
801 hddLog(LOGE,
802 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
803 } else if (global_p2p_connection_status ==
804 P2P_CLIENT_CONNECTING_STATE_2) {
805 global_p2p_connection_status =
806 P2P_CLIENT_COMPLETED_STATE;
807 hddLog(LOGE,
808 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
809 }
810 }
811#endif
812 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
813 MAC_ADDRESS_STR "\n",
814 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
815 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
816 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
817
818 /*
819 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
820 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800821 * fFTEnable is true.
822 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 if ((pRoamProfile->AuthType.authType[0] ==
825 eCSR_AUTH_TYPE_FT_RSN_PSK)
826 || (pRoamProfile->AuthType.authType[0] ==
827 eCSR_AUTH_TYPE_FT_RSN)
828#ifdef FEATURE_WLAN_ESE
829 || (pRoamProfile->AuthType.authType[0] ==
830 eCSR_AUTH_TYPE_CCKM_RSN)
831 || (pRoamProfile->AuthType.authType[0] ==
832 eCSR_AUTH_TYPE_CCKM_WPA)
833#endif
834 ) {
835 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
836 }
Krunal Sonibe766b02016-03-10 13:00:44 -0800837 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 tSirSmeChanInfo chan_info;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530839 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840 &pHddStaCtx->conn_info.bssId);
841 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
842 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
843 chan_info.info = pCsrRoamInfo->chan_info.info;
844 chan_info.band_center_freq1 =
845 pCsrRoamInfo->chan_info.band_center_freq1;
846 chan_info.band_center_freq2 =
847 pCsrRoamInfo->chan_info.band_center_freq2;
848 chan_info.reg_info_1 =
849 pCsrRoamInfo->chan_info.reg_info_1;
850 chan_info.reg_info_2 =
851 pCsrRoamInfo->chan_info.reg_info_2;
852
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 }
861#ifdef MSM_PLATFORM
862#ifdef CONFIG_CNSS
863 /* start timer in sta/p2p_cli */
864 spin_lock_bh(&pHddCtx->bus_bw_lock);
865 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
866 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
Himanshu Agarwal11c874a2016-05-06 18:35:29 +0530867 pAdapter->prev_fwd_packets =
868 ol_rx_get_fwd_to_tx_packet_count(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 spin_unlock_bh(&pHddCtx->bus_bw_lock);
870 hdd_start_bus_bw_compute_timer(pAdapter);
871#endif
872#endif
873 } else if (eConnectionState_IbssConnected == /* IBss Associated */
874 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800875 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
877 ETH_ALEN);
878 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
879 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
880 } else { /* Not Associated */
881
882 pr_info("wlan: disconnected\n");
883 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530884 cds_decr_session_set_pcl(pAdapter->device_mode,
885 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887
888#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
889 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
890#endif
891
Krunal Sonibe766b02016-03-10 13:00:44 -0800892 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530893 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 &pHddStaCtx->conn_info.bssId);
895
896 /* send peer status indication to oem app */
897 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
898 ePeerDisconnected, 0,
899 pAdapter->sessionId,
900 NULL);
901 }
902#ifdef WLAN_FEATURE_LPSS
903 pAdapter->rssi_send = false;
904 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
905#endif
906#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800907 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 (pCsrRoamInfo)) {
909 hddLog(LOG4,
910 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
911 pCsrRoamInfo->tdls_prohibited,
912 pCsrRoamInfo->tdls_chan_swit_prohibited);
913
914 wlan_hdd_update_tdls_info(pAdapter,
915 pCsrRoamInfo->tdls_prohibited,
916 pCsrRoamInfo->tdls_chan_swit_prohibited);
917 }
918#endif
919#ifdef MSM_PLATFORM
920 /* stop timer in sta/p2p_cli */
921 spin_lock_bh(&pHddCtx->bus_bw_lock);
922 pAdapter->prev_tx_packets = 0;
923 pAdapter->prev_rx_packets = 0;
Himanshu Agarwal11c874a2016-05-06 18:35:29 +0530924 pAdapter->prev_fwd_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 spin_unlock_bh(&pHddCtx->bus_bw_lock);
926 hdd_stop_bus_bw_compute_timer(pAdapter);
927#endif
928 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800929 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 /* Send SCC/MCC Switching event to IPA */
931 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
932
933 msg = NULL;
934 /*During the WLAN uninitialization,supplicant is stopped before the
935 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800936 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937 wireless_send_event(dev, we_event, &wrqu, msg);
938#ifdef FEATURE_WLAN_ESE
939 if (eConnectionState_Associated ==
940 pHddStaCtx->conn_info.connState) {
941 if ((pRoamProfile->AuthType.authType[0] ==
942 eCSR_AUTH_TYPE_CCKM_RSN) ||
943 (pRoamProfile->AuthType.authType[0] ==
944 eCSR_AUTH_TYPE_CCKM_WPA))
945 hdd_send_new_ap_channel_info(dev, pAdapter,
946 pCsrRoamInfo);
947 }
948#endif
949 }
950}
951
952/**
953 * hdd_conn_remove_connect_info() - remove connection info
954 * @pHddStaCtx: pointer to global HDD station context
955 * @pCsrRoamInfo: pointer to roam info
956 *
957 * Return: none
958 */
959static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
960{
961 /* Remove staId, bssId and peerMacAddress */
962 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530963 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
964 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530965 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966
967 /* Clear all security settings */
968 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
969 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
970 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
971
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530972 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
973 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974
975 /* Set not-connected state */
976 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
977 pHddStaCtx->conn_info.proxyARPService = 0;
978
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530979 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980}
981
982/**
983 * hdd_roam_deregister_sta() - deregister station
984 * @pAdapter: pointer to adapter
985 * @staId: station identifier
986 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530987 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530989static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
991{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530992 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800993 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
994
995 if (eConnectionState_IbssDisconnected ==
996 pHddStaCtx->conn_info.connState) {
997 /*
998 * Do not set the carrier off when the last peer leaves.
999 * We will set the carrier off while stopping the IBSS.
1000 */
1001 }
1002
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301003 qdf_status = ol_txrx_clear_peer(staId);
1004 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001005 hddLog(LOGE,
1006 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301007 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301009 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010}
1011
1012/**
1013 * hdd_dis_connect_handler() - disconnect event handler
1014 * @pAdapter: pointer to adapter
1015 * @pRoamInfo: pointer to roam info
1016 * @roamId: roam identifier
1017 * @roamStatus: roam status
1018 * @roamResult: roam result
1019 *
1020 * This function handles disconnect event:
1021 * 1. Disable transmit queues;
1022 * 2. Clean up internal connection states and data structures;
1023 * 3. Send disconnect indication to supplicant.
1024 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301025 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001026 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301027static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028 tCsrRoamInfo *pRoamInfo,
1029 uint32_t roamId,
1030 eRoamCmdStatus roamStatus,
1031 eCsrRoamResult roamResult)
1032{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301033 QDF_STATUS status = QDF_STATUS_SUCCESS;
1034 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035 struct net_device *dev = pAdapter->dev;
1036 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1037 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1038 uint8_t sta_id;
1039 bool sendDisconInd = true;
1040
1041 if (dev == NULL) {
1042 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301043 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 }
1045 /* notify apps that we can't pass traffic anymore */
1046 hddLog(LOG1, FL("Disabling queues"));
1047 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1048 WLAN_CONTROL_PATH);
1049
1050 if (hdd_ipa_is_enabled(pHddCtx))
1051 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1052 WLAN_STA_DISCONNECT,
1053 pHddStaCtx->conn_info.bssId.bytes);
1054
1055#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1056 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1057#endif
1058
1059#ifdef QCA_PKT_PROTO_TRACE
1060 /* STA disconnected, update into trace buffer */
1061 if (pHddCtx->config->gEnableDebugLog)
1062 cds_pkt_trace_buf_update("ST:DISASC");
1063#endif /* QCA_PKT_PROTO_TRACE */
1064
1065 /* HDD has initiated disconnect, do not send disconnect indication
1066 * to kernel. Sending disconnected event to kernel for userspace
1067 * initiated disconnect will be handled by hdd_DisConnectHandler call
1068 * to cfg80211_disconnected.
1069 */
1070 if ((eConnectionState_Disconnecting ==
1071 pHddStaCtx->conn_info.connState) ||
1072 (eConnectionState_NotConnected ==
1073 pHddStaCtx->conn_info.connState)) {
1074 hddLog(LOG1,
1075 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1076 sendDisconInd = false;
1077 }
1078
1079 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1080 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081 hdd_conn_set_connection_state(pAdapter,
1082 eConnectionState_Disconnecting);
1083 }
1084
1085 hdd_clear_roam_profile_ie(pAdapter);
1086 hdd_wmm_init(pAdapter);
1087
1088 /* indicate 'disconnect' status to wpa_supplicant... */
1089 hdd_send_association_event(dev, pRoamInfo);
1090 /* indicate disconnected event to nl80211 */
1091 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1092 /*
1093 * Only send indication to kernel if not initiated
1094 * by kernel
1095 */
1096 if (sendDisconInd) {
1097 /*
1098 * To avoid wpa_supplicant sending "HANGED" CMD
1099 * to ICS UI.
1100 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001101 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1102 if (pRoamInfo->reasonCode ==
1103 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1104 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001105 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001106 reasonCode, NULL, 0,
1107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1108 true,
1109#endif
1110 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001111 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001112 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001113 WLAN_REASON_UNSPECIFIED, NULL, 0,
1114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1115 true,
1116#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001118 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001119
1120 hdd_info("sent disconnected event to nl80211, rssi: %d",
1121 pAdapter->rssi);
1122 }
1123 /*
1124 * During the WLAN uninitialization,supplicant is stopped
1125 * before the driver so not sending the status of the
1126 * connection to supplicant.
1127 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001128 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001129#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001130 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001131 if (global_p2p_connection_status ==
1132 P2P_CLIENT_CONNECTED_STATE_1) {
1133 global_p2p_connection_status =
1134 P2P_CLIENT_DISCONNECTED_STATE;
1135 hddLog(LOGE,
1136 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1137 } else if (global_p2p_connection_status ==
1138 P2P_CLIENT_COMPLETED_STATE) {
1139 global_p2p_connection_status =
1140 P2P_NOT_ACTIVE;
1141 hddLog(LOGE,
1142 "[P2P State] P2P Client is removed and moved to inactive state");
1143 }
1144 }
1145#endif
1146
1147 }
1148 }
1149
1150 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001151 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001152 if (hdd_remove_beacon_filter(pAdapter) != 0)
1153 hdd_err("hdd_remove_beacon_filter() failed");
1154
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301156 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301157 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001158 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301159 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301160 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1161 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301162 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 }
1164 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301165 /* Clear all the peer sta register with TL. */
1166 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1167 if (0 == pHddStaCtx->conn_info.staId[i])
1168 continue;
1169 sta_id = pHddStaCtx->conn_info.staId[i];
1170 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1171 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301172 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301173 hddLog(LOGE,
1174 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1175 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301176 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301177 }
1178 /* set the staid and peer mac as 0, all other
1179 * reset are done in hdd_connRemoveConnectInfo.
1180 */
1181 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301182 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301183 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301184 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1185 pHddCtx->sta_to_adapter[sta_id] = NULL;
1186 }
1187 } else {
1188 sta_id = pHddStaCtx->conn_info.staId[0];
1189 /* We should clear all sta register with TL,
1190 * for now, only one.
1191 */
1192 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301193 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301194 hddLog(LOGE,
1195 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1196 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301197 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301198 }
1199 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 /* Clear saved connection information in HDD */
1202 hdd_conn_remove_connect_info(pHddStaCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1204#ifdef WLAN_FEATURE_GTK_OFFLOAD
Krunal Sonibe766b02016-03-10 13:00:44 -08001205 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1206 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1208 sizeof(tSirGtkOffloadParams));
1209 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1210 }
1211#endif
1212
1213#ifdef FEATURE_WLAN_TDLS
1214 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1215 wlan_hdd_tdls_disconnection_callback(pAdapter);
1216#endif
1217
Krunal Sonibe766b02016-03-10 13:00:44 -08001218 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1219 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1221 (pAdapter),
1222 pAdapter->sessionId);
1223 }
1224 /* Unblock anyone waiting for disconnect to complete */
1225 complete(&pAdapter->disconnect_comp_var);
1226 return status;
1227}
1228
1229/**
1230 * hdd_set_peer_authorized_event() - set peer_authorized_event
1231 * @vdev_id: vdevid
1232 *
1233 * Return: None
1234 */
1235void hdd_set_peer_authorized_event(uint32_t vdev_id)
1236{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301237 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238 hdd_adapter_t *adapter = NULL;
1239
1240 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1241 if (adapter == NULL) {
1242 hddLog(LOGE,
1243 "%s: Invalid vdev_id", __func__);
1244 }
1245 complete(&adapter->sta_authorized_event);
1246}
1247
1248/**
1249 * hdd_change_peer_state() - change peer state
1250 * @pAdapter: HDD adapter
1251 * @sta_state: peer state
1252 * @roam_synch_in_progress: roam synch in progress
1253 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301254 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301256QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 uint8_t sta_id,
1258 enum ol_txrx_peer_state sta_state,
1259 bool roam_synch_in_progress)
1260{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301261 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001262 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001263 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001264 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265
1266 if (!pdev) {
1267 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301268 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 }
1270
1271 if (sta_id >= WLAN_MAX_STA_COUNT) {
1272 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301273 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274 }
1275
1276 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1277 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301278 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001280 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1281 if (peer_mac_addr == NULL) {
1282 hddLog(LOGE, "peer mac addr is NULL");
1283 return QDF_STATUS_E_FAULT;
1284 }
1285
1286 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301287 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301289 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 }
1291#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1292 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301293 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294#endif
1295
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001296 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001297#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1298 /* make sure event is reset */
1299 INIT_COMPLETION(pAdapter->sta_authorized_event);
1300#endif
1301
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001302 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 hdd_set_peer_authorized_event,
1304 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301305 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301307 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001308 }
1309
Krunal Sonibe766b02016-03-10 13:00:44 -08001310 if (pAdapter->device_mode == QDF_STA_MODE ||
1311 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Houston Hoffman52ec6692016-04-21 16:36:45 -07001313 ol_txrx_vdev_handle vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 unsigned long rc;
1315
1316 /* wait for event from firmware to set the event */
1317 rc = wait_for_completion_timeout(
1318 &pAdapter->sta_authorized_event,
1319 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1320 if (!rc) {
1321 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1322 __func__);
1323 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001324 vdev = ol_txrx_get_vdev_for_peer(peer);
1325 ol_txrx_vdev_unpause(vdev,
1326 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327#endif
1328 }
1329 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301330 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331}
1332
1333/**
1334 * hdd_roam_register_sta() - register station
1335 * @pAdapter: pointer to adapter
1336 * @pRoamInfo: pointer to roam info
1337 * @staId: station identifier
1338 * @pPeerMacAddress: peer MAC address
1339 * @pBssDesc: pointer to BSS description
1340 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301341 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301343static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 tCsrRoamInfo *pRoamInfo,
1345 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301346 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347 tSirBssDescription *pBssDesc)
1348{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301349 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350 struct ol_txrx_desc_type staDesc = { 0 };
1351 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001352 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353
1354 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301355 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356
1357 /* Get the Station ID from the one saved during the association */
1358 staDesc.sta_id = staId;
1359
1360 /* set the QoS field appropriately */
1361 if (hdd_wmm_is_active(pAdapter))
1362 staDesc.is_qos_enabled = 1;
1363 else
1364 staDesc.is_qos_enabled = 0;
1365
1366#ifdef FEATURE_WLAN_WAPI
1367 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1368 pAdapter->wapi_info.fIsWapiSta);
1369 if (pAdapter->wapi_info.fIsWapiSta)
1370 staDesc.is_wapi_supported = 1;
1371 else
1372 staDesc.is_wapi_supported = 0;
1373#endif /* FEATURE_WLAN_WAPI */
1374
Dhanashri Atre50141c52016-04-07 13:15:29 -07001375 /* Register the vdev transmit and receive functions */
1376 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1377 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1378 ol_txrx_vdev_register(
1379 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1380 pAdapter, &txrx_ops);
1381 pAdapter->tx_fn = txrx_ops.tx.tx;
1382
Dhanashri Atre182b0272016-02-17 15:35:07 -08001383 qdf_status = ol_txrx_register_peer(&staDesc);
1384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301385 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 hddLog(LOGW,
1387 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301388 qdf_status, qdf_status);
1389 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 }
1391
1392 if (!pRoamInfo->fAuthRequired) {
1393 /*
1394 * Connections that do not need Upper layer auth, transition
1395 * TLSHIM directly to 'Authenticated' state
1396 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301397 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001399 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1401 pRoamInfo->roamSynchInProgress
1402#else
1403 false
1404#endif
1405 );
1406
1407 hdd_conn_set_authenticated(pAdapter, true);
1408 } else {
1409 hddLog(LOG3,
1410 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1411 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301412 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001414 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1416 pRoamInfo->roamSynchInProgress
1417#else
1418 false
1419#endif
1420 );
1421 hdd_conn_set_authenticated(pAdapter, false);
1422 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301423 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424}
1425
1426/**
1427 * hdd_send_re_assoc_event() - send reassoc event
1428 * @dev: pointer to net device
1429 * @pAdapter: pointer to adapter
1430 * @pCsrRoamInfo: pointer to roam info
1431 * @reqRsnIe: pointer to RSN Information element
1432 * @reqRsnLength: length of RSN IE
1433 *
1434 * Return: none
1435 */
1436static void hdd_send_re_assoc_event(struct net_device *dev,
1437 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1438 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1439{
1440 unsigned int len = 0;
1441 u8 *pFTAssocRsp = NULL;
1442 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001443 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001444 uint32_t rspRsnLength = 0;
1445 struct ieee80211_channel *chan;
1446 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1447 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1448 uint8_t *buf_ptr, ssid_ie_len;
1449 struct cfg80211_bss *bss = NULL;
1450 uint8_t *final_req_ie = NULL;
1451 tCsrRoamConnectedProfile roam_profile;
1452 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1453
1454 if (!rspRsnIe) {
1455 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001456 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001457 }
1458
Naveen Rawat14298b92015-11-25 16:27:41 -08001459 if (!assoc_req_ies) {
1460 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001461 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001462 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 if (pCsrRoamInfo == NULL) {
1464 hddLog(LOGE, FL("Invalid CSR roam info"));
1465 goto done;
1466 }
1467
1468 if (pCsrRoamInfo->nAssocRspLength == 0) {
1469 hddLog(LOGE, FL("Invalid assoc response length"));
1470 goto done;
1471 }
1472
1473 pFTAssocRsp =
1474 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1475 pCsrRoamInfo->nAssocReqLength);
1476 if (pFTAssocRsp == NULL)
1477 goto done;
1478
1479 /* pFTAssocRsp needs to point to the IEs */
1480 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1481 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1482 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1483
1484 /*
1485 * Active session count is decremented upon disconnection, but during
1486 * roaming, there is no disconnect indication and hence active session
1487 * count is not decremented.
1488 * After roaming is completed, active session count is incremented
1489 * as a part of connect indication but effectively after roaming the
1490 * active session count should still be the same and hence upon
1491 * successful reassoc decrement the active session count here.
1492 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001493 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301494 cds_decr_session_set_pcl(pAdapter->device_mode,
1495 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496
1497 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1498 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1499 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301500 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1501 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502
1503 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1504 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301505 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1507 &roam_profile);
1508 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1509 pCsrRoamInfo->bssid.bytes,
1510 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001511#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001513#else
1514 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1515#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516
1517 if (bss == NULL)
1518 hddLog(LOGE, FL("Get BSS returned NULL"));
1519 buf_ptr = buf_ssid_ie;
1520 *buf_ptr = SIR_MAC_SSID_EID;
1521 buf_ptr++;
1522 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1523 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301524 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 roam_profile.SSID.length);
1526 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001527 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301528 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001529 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001530 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1531 if (final_req_ie == NULL)
1532 goto done;
1533 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301534 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301536 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1537 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1538 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001540 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301541 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001542 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543 cfg80211_roamed_bss(dev, bss,
1544 final_req_ie, (ssid_ie_len + reqRsnLength),
1545 rspRsnIe, rspRsnLength, GFP_KERNEL);
1546
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301547 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001548 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1549 pCsrRoamInfo->nAssocReqLength);
1550
1551 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301552 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001553 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1554
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001555 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001556 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1557 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001558 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001560 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561 if (final_req_ie)
1562 kfree(final_req_ie);
1563 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001564 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565}
1566
1567/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301568 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001569 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301570 *
1571 * Return: roam sync status if roaming offloaded else false
1572 */
1573#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001574bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301575{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001576 if (roaminfo)
1577 return roaminfo->roamSynchInProgress;
1578 else
1579 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301580}
1581#endif
1582
1583
1584/**
1585 * hdd_change_sta_state_authenticated()-
1586 * This function changes STA state to authenticated
1587 * @adapter: pointer to the adapter structure.
1588 * @roaminfo: pointer to the RoamInfo structure.
1589 *
1590 * This is called from hdd_RoamSetKeyCompleteHandler
1591 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1592 *
1593 * Return: 0 on success and errno on failure
1594 */
1595static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1596 tCsrRoamInfo *roaminfo)
1597{
1598 int ret;
1599 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1600
1601 hddLog(LOG1,
1602 "Changing TL state to AUTHENTICATED for StaId= %d",
1603 hddstactx->conn_info.staId[0]);
1604
1605 /* Connections that do not need Upper layer authentication,
1606 * transition TL to 'Authenticated' state after the keys are set
1607 */
1608 ret = hdd_change_peer_state(adapter,
1609 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001610 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301611 hdd_is_roam_sync_in_progress(roaminfo));
1612 hdd_conn_set_authenticated(adapter, true);
Krunal Sonibe766b02016-03-10 13:00:44 -08001613 if ((QDF_STA_MODE == adapter->device_mode) ||
1614 (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301615 sme_ps_enable_auto_ps_timer(
1616 WLAN_HDD_GET_HAL_CTX(adapter),
1617 adapter->sessionId,
1618 hddstactx->hdd_ReassocScenario);
1619 }
1620
1621 return ret;
1622}
1623
1624/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625 * hdd_roam_set_key_complete_handler() - Update the security parameters
1626 * @pAdapter: pointer to adapter
1627 * @pRoamInfo: pointer to roam info
1628 * @roamId: roam id
1629 * @roamStatus: roam status
1630 * @roamResult: roam result
1631 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301632 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301634static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 tCsrRoamInfo *pRoamInfo,
1636 uint32_t roamId,
1637 eRoamCmdStatus roamStatus,
1638 eCsrRoamResult roamResult)
1639{
1640 eCsrEncryptionType connectedCipherAlgo;
1641 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301642 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301644 tHalHandle hal_ctx = WLAN_HDD_GET_HAL_CTX(pAdapter);
1645 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1646
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001647 ENTER();
1648
1649 if (NULL == pRoamInfo) {
1650 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301651 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 }
1653 /*
1654 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1655 * then go to 'authenticated'. For all other authentication types
1656 * (those that do not require upper layer authentication) we can put TL
1657 * directly into 'authenticated' state.
1658 */
1659 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1660 MAC_ADDRESS_STR, roamStatus, roamResult,
1661 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1662
1663 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1664 &connectedCipherAlgo);
1665 if (fConnected) {
Krunal Sonibe766b02016-03-10 13:00:44 -08001666 if (QDF_IBSS_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 uint8_t staId;
1668
Anurag Chouhanc5548422016-02-24 18:33:27 +05301669 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 pHddStaCtx->roam_info.roamingState =
1671 HDD_ROAM_STATE_NONE;
1672 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301673 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674 pHddStaCtx,
1675 &pRoamInfo->peerMac,
1676 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301677 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678 hddLog(LOG2,
1679 "WLAN TL STA Ptk Installed for STAID=%d",
1680 staId);
1681 pHddStaCtx->roam_info.roamingState =
1682 HDD_ROAM_STATE_NONE;
1683 }
1684 }
1685 } else {
1686 /*
1687 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301688 * HDD later.This routine is invoked twice.
1689 * 1)set PTK 2)set GTK.The following if
1690 * statement will be TRUE when setting GTK.
1691 * At this time we don't handle the state in detail.
1692 * Related CR: 174048 - TL not in authenticated state
1693 */
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301694 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301695 pHddStaCtx->conn_info.gtk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301696 /*
1697 * PTK exchange happens in preauthentication
1698 * itself if key_mgmt is FT-PSK, ptk_installed
1699 * was false as there is no set PTK after
1700 * roaming. STA TL state moves to authenticated
1701 * only if ptk_installed is true. So, make
1702 * ptk_installed to true in case of 11R roaming.
1703 */
1704 if (csr_neighbor_roam_is11r_assoc(mac_ctx,
1705 pAdapter->sessionId))
1706 pHddStaCtx->conn_info.ptk_installed =
1707 true;
1708 } else {
Govind Singhedc5cda2015-10-23 17:11:35 +05301709 pHddStaCtx->conn_info.ptk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301710 }
Govind Singhedc5cda2015-10-23 17:11:35 +05301711
1712 /* In WPA case move STA to authenticated when
1713 * ptk is installed.Earlier in WEP case STA
1714 * was moved to AUTHENTICATED prior to setting
1715 * the unicast key and it was resulting in sending
1716 * few un-encrypted packet. Now in WEP case
1717 * STA state will be moved to AUTHENTICATED
1718 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301720 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1721 eCSR_ENCRYPT_TYPE_WEP40) ||
1722 (pHddStaCtx->conn_info.ucEncryptionType ==
1723 eCSR_ENCRYPT_TYPE_WEP104) ||
1724 (pHddStaCtx->conn_info.ucEncryptionType ==
1725 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1726 (pHddStaCtx->conn_info.ucEncryptionType ==
1727 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1728 if (pHddStaCtx->conn_info.gtk_installed &&
1729 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301730 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301731 hdd_change_sta_state_authenticated(pAdapter,
1732 pRoamInfo);
1733 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301734 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301735 hdd_change_sta_state_authenticated(pAdapter,
1736 pRoamInfo);
1737 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738
Govind Singhedc5cda2015-10-23 17:11:35 +05301739 if (pHddStaCtx->conn_info.gtk_installed &&
1740 pHddStaCtx->conn_info.ptk_installed) {
1741 pHddStaCtx->conn_info.gtk_installed = false;
1742 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 }
1744
1745 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301746 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747 }
1748 } else {
1749 /*
1750 * possible disassoc after issuing set key and waiting
1751 * set key complete.
1752 */
1753 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1754 }
1755
1756 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301757 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001758}
1759
1760/**
1761 * hdd_perform_roam_set_key_complete() - perform set key complete
1762 * @pAdapter: pointer to adapter
1763 *
1764 * Return: none
1765 */
1766void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1767{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301768 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1770 tCsrRoamInfo roamInfo;
1771 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301772 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301773 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301774 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301775 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301777 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 hdd_roam_set_key_complete_handler(pAdapter,
1779 &roamInfo,
1780 pHddStaCtx->roam_info.roamId,
1781 pHddStaCtx->roam_info.roamStatus,
1782 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301783 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001784 hddLog(LOGE, FL("Set Key complete failure"));
1785
1786 pHddStaCtx->roam_info.deferKeyComplete = false;
1787}
1788
1789/**
1790 * hdd_association_completion_handler() - association completion handler
1791 * @pAdapter: pointer to adapter
1792 * @pRoamInfo: pointer to roam info
1793 * @roamId: roam id
1794 * @roamStatus: roam status
1795 * @roamResult: roam result
1796 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301797 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301799static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 tCsrRoamInfo *pRoamInfo,
1801 uint32_t roamId,
1802 eRoamCmdStatus roamStatus,
1803 eCsrRoamResult roamResult)
1804{
1805 struct net_device *dev = pAdapter->dev;
1806 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1807 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301808 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001809 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1810 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 bool hddDisconInProgress = false;
1813 unsigned long rc;
1814
1815 if (!pHddCtx) {
1816 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301817 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 }
1819
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 /* HDD has initiated disconnect, do not send connect result indication
1821 * to kernel as it will be handled by __cfg80211_disconnect.
1822 */
1823 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1824 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1825 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1826 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1827 hddDisconInProgress = true;
1828 }
1829
1830 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1831 if (NULL == pRoamInfo) {
1832 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301833 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 }
1835 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836 hdd_conn_set_connection_state(pAdapter,
1837 eConnectionState_Associated);
1838 }
1839 /* Save the connection info from CSR... */
1840 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1841 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001842
1843 if (hdd_add_beacon_filter(pAdapter) != 0)
1844 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845#ifdef FEATURE_WLAN_WAPI
1846 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1847 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1848 || pRoamInfo->u.pConnectedProfile->AuthType ==
1849 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1850 pAdapter->wapi_info.fIsWapiSta = 1;
1851 } else {
1852 pAdapter->wapi_info.fIsWapiSta = 0;
1853 }
1854#endif /* FEATURE_WLAN_WAPI */
1855
1856 /* Indicate 'connect' status to user space */
1857 hdd_send_association_event(dev, pRoamInfo);
1858
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001859 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 if (pHddCtx->miracast_value)
1861 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1862 }
1863
1864 /* Initialize the Linkup event completion variable */
1865 INIT_COMPLETION(pAdapter->linkup_event_var);
1866
1867 /*
1868 * Sometimes Switching ON the Carrier is taking time to activate
1869 * the device properly. Before allowing any packet to go up to
1870 * the application, device activation has to be ensured for
1871 * proper queue mapping by the kernel. we have registered net
1872 * device notifier for device change notification. With this we
1873 * will come to know that the device is getting
1874 * activated properly.
1875 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001877 /*
1878 * Enable Linkup Event Servicing which allows the net
1879 * device notifier to set the linkup event variable.
1880 */
1881 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001883 /* Switch on the Carrier to activate the device */
1884 wlan_hdd_netif_queue_control(pAdapter,
1885 WLAN_NETIF_CARRIER_ON,
1886 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001888 /*
1889 * Wait for the Link to up to ensure all the queues
1890 * are set properly by the kernel.
1891 */
1892 rc = wait_for_completion_timeout(
1893 &pAdapter->linkup_event_var,
1894 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1895 );
1896 if (!rc)
1897 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001898
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001899 /*
1900 * Disable Linkup Event Servicing - no more service
1901 * required from the net device notifier call.
1902 */
1903 pAdapter->isLinkUpSvcNeeded = false;
1904 } else {
1905 pHddStaCtx->ft_carrier_on = false;
1906 ft_carrier_on = true;
1907 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1909 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1910 else
1911 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1912 pRoamInfo->staId);
1913
1914 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1915
1916 if (hdd_ipa_is_enabled(pHddCtx))
1917 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1918 WLAN_STA_CONNECT,
1919 pRoamInfo->bssid.bytes);
1920
1921#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1922 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1923#endif
1924
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301925 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001926 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001927 pAdapter);
1928
1929#ifdef FEATURE_WLAN_TDLS
1930 wlan_hdd_tdls_connection_callback(pAdapter);
1931#endif
1932
1933#ifdef QCA_PKT_PROTO_TRACE
1934 /* STA Associated, update into trace buffer */
1935 if (pHddCtx->config->gEnableDebugLog)
1936 cds_pkt_trace_buf_update("ST:ASSOC");
1937#endif /* QCA_PKT_PROTO_TRACE */
1938 /*
1939 * For reassoc, the station is already registered, all we need
1940 * is to change the state of the STA in TL.
1941 * If authentication is required (WPA/WPA2/DWEP), change TL to
1942 * CONNECTED instead of AUTHENTICATED.
1943 */
1944 if (!pRoamInfo->fReassocReq) {
1945 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001946 u8 *pFTAssocRsp = NULL;
1947 unsigned int assocRsplen = 0;
1948 u8 *pFTAssocReq = NULL;
1949 unsigned int assocReqlen = 0;
1950 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001951 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1952 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1953
1954 /* add bss_id to cfg80211 data base */
1955 bss =
1956 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1957 pRoamInfo);
1958 if (NULL == bss) {
1959 pr_err("wlan: Not able to create BSS entry\n");
1960 wlan_hdd_netif_queue_control(pAdapter,
1961 WLAN_NETIF_CARRIER_OFF,
1962 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301963 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1966 eCSR_AUTH_TYPE_FT_RSN
1967 || pRoamInfo->u.pConnectedProfile->AuthType ==
1968 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1969
1970 /* Association Response */
1971 pFTAssocRsp =
1972 (u8 *) (pRoamInfo->pbFrames +
1973 pRoamInfo->nBeaconLength +
1974 pRoamInfo->nAssocReqLength);
1975 if (pFTAssocRsp != NULL) {
1976 /*
1977 * pFTAssocRsp needs to point to the IEs
1978 */
1979 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1980 hddLog(LOG1,
1981 FL("AssocRsp is now at %02x%02x"),
1982 (unsigned int)pFTAssocRsp[0],
1983 (unsigned int)pFTAssocRsp[1]);
1984 assocRsplen =
1985 pRoamInfo->nAssocRspLength -
1986 FT_ASSOC_RSP_IES_OFFSET;
1987 } else {
1988 hddLog(LOGE, FL("AssocRsp is NULL"));
1989 assocRsplen = 0;
1990 }
1991
1992 /* Association Request */
1993 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1994 pRoamInfo->nBeaconLength);
1995 if (pFTAssocReq != NULL) {
1996 if (!ft_carrier_on) {
1997 /*
1998 * pFTAssocReq needs to point to
1999 * the IEs
2000 */
2001 pFTAssocReq +=
2002 FT_ASSOC_REQ_IES_OFFSET;
2003 hddLog(LOG1,
2004 FL("pFTAssocReq is now at %02x%02x"),
2005 (unsigned int)
2006 pFTAssocReq[0],
2007 (unsigned int)
2008 pFTAssocReq[1]);
2009 assocReqlen =
2010 pRoamInfo->nAssocReqLength -
2011 FT_ASSOC_REQ_IES_OFFSET;
2012 } else {
2013 /*
2014 * This should contain only the
2015 * FTIEs
2016 */
2017 assocReqlen =
2018 pRoamInfo->nAssocReqLength;
2019 }
2020 } else {
2021 hddLog(LOGE, FL("AssocReq is NULL"));
2022 assocReqlen = 0;
2023 }
2024
2025 if (ft_carrier_on) {
2026 if (!hddDisconInProgress) {
2027 /*
2028 * After roaming is completed,
2029 * active session count is
2030 * incremented as a part of
2031 * connect indication but
2032 * effectively the active
2033 * session count should still
2034 * be the same and hence upon
2035 * successful reassoc
2036 * decrement the active session
2037 * count here.
2038 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002039 if (!hdd_is_roam_sync_in_progress
2040 (pRoamInfo))
2041 cds_decr_session_set_pcl
2042 (pAdapter->device_mode,
2043 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002044 hddLog(LOG1,
2045 FL("ft_carrier_on is %d, sending roamed indication"),
2046 ft_carrier_on);
2047 chan =
2048 ieee80211_get_channel
2049 (pAdapter->wdev.wiphy,
2050 (int)pRoamInfo->pBssDesc->
2051 channelId);
2052 hddLog(LOG1,
2053 "assocReqlen %d assocRsplen %d",
2054 assocReqlen,
2055 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002056
2057 hdd_notice(
2058 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302059 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302060 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302061 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002062 pFTAssocReq,
2063 assocReqlen);
2064
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002065 cfg80211_roamed(dev, chan,
2066 pRoamInfo->
2067 bssid.bytes,
2068 pFTAssocReq,
2069 assocReqlen,
2070 pFTAssocRsp,
2071 assocRsplen,
2072 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002073 wlan_hdd_send_roam_auth_event(
2074 pHddCtx,
2075 pRoamInfo->bssid.bytes,
2076 pFTAssocReq,
2077 assocReqlen,
2078 pFTAssocRsp,
2079 assocRsplen,
2080 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002081 }
2082 if (sme_get_ftptk_state
2083 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2084 pAdapter->sessionId)) {
2085 sme_set_ftptk_state
2086 (WLAN_HDD_GET_HAL_CTX
2087 (pAdapter),
2088 pAdapter->sessionId,
2089 false);
2090 pRoamInfo->fAuthRequired =
2091 false;
2092
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302093 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094 roam_info.bssid,
2095 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302096 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302097 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002098 roam_info.peerMac,
2099 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302100 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101 pHddStaCtx->roam_info.roamId =
2102 roamId;
2103 pHddStaCtx->roam_info.
2104 roamStatus = roamStatus;
2105 pHddStaCtx->roam_info.
2106 deferKeyComplete = true;
2107 }
2108 } else if (!hddDisconInProgress) {
2109 hddLog(LOG1,
2110 FL("ft_carrier_on is %d, sending connect indication"),
2111 ft_carrier_on);
2112 cfg80211_connect_result(dev,
2113 pRoamInfo->
2114 bssid.bytes,
2115 pFTAssocReq,
2116 assocReqlen,
2117 pFTAssocRsp,
2118 assocRsplen,
2119 WLAN_STATUS_SUCCESS,
2120 GFP_KERNEL);
2121 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002122 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123 /*
2124 * wpa supplicant expecting WPA/RSN IE in
2125 * connect result.
2126 */
2127 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2128 (pAdapter),
2129 pAdapter->sessionId,
2130 &reqRsnLength,
2131 reqRsnIe);
2132
2133 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2134 (pAdapter),
2135 pAdapter->sessionId,
2136 &rspRsnLength,
2137 rspRsnIe);
2138 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002139 if (ft_carrier_on)
2140 hdd_send_re_assoc_event(dev,
2141 pAdapter,
2142 pRoamInfo,
2143 reqRsnIe,
2144 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002145 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002146 hddLog(LOG1,
2147 FL("sending connect indication to nl80211:for bssid "
2148 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302149 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 MAC_ADDR_ARRAY
2151 (pRoamInfo->bssid.bytes),
2152 roamResult, roamStatus);
2153
2154 /* inform connect result to nl80211 */
2155 cfg80211_connect_result(dev,
2156 pRoamInfo->
2157 bssid.bytes,
2158 reqRsnIe,
2159 reqRsnLength,
2160 rspRsnIe,
2161 rspRsnLength,
2162 WLAN_STATUS_SUCCESS,
2163 GFP_KERNEL);
2164 }
2165 }
2166 }
2167 if (!hddDisconInProgress) {
2168 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002169 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170 bss);
2171
2172 /*
2173 * Perform any WMM-related association
2174 * processing.
2175 */
2176 hdd_wmm_assoc(pAdapter, pRoamInfo,
2177 eCSR_BSS_TYPE_INFRASTRUCTURE);
2178
2179 /*
2180 * Start the Queue - Start tx queues before
2181 * hdd_roam_register_sta, since
2182 * hdd_roam_register_sta will flush any cached
2183 * data frames immediately.
2184 */
2185 hddLog(LOG1, FL("Enabling queues"));
2186 wlan_hdd_netif_queue_control(pAdapter,
2187 WLAN_WAKE_ALL_NETIF_QUEUE,
2188 WLAN_CONTROL_PATH);
2189
2190 /*
2191 * Register the Station with TL after associated
2192 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302193 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194 pRoamInfo,
2195 pHddStaCtx->
2196 conn_info.
2197 staId[0],
2198 NULL,
2199 pRoamInfo->
2200 pBssDesc);
2201 }
2202 } else {
2203 /*
2204 * wpa supplicant expecting WPA/RSN IE in connect result
2205 * in case of reassociation also need to indicate it to
2206 * supplicant.
2207 */
2208 csr_roam_get_wpa_rsn_req_ie(
2209 WLAN_HDD_GET_HAL_CTX(pAdapter),
2210 pAdapter->sessionId,
2211 &reqRsnLength, reqRsnIe);
2212
2213 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2214 reqRsnIe, reqRsnLength);
2215 /* Reassoc successfully */
2216 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302217 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218 hdd_change_peer_state(pAdapter,
2219 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002220 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002221#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2222 pRoamInfo->roamSynchInProgress
2223#else
2224 false
2225#endif
2226 );
2227 hdd_conn_set_authenticated(pAdapter, false);
2228 } else {
2229 hddLog(LOG2,
2230 FL("staId: %d Changing TL state to AUTHENTICATED"),
2231 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302232 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233 hdd_change_peer_state(pAdapter,
2234 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002235 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002236#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2237 pRoamInfo->roamSynchInProgress
2238#else
2239 false
2240#endif
2241 );
2242 hdd_conn_set_authenticated(pAdapter, true);
2243 }
2244
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302245 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246 /*
2247 * Perform any WMM-related association
2248 * processing
2249 */
2250 hdd_wmm_assoc(pAdapter, pRoamInfo,
2251 eCSR_BSS_TYPE_INFRASTRUCTURE);
2252 }
2253
2254 /* Start the tx queues */
2255#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2256 if (pRoamInfo->roamSynchInProgress)
2257 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2258#endif
2259 hddLog(LOG1, FL("Enabling queues"));
2260 wlan_hdd_netif_queue_control(pAdapter,
2261 WLAN_WAKE_ALL_NETIF_QUEUE,
2262 WLAN_CONTROL_PATH);
2263 }
2264
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302265 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002266 hddLog(LOGE,
2267 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302268 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 }
2270#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302271 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002272 sizeof(pAdapter->hdd_stats.hddPmfStats));
2273#endif
2274 } else {
2275 hdd_wext_state_t *pWextState =
2276 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2277 if (pRoamInfo)
2278 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302279 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2281 roamResult, roamStatus);
2282 else
2283 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302284 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2286 roamResult, roamStatus);
2287
2288 /*
2289 * CR465478: Only send up a connection failure result when CSR
2290 * has completed operation - with a ASSOCIATION_FAILURE status.
2291 */
2292 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2293 && !hddDisconInProgress) {
2294 if (pRoamInfo)
2295 hddLog(LOGE,
2296 FL("send connect failure to nl80211: for bssid "
2297 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302298 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302300 roamResult, roamStatus,
2301 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002302 else
2303 hddLog(LOGE,
2304 FL("connect failed: for bssid "
2305 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302306 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2308 roamResult, roamStatus);
2309
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002310 /* inform association failure event to nl80211 */
2311 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2312 roamResult) {
2313 if (pRoamInfo)
2314 cfg80211_connect_result(dev,
2315 pRoamInfo->bssid.bytes,
2316 NULL, 0, NULL, 0,
2317 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2318 GFP_KERNEL);
2319 else
2320 cfg80211_connect_result(dev,
2321 pWextState->req_bssId.bytes,
2322 NULL, 0, NULL, 0,
2323 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2324 GFP_KERNEL);
2325 } else {
2326 if (pRoamInfo) {
2327 eCsrAuthType authType =
2328 pWextState->roamProfile.AuthType.
2329 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302330 eCsrEncryptionType encryption_type =
2331 pWextState->roamProfile.
2332 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302334 (((authType ==
2335 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302337 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2338 ((encryption_type ==
2339 eCSR_ENCRYPT_TYPE_WEP40) ||
2340 (encryption_type ==
2341 eCSR_ENCRYPT_TYPE_WEP104) ||
2342 (encryption_type ==
2343 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2344 (encryption_type ==
2345 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 /*
2347 * In case of OPEN-WEP or SHARED-WEP
2348 * authentication, send exact protocol
2349 * reason code. This enables user
2350 * applications to reconnect the station
2351 * with correct configuration.
2352 */
2353 cfg80211_connect_result(dev,
2354 pRoamInfo->bssid.bytes, NULL, 0,
2355 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302356 (isWep &&
2357 pRoamInfo->reasonCode) ?
2358 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002359 WLAN_STATUS_UNSPECIFIED_FAILURE,
2360 GFP_KERNEL);
2361 } else
2362 cfg80211_connect_result(dev,
2363 pWextState->req_bssId.bytes,
2364 NULL, 0, NULL, 0,
2365 WLAN_STATUS_UNSPECIFIED_FAILURE,
2366 GFP_KERNEL);
2367 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302368 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369 }
2370
2371 if (pRoamInfo) {
2372 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2373 pRoamInfo->statusCode)
2374 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2375 pRoamInfo->statusCode)
2376 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2377 pRoamInfo->statusCode)) {
2378 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2379 pRoamInfo);
2380 }
2381 }
2382
2383 /*
2384 * Set connection state to eConnectionState_NotConnected only
2385 * when CSR has completed operation - with a
2386 * ASSOCIATION_FAILURE status.
2387 */
2388 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2389 && !hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 hdd_conn_set_connection_state(pAdapter,
2391 eConnectionState_NotConnected);
2392 }
2393 hdd_wmm_init(pAdapter);
2394
2395 hddLog(LOG1, FL("Disabling queues"));
2396 wlan_hdd_netif_queue_control(pAdapter,
2397 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2398 WLAN_CONTROL_PATH);
2399 }
2400
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302401 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302403 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404
Govind Singh24db1ed2015-12-18 15:54:59 +05302405 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2406 cds_force_sap_on_scc(roamResult,
2407 pRoamInfo->pBssDesc->channelId);
2408 } else {
2409 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302410 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302411 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002412
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302413 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414}
2415
2416/**
2417 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2418 * @pAdapter: pointer to adapter
2419 * @pRoamInfo: pointer to roam info
2420 * @roamId: roam id
2421 * @roamStatus: roam status
2422 * @roamResult: roam result
2423 *
2424 * Here we update the status of the Ibss when we receive information that we
2425 * have started/joined an ibss session.
2426 *
2427 * Return: none
2428 */
2429static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2430 tCsrRoamInfo *pRoamInfo,
2431 uint32_t roamId,
2432 eRoamCmdStatus roamStatus,
2433 eCsrRoamResult roamResult)
2434{
2435 hddLog(LOG1, "%s: id %d, status %d, result %d",
2436 pAdapter->dev->name, roamId, roamStatus, roamResult);
2437
2438 switch (roamResult) {
2439 /* both IBSS Started and IBSS Join should come in here. */
2440 case eCSR_ROAM_RESULT_IBSS_STARTED:
2441 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2442 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2443 {
2444 hdd_context_t *pHddCtx =
2445 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302446 hdd_station_ctx_t *hdd_sta_ctx =
2447 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302448 struct qdf_mac_addr broadcastMacAddr =
2449 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450
2451 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302452 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453 return;
2454 }
2455
2456 /* When IBSS Started comes from CSR, we need to move
2457 * connection state to IBSS Disconnected (meaning no peers
2458 * are in the IBSS).
2459 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460 hdd_conn_set_connection_state(pAdapter,
2461 eConnectionState_IbssDisconnected);
2462 /* notify wmm */
2463 hdd_wmm_connect(pAdapter, pRoamInfo,
2464 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302465
2466 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2467
2468 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 pAdapter;
2470 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302471 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 &broadcastMacAddr,
2473 pRoamInfo->pBssDesc);
2474
2475 if (pRoamInfo->pBssDesc) {
2476 struct cfg80211_bss *bss;
2477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2478 struct ieee80211_channel *chan;
2479 int chan_no;
2480 unsigned int freq;
2481#endif
2482 /* we created the IBSS, notify supplicant */
2483 hddLog(LOG1,
2484 FL("%s: created ibss " MAC_ADDRESS_STR),
2485 pAdapter->dev->name,
2486 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2487
2488 /* we must first give cfg80211 the BSS information */
2489 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2490 pRoamInfo);
2491 if (NULL == bss) {
2492 hddLog(LOGE,
2493 FL("%s: unable to create IBSS entry"),
2494 pAdapter->dev->name);
2495 return;
2496 }
2497 hddLog(LOG1, FL("Enabling queues"));
2498 wlan_hdd_netif_queue_control(pAdapter,
2499 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2500 WLAN_CONTROL_PATH);
2501
2502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2503 chan_no = pRoamInfo->pBssDesc->channelId;
2504
2505 if (chan_no <= 14)
2506 freq = ieee80211_channel_to_frequency(chan_no,
2507 IEEE80211_BAND_2GHZ);
2508 else
2509 freq = ieee80211_channel_to_frequency(chan_no,
2510 IEEE80211_BAND_5GHZ);
2511
2512 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2513
2514 if (chan)
2515 cfg80211_ibss_joined(pAdapter->dev,
2516 bss->bssid, chan,
2517 GFP_KERNEL);
2518 else
2519 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2520 pAdapter->dev->name,
2521 (int)pRoamInfo->pBssDesc->channelId);
2522#else
2523 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2524 GFP_KERNEL);
2525#endif
2526 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002527 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 bss);
2529 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002530 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002531 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002532 pAdapter->sessionId);
2533 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2534 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002535 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002536 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 break;
2538 }
2539
2540 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2541 {
2542 hddLog(LOGE,
2543 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2544 break;
2545 }
2546
2547 default:
2548 hddLog(LOGE, FL("%s: unexpected result %d"),
2549 pAdapter->dev->name, (int)roamResult);
2550 break;
2551 }
2552
2553 return;
2554}
2555
2556/**
2557 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2558 * @pHddStaCtx: pointer to global HDD station context
2559 * @staId: station id
2560 * @peerMacAddress: pointer to peer MAC address
2561 *
2562 * This information is passed to iwconfig later. The peer that joined
2563 * last is passed as information to iwconfig.
2564 *
2565 * Return:
2566 * true if we add MAX_IBSS_PEERS or less STA
2567 * false otherwise.
2568 */
2569static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302570 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002571{
2572 bool fSuccess = false;
2573 int idx = 0;
2574
2575 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2576 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2577 pHddStaCtx->conn_info.staId[idx] = staId;
2578
Anurag Chouhanc5548422016-02-24 18:33:27 +05302579 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002580 peerMacAddress[idx], peerMacAddress);
2581
2582 fSuccess = true;
2583 break;
2584 }
2585 }
2586
2587 return fSuccess;
2588}
2589
2590/**
2591 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2592 * @pAdapter: pointer to adapter
2593 * @staId: station id
2594 *
2595 * Return:
2596 * true if we remove MAX_IBSS_PEERS or less STA
2597 * false otherwise.
2598 */
2599static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2600{
2601 bool fSuccess = false;
2602 int idx = 0;
2603 uint8_t valid_idx = 0;
2604 uint8_t del_idx = 0;
2605 uint8_t empty_slots = 0;
2606 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2607
2608 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2609 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2610 pHddStaCtx->conn_info.staId[idx] = 0;
2611
Anurag Chouhanc5548422016-02-24 18:33:27 +05302612 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002613 peerMacAddress[idx]);
2614
2615 fSuccess = true;
2616
2617 /*
2618 * Note the deleted Index, if its 0 we need special
2619 * handling.
2620 */
2621 del_idx = idx;
2622
2623 empty_slots++;
2624 } else {
2625 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2626 valid_idx = idx;
2627 } else {
2628 /* Found an empty slot */
2629 empty_slots++;
2630 }
2631 }
2632 }
2633
2634 if (MAX_IBSS_PEERS == empty_slots) {
2635 /* Last peer departed, set the IBSS state appropriately */
2636 pHddStaCtx->conn_info.connState =
2637 eConnectionState_IbssDisconnected;
2638 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2639 }
2640 /* Find next active staId, to have a valid sta trigger for TL. */
2641 if (fSuccess == true) {
2642 if (del_idx == 0) {
2643 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2644 pHddStaCtx->conn_info.staId[0] =
2645 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302646 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002647 peerMacAddress[0],
2648 &pHddStaCtx->conn_info.
2649 peerMacAddress[valid_idx]);
2650
2651 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302652 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002653 peerMacAddress[valid_idx]);
2654 }
2655 }
2656 }
2657 return fSuccess;
2658}
2659
2660/**
2661 * roam_ibss_connect_handler() - IBSS connection handler
2662 * @pAdapter: pointer to adapter
2663 * @pRoamInfo: pointer to roam info
2664 *
2665 * We update the status of the IBSS to connected in this function.
2666 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302667 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002668 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302669static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 tCsrRoamInfo *pRoamInfo)
2671{
2672 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673 /*
2674 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2675 * a partner stations).
2676 */
2677 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2678
2679 /* Save the connection info from CSR... */
2680 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2681
2682 /* Send the bssid address to the wext. */
2683 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2684 /* add bss_id to cfg80211 data base */
2685 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2686 if (NULL == bss) {
2687 hddLog(LOGE,
2688 FL("%s: unable to create IBSS entry"),
2689 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302690 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691 }
2692 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 bss);
2695
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302696 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697}
2698
2699/**
2700 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2701 * @pAdapter: pointer to adapter
2702 * @pRoamInfo: pointer to roam info
2703 * @roamId: roam id
2704 * @roamStatus: roam status
2705 * @roamResult: roam result
2706 *
2707 * This function indicates the Mic failure to the supplicant
2708 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302709 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002710 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302711static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2713 tCsrRoamInfo *pRoamInfo,
2714 uint32_t roamId,
2715 eRoamCmdStatus roamStatus,
2716 eCsrRoamResult roamResult)
2717{
2718 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2719
2720 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2721 TKIP_COUNTER_MEASURE_STOPED ==
2722 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2723 struct iw_michaelmicfailure msg;
2724 union iwreq_data wreq;
2725 memset(&msg, '\0', sizeof(msg));
2726 msg.src_addr.sa_family = ARPHRD_ETHER;
2727 memcpy(msg.src_addr.sa_data,
2728 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2729 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2730 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2731 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2732
2733 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2734 msg.flags = IW_MICFAILURE_GROUP;
2735 else
2736 msg.flags = IW_MICFAILURE_PAIRWISE;
2737 memset(&wreq, 0, sizeof(wreq));
2738 wreq.data.length = sizeof(msg);
2739 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2740 (char *)&msg);
2741 /* inform mic failure to nl80211 */
2742 cfg80211_michael_mic_failure(pAdapter->dev,
2743 pRoamInfo->u.pMICFailureInfo->
2744 taMacAddr,
2745 ((pRoamInfo->u.pMICFailureInfo->
2746 multicast ==
2747 eSIR_TRUE) ?
2748 NL80211_KEYTYPE_GROUP :
2749 NL80211_KEYTYPE_PAIRWISE),
2750 pRoamInfo->u.pMICFailureInfo->
2751 keyId,
2752 pRoamInfo->u.pMICFailureInfo->TSC,
2753 GFP_KERNEL);
2754
2755 }
2756
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302757 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758}
2759
2760/**
2761 * roam_roam_connect_status_update_handler() - IBSS connect status update
2762 * @pAdapter: pointer to adapter
2763 * @pRoamInfo: pointer to roam info
2764 * @roamId: roam id
2765 * @roamStatus: roam status
2766 * @roamResult: roam result
2767 *
2768 * The Ibss connection status is updated regularly here in this function.
2769 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302770 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302772static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2774 tCsrRoamInfo *pRoamInfo,
2775 uint32_t roamId,
2776 eRoamCmdStatus roamStatus,
2777 eCsrRoamResult roamResult)
2778{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302779 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780
2781 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2782 switch (roamResult) {
2783 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2784 {
2785 hdd_station_ctx_t *pHddStaCtx =
2786 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2787 struct station_info staInfo;
2788
2789 pr_info("IBSS New Peer indication from SME "
2790 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2791 MAC_ADDRESS_STR " and stationID= %d",
2792 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2793 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2794 pRoamInfo->staId);
2795
2796 if (!roam_save_ibss_station
2797 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2798 pRoamInfo->staId,
2799 &pRoamInfo->peerMac)) {
2800 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2801 break;
2802 }
2803
2804 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2805
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002806 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302807 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 pRoamInfo,
2809 pRoamInfo->staId,
2810 &pRoamInfo->peerMac,
2811 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302812 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002813 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302814 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2815 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002816 }
2817 pHddStaCtx->ibss_sta_generation++;
2818 memset(&staInfo, 0, sizeof(staInfo));
2819 staInfo.filled = 0;
2820 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2821
2822 cfg80211_new_sta(pAdapter->dev,
2823 (const u8 *)pRoamInfo->peerMac.bytes,
2824 &staInfo, GFP_KERNEL);
2825
2826 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2827 pHddStaCtx->ibss_enc_key.encType
2828 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2829 pHddStaCtx->ibss_enc_key.encType
2830 || eCSR_ENCRYPT_TYPE_TKIP ==
2831 pHddStaCtx->ibss_enc_key.encType
2832 || eCSR_ENCRYPT_TYPE_AES ==
2833 pHddStaCtx->ibss_enc_key.encType) {
2834 pHddStaCtx->ibss_enc_key.keyDirection =
2835 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302836 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002837 &pRoamInfo->peerMac);
2838
2839 hddLog(LOG2, "New peer joined set PTK encType=%d",
2840 pHddStaCtx->ibss_enc_key.encType);
2841
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302842 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002843 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2844 (pAdapter),
2845 pAdapter->sessionId,
2846 &pHddStaCtx->ibss_enc_key,
2847 &roamId);
2848
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302849 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002850 hddLog(LOGE,
2851 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302852 qdf_status);
2853 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002854 }
2855 }
2856 hddLog(LOG1, FL("Enabling queues"));
2857 wlan_hdd_netif_queue_control(pAdapter,
2858 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2859 WLAN_CONTROL_PATH);
2860 break;
2861 }
2862
2863 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2864 {
2865
2866 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2867
2868 break;
2869 }
2870 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2871 {
2872 hdd_station_ctx_t *pHddStaCtx =
2873 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2874
2875 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2876 hddLog(LOGW,
2877 "IBSS peer departed by cannot find peer in our registration table with TL");
2878
2879 pr_info("IBSS Peer Departed from SME "
2880 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2881 MAC_ADDRESS_STR " and stationID= %d",
2882 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2883 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2884 pRoamInfo->staId);
2885
2886 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2887
2888 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2889 pHddStaCtx->ibss_sta_generation++;
2890
2891 cfg80211_del_sta(pAdapter->dev,
2892 (const u8 *)&pRoamInfo->peerMac.bytes,
2893 GFP_KERNEL);
2894 break;
2895 }
2896 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2897 {
2898 hddLog(LOG3,
2899 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2900 /* Stop only when we are inactive */
2901 hddLog(LOG1, FL("Disabling queues"));
2902 wlan_hdd_netif_queue_control(pAdapter,
2903 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2904 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002905 hdd_conn_set_connection_state(pAdapter,
2906 eConnectionState_NotConnected);
2907
2908 /* Send the bssid address to the wext. */
2909 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2910 break;
2911 }
2912 default:
2913 break;
2914
2915 }
2916
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302917 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002918}
2919
2920#ifdef FEATURE_WLAN_TDLS
2921/**
2922 * hdd_roam_register_tdlssta() - register new TDLS station
2923 * @pAdapter: pointer to adapter
2924 * @peerMac: pointer to peer MAC address
2925 * @staId: station identifier
2926 * @ucastSig: unicast signature
2927 *
2928 * Construct the staDesc and register with TL the new STA.
2929 * This is called as part of ADD_STA in the TDLS setup.
2930 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302931 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002932 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302933QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934 const uint8_t *peerMac, uint16_t staId,
2935 uint8_t ucastSig)
2936{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302937 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002939 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940
2941 /*
2942 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2943 * be peer MAC, here we are working on direct Link
2944 */
2945 staDesc.sta_id = staId;
2946
2947 /* set the QoS field appropriately .. */
2948 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2949 : (staDesc.is_qos_enabled = 0);
2950
Dhanashri Atre50141c52016-04-07 13:15:29 -07002951 /* Register the vdev transmit and receive functions */
2952 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2953 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2954 ol_txrx_vdev_register(
2955 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2956 pAdapter, &txrx_ops);
2957 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002958
2959 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002960 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302961 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002962 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302963 qdf_status, qdf_status);
2964 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002965 }
2966
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302967 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002968}
2969
2970/**
2971 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2972 * @pAdapter: pointer to adapter
2973 * @staId: station identifier
2974 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302975 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002976 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302977static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978 uint8_t staId)
2979{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302980 QDF_STATUS qdf_status;
2981 qdf_status = ol_txrx_clear_peer(staId);
2982 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002983 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302984 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002985 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302986 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002987}
2988
2989/**
2990 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2991 * @pAdapter: pointer to adapter
2992 * @pRoamInfo: pointer to roam info
2993 * @roamId: roam id
2994 * @roamStatus: roam status
2995 * @roamResult: roam result
2996 *
2997 * HDD interface between SME and TL to ensure TDLS client registration with
2998 * TL in case of new TDLS client is added and deregistration at the time
2999 * TDLS client is deleted.
3000 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303001 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003002 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303003static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003004hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3005 tCsrRoamInfo *pRoamInfo,
3006 uint32_t roamId,
3007 eRoamCmdStatus roamStatus,
3008 eCsrRoamResult roamResult)
3009{
3010 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3011 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3012 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303013 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003014 uint8_t staIdx;
3015 hddTdlsPeer_t *curr_peer;
3016 uint32_t reason;
3017
3018 hddLog(LOG2,
3019 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3020 roamResult ==
3021 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3022 ==
3023 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3024 roamResult ==
3025 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3026 : roamResult ==
3027 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3028 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3029 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3030 roamResult ==
3031 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3032 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3033 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3034 : roamResult ==
3035 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3036 : roamResult ==
3037 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3038 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3039 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3040
3041 if (!pHddTdlsCtx) {
3042 hddLog(LOG1,
3043 FL("TDLS ctx is null, ignore roamResult (%d)"),
3044 roamResult);
3045 return status;
3046 }
3047
3048 switch (roamResult) {
3049 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3050 {
3051 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3052 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3053 pRoamInfo->statusCode);
3054 } else {
3055 /*
3056 * Check if there is available index for this new TDLS
3057 * STA.
3058 */
3059 for (staIdx = 0;
3060 staIdx < pHddCtx->max_num_tdls_sta;
3061 staIdx++) {
3062 if (0 ==
3063 pHddCtx->tdlsConnInfo[staIdx].
3064 staId) {
3065 pHddCtx->tdlsConnInfo[staIdx].
3066 sessionId =
3067 pRoamInfo->sessionId;
3068 pHddCtx->tdlsConnInfo[staIdx].
3069 staId = pRoamInfo->staId;
3070
3071 hddLog(LOGW,
3072 ("TDLS: STA IDX at %d is %d "
3073 "of mac "
3074 MAC_ADDRESS_STR),
3075 staIdx,
3076 pHddCtx->
3077 tdlsConnInfo[staIdx].
3078 staId,
3079 MAC_ADDR_ARRAY
3080 (pRoamInfo->peerMac.bytes));
3081
Anurag Chouhanc5548422016-02-24 18:33:27 +05303082 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 tdlsConnInfo
3084 [staIdx].
3085 peerMac,
3086 &pRoamInfo->
3087 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303088 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 break;
3090 }
3091 }
3092 if (staIdx < pHddCtx->max_num_tdls_sta) {
3093 if (-1 ==
3094 wlan_hdd_tdls_set_sta_id(pAdapter,
3095 pRoamInfo->
3096 peerMac.bytes,
3097 pRoamInfo->
3098 staId)) {
3099 hddLog(LOGE,
3100 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303101 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102 }
3103
3104 (WLAN_HDD_GET_CTX(pAdapter))->
3105 sta_to_adapter[pRoamInfo->staId] =
3106 pAdapter;
3107 /*
3108 * store the ucast signature,
3109 * if required for further reference.
3110 */
3111
3112 wlan_hdd_tdls_set_signature(pAdapter,
3113 pRoamInfo->
3114 peerMac.bytes,
3115 pRoamInfo->
3116 ucastSig);
3117 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303118 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003119 hddLog(LOGE,
3120 FL("no available slot in conn_info. staId %d cannot be stored"),
3121 pRoamInfo->staId);
3122 }
3123 pAdapter->tdlsAddStaStatus = status;
3124 }
3125 complete(&pAdapter->tdls_add_station_comp);
3126 break;
3127 }
3128 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3129 {
3130 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3131 hddLog(LOGE,
3132 FL("Add Sta failed. status code(=%d)"),
3133 pRoamInfo->statusCode);
3134 }
3135 /* store the ucast signature which will be used later when
3136 * registering to TL
3137 */
3138 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3139 complete(&pAdapter->tdls_add_station_comp);
3140 break;
3141 }
3142 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3143 {
3144 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3145 hddLog(LOGE,
3146 FL("Link Establish Request failed. status(=%d)"),
3147 pRoamInfo->statusCode);
3148 }
3149 complete(&pAdapter->tdls_link_establish_req_comp);
3150 break;
3151 }
3152 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3153 {
3154 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3155 staIdx++) {
3156 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3157 pRoamInfo->sessionId)
3158 && pRoamInfo->staId ==
3159 pHddCtx->tdlsConnInfo[staIdx].staId) {
3160 hddLog(LOGW,
3161 ("HDD: del STA IDX = %x"),
3162 pRoamInfo->staId);
3163
3164 curr_peer =
3165 wlan_hdd_tdls_find_peer(pAdapter,
3166 pRoamInfo->
3167 peerMac.bytes,
3168 true);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303169 if (NULL != curr_peer) {
3170 hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
3171 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3172 curr_peer->link_status);
3173 if (TDLS_IS_CONNECTED(curr_peer)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003174 hdd_roam_deregister_tdlssta
3175 (pAdapter,
3176 pRoamInfo->staId);
3177 wlan_hdd_tdls_decrement_peer_count
3178 (pAdapter);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303179 } else if (eTDLS_LINK_CONNECTING ==
3180 curr_peer->link_status) {
3181 hdd_roam_deregister_tdlssta
3182 (pAdapter,
3183 pRoamInfo->staId);
3184 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185 }
3186 wlan_hdd_tdls_reset_peer(pAdapter,
3187 pRoamInfo->
3188 peerMac.bytes);
3189
3190 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3191 pHddCtx->tdlsConnInfo[staIdx].
3192 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303193 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003194 tdlsConnInfo[staIdx].
3195 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303196 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303197 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003198 break;
3199 }
3200 }
3201 complete(&pAdapter->tdls_del_station_comp);
3202 }
3203 break;
3204 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3205 {
3206 hddLog(LOGE,
3207 FL("Sending teardown to supplicant with reason code %u"),
3208 pRoamInfo->reasonCode);
3209
3210 curr_peer =
3211 wlan_hdd_tdls_find_peer(pAdapter,
3212 pRoamInfo->peerMac.bytes, true);
3213 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3214 pRoamInfo->reasonCode);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303215 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
3216 curr_peer->peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303217 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003218 break;
3219 }
3220 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3221 {
3222 /* 0 staIdx is assigned to AP we dont want to touch that */
3223 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3224 staIdx++) {
3225 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3226 pRoamInfo->sessionId)
3227 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3228 hddLog(LOGW,
3229 ("hdd_tdlsStatusUpdate: staIdx %d "
3230 MAC_ADDRESS_STR),
3231 pHddCtx->tdlsConnInfo[staIdx].
3232 staId,
3233 MAC_ADDR_ARRAY(pHddCtx->
3234 tdlsConnInfo
3235 [staIdx].
3236 peerMac.
3237 bytes));
3238 wlan_hdd_tdls_reset_peer(pAdapter,
3239 pHddCtx->
3240 tdlsConnInfo
3241 [staIdx].
3242 peerMac.bytes);
3243 hdd_roam_deregister_tdlssta(pAdapter,
3244 pHddCtx->
3245 tdlsConnInfo
3246 [staIdx].
3247 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303248 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 sizeof
3250 (smeTdlsPeerStateParams));
3251 smeTdlsPeerStateParams.vdevId =
3252 pHddCtx->tdlsConnInfo[staIdx].
3253 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303254 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003255 peerMacAddr,
3256 &pHddCtx->
3257 tdlsConnInfo[staIdx].
3258 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303259 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 smeTdlsPeerStateParams.peerState =
3261 eSME_TDLS_PEER_STATE_TEARDOWN;
3262
3263 hddLog(LOG1,
3264 FL("calling sme_update_tdls_peer_state for staIdx %d "
3265 MAC_ADDRESS_STR),
3266 pHddCtx->tdlsConnInfo[staIdx].
3267 staId,
3268 MAC_ADDR_ARRAY(pHddCtx->
3269 tdlsConnInfo
3270 [staIdx].
3271 peerMac.
3272 bytes));
3273 status =
3274 sme_update_tdls_peer_state(
3275 pHddCtx->hHal,
3276 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303277 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 hddLog(LOGE,
3279 FL("sme_update_tdls_peer_state failed for "
3280 MAC_ADDRESS_STR),
3281 MAC_ADDR_ARRAY
3282 (pHddCtx->
3283 tdlsConnInfo[staIdx].
3284 peerMac.bytes));
3285 }
3286 wlan_hdd_tdls_decrement_peer_count
3287 (pAdapter);
3288
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303289 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003290 tdlsConnInfo[staIdx].
3291 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303292 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003293 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3294 pHddCtx->tdlsConnInfo[staIdx].
3295 sessionId = 255;
3296
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303297 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003298 }
3299 }
3300 break;
3301 }
3302 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3303 {
3304 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303305 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3306 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003307 hddLog(LOG2,
3308 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3309 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303310 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303311 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003312 break;
3313 }
3314
3315 curr_peer =
3316 wlan_hdd_tdls_get_peer(pAdapter,
3317 pRoamInfo->peerMac.bytes);
3318 if (!curr_peer) {
3319 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303320 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321 } else {
3322 if (eTDLS_LINK_CONNECTED ==
3323 curr_peer->link_status) {
3324 hddLog(LOGE,
3325 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3326 } else {
3327 /*
3328 * If external control is enabled then initiate
3329 * TDLS only if forced peer is set otherwise
3330 * ignore should Discover trigger from fw.
3331 */
3332 if (pHddCtx->config->
3333 fTDLSExternalControl
3334 && (false ==
3335 curr_peer->isForcedPeer)) {
3336 hddLog(LOG2,
3337 FL
3338 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303339 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003340 break;
3341 } else {
3342 hddLog(LOG2,
3343 FL
3344 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3345 pHddCtx->config->
3346 fTDLSExternalControl,
3347 curr_peer->isForcedPeer,
3348 pRoamInfo->reasonCode);
3349 }
3350 wlan_hdd_tdls_pre_setup_init_work
3351 (pHddTdlsCtx, curr_peer);
3352 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303353 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003354 }
3355 break;
3356 }
3357
3358 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3359 {
3360 curr_peer =
3361 wlan_hdd_tdls_find_peer(pAdapter,
3362 pRoamInfo->peerMac.bytes, true);
3363 if (!curr_peer) {
3364 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303365 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003366 } else {
3367 if (eTDLS_LINK_CONNECTED ==
3368 curr_peer->link_status) {
3369 hddLog(LOGE,
3370 FL
3371 ("Received SHOULD_TEARDOWN for peer "
3372 MAC_ADDRESS_STR
3373 " staId: %d, reason: %d"),
3374 MAC_ADDR_ARRAY(pRoamInfo->
3375 peerMac.bytes),
3376 pRoamInfo->staId,
3377 pRoamInfo->reasonCode);
3378
3379 if (pRoamInfo->reasonCode ==
3380 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3381 pRoamInfo->reasonCode ==
3382 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3383 pRoamInfo->reasonCode ==
3384 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3385 pRoamInfo->reasonCode ==
3386 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3387 reason =
3388 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3389 } else
3390 reason =
3391 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3392
3393 wlan_hdd_tdls_indicate_teardown
3394 (pHddTdlsCtx->pAdapter, curr_peer,
3395 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303396 hdd_send_wlan_tdls_teardown_event(
3397 eTDLS_TEARDOWN_BSS_DISCONNECT,
3398 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399 } else {
3400 hddLog(LOGE,
3401 FL
3402 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3403 pRoamInfo->reasonCode);
3404 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303405 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003406 }
3407 break;
3408 }
3409
3410 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3411 {
3412 curr_peer =
3413 wlan_hdd_tdls_find_peer(pAdapter,
3414 pRoamInfo->peerMac.bytes, true);
3415 if (!curr_peer) {
3416 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303417 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003418 } else {
3419 if (eTDLS_LINK_CONNECTED ==
3420 curr_peer->link_status) {
3421 hddLog(LOGE,
3422 FL
3423 ("Received SHOULD_PEER_DISCONNECTED for peer "
3424 MAC_ADDRESS_STR
3425 " staId: %d, reason: %d"),
3426 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3427 pRoamInfo->staId,
3428 pRoamInfo->reasonCode);
3429
3430 if (pRoamInfo->reasonCode ==
3431 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3432 pRoamInfo->reasonCode ==
3433 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3434 pRoamInfo->reasonCode ==
3435 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3436 pRoamInfo->reasonCode ==
3437 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3438 reason =
3439 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3440 } else
3441 reason =
3442 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3443
3444 wlan_hdd_tdls_indicate_teardown
3445 (pHddTdlsCtx->pAdapter, curr_peer,
3446 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303447 hdd_send_wlan_tdls_teardown_event(
3448 eTDLS_TEARDOWN_BSS_DISCONNECT,
3449 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003450 } else {
3451 hddLog(LOGE,
3452 FL
3453 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3454 pRoamInfo->reasonCode);
3455 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303456 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457 }
3458 break;
3459 }
3460 default:
3461 {
3462 break;
3463 }
3464 }
3465
3466 return status;
3467}
3468#endif
3469
3470#ifdef WLAN_FEATURE_11W
3471/**
3472 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3473 * @pAdapter: pointer to the adapter
3474 * @nFrameLength: Length of the unprotected frame being passed
3475 * @pbFrames: Pointer to the frame buffer
3476 * @frameType: 802.11 frame type
3477 *
3478 * This function forwards the unprotected management frame to the supplicant.
3479 *
3480 * Return: nothing
3481 */
3482static void
3483hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3484 uint8_t *pbFrames, uint8_t frameType)
3485{
3486 uint8_t type = 0;
3487 uint8_t subType = 0;
3488
3489 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3490 frameType, nFrameLength);
3491
3492 /* Sanity Checks */
3493 if (NULL == pAdapter) {
3494 hddLog(LOGE, FL("pAdapter is NULL"));
3495 return;
3496 }
3497
3498 if (NULL == pAdapter->dev) {
3499 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3500 return;
3501 }
3502
3503 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3504 hddLog(LOGE, FL("pAdapter has invalid magic"));
3505 return;
3506 }
3507
3508 if (!nFrameLength) {
3509 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3510 return;
3511 }
3512
3513 if (NULL == pbFrames) {
3514 hddLog(LOGE, FL("pbFrames is NULL"));
3515 return;
3516 }
3517
3518 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3519 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3520
3521 /* Get pAdapter from Destination mac address of the frame */
3522 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3524 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3525 nFrameLength);
3526#else
3527 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3528 nFrameLength);
3529#endif
3530 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3531 } else if (type == SIR_MAC_MGMT_FRAME &&
3532 subType == SIR_MAC_MGMT_DEAUTH) {
3533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3534 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3535 nFrameLength);
3536#else
3537 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3538 nFrameLength);
3539#endif
3540 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3541 } else {
3542 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3543 type, subType);
3544 return;
3545 }
3546}
3547#endif
3548
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003549#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003550/**
3551 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3552 * @pAdapter: pointer to adapter
3553 * @tid: traffic identifier
3554 * @state: state
3555 * @measInterval: measurement interval
3556 *
3557 * This function sends traffic stream metrics IE information to
3558 * the supplicant via wireless event.
3559 *
3560 * Return: none
3561 */
3562static void
3563hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3564 uint8_t state, uint16_t measInterval)
3565{
3566 union iwreq_data wrqu;
3567 char buf[IW_CUSTOM_MAX + 1];
3568 int nBytes = 0;
3569
3570 if (NULL == pAdapter)
3571 return;
3572
3573 /* create the event */
3574 memset(&wrqu, '\0', sizeof(wrqu));
3575 memset(buf, '\0', sizeof(buf));
3576
3577 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3578 tid, state, measInterval);
3579
3580 nBytes =
3581 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3582 measInterval);
3583
3584 wrqu.data.pointer = buf;
3585 wrqu.data.length = nBytes;
3586 /* send the event */
3587 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3588}
3589
3590/**
3591 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3592 * @pAdapter: pointer to adapter
3593 * @pRoamInfo: pointer to roam info
3594 *
3595 * This function sends cckm preauth indication to the supplicant
3596 * via wireless custom event.
3597 *
3598 * Return: none
3599 */
3600static void
3601hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3602{
3603 union iwreq_data wrqu;
3604 char buf[IW_CUSTOM_MAX + 1];
3605 char *pos = buf;
3606 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3607
3608 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3609 return;
3610
3611 /* create the event */
3612 memset(&wrqu, '\0', sizeof(wrqu));
3613 memset(buf, '\0', sizeof(buf));
3614
3615 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3616 hddLog(LOG1,
3617 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3618 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3619 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3620
3621 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3622 pos += nBytes;
3623 freeBytes -= nBytes;
3624
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303625 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303626 pos += QDF_MAC_ADDR_SIZE;
3627 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003628
3629 nBytes = snprintf(pos, freeBytes, " %u:%u",
3630 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3631 freeBytes -= nBytes;
3632
3633 wrqu.data.pointer = buf;
3634 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3635
3636 /* send the event */
3637 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3638}
3639
3640/**
3641 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3642 * @pAdapter: pointer to adapter
3643 * @pRoamInfo: pointer to roam info
3644 *
3645 * Return: none
3646 */
3647static void
3648hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3649 tCsrRoamInfo *pRoamInfo)
3650{
3651 union iwreq_data wrqu;
3652 char buf[IW_CUSTOM_MAX + 1];
3653 int nBytes = 0;
3654
3655 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3656 return;
3657
3658 /* create the event */
3659 memset(&wrqu, '\0', sizeof(wrqu));
3660 memset(buf, '\0', sizeof(buf));
3661
3662 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3663
3664 nBytes =
3665 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3666 pRoamInfo->tsmRoamDelay);
3667
3668 wrqu.data.pointer = buf;
3669 wrqu.data.length = nBytes;
3670
3671 /* send the event */
3672 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3673}
3674
3675/**
3676 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3677 * @pAdapter: pointer to adapter
3678 * @measurementToken: measurement token
3679 * @flag: flag
3680 * @numBss: number of bss
3681 *
3682 * If the measurement is none and no scan results found,
3683 * indicate the supplicant about measurement done.
3684 *
3685 * Return: none
3686 */
3687void
3688hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3689 const uint16_t measurementToken,
3690 const bool flag, const uint8_t numBss)
3691{
3692 union iwreq_data wrqu;
3693 char buf[IW_CUSTOM_MAX];
3694 char *pos = buf;
3695 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3696
3697 memset(&wrqu, '\0', sizeof(wrqu));
3698 memset(buf, '\0', sizeof(buf));
3699
3700 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3701 flag, numBss);
3702
3703 nBytes =
3704 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3705 flag, numBss);
3706
3707 wrqu.data.pointer = buf;
3708 wrqu.data.length = nBytes;
3709 /* send the event */
3710 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3711}
3712
3713/**
3714 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3715 * @pAdapter: pointer to adapter
3716 * @pRoamInfo: pointer to roam info
3717 *
3718 * If the measurement is none and no scan results found,
3719 * indicate the supplicant about measurement done.
3720 *
3721 * Return: none
3722 */
3723static void
3724hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3725 const tCsrRoamInfo *pRoamInfo)
3726{
3727 union iwreq_data wrqu;
3728 char buf[IW_CUSTOM_MAX];
3729 char *pos = buf;
3730 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3731 uint8_t i = 0, len = 0;
3732 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3733 uint8_t lastSent = 0, sendBss = 0;
3734 int bcnRepFieldSize =
3735 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3736 bcnReportFields);
3737 uint8_t ieLenByte = 1;
3738 /*
3739 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3740 */
3741#define ESEBCNREPHEADER_LEN (18)
3742
3743 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3744 return;
3745
3746 /*
3747 * Custom event can pass maximum of 256 bytes of data,
3748 * based on the IE len we need to identify how many BSS info can
3749 * be filled in to custom event data.
3750 */
3751 /*
3752 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3753 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3754 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3755 */
3756
3757 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3758 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3759 hddLog(LOG1,
3760 "Measurement Done but no scan results");
3761 /* If the measurement is none and no scan results found,
3762 indicate the supplicant about measurement done */
3763 hdd_indicate_ese_bcn_report_no_results(
3764 pAdapter,
3765 pRoamInfo->pEseBcnReportRsp->
3766 measurementToken,
3767 pRoamInfo->pEseBcnReportRsp->flag,
3768 pRoamInfo->pEseBcnReportRsp->numBss);
3769 } else {
3770 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3771 memset(&wrqu, '\0', sizeof(wrqu));
3772 memset(buf, '\0', sizeof(buf));
3773 tot_bcn_ieLen = 0;
3774 sendBss = 0;
3775 pos = buf;
3776 freeBytes = IW_CUSTOM_MAX;
3777
3778 for (i = lastSent;
3779 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3780 len =
3781 bcnRepFieldSize + ieLenByte +
3782 pRoamInfo->pEseBcnReportRsp->
3783 bcnRepBssInfo[i].ieLen;
3784 if ((len + tot_bcn_ieLen) >
3785 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3786 break;
3787 }
3788 tot_bcn_ieLen += len;
3789 sendBss++;
3790 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3791 i, bcnRepFieldSize, 1,
3792 pRoamInfo->pEseBcnReportRsp->
3793 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3794 }
3795
3796 hddLog(LOG1, "Sending %d BSS Info",
3797 sendBss);
3798 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3799 pRoamInfo->pEseBcnReportRsp->measurementToken,
3800 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3801 tot_bcn_ieLen);
3802
3803 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3804 pRoamInfo->pEseBcnReportRsp->
3805 measurementToken,
3806 pRoamInfo->pEseBcnReportRsp->flag,
3807 sendBss);
3808 pos += nBytes;
3809 freeBytes -= nBytes;
3810
3811 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303812 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003813 sizeof(tot_bcn_ieLen));
3814 pos += sizeof(tot_bcn_ieLen);
3815 freeBytes -= sizeof(tot_bcn_ieLen);
3816
3817 for (i = 0; i < sendBss; i++) {
3818 hddLog(LOG1,
3819 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3820 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3821 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3822 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3823 pRoamInfo->pEseBcnReportRsp->
3824 bcnRepBssInfo[i +
3825 lastSent].bcnReportFields.
3826 ChanNum,
3827 pRoamInfo->pEseBcnReportRsp->
3828 bcnRepBssInfo[i +
3829 lastSent].bcnReportFields.
3830 Spare,
3831 pRoamInfo->pEseBcnReportRsp->
3832 bcnRepBssInfo[i +
3833 lastSent].bcnReportFields.
3834 MeasDuration,
3835 pRoamInfo->pEseBcnReportRsp->
3836 bcnRepBssInfo[i +
3837 lastSent].bcnReportFields.
3838 PhyType,
3839 pRoamInfo->pEseBcnReportRsp->
3840 bcnRepBssInfo[i +
3841 lastSent].bcnReportFields.
3842 RecvSigPower,
3843 pRoamInfo->pEseBcnReportRsp->
3844 bcnRepBssInfo[i +
3845 lastSent].bcnReportFields.
3846 ParentTsf,
3847 pRoamInfo->pEseBcnReportRsp->
3848 bcnRepBssInfo[i +
3849 lastSent].bcnReportFields.
3850 TargetTsf[0],
3851 pRoamInfo->pEseBcnReportRsp->
3852 bcnRepBssInfo[i +
3853 lastSent].bcnReportFields.
3854 TargetTsf[1],
3855 pRoamInfo->pEseBcnReportRsp->
3856 bcnRepBssInfo[i +
3857 lastSent].bcnReportFields.
3858 BcnInterval,
3859 pRoamInfo->pEseBcnReportRsp->
3860 bcnRepBssInfo[i +
3861 lastSent].bcnReportFields.
3862 CapabilityInfo,
3863 pRoamInfo->pEseBcnReportRsp->
3864 bcnRepBssInfo[i +
3865 lastSent].bcnReportFields.
3866 Bssid[0],
3867 pRoamInfo->pEseBcnReportRsp->
3868 bcnRepBssInfo[i +
3869 lastSent].bcnReportFields.
3870 Bssid[1],
3871 pRoamInfo->pEseBcnReportRsp->
3872 bcnRepBssInfo[i +
3873 lastSent].bcnReportFields.
3874 Bssid[2],
3875 pRoamInfo->pEseBcnReportRsp->
3876 bcnRepBssInfo[i +
3877 lastSent].bcnReportFields.
3878 Bssid[3],
3879 pRoamInfo->pEseBcnReportRsp->
3880 bcnRepBssInfo[i +
3881 lastSent].bcnReportFields.
3882 Bssid[4],
3883 pRoamInfo->pEseBcnReportRsp->
3884 bcnRepBssInfo[i +
3885 lastSent].bcnReportFields.
3886 Bssid[5]);
3887
3888 /* bcn report fields are copied */
3889 len =
3890 sizeof(pRoamInfo->pEseBcnReportRsp->
3891 bcnRepBssInfo[i +
3892 lastSent].
3893 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303894 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895 (char *)&pRoamInfo->
3896 pEseBcnReportRsp->bcnRepBssInfo[i +
3897 lastSent].
3898 bcnReportFields, len);
3899 pos += len;
3900 freeBytes -= len;
3901
3902 /* Add 1 byte of ie len */
3903 len =
3904 pRoamInfo->pEseBcnReportRsp->
3905 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303906 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003907 pos += sizeof(len);
3908 freeBytes -= sizeof(len);
3909
3910 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303911 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003912 (char *)pRoamInfo->
3913 pEseBcnReportRsp->bcnRepBssInfo[i +
3914 lastSent].
3915 pBuf, len);
3916 pos += len;
3917 freeBytes -= len;
3918 }
3919
3920 wrqu.data.pointer = buf;
3921 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3922
3923 /* send the event */
3924 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3925 buf);
3926 lastSent += sendBss;
3927 }
3928 }
3929}
3930
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003931#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003932
3933/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303934 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3935 * @pHddStaCtx: Station Context
3936 *
3937 * API to check if the connection authentication type is 8021x_sha256.
3938 *
3939 * Return: bool
3940 */
3941#ifdef WLAN_FEATURE_11W
3942static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3943{
3944 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3945 pHddStaCtx->conn_info.authType;
3946}
3947#else
3948static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3949{
3950 return false;
3951}
3952#endif
3953
3954/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003955 * hdd_sme_roam_callback() - hdd sme roam callback
3956 * @pContext: pointer to adapter context
3957 * @pRoamInfo: pointer to roam info
3958 * @roamId: roam id
3959 * @roamStatus: roam status
3960 * @roamResult: roam result
3961 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303962 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003963 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303964QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003965hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3966 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3967{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303968 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003969 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3970 hdd_wext_state_t *pWextState = NULL;
3971 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303972 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003973 hdd_context_t *pHddCtx = NULL;
3974
3975 hddLog(LOG2,
3976 "CSR Callback: status= %d result= %d roamID=%d",
3977 roamStatus, roamResult, roamId);
3978
3979 /* Sanity check */
3980 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3981 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303982 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003983 }
3984
3985 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3986 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3987
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303988 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303989 pAdapter->sessionId, roamStatus));
3990
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003991 switch (roamStatus) {
3992 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303993 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3994 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003995 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003996 break;
3997
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003998 /*
3999 * We did pre-auth,then we attempted a 11r or ese reassoc.
4000 * reassoc failed due to failure, timeout, reject from ap
4001 * in any case tell the OS, our carrier is off and mark
4002 * interface down.
4003 */
4004 case eCSR_ROAM_FT_REASSOC_FAILED:
4005 hddLog(LOGE,
4006 FL
4007 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
4008 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304009 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4011 roamStatus, roamResult);
4012 /*
4013 * Check if Mcast/Bcast Filters are set, if yes
4014 * clear the filters here.
4015 */
4016 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4017 true) {
4018 (WLAN_HDD_GET_CTX(pAdapter))->
4019 hdd_mcastbcast_filter_set = false;
4020 }
4021 pHddStaCtx->ft_carrier_on = false;
4022 pHddStaCtx->hdd_ReassocScenario = false;
4023 hddLog(LOG1,
4024 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4025 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4026 break;
4027
4028 case eCSR_ROAM_FT_START:
4029 /*
4030 * When we roam for ESE and 11r, we dont want the OS to be
4031 * informed that the link is down. So mark the link ready for
4032 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4033 * be received. Where in we will not mark the link down
4034 * Also we want to stop tx at this point when we will be
4035 * doing disassoc at this time. This saves 30-60 msec
4036 * after reassoc.
4037 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004039 wlan_hdd_netif_queue_control(pAdapter,
4040 WLAN_NETIF_TX_DISABLE,
4041 WLAN_CONTROL_PATH);
4042 status = hdd_roam_deregister_sta(pAdapter,
4043 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304044 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304045 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004046 pHddStaCtx->ft_carrier_on = true;
4047 pHddStaCtx->hdd_ReassocScenario = true;
4048 hddLog(LOG1,
4049 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4050 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4051 break;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004052 case eCSR_ROAM_DISABLE_QUEUES:
4053 hdd_info("Disabling queues");
4054 wlan_hdd_netif_queue_control(pAdapter,
4055 WLAN_NETIF_TX_DISABLE,
4056 WLAN_CONTROL_PATH);
4057 break;
4058 case eCSR_ROAM_ENABLE_QUEUES:
4059 hdd_info("Enabling queues");
4060 wlan_hdd_netif_queue_control(pAdapter,
4061 WLAN_WAKE_ALL_NETIF_QUEUE,
4062 WLAN_CONTROL_PATH);
4063 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004064
4065 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 /* notify apps that we can't pass traffic anymore */
4067 hddLog(LOG1, FL("Disabling queues"));
4068 wlan_hdd_netif_queue_control(pAdapter,
4069 WLAN_NETIF_TX_DISABLE,
4070 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004071 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004072 wlan_hdd_netif_queue_control(pAdapter,
4073 WLAN_NETIF_CARRIER_OFF,
4074 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076 break;
4077 case eCSR_ROAM_LOSTLINK:
4078 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4079 hddLog(LOG2, "Roaming started due to connection lost");
4080 hddLog(LOG1, FL("Disabling queues"));
4081 wlan_hdd_netif_queue_control(pAdapter,
4082 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4083 WLAN_CONTROL_PATH);
4084 break;
4085 }
4086 case eCSR_ROAM_DISASSOCIATED:
4087 {
4088 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304089 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004090 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4091 roamStatus, roamResult);
4092 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4094 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4095 hdd_conf_mcastbcast_filter(pHddCtx, false);
4096
4097 if (true ==
4098 pHddCtx->sus_res_mcastbcast_filter_valid) {
4099 pHddCtx->configuredMcastBcastFilter =
4100 pHddCtx->sus_res_mcastbcast_filter;
4101 pHddCtx->
4102 sus_res_mcastbcast_filter_valid =
4103 false;
4104 }
4105
4106 hddLog(LOG1,
4107 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4108 hddLog(LOG1,
4109 "McastBcastFilter = %d",
4110 pHddCtx->configuredMcastBcastFilter);
4111 hddLog(LOG1,
4112 "offload: already called mcastbcast filter");
4113 (WLAN_HDD_GET_CTX(pAdapter))->
4114 hdd_mcastbcast_filter_set = false;
4115 }
4116 /* Call to clear any MC Addr List filter applied after
4117 * successful connection.
4118 */
4119 wlan_hdd_set_mc_addr_list(pAdapter, false);
4120 }
4121 break;
4122 case eCSR_ROAM_IBSS_LEAVE:
4123 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304124 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4126 roamStatus, roamResult);
4127 break;
4128 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4129 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4130 /*
4131 * To Do - address probable memory leak with WEP encryption upon
4132 * successful association.
4133 */
4134 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4135 /* Clear saved connection information in HDD */
4136 hdd_conn_remove_connect_info(
4137 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4138 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304139 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140 hdd_association_completion_handler(pAdapter, pRoamInfo,
4141 roamId, roamStatus,
4142 roamResult);
4143#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4144 if (pRoamInfo)
4145 pRoamInfo->roamSynchInProgress = false;
4146#endif
4147 break;
4148 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304149 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004150 pRoamInfo,
4151 roamId,
4152 roamStatus,
4153 roamResult);
4154 break;
4155 case eCSR_ROAM_IBSS_IND:
4156 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4157 roamStatus, roamResult);
4158 break;
4159
4160 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304161 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004162 roam_roam_connect_status_update_handler(pAdapter,
4163 pRoamInfo,
4164 roamId,
4165 roamStatus,
4166 roamResult);
4167 break;
4168
4169 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304170 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004171 hdd_roam_mic_error_indication_handler(pAdapter,
4172 pRoamInfo,
4173 roamId,
4174 roamStatus,
4175 roamResult);
4176 break;
4177
4178 case eCSR_ROAM_SET_KEY_COMPLETE:
4179 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304180 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004181 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4182 roamId, roamStatus,
4183 roamResult);
4184 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4185 pHddStaCtx->hdd_ReassocScenario = false;
4186 hddLog(LOG1,
4187 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4188 pHddStaCtx->hdd_ReassocScenario,
4189 pAdapter->sessionId);
4190 }
4191 }
4192#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4193 if (pRoamInfo != NULL)
4194 pRoamInfo->roamSynchInProgress = false;
4195#endif
4196 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004197
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004198 case eCSR_ROAM_FT_RESPONSE:
4199 hdd_send_ft_event(pAdapter);
4200 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004201
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004202 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304203 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4204 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004205 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304206 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004207 wlan_hdd_cfg80211_pmksa_candidate_notify(
4208 pAdapter, pRoamInfo, 1, false);
4209 }
4210 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004211
4212#ifdef FEATURE_WLAN_LFR_METRICS
4213 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4214 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304215 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004216 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4217 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304218 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004219 }
4220 break;
4221 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4222 /*
4223 * This event will notify pre-auth completion in case of success
4224 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304225 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4227 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304228 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004229 }
4230 break;
4231 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4232 /*
4233 * This event will notify pre-auth completion incase of failure.
4234 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304235 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004236 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4237 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304238 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004239 }
4240 break;
4241 case eCSR_ROAM_HANDOVER_SUCCESS:
4242 /* This event is to notify handover success.
4243 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304244 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4246 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304247 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248 }
4249 break;
4250#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251 case eCSR_ROAM_REMAIN_CHAN_READY:
4252 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4253 break;
4254 case eCSR_ROAM_SEND_ACTION_CNF:
4255 hdd_send_action_cnf(pAdapter,
4256 (roamResult ==
4257 eCSR_ROAM_RESULT_NONE) ? true : false);
4258 break;
4259#ifdef FEATURE_WLAN_TDLS
4260 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304261 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004262 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4263 roamId,
4264 roamStatus,
4265 roamResult);
4266 break;
4267 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4268 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4269 pRoamInfo->reasonCode);
4270 break;
4271#endif
4272#ifdef WLAN_FEATURE_11W
4273 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4274 hdd_indicate_unprot_mgmt_frame(pAdapter,
4275 pRoamInfo->nFrameLength,
4276 pRoamInfo->pbFrames,
4277 pRoamInfo->frameType);
4278 break;
4279#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004280#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281 case eCSR_ROAM_TSM_IE_IND:
4282 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4283 pRoamInfo->tsmIe.state,
4284 pRoamInfo->tsmIe.msmt_interval);
4285 break;
4286
4287 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4288 {
4289 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4290 pHddStaCtx->conn_info.authType
4291 || eCSR_AUTH_TYPE_CCKM_RSN ==
4292 pHddStaCtx->conn_info.authType) {
4293 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4294 }
4295 break;
4296 }
4297
4298 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4299 {
4300 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4301 break;
4302 }
4303
4304 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4305 {
4306 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4307 break;
4308 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004309#endif /* FEATURE_WLAN_ESE */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304310 case eCSR_ROAM_STA_CHANNEL_SWITCH:
4311 hdd_info("channel switch for session:%d to channel:%d",
4312 pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
4313
4314 status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
4315 pRoamInfo->chan_info.chan_id);
4316 if (QDF_IS_STATUS_ERROR(status))
4317 hdd_err("channel change notification failed");
4318
4319 status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
4320 if (QDF_IS_STATUS_ERROR(status))
4321 hdd_info("set hw mode change not done");
4322 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004323 default:
4324 break;
4325 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304326 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004327}
4328
4329/**
4330 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4331 * @auth_suite: auth suite
4332 *
4333 * Return: eCsrAuthType enumeration
4334 */
4335eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4336{
4337 eCsrAuthType auth_type;
4338 /* is the auth type supported? */
4339 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4340 auth_type = eCSR_AUTH_TYPE_RSN;
4341 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4342 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004343 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004344 /* Check for 11r FT Authentication with PSK */
4345 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4346 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4347 /* Check for 11R FT Authentication with 802.1X */
4348 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4349 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004350#ifdef FEATURE_WLAN_ESE
4351 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4352 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4353 } else
4354#endif /* FEATURE_WLAN_ESE */
4355#ifdef WLAN_FEATURE_11W
4356 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4357 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4358 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4359 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4360 } else
4361#endif
4362 {
4363 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4364 }
4365 return auth_type;
4366}
4367
4368/**
4369 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4370 * @auth_suite: auth suite
4371 *
4372 * Return: eCsrAuthType enumeration
4373 */
4374eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4375{
4376 eCsrAuthType auth_type;
4377 /* is the auth type supported? */
4378 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4379 auth_type = eCSR_AUTH_TYPE_WPA;
4380 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4381 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4382 } else
4383#ifdef FEATURE_WLAN_ESE
4384 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4385 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4386 } else
4387#endif /* FEATURE_WLAN_ESE */
4388 {
4389 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4390 }
4391 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4392 return auth_type;
4393}
4394
4395/**
4396 * hdd_translate_rsn_to_csr_encryption_type() -
4397 * Translate RSN to CSR encryption type
4398 * @cipher_suite: cipher suite
4399 *
4400 * Return: eCsrEncryptionType enumeration
4401 */
4402eCsrEncryptionType
4403hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4404{
4405 eCsrEncryptionType cipher_type;
4406
4407 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4408 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4409 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4410 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4411 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4412 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4413 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4414 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4415 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4416 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4417 else
4418 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4419
4420 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4421 return cipher_type;
4422}
4423
4424/**
4425 * hdd_translate_wpa_to_csr_encryption_type() -
4426 * Translate WPA to CSR encryption type
4427 * @cipher_suite: cipher suite
4428 *
4429 * Return: eCsrEncryptionType enumeration
4430 */
4431eCsrEncryptionType
4432hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4433{
4434 eCsrEncryptionType cipher_type;
4435
4436 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4437 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4438 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4439 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4440 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4441 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4442 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4443 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4444 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4445 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4446 else
4447 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4448
4449 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4450 return cipher_type;
4451}
4452
4453/**
4454 * hdd_process_genie() - process gen ie
4455 * @pAdapter: pointer to adapter
4456 * @bssid: pointer to mac address
4457 * @pEncryptType: pointer to encryption type
4458 * @mcEncryptType: pointer to multicast encryption type
4459 * @pAuthType: pointer to auth type
4460 *
4461 * Return: 0 on success, error number otherwise
4462 */
4463static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4464 u8 *bssid,
4465 eCsrEncryptionType *pEncryptType,
4466 eCsrEncryptionType *mcEncryptType,
4467 eCsrAuthType *pAuthType,
4468#ifdef WLAN_FEATURE_11W
4469 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4470#endif
4471 uint16_t gen_ie_len, uint8_t *gen_ie)
4472{
4473 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304474 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004475 tDot11fIERSN dot11RSNIE;
4476 tDot11fIEWPA dot11WPAIE;
4477 uint32_t i;
4478 uint8_t *pRsnIe;
4479 uint16_t RSNIeLen;
4480 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4481 bool updatePMKCache = false;
4482
4483 /*
4484 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4485 * setting present flag to 0.
4486 */
4487 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4488 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4489
4490 /* Type check */
4491 if (gen_ie[0] == DOT11F_EID_RSN) {
4492 /* Validity checks */
4493 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4494 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4495 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4496 gen_ie_len);
4497 return -EINVAL;
4498 }
4499 /* Skip past the EID byte and length byte */
4500 pRsnIe = gen_ie + 2;
4501 RSNIeLen = gen_ie_len - 2;
4502 /* Unpack the RSN IE */
4503 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4504 pRsnIe, RSNIeLen, &dot11RSNIE);
4505 /* Copy out the encryption and authentication types */
4506 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4507 dot11RSNIE.pwise_cipher_suite_count);
4508 hddLog(LOG1, FL("authentication suite count: %d"),
4509 dot11RSNIE.akm_suite_count);
4510 /*Here we have followed the apple base code,
4511 but probably I suspect we can do something different */
4512 /* dot11RSNIE.akm_suite_count */
4513 /* Just translate the FIRST one */
4514 *pAuthType =
4515 hdd_translate_rsn_to_csr_auth_type(
4516 dot11RSNIE.akm_suites[0]);
4517 /* dot11RSNIE.pwise_cipher_suite_count */
4518 *pEncryptType =
4519 hdd_translate_rsn_to_csr_encryption_type(
4520 dot11RSNIE.pwise_cipher_suites[0]);
4521 /* dot11RSNIE.gp_cipher_suite_count */
4522 *mcEncryptType =
4523 hdd_translate_rsn_to_csr_encryption_type(
4524 dot11RSNIE.gp_cipher_suite);
4525#ifdef WLAN_FEATURE_11W
4526 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4527 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4528#endif
4529 /* Set the PMKSA ID Cache for this interface */
4530 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4531 if (is_zero_ether_addr(bssid)) {
4532 hddLog(LOGE, FL("MAC address is all zeroes"));
4533 break;
4534 }
4535 updatePMKCache = true;
4536 /*
4537 * For right now, I assume setASSOCIATE() has passed
4538 * in the bssid.
4539 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304540 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304541 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304542 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004543 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4544 }
4545
4546 if (updatePMKCache) {
4547 /*
4548 * Calling csr_roam_set_pmkid_cache to configure the
4549 * PMKIDs into the cache.
4550 */
4551 hddLog(LOG1,
4552 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4553 i);
4554 /* Finally set the PMKSA ID Cache in CSR */
4555 result =
4556 sme_roam_set_pmkid_cache(halHandle,
4557 pAdapter->sessionId,
4558 PMKIDCache,
4559 dot11RSNIE.pmkid_count,
4560 false);
4561 }
4562 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4563 /* Validity checks */
4564 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4565 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4566 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4567 gen_ie_len);
4568 return -EINVAL;
4569 }
4570 /* Skip past the EID and length byte - and four byte WiFi OUI */
4571 pRsnIe = gen_ie + 2 + 4;
4572 RSNIeLen = gen_ie_len - (2 + 4);
4573 /* Unpack the WPA IE */
4574 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4575 pRsnIe, RSNIeLen, &dot11WPAIE);
4576 /* Copy out the encryption and authentication types */
4577 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4578 dot11WPAIE.unicast_cipher_count);
4579 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4580 dot11WPAIE.auth_suite_count);
4581 /* dot11WPAIE.auth_suite_count */
4582 /* Just translate the FIRST one */
4583 *pAuthType =
4584 hdd_translate_wpa_to_csr_auth_type(
4585 dot11WPAIE.auth_suites[0]);
4586 /* dot11WPAIE.unicast_cipher_count */
4587 *pEncryptType =
4588 hdd_translate_wpa_to_csr_encryption_type(
4589 dot11WPAIE.unicast_ciphers[0]);
4590 /* dot11WPAIE.unicast_cipher_count */
4591 *mcEncryptType =
4592 hdd_translate_wpa_to_csr_encryption_type(
4593 dot11WPAIE.multicast_cipher);
4594 } else {
4595 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4596 return -EINVAL;
4597 }
4598 return 0;
4599}
4600
4601/**
4602 * hdd_set_genie_to_csr() - set genie to csr
4603 * @pAdapter: pointer to adapter
4604 * @RSNAuthType: pointer to auth type
4605 *
4606 * Return: 0 on success, error number otherwise
4607 */
4608int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4609{
4610 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4611 uint32_t status = 0;
4612 eCsrEncryptionType RSNEncryptType;
4613 eCsrEncryptionType mcRSNEncryptType;
4614#ifdef WLAN_FEATURE_11W
4615 uint8_t RSNMfpRequired = 0;
4616 uint8_t RSNMfpCapable = 0;
4617#endif
4618 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4619 /* MAC address of assoc peer */
4620 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304621 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004622 pWextState->roamProfile.BSSIDs.bssid,
4623 sizeof(bssid));
4624 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4625 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4626 /* continue */
4627 } else {
4628 return 0;
4629 }
4630 /* The actual processing may eventually be more extensive than this. */
4631 /* Right now, just consume any PMKIDs that are sent in by the app. */
4632 status = hdd_process_genie(pAdapter, bssid,
4633 &RSNEncryptType,
4634 &mcRSNEncryptType, RSNAuthType,
4635#ifdef WLAN_FEATURE_11W
4636 &RSNMfpRequired, &RSNMfpCapable,
4637#endif
4638 pWextState->WPARSNIE[1] + 2,
4639 pWextState->WPARSNIE);
4640 if (status == 0) {
4641 /*
4642 * Now copy over all the security attributes
4643 * you have parsed out.
4644 */
4645 pWextState->roamProfile.EncryptionType.numEntries = 1;
4646 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4647
4648 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4649 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4650 mcRSNEncryptType;
4651
Krunal Sonibe766b02016-03-10 13:00:44 -08004652 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004653 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4654 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4655 /*
4656 * For wpa none supplicant sends the WPA IE with unicast
4657 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4658 * multicast cipher as either AES/TKIP based on group
4659 * cipher configuration mentioned in the
4660 * wpa_supplicant.conf.
4661 */
4662
4663 /* Set the unicast cipher same as multicast cipher */
4664 pWextState->roamProfile.EncryptionType.encryptionType[0]
4665 = mcRSNEncryptType;
4666 }
4667#ifdef WLAN_FEATURE_11W
4668 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4669 RSNMfpRequired, RSNMfpCapable);
4670 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4671 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4672#endif
4673 hddLog(LOG1,
4674 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4675 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4676 }
4677 return 0;
4678}
4679
4680/**
4681 * hdd_set_csr_auth_type() - set csr auth type
4682 * @pAdapter: pointer to adapter
4683 * @RSNAuthType: auth type
4684 *
4685 * Return: 0 on success, error number otherwise
4686 */
4687int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4688{
4689 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4690 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4691 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004692
4693 pRoamProfile->AuthType.numEntries = 1;
4694 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4695 pHddStaCtx->conn_info.authType);
4696
4697 switch (pHddStaCtx->conn_info.authType) {
4698 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4699#ifdef FEATURE_WLAN_ESE
4700 case eCSR_AUTH_TYPE_CCKM_WPA:
4701 case eCSR_AUTH_TYPE_CCKM_RSN:
4702#endif
4703 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4704
4705 pRoamProfile->AuthType.authType[0] =
4706 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4707 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4708
4709#ifdef FEATURE_WLAN_ESE
4710 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4711 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4712 == IW_AUTH_KEY_MGMT_802_1X)) {
4713 hddLog(LOG1,
4714 FL("set authType to CCKM WPA. AKM also 802.1X."));
4715 pRoamProfile->AuthType.authType[0] =
4716 eCSR_AUTH_TYPE_CCKM_WPA;
4717 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4718 hddLog(LOG1,
4719 FL("Last chance to set authType to CCKM WPA."));
4720 pRoamProfile->AuthType.authType[0] =
4721 eCSR_AUTH_TYPE_CCKM_WPA;
4722 } else
4723#endif
4724 if ((pWextState->
4725 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4726 == IW_AUTH_KEY_MGMT_802_1X) {
4727 pRoamProfile->AuthType.authType[0] =
4728 eCSR_AUTH_TYPE_WPA;
4729 } else
4730 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4731 == IW_AUTH_KEY_MGMT_PSK) {
4732 pRoamProfile->AuthType.authType[0] =
4733 eCSR_AUTH_TYPE_WPA_PSK;
4734 } else {
4735 pRoamProfile->AuthType.authType[0] =
4736 eCSR_AUTH_TYPE_WPA_NONE;
4737 }
4738 }
4739 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4740#ifdef FEATURE_WLAN_ESE
4741 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4742 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4743 == IW_AUTH_KEY_MGMT_802_1X)) {
4744 hddLog(LOG1,
4745 FL("set authType to CCKM RSN. AKM also 802.1X."));
4746 pRoamProfile->AuthType.authType[0] =
4747 eCSR_AUTH_TYPE_CCKM_RSN;
4748 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4749 hddLog(LOG1,
4750 FL("Last chance to set authType to CCKM RSN."));
4751 pRoamProfile->AuthType.authType[0] =
4752 eCSR_AUTH_TYPE_CCKM_RSN;
4753 } else
4754#endif
4755
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004756 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4757 ((pWextState->
4758 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4759 == IW_AUTH_KEY_MGMT_802_1X)) {
4760 pRoamProfile->AuthType.authType[0] =
4761 eCSR_AUTH_TYPE_FT_RSN;
4762 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4763 &&
4764 ((pWextState->
4765 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4766 == IW_AUTH_KEY_MGMT_PSK)) {
4767 pRoamProfile->AuthType.authType[0] =
4768 eCSR_AUTH_TYPE_FT_RSN_PSK;
4769 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004770
4771#ifdef WLAN_FEATURE_11W
4772 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4773 pRoamProfile->AuthType.authType[0] =
4774 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4775 } else if (RSNAuthType ==
4776 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4777 pRoamProfile->AuthType.authType[0] =
4778 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4779 } else
4780#endif
4781
4782 if ((pWextState->
4783 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4784 == IW_AUTH_KEY_MGMT_802_1X) {
4785 pRoamProfile->AuthType.authType[0] =
4786 eCSR_AUTH_TYPE_RSN;
4787 } else
4788 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4789 == IW_AUTH_KEY_MGMT_PSK) {
4790 pRoamProfile->AuthType.authType[0] =
4791 eCSR_AUTH_TYPE_RSN_PSK;
4792 } else {
4793 pRoamProfile->AuthType.authType[0] =
4794 eCSR_AUTH_TYPE_UNKNOWN;
4795 }
4796 }
4797 break;
4798
4799 case eCSR_AUTH_TYPE_SHARED_KEY:
4800
4801 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4802 break;
4803 default:
4804
4805#ifdef FEATURE_WLAN_ESE
4806 hddLog(LOG1, FL("In default, unknown auth type."));
4807#endif /* FEATURE_WLAN_ESE */
4808 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4809 break;
4810 }
4811
4812 hddLog(LOG1, FL("Set roam Authtype to %d"),
4813 pWextState->roamProfile.AuthType.authType[0]);
4814
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004815 return 0;
4816}
4817
4818/**
4819 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4820 * to the CSR roam profile.
4821 *
4822 * @dev: Pointer to the net device.
4823 * @info: Pointer to the iw_request_info.
4824 * @wrqu: Pointer to the iwreq_data.
4825 * @extra: Pointer to the data.
4826 *
4827 * Return: 0 for success, error number on failure
4828 */
4829static int __iw_set_essid(struct net_device *dev,
4830 struct iw_request_info *info,
4831 union iwreq_data *wrqu, char *extra)
4832{
4833 unsigned long rc;
4834 uint32_t status = 0;
4835 hdd_wext_state_t *pWextState;
4836 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4837 hdd_context_t *hdd_ctx;
4838 uint32_t roamId;
4839 tCsrRoamProfile *pRoamProfile;
4840 eMib_dot11DesiredBssType connectedBssType;
4841 eCsrAuthType RSNAuthType;
4842 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4843 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4844 int ret;
4845
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004846 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004847
4848 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4849 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304850 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851 return ret;
4852
Krunal Sonibe766b02016-03-10 13:00:44 -08004853 if (pAdapter->device_mode != QDF_STA_MODE &&
4854 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004855 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4856 hdd_device_mode_to_string(pAdapter->device_mode),
4857 pAdapter->device_mode);
4858 return -EINVAL;
4859 }
4860
4861 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4862
4863 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4864 hddLog(LOG2, FL("Counter measure is in progress"));
4865 return -EBUSY;
4866 }
4867 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4868 return -EINVAL;
4869
4870 pRoamProfile = &pWextState->roamProfile;
4871 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4872 (eMib_dot11DesiredBssType_independent ==
4873 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304874 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004875
4876 /* Need to issue a disconnect to CSR. */
4877 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304878 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004879 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4880
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304881 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004882 rc = wait_for_completion_timeout(&pAdapter->
4883 disconnect_comp_var,
4884 msecs_to_jiffies
4885 (WLAN_WAIT_TIME_DISCONNECT));
4886 if (!rc)
4887 hddLog(LOGE, FL("Disconnect event timed out"));
4888 }
4889 }
4890
4891 /*
4892 * when cfg80211 defined, wpa_supplicant wext driver uses
4893 * zero-length, null-string ssid for force disconnection.
4894 * after disconnection (if previously connected) and cleaning ssid,
4895 * driver MUST return success.
4896 */
4897 if (0 == wrqu->essid.length)
4898 return 0;
4899
4900 status = hdd_wmm_get_uapsd_mask(pAdapter,
4901 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304902 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004903 pWextState->roamProfile.uapsd_mask = 0;
4904
4905 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4906
4907 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4908 wrqu->essid.length;
4909
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304910 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004911 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304912 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004913 ssId), extra, wrqu->essid.length);
4914 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4915 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4916
4917 /* set gen ie */
4918 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4919
4920 /* set auth */
4921 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4922 }
4923#ifdef FEATURE_WLAN_WAPI
4924 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4925 if (pAdapter->wapi_info.nWapiMode) {
4926 switch (pAdapter->wapi_info.wapiAuthMode) {
4927 case WAPI_AUTH_MODE_PSK:
4928 {
4929 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4930 pAdapter->wapi_info.wapiAuthMode);
4931 pRoamProfile->AuthType.numEntries = 1;
4932 pRoamProfile->AuthType.authType[0] =
4933 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4934 break;
4935 }
4936 case WAPI_AUTH_MODE_CERT:
4937 {
4938 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4939 pAdapter->wapi_info.wapiAuthMode);
4940 pRoamProfile->AuthType.numEntries = 1;
4941 pRoamProfile->AuthType.authType[0] =
4942 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4943 break;
4944 }
4945 } /* End of switch */
4946 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4947 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4948 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4949 pRoamProfile->EncryptionType.numEntries = 1;
4950 pRoamProfile->EncryptionType.encryptionType[0] =
4951 eCSR_ENCRYPT_TYPE_WPI;
4952 pRoamProfile->mcEncryptionType.numEntries = 1;
4953 pRoamProfile->mcEncryptionType.encryptionType[0] =
4954 eCSR_ENCRYPT_TYPE_WPI;
4955 }
4956 }
4957#endif /* FEATURE_WLAN_WAPI */
4958 /* if previous genIE is not NULL, update AssocIE */
4959 if (0 != pWextState->genIE.length) {
4960 memset(&pWextState->assocAddIE, 0,
4961 sizeof(pWextState->assocAddIE));
4962 memcpy(pWextState->assocAddIE.addIEdata,
4963 pWextState->genIE.addIEdata, pWextState->genIE.length);
4964 pWextState->assocAddIE.length = pWextState->genIE.length;
4965 pWextState->roamProfile.pAddIEAssoc =
4966 pWextState->assocAddIE.addIEdata;
4967 pWextState->roamProfile.nAddIEAssocLength =
4968 pWextState->assocAddIE.length;
4969
4970 /* clear previous genIE after use it */
4971 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4972 }
4973
4974 /*
4975 * Assumes it is not WPS Association by default, except when
4976 * pAddIEAssoc has WPS IE.
4977 */
4978 pWextState->roamProfile.bWPSAssociation = false;
4979
4980 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4981 pWextState->roamProfile.
4982 nAddIEAssocLength))
4983 pWextState->roamProfile.bWPSAssociation = true;
4984
4985 /* Disable auto BMPS entry by PMC until DHCP is done */
4986 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4987 true);
4988
4989 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4990
4991 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4992 hdd_select_cbmode(pAdapter,
4993 (WLAN_HDD_GET_CTX(pAdapter))->config->
4994 AdHocChannel5G);
4995 }
Agrawal Ashish6b015762016-05-05 11:22:18 +05304996 /*
4997 * Change conn_state to connecting before sme_roam_connect(),
4998 * because sme_roam_connect() has a direct path to call
4999 * hdd_sme_roam_callback(), which will change the conn_state
5000 * If direct path, conn_state will be accordingly changed to
5001 * NotConnected or Associated by either
5002 * hdd_association_completion_handler() or hdd_dis_connect_handler()
5003 * in sme_RoamCallback()if sme_RomConnect is to be queued,
5004 * Connecting state will remain until it is completed.
5005 *
5006 * If connection state is not changed,
5007 * connection state will remain in eConnectionState_NotConnected state.
5008 * In hdd_association_completion_handler, "hddDisconInProgress" is
5009 * set to true if conn state is eConnectionState_NotConnected.
5010 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
5011 * informed of connect result indication which is an issue.
5012 */
5013 if (QDF_STA_MODE == pAdapter->device_mode ||
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305014 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)
Agrawal Ashish6b015762016-05-05 11:22:18 +05305015 hdd_conn_set_connection_state(pAdapter,
5016 eConnectionState_Connecting);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305017
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005018 status = sme_roam_connect(hHal, pAdapter->sessionId,
5019 &(pWextState->roamProfile), &roamId);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305020 if ((QDF_STATUS_SUCCESS != status) &&
5021 (QDF_STA_MODE == pAdapter->device_mode ||
5022 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
5023 hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
5024 pAdapter->sessionId, status);
5025 /* change back to NotAssociated */
5026 hdd_conn_set_connection_state(pAdapter,
5027 eConnectionState_NotConnected);
5028 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005029 pRoamProfile->ChannelInfo.ChannelList = NULL;
5030 pRoamProfile->ChannelInfo.numOfChannels = 0;
5031
5032 EXIT();
5033 return status;
5034}
5035
5036/**
5037 * iw_set_essid() - set essid handler function
5038 * @dev: Pointer to the net device.
5039 * @info: Pointer to the iw_request_info.
5040 * @wrqu: Pointer to the iwreq_data.
5041 * @extra: Pointer to the data.
5042 *
5043 * Return: 0 for success, error number on failure
5044 */
5045int iw_set_essid(struct net_device *dev,
5046 struct iw_request_info *info,
5047 union iwreq_data *wrqu, char *extra)
5048{
5049 int ret;
5050
5051 cds_ssr_protect(__func__);
5052 ret = __iw_set_essid(dev, info, wrqu, extra);
5053 cds_ssr_unprotect(__func__);
5054
5055 return ret;
5056}
5057
5058/**
5059 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
5060 * @dev: pointer to the net device
5061 * @info: pointer to the iw request info
5062 * @dwrq: pointer to iw_point
5063 * @extra: pointer to the data
5064 *
5065 * Return: 0 on success, error number otherwise
5066 */
5067static int __iw_get_essid(struct net_device *dev,
5068 struct iw_request_info *info,
5069 struct iw_point *dwrq, char *extra)
5070{
5071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5072 hdd_context_t *hdd_ctx;
5073 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5074 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5075 int ret;
5076
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005077 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005078
5079 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5080 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305081 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005082 return ret;
5083
5084 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5085 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5086 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5087 || pHddStaCtx->conn_info.connState ==
5088 eConnectionState_IbssDisconnected)
5089 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5090 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5091 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5092 dwrq->length);
5093 dwrq->flags = 1;
5094 } else {
5095 memset(extra, 0, dwrq->length);
5096 dwrq->length = 0;
5097 dwrq->flags = 0;
5098 }
5099 EXIT();
5100 return 0;
5101}
5102
5103/**
5104 * iw_get_essid() - get essid handler function
5105 * @dev: Pointer to the net device.
5106 * @info: Pointer to the iw_request_info.
5107 * @wrqu: Pointer to the iwreq_data.
5108 * @extra: Pointer to the data.
5109 *
5110 * Return: 0 for success, error number on failure
5111 */
5112int iw_get_essid(struct net_device *dev,
5113 struct iw_request_info *info,
5114 struct iw_point *wrqu, char *extra)
5115{
5116 int ret;
5117
5118 cds_ssr_protect(__func__);
5119 ret = __iw_get_essid(dev, info, wrqu, extra);
5120 cds_ssr_unprotect(__func__);
5121
5122 return ret;
5123}
5124
5125/**
5126 * __iw_set_auth() -
5127 * This function sets the auth type received from the wpa_supplicant
5128 * @dev: pointer to the net device
5129 * @info: pointer to the iw request info
5130 * @wrqu: pointer to iwreq_data
5131 * @extra: pointer to the data
5132 *
5133 * Return: 0 on success, error number otherwise
5134 */
5135static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5136 union iwreq_data *wrqu, char *extra)
5137{
5138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5139 hdd_context_t *hdd_ctx;
5140 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5141 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5142 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5143 eCsrEncryptionType mcEncryptionType;
5144 eCsrEncryptionType ucEncryptionType;
5145 int ret;
5146
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005147 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005148
5149 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5150 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305151 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005152 return ret;
5153
5154 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5155 case IW_AUTH_WPA_VERSION:
5156 pWextState->wpaVersion = wrqu->param.value;
5157 break;
5158
5159 case IW_AUTH_CIPHER_PAIRWISE:
5160 {
5161 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5162 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5163 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5164 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5165 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5166 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5167 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5168 if ((IW_AUTH_KEY_MGMT_802_1X
5169 ==
5170 (pWextState->
5171 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5172 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5173 pHddStaCtx->conn_info.authType))
5174 /*Dynamic WEP key */
5175 ucEncryptionType =
5176 eCSR_ENCRYPT_TYPE_WEP40;
5177 else
5178 /*Static WEP key */
5179 ucEncryptionType =
5180 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5181 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5182 if ((IW_AUTH_KEY_MGMT_802_1X
5183 ==
5184 (pWextState->
5185 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5186 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5187 pHddStaCtx->conn_info.authType))
5188 /*Dynamic WEP key */
5189 ucEncryptionType =
5190 eCSR_ENCRYPT_TYPE_WEP104;
5191 else
5192 /*Static WEP key */
5193 ucEncryptionType =
5194 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5195 } else {
5196 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5197 wrqu->param.value);
5198 return -EINVAL;
5199 }
5200
5201 pRoamProfile->EncryptionType.numEntries = 1;
5202 pRoamProfile->EncryptionType.encryptionType[0] =
5203 ucEncryptionType;
5204 }
5205 break;
5206 case IW_AUTH_CIPHER_GROUP:
5207 {
5208 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5209 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5210 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5211 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5212 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5213 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5214 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5215 if ((IW_AUTH_KEY_MGMT_802_1X
5216 ==
5217 (pWextState->
5218 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5219 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5220 pHddStaCtx->conn_info.authType))
5221 mcEncryptionType =
5222 eCSR_ENCRYPT_TYPE_WEP40;
5223 else
5224 mcEncryptionType =
5225 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5226 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5227 /* Dynamic WEP keys won't work with shared keys */
5228 if ((IW_AUTH_KEY_MGMT_802_1X
5229 ==
5230 (pWextState->
5231 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5232 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5233 pHddStaCtx->conn_info.authType)) {
5234 mcEncryptionType =
5235 eCSR_ENCRYPT_TYPE_WEP104;
5236 } else {
5237 mcEncryptionType =
5238 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5239 }
5240 } else {
5241 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5242 wrqu->param.value);
5243 return -EINVAL;
5244 }
5245
5246 pRoamProfile->mcEncryptionType.numEntries = 1;
5247 pRoamProfile->mcEncryptionType.encryptionType[0] =
5248 mcEncryptionType;
5249 }
5250 break;
5251
5252 case IW_AUTH_80211_AUTH_ALG:
5253 {
5254 /* Save the auth algo here and set auth type to SME Roam profile
5255 in the iw_set_ap_address */
5256 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5257 pHddStaCtx->conn_info.authType =
5258 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5259
5260 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5261 pHddStaCtx->conn_info.authType =
5262 eCSR_AUTH_TYPE_SHARED_KEY;
5263
5264 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5265 /*Not supported */
5266 pHddStaCtx->conn_info.authType =
5267 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5268 pWextState->roamProfile.AuthType.authType[0] =
5269 pHddStaCtx->conn_info.authType;
5270 }
5271 break;
5272
5273 case IW_AUTH_KEY_MGMT:
5274 {
5275#ifdef FEATURE_WLAN_ESE
5276#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5277 /*Check for CCKM AKM type */
5278 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5279 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5280 /* Set the CCKM bit in authKeyMgmt */
5281 /*
5282 * Right now, this breaks all ref to authKeyMgmt because
5283 * our code doesn't realize it is a "bitfield"
5284 */
5285 pWextState->authKeyMgmt |=
5286 IW_AUTH_KEY_MGMT_CCKM;
5287 /* Set the key management to 802.1X */
5288 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5289 pWextState->isESEConnection = true;
5290 /*
5291 * This is test code. I need to actually KNOW whether
5292 * this is an RSN Assoc or WPA.
5293 */
5294 pWextState->collectedAuthType =
5295 eCSR_AUTH_TYPE_CCKM_RSN;
5296 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5297 /* Save the key management */
5298 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5299 pWextState->collectedAuthType =
5300 eCSR_AUTH_TYPE_RSN;
5301 } else
5302 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5303 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5304 /* Save the key management anyway */
5305 pWextState->authKeyMgmt = wrqu->param.value;
5306 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5307 /* Save the key management */
5308 pWextState->authKeyMgmt |=
5309 IW_AUTH_KEY_MGMT_802_1X;
5310 pWextState->collectedAuthType =
5311 eCSR_AUTH_TYPE_RSN;
5312 }
5313#else
5314 /* Save the key management */
5315 pWextState->authKeyMgmt = wrqu->param.value;
5316#endif /* FEATURE_WLAN_ESE */
5317 }
5318 break;
5319
5320 case IW_AUTH_TKIP_COUNTERMEASURES:
5321 {
5322 if (wrqu->param.value) {
5323 hddLog(LOG2,
5324 "Counter Measure started %d",
5325 wrqu->param.value);
5326 pWextState->mTKIPCounterMeasures =
5327 TKIP_COUNTER_MEASURE_STARTED;
5328 } else {
5329 hddLog(LOG2,
5330 "Counter Measure stopped=%d",
5331 wrqu->param.value);
5332 pWextState->mTKIPCounterMeasures =
5333 TKIP_COUNTER_MEASURE_STOPED;
5334 }
5335 }
5336 break;
5337 case IW_AUTH_DROP_UNENCRYPTED:
5338 case IW_AUTH_WPA_ENABLED:
5339 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5340 case IW_AUTH_ROAMING_CONTROL:
5341 case IW_AUTH_PRIVACY_INVOKED:
5342
5343 default:
5344
5345 hddLog(LOGW, FL("called with unsupported auth type %d"),
5346 wrqu->param.flags & IW_AUTH_INDEX);
5347 break;
5348 }
5349
5350 EXIT();
5351 return 0;
5352}
5353
5354/**
5355 * iw_set_auth() - set auth callback function
5356 * @dev: Pointer to the net device.
5357 * @info: Pointer to the iw_request_info.
5358 * @wrqu: Pointer to the iwreq_data.
5359 * @extra: Pointer to the data.
5360 *
5361 * Return: 0 for success, error number on failure.
5362 */
5363int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5364 union iwreq_data *wrqu, char *extra)
5365{
5366 int ret;
5367
5368 cds_ssr_protect(__func__);
5369 ret = __iw_set_auth(dev, info, wrqu, extra);
5370 cds_ssr_unprotect(__func__);
5371
5372 return ret;
5373}
5374
5375/**
5376 * __iw_get_auth() -
5377 * This function returns the auth type to the wpa_supplicant
5378 * @dev: pointer to the net device
5379 * @info: pointer to the iw request info
5380 * @wrqu: pointer to iwreq_data
5381 * @extra: pointer to the data
5382 *
5383 * Return: 0 on success, error number otherwise
5384 */
5385static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5386 union iwreq_data *wrqu, char *extra)
5387{
5388 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5389 hdd_context_t *hdd_ctx;
5390 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5391 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5392 int ret;
5393
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005394 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005395
5396 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5397 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305398 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005399 return ret;
5400
5401 switch (pRoamProfile->negotiatedAuthType) {
5402 case eCSR_AUTH_TYPE_WPA_NONE:
5403 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5404 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5405 break;
5406 case eCSR_AUTH_TYPE_WPA:
5407 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5408 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5409 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005410
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005411 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005412 case eCSR_AUTH_TYPE_RSN:
5413 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5414 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5415 break;
5416 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5417 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5418 break;
5419 case eCSR_AUTH_TYPE_SHARED_KEY:
5420 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5421 break;
5422 case eCSR_AUTH_TYPE_UNKNOWN:
5423 hddLog(LOG1, FL("called with unknown auth type"));
5424 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5425 break;
5426 case eCSR_AUTH_TYPE_AUTOSWITCH:
5427 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5428 break;
5429 case eCSR_AUTH_TYPE_WPA_PSK:
5430 hddLog(LOG1, FL("called with WPA PSK auth type"));
5431 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5432 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005433
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005434 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005435 case eCSR_AUTH_TYPE_RSN_PSK:
5436#ifdef WLAN_FEATURE_11W
5437 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5438 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5439#endif
5440 hddLog(LOG1, FL("called with RSN PSK auth type"));
5441 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5442 return -EIO;
5443 default:
5444 hddLog(LOGE, FL("called with unknown auth type"));
5445 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5446 return -EIO;
5447 }
5448 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5449 switch (pRoamProfile->negotiatedUCEncryptionType) {
5450 case eCSR_ENCRYPT_TYPE_NONE:
5451 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5452 break;
5453 case eCSR_ENCRYPT_TYPE_WEP40:
5454 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5455 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5456 break;
5457 case eCSR_ENCRYPT_TYPE_TKIP:
5458 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5459 break;
5460 case eCSR_ENCRYPT_TYPE_WEP104:
5461 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5462 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5463 break;
5464 case eCSR_ENCRYPT_TYPE_AES:
5465 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5466 break;
5467 default:
5468 hddLog(LOG1, FL("called with unknown auth type %d"),
5469 pRoamProfile->negotiatedUCEncryptionType);
5470 return -EIO;
5471 }
5472 }
5473
5474 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5475 switch (pRoamProfile->negotiatedMCEncryptionType) {
5476 case eCSR_ENCRYPT_TYPE_NONE:
5477 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5478 break;
5479 case eCSR_ENCRYPT_TYPE_WEP40:
5480 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5481 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5482 break;
5483 case eCSR_ENCRYPT_TYPE_TKIP:
5484 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5485 break;
5486 case eCSR_ENCRYPT_TYPE_WEP104:
5487 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5488 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5489 break;
5490 case eCSR_ENCRYPT_TYPE_AES:
5491 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5492 break;
5493 default:
5494 hddLog(LOG1, FL("called with unknown auth type %d"),
5495 pRoamProfile->negotiatedMCEncryptionType);
5496 return -EIO;
5497 }
5498 }
5499
5500 hddLog(LOG1, FL("called with auth type %d"),
5501 pRoamProfile->AuthType.authType[0]);
5502 EXIT();
5503 return 0;
5504}
5505
5506/**
5507 * iw_get_auth() - get auth callback function
5508 * @dev: Pointer to the net device.
5509 * @info: Pointer to the iw_request_info.
5510 * @wrqu: Pointer to the iwreq_data.
5511 * @extra: Pointer to the data.
5512 *
5513 * Return: 0 for success, error number on failure.
5514 */
5515int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5516 union iwreq_data *wrqu, char *extra)
5517{
5518 int ret;
5519
5520 cds_ssr_protect(__func__);
5521 ret = __iw_get_auth(dev, info, wrqu, extra);
5522 cds_ssr_unprotect(__func__);
5523
5524 return ret;
5525}
5526
5527/**
5528 * __iw_set_ap_address() - set ap address
5529 * @dev: pointer to the net device
5530 * @info: pointer to the iw request info
5531 * @wrqu: pointer to iwreq_data
5532 * @extra: pointer to the data
5533 *
5534 * This function updates the HDD global station context connection info
5535 * BSSID with the MAC address received from the wpa_supplicant.
5536 *
5537 * Return: 0 on success, error number otherwise
5538 */
5539static int __iw_set_ap_address(struct net_device *dev,
5540 struct iw_request_info *info,
5541 union iwreq_data *wrqu, char *extra)
5542{
5543
5544 hdd_adapter_t *adapter;
5545 hdd_context_t *hdd_ctx;
5546 hdd_station_ctx_t *pHddStaCtx =
5547 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5548 uint8_t *pMacAddress = NULL;
5549 int ret;
5550
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005551 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005552
5553 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5554
5555 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5556 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305557 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005558 return ret;
5559
5560 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5561 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305562 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305563 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005564 EXIT();
5565
5566 return 0;
5567}
5568
5569/**
5570 * iw_set_ap_address() - set ap addresses callback function
5571 * @dev: Pointer to the net device.
5572 * @info: Pointer to the iw_request_info.
5573 * @wrqu: Pointer to the iwreq_data.
5574 * @extra: Pointer to the data.
5575 *
5576 * Return: 0 for success, error number on failure.
5577 */
5578int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5579 union iwreq_data *wrqu, char *extra)
5580{
5581 int ret;
5582
5583 cds_ssr_protect(__func__);
5584 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5585 cds_ssr_unprotect(__func__);
5586
5587 return ret;
5588}
5589
5590/**
5591 * __iw_get_ap_address() - get ap address
5592 * @dev: pointer to the net device
5593 * @info: pointer to the iw request info
5594 * @wrqu: pointer to iwreq_data
5595 * @extra: pointer to the data
5596 *
5597 * This function returns currently associated BSSID.
5598 *
5599 * Return: 0 on success, error number otherwise
5600 */
5601static int __iw_get_ap_address(struct net_device *dev,
5602 struct iw_request_info *info,
5603 union iwreq_data *wrqu, char *extra)
5604{
5605 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5606 hdd_context_t *hdd_ctx;
5607 hdd_station_ctx_t *pHddStaCtx =
5608 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5609 int ret;
5610
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005611 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005612
5613 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5614 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305615 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005616 return ret;
5617
5618 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5619 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305620 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005621 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305622 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005623 } else {
5624 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5625 }
5626 EXIT();
5627 return 0;
5628}
5629
5630/**
5631 * iw_get_ap_address() - get ap addresses callback function
5632 * @dev: Pointer to the net device.
5633 * @info: Pointer to the iw_request_info.
5634 * @wrqu: Pointer to the iwreq_data.
5635 * @extra: Pointer to the data.
5636 *
5637 * Return: 0 for success, error number on failure.
5638 */
5639int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5640 union iwreq_data *wrqu, char *extra)
5641{
5642 int ret;
5643
5644 cds_ssr_protect(__func__);
5645 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5646 cds_ssr_unprotect(__func__);
5647
5648 return ret;
5649}