blob: ea597dbe04bdcbfe3ef75a0baac9f86dd236bfc6 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
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"
39#include <linux/ieee80211.h>
40#include <linux/wireless.h>
41#include <linux/etherdevice.h>
42#include <net/cfg80211.h>
43#include "wlan_hdd_cfg80211.h"
44#include "csr_inside_api.h"
45#include "wlan_hdd_p2p.h"
46#ifdef FEATURE_WLAN_TDLS
47#include "wlan_hdd_tdls.h"
48#endif
49#include "sme_api.h"
50#include "wlan_hdd_hostapd.h"
51#include <wlan_hdd_ipa.h>
52#include <cds_sched.h>
53#include "cds_concurrency.h"
54#include "sme_power_save_api.h"
55#include "ol_txrx_ctrl_api.h"
56#include "ol_txrx_types.h"
57
58/* These are needed to recognize WPA and RSN suite types */
59#define HDD_WPA_OUI_SIZE 4
60#define HDD_RSN_OUI_SIZE 4
61uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
62uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
63uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
64uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
65uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
66uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
67
68#ifdef FEATURE_WLAN_ESE
69/* CCKM */
70uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
71/* CCKM */
72uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
73#endif /* FEATURE_WLAN_ESE */
74
75/* group cipher */
76uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
77
78/* WEP-40 or RSN */
79uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
80
81/* TKIP or RSN-PSK */
82uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
83
84/* Reserved */
85uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
86
87/* AES-CCMP */
88uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
89
90/* WEP-104 */
91uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
92
93#ifdef WLAN_FEATURE_11W
94/* RSN-PSK-SHA256 */
95uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
96
97/* RSN-8021X-SHA256 */
98uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
99#endif
100
101#if defined(WLAN_FEATURE_VOWIFI_11R)
102/* Offset where the EID-Len-IE, start. */
103#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
104#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
105#endif
106
107#define BEACON_FRAME_IES_OFFSET 12
108#define HDD_PEER_AUTHORIZE_WAIT 10
109
110/**
111 * hdd_conn_set_authenticated() - set authentication state
112 * @pAdapter: pointer to the adapter
113 * @authState: authentication state
114 *
115 * This function updates the global HDD station context
116 * authentication state.
117 *
118 * Return: none
119 */
120static void
121hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
122{
123 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
124 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
125
126 /* save the new connection state */
127 hddLog(LOG1,
128 FL("Authenticated state Changed from oldState:%d to State:%d"),
129 pHddStaCtx->conn_info.uIsAuthenticated, authState);
130 pHddStaCtx->conn_info.uIsAuthenticated = authState;
131
132 /* Check is pending ROC request or not when auth state changed */
133 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
134}
135
136/**
137 * hdd_conn_set_connection_state() - set connection state
138 * @pAdapter: pointer to the adapter
139 * @connState: connection state
140 *
141 * This function updates the global HDD station context connection state.
142 *
143 * Return: none
144 */
145void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
146 eConnectionState connState)
147{
148 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
149 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
150
151 /* save the new connection state */
152 hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"),
153 pHddStaCtx->conn_info.connState, connState);
154 pHddStaCtx->conn_info.connState = connState;
155
156 /* Check is pending ROC request or not when connection state changed */
157 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
158}
159
160/**
161 * hdd_conn_get_connection_state() - get connection state
162 * @pAdapter: pointer to the adapter
163 * @pConnState: pointer to connection state
164 *
165 * This function updates the global HDD station context connection state.
166 *
167 * Return: true if (Infra Associated or IBSS Connected)
168 * and sets output parameter pConnState;
169 * false otherwise
170 */
171static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
172 eConnectionState *pConnState)
173{
174 bool fConnected = false;
175 eConnectionState connState;
176
177 /* get the connection state. */
178 connState = pHddStaCtx->conn_info.connState;
179
180 if (eConnectionState_Associated == connState ||
181 eConnectionState_IbssConnected == connState ||
182 eConnectionState_IbssDisconnected == connState) {
183 fConnected = true;
184 }
185
186 if (pConnState)
187 *pConnState = connState;
188
189 return fConnected;
190}
191
192/**
193 * hdd_is_connecting() - Function to check connection progress
194 * @hdd_sta_ctx: pointer to global HDD Station context
195 *
196 * Return: true if connecting, false otherwise
197 */
198bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
199{
200 return hdd_sta_ctx->conn_info.connState ==
201 eConnectionState_Connecting;
202}
203
204/**
205 * hdd_conn_is_connected() - Function to check connection status
206 * @pHddStaCtx: pointer to global HDD Station context
207 *
208 * Return: false if any errors encountered, true otherwise
209 */
210bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
211{
212 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
213}
214
215/**
216 * hdd_conn_get_connected_band() - get current connection radio band
217 * @pHddStaCtx: pointer to global HDD Station context
218 *
219 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
220 * eCSR_BAND_ALL if not connected
221 */
222eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
223{
224 uint8_t staChannel = 0;
225
226 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
227 staChannel = pHddStaCtx->conn_info.operationChannel;
228
229 if (staChannel > 0 && staChannel < 14)
230 return eCSR_BAND_24;
231 else if (staChannel >= 36 && staChannel <= 184)
232 return eCSR_BAND_5G;
233 else /* If station is not connected return as eCSR_BAND_ALL */
234 return eCSR_BAND_ALL;
235}
236
237/**
238 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
239 * @pHddStaCtx: pointer to global HDD Station context
240 * @pConnectedCipherAlgo: pointer to connected cipher algo
241 *
242 * Return: false if any errors encountered, true otherwise
243 */
244static inline bool
245hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
246 eCsrEncryptionType *pConnectedCipherAlgo)
247{
248 bool fConnected = false;
249
250 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
251
252 if (pConnectedCipherAlgo)
253 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
254
255 return fConnected;
256}
257
258/**
259 * hdd_conn_get_connected_bss_type() - get current bss type
260 * @pHddStaCtx: pointer to global HDD Station context
261 * @pConnectedBssType: pointer to connected bss type
262 *
263 * Return: false if any errors encountered, true otherwise
264 */
265inline bool
266hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
267 eMib_dot11DesiredBssType *pConnectedBssType)
268{
269 bool fConnected = false;
270
271 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
272
273 if (pConnectedBssType) {
274 *pConnectedBssType =
275 pHddStaCtx->conn_info.connDot11DesiredBssType;
276 }
277
278 return fConnected;
279}
280
281/**
282 * hdd_conn_save_connected_bss_type() - set connected bss type
283 * @pHddStaCtx: pointer to global HDD Station context
284 * @csr_roamBssType: bss type
285 *
286 * Return: none
287 */
288static inline void
289hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
290 eCsrRoamBssType csr_roamBssType)
291{
292 switch (csr_roamBssType) {
293 case eCSR_BSS_TYPE_INFRASTRUCTURE:
294 pHddStaCtx->conn_info.connDot11DesiredBssType =
295 eMib_dot11DesiredBssType_infrastructure;
296 break;
297
298 case eCSR_BSS_TYPE_IBSS:
299 case eCSR_BSS_TYPE_START_IBSS:
300 pHddStaCtx->conn_info.connDot11DesiredBssType =
301 eMib_dot11DesiredBssType_independent;
302 break;
303
304 /** We will never set the BssType to 'any' when attempting a connection
305 so CSR should never send this back to us.*/
306 case eCSR_BSS_TYPE_ANY:
307 default:
308 CDF_ASSERT(0);
309 break;
310 }
311}
312
313/**
314 * hdd_conn_save_connect_info() - save current connection information
315 * @pAdapter: pointer to adapter
316 * @pRoamInfo: pointer to roam info
317 * @eBssType: bss type
318 *
319 * Return: none
320 */
321static void
322hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
323 eCsrRoamBssType eBssType)
324{
325 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
326 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
327
328 CDF_ASSERT(pRoamInfo);
329
330 if (pRoamInfo) {
331 /* Save the BSSID for the connection */
332 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
333 CDF_ASSERT(pRoamInfo->pBssDesc);
334 cdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
335 &pRoamInfo->bssid);
336
337 /*
338 * Save the Station ID for this station from
339 * the 'Roam Info'. For IBSS mode, staId is
340 * assigned in NEW_PEER_IND. For reassoc,
341 * the staID doesn't change and it may be invalid
342 * in this structure so no change here.
343 */
344 if (!pRoamInfo->fReassocReq) {
345 pHddStaCtx->conn_info.staId[0] =
346 pRoamInfo->staId;
347 }
348 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
349 cdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
350 &pRoamInfo->bssid);
351 } else {
352 /*
353 * can't happen. We need a valid IBSS or Infra setting
354 * in the BSSDescription or we can't function.
355 */
356 CDF_ASSERT(0);
357 }
358
359 /* notify WMM */
360 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
361
362 if (!pRoamInfo->u.pConnectedProfile) {
363 CDF_ASSERT(pRoamInfo->u.pConnectedProfile);
364 } else {
365 /* Get Multicast Encryption Type */
366 encryptType =
367 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
368 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
369 /* Get Unicast Encryption Type */
370 encryptType =
371 pRoamInfo->u.pConnectedProfile->EncryptionType;
372 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
373
374 pHddStaCtx->conn_info.authType =
375 pRoamInfo->u.pConnectedProfile->AuthType;
376
377 pHddStaCtx->conn_info.operationChannel =
378 pRoamInfo->u.pConnectedProfile->operationChannel;
379
380 /* Save the ssid for the connection */
381 cdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
382 &pRoamInfo->u.pConnectedProfile->SSID,
383 sizeof(tSirMacSSid));
384
385 /* Save dot11mode in which STA associated to AP */
386 pHddStaCtx->conn_info.dot11Mode =
387 pRoamInfo->u.pConnectedProfile->dot11Mode;
388
389 pHddStaCtx->conn_info.proxyARPService =
390 pRoamInfo->u.pConnectedProfile->proxyARPService;
391 }
392 }
393 /* save the connected BssType */
394 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
395}
396
397#if defined(WLAN_FEATURE_VOWIFI_11R)
398/**
399 * hdd_send_ft_assoc_response() - send fast transition assoc response
400 * @dev: pointer to net device
401 * @pAdapter: pointer to adapter
402 * @pCsrRoamInfo: pointer to roam info
403 *
404 * Send the 11R key information to the supplicant. Only then can the supplicant
405 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
406 * for the same purpose.)
407 *
408 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
409 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
410 * This is the Assoc Response.
411 *
412 * Return: none
413 */
414static void
415hdd_send_ft_assoc_response(struct net_device *dev,
416 hdd_adapter_t *pAdapter,
417 tCsrRoamInfo *pCsrRoamInfo)
418{
419 union iwreq_data wrqu;
420 char *buff;
421 unsigned int len = 0;
422 u8 *pFTAssocRsp = NULL;
423
424 if (pCsrRoamInfo->nAssocRspLength == 0) {
425 hddLog(LOGE,
426 FL("pCsrRoamInfo->nAssocRspLength=%d"),
427 (int)pCsrRoamInfo->nAssocRspLength);
428 return;
429 }
430
431 pFTAssocRsp =
432 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
433 pCsrRoamInfo->nAssocReqLength);
434 if (pFTAssocRsp == NULL) {
435 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
436 return;
437 }
438 /* pFTAssocRsp needs to point to the IEs */
439 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
440 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
441 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
442
443 /* We need to send the IEs to the supplicant. */
444 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
445 if (buff == NULL) {
446 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
447 return;
448 }
449 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
450 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
451 wrqu.data.length = len;
452 memset(buff, 0, IW_GENERIC_IE_MAX);
453 memcpy(buff, pFTAssocRsp, len);
454 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
455
456 kfree(buff);
457}
458#endif /* WLAN_FEATURE_VOWIFI_11R */
459
460#ifdef WLAN_FEATURE_VOWIFI_11R
461/**
462 * hdd_send_ft_event() - send fast transition event
463 * @pAdapter: pointer to adapter
464 *
465 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
466 * FT events to the supplicant. At the reception of Auth2 we send the RIC
467 * followed by the auth response IEs to the supplicant.
468 * Once both are received in the supplicant, an FT event is generated
469 * to the supplicant.
470 *
471 * Return: none
472 */
473static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
474{
475 uint16_t auth_resp_len = 0;
476 uint32_t ric_ies_length = 0;
477 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
478
479#if defined(KERNEL_SUPPORT_11R_CFG80211)
480 struct cfg80211_ft_event_params ftEvent;
481 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
482 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
483 struct net_device *dev = pAdapter->dev;
484#else
485 char *buff;
486 union iwreq_data wrqu;
487 uint16_t str_len;
488#endif
489
490#if defined(KERNEL_SUPPORT_11R_CFG80211)
491 cdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
492 cdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
493
494 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
495 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
496 if (ric_ies_length == 0) {
497 hddLog(LOGW,
498 FL("RIC IEs is of length 0 not sending RIC Information for now"));
499 }
500
501 ftEvent.ric_ies = ricIe;
502 ftEvent.ric_ies_len = ric_ies_length;
503 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
504
505 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
506 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
507 &auth_resp_len);
508
509 if (auth_resp_len == 0) {
510 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
511 return;
512 }
513
514 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
515
516 ftEvent.target_ap = ftIe;
517
518 ftEvent.ies = (u8 *) (ftIe + CDF_MAC_ADDR_SIZE);
519 ftEvent.ies_len = auth_resp_len - CDF_MAC_ADDR_SIZE;
520
521 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
522 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
523 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
524 ftEvent.target_ap[0], ftEvent.target_ap[1],
525 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
526 ftEvent.target_ap[5]);
527
528 (void)cfg80211_ft_event(dev, &ftEvent);
529
530#else
531 /* We need to send the IEs to the supplicant */
532 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
533 if (buff == NULL) {
534 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
535 return;
536 }
537 cdf_mem_zero(buff, IW_CUSTOM_MAX);
538
539 /* Sme needs to send the RIC IEs first */
540 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
541 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
542 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
543 &ric_ies_length);
544 if (ric_ies_length == 0) {
545 hddLog(LOGW,
546 FL("RIC IEs is of length 0 not sending RIC Information for now"));
547 } else {
548 wrqu.data.length = str_len + ric_ies_length;
549 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
550 }
551
552 /* Sme needs to provide the Auth Resp */
553 cdf_mem_zero(buff, IW_CUSTOM_MAX);
554 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
555 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
556 (u8 *) &buff[str_len],
557 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
558
559 if (auth_resp_len == 0) {
560 kfree(buff);
561 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
562 return;
563 }
564
565 wrqu.data.length = str_len + auth_resp_len;
566 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
567
568 kfree(buff);
569#endif
570}
571
572#endif /* WLAN_FEATURE_VOWIFI_11R */
573
574#ifdef FEATURE_WLAN_ESE
575/**
576 * hdd_send_new_ap_channel_info() - send new ap channel info
577 * @dev: pointer to net device
578 * @pAdapter: pointer to adapter
579 * @pCsrRoamInfo: pointer to roam info
580 *
581 * Send the ESE required "new AP Channel info" to the supplicant.
582 * (This keeps the supplicant "up to date" on the current channel.)
583 *
584 * The current (new AP) channel information is passed in.
585 *
586 * Return: none
587 */
588static void
589hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
590 tCsrRoamInfo *pCsrRoamInfo)
591{
592 union iwreq_data wrqu;
593 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
594
595 if (descriptor == NULL) {
596 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
597 return;
598 }
599 /*
600 * Send the Channel event, the supplicant needs this to generate
601 * the Adjacent AP report.
602 */
603 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
604 descriptor->channelId);
605 memset(&wrqu, '\0', sizeof(wrqu));
606 wrqu.freq.m = descriptor->channelId;
607 wrqu.freq.e = 0;
608 wrqu.freq.i = 0;
609 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
610}
611
612#endif /* FEATURE_WLAN_ESE */
613
614/**
615 * hdd_send_update_beacon_ies_event() - send update beacons ie event
616 * @pAdapter: pointer to adapter
617 * @pCsrRoamInfo: pointer to roam info
618 *
619 * Return: none
620 */
621static void
622hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
623 tCsrRoamInfo *pCsrRoamInfo)
624{
625 union iwreq_data wrqu;
626 u8 *pBeaconIes;
627 u8 currentLen = 0;
628 char *buff;
629 int totalIeLen = 0, currentOffset = 0, strLen;
630
631 memset(&wrqu, '\0', sizeof(wrqu));
632
633 if (0 == pCsrRoamInfo->nBeaconLength) {
634 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
635 return;
636 }
637 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
638 if (pBeaconIes == NULL) {
639 hddLog(LOGW, FL("Beacon IEs is NULL"));
640 return;
641 }
642 /* pBeaconIes needs to point to the IEs */
643 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
644 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
645 hddLog(LOG1, FL("Beacon IEs length = %d"),
646 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
647
648 /* We need to send the IEs to the supplicant. */
649 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
650 if (buff == NULL) {
651 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
652 return;
653 }
654 cdf_mem_zero(buff, IW_CUSTOM_MAX);
655
656 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
657 currentLen = strLen + 1;
658
659 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
660 do {
661 /*
662 * If the beacon size exceeds max CUSTOM event size, break it
663 * into chunks of CUSTOM event max size and send it to
664 * supplicant. Changes are done in supplicant to handle this.
665 */
666 cdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
667 currentLen =
668 CDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
669 cdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
670 currentLen);
671 currentOffset += currentLen;
672 totalIeLen -= currentLen;
673 wrqu.data.length = strLen + 1 + currentLen;
674 if (totalIeLen)
675 buff[strLen] = 1; /* more chunks pending */
676 else
677 buff[strLen] = 0; /* last chunk */
678
679 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
680 currentLen);
681 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
682 } while (totalIeLen > 0);
683
684 kfree(buff);
685}
686
687/**
688 * hdd_send_association_event() - send association event
689 * @dev: pointer to net device
690 * @pCsrRoamInfo: pointer to roam info
691 *
692 * Return: none
693 */
694static void hdd_send_association_event(struct net_device *dev,
695 tCsrRoamInfo *pCsrRoamInfo)
696{
697 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
698 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
699 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
700 union iwreq_data wrqu;
701 int we_event;
702 char *msg;
703 struct cdf_mac_addr peerMacAddr;
704
705#ifdef WLAN_FEATURE_VOWIFI_11R
706 /* Added to find the auth type on the fly at run time */
707 /* rather than with cfg to see if FT is enabled */
708 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
709 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
710#endif
711
712 memset(&wrqu, '\0', sizeof(wrqu));
713 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
714 we_event = SIOCGIWAP;
715#ifdef WLAN_FEATURE_ROAM_OFFLOAD
716 if (NULL != pCsrRoamInfo)
717 if (pCsrRoamInfo->roamSynchInProgress)
718 /* change logging before release */
719 hddLog(LOG4, "LFR3:hdd_send_association_event");
720#endif
721 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
722 if (!pCsrRoamInfo) {
723 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
724 return;
725 }
726
727 cds_incr_active_session(pHddCtx, pAdapter->device_mode,
728 pAdapter->sessionId);
729 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
730 sizeof(pCsrRoamInfo->pBssDesc->bssId));
731
732#ifdef WLAN_FEATURE_P2P_DEBUG
733 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
734 if (global_p2p_connection_status ==
735 P2P_CLIENT_CONNECTING_STATE_1) {
736 global_p2p_connection_status =
737 P2P_CLIENT_CONNECTED_STATE_1;
738 hddLog(LOGE,
739 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
740 } else if (global_p2p_connection_status ==
741 P2P_CLIENT_CONNECTING_STATE_2) {
742 global_p2p_connection_status =
743 P2P_CLIENT_COMPLETED_STATE;
744 hddLog(LOGE,
745 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
746 }
747 }
748#endif
749 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
750 MAC_ADDRESS_STR "\n",
751 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
752 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
753 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
754
755 /*
756 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
757 * is Enabled Or Send IWEVASSOCRESPIE Event if
758 * WLAN_FEATURE_VOWIFI_11R is Enabled and fFTEnable is true.
759 */
760#ifdef WLAN_FEATURE_VOWIFI_11R
761 /* Send FT Keys to the supplicant when FT is enabled */
762 if ((pRoamProfile->AuthType.authType[0] ==
763 eCSR_AUTH_TYPE_FT_RSN_PSK)
764 || (pRoamProfile->AuthType.authType[0] ==
765 eCSR_AUTH_TYPE_FT_RSN)
766#ifdef FEATURE_WLAN_ESE
767 || (pRoamProfile->AuthType.authType[0] ==
768 eCSR_AUTH_TYPE_CCKM_RSN)
769 || (pRoamProfile->AuthType.authType[0] ==
770 eCSR_AUTH_TYPE_CCKM_WPA)
771#endif
772 ) {
773 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
774 }
775#endif
776 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
777 tSirSmeChanInfo chan_info;
778 cdf_copy_macaddr(&peerMacAddr,
779 &pHddStaCtx->conn_info.bssId);
780 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
781 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
782 chan_info.info = pCsrRoamInfo->chan_info.info;
783 chan_info.band_center_freq1 =
784 pCsrRoamInfo->chan_info.band_center_freq1;
785 chan_info.band_center_freq2 =
786 pCsrRoamInfo->chan_info.band_center_freq2;
787 chan_info.reg_info_1 =
788 pCsrRoamInfo->chan_info.reg_info_1;
789 chan_info.reg_info_2 =
790 pCsrRoamInfo->chan_info.reg_info_2;
791
792 /* send peer status indication to oem app */
793 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
794 ePeerConnected,
795 pCsrRoamInfo->
796 timingMeasCap,
797 pAdapter->sessionId,
798 &chan_info);
799 }
800#ifdef MSM_PLATFORM
801#ifdef CONFIG_CNSS
802 /* start timer in sta/p2p_cli */
803 spin_lock_bh(&pHddCtx->bus_bw_lock);
804 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
805 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
806 spin_unlock_bh(&pHddCtx->bus_bw_lock);
807 hdd_start_bus_bw_compute_timer(pAdapter);
808#endif
809#endif
810 } else if (eConnectionState_IbssConnected == /* IBss Associated */
811 pHddStaCtx->conn_info.connState) {
812 cds_incr_active_session(pHddCtx, pAdapter->device_mode,
813 pAdapter->sessionId);
814 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
815 ETH_ALEN);
816 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
817 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
818 } else { /* Not Associated */
819
820 pr_info("wlan: disconnected\n");
821 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
822 cds_decr_session_set_pcl(
823 pHddCtx, pAdapter->device_mode,
824 pAdapter->sessionId);
825#if defined(FEATURE_WLAN_LFR)
826 wlan_hdd_enable_roaming(pAdapter);
827#endif
828
829#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
830 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
831#endif
832
833 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
834 cdf_copy_macaddr(&peerMacAddr,
835 &pHddStaCtx->conn_info.bssId);
836
837 /* send peer status indication to oem app */
838 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
839 ePeerDisconnected, 0,
840 pAdapter->sessionId,
841 NULL);
842 }
843#ifdef WLAN_FEATURE_LPSS
844 pAdapter->rssi_send = false;
845 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
846#endif
847#ifdef FEATURE_WLAN_TDLS
848 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
849 (pCsrRoamInfo)) {
850 hddLog(LOG4,
851 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
852 pCsrRoamInfo->tdls_prohibited,
853 pCsrRoamInfo->tdls_chan_swit_prohibited);
854
855 wlan_hdd_update_tdls_info(pAdapter,
856 pCsrRoamInfo->tdls_prohibited,
857 pCsrRoamInfo->tdls_chan_swit_prohibited);
858 }
859#endif
860#ifdef MSM_PLATFORM
861 /* stop timer in sta/p2p_cli */
862 spin_lock_bh(&pHddCtx->bus_bw_lock);
863 pAdapter->prev_tx_packets = 0;
864 pAdapter->prev_rx_packets = 0;
865 spin_unlock_bh(&pHddCtx->bus_bw_lock);
866 hdd_stop_bus_bw_compute_timer(pAdapter);
867#endif
868 }
869 cds_dump_concurrency_info(pHddCtx);
870 /* Send SCC/MCC Switching event to IPA */
871 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
872
873 msg = NULL;
874 /*During the WLAN uninitialization,supplicant is stopped before the
875 driver so not sending the status of the connection to supplicant */
876 if ((pHddCtx->isLoadInProgress != true) &&
877 (pHddCtx->isUnloadInProgress != true)) {
878 wireless_send_event(dev, we_event, &wrqu, msg);
879#ifdef FEATURE_WLAN_ESE
880 if (eConnectionState_Associated ==
881 pHddStaCtx->conn_info.connState) {
882 if ((pRoamProfile->AuthType.authType[0] ==
883 eCSR_AUTH_TYPE_CCKM_RSN) ||
884 (pRoamProfile->AuthType.authType[0] ==
885 eCSR_AUTH_TYPE_CCKM_WPA))
886 hdd_send_new_ap_channel_info(dev, pAdapter,
887 pCsrRoamInfo);
888 }
889#endif
890 }
891}
892
893/**
894 * hdd_conn_remove_connect_info() - remove connection info
895 * @pHddStaCtx: pointer to global HDD station context
896 * @pCsrRoamInfo: pointer to roam info
897 *
898 * Return: none
899 */
900static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
901{
902 /* Remove staId, bssId and peerMacAddress */
903 pHddStaCtx->conn_info.staId[0] = 0;
904 cdf_mem_zero(&pHddStaCtx->conn_info.bssId, CDF_MAC_ADDR_SIZE);
905 cdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
906 CDF_MAC_ADDR_SIZE);
907
908 /* Clear all security settings */
909 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
910 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
911 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
912
913 cdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
914 cdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
915
916 /* Set not-connected state */
917 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
918 pHddStaCtx->conn_info.proxyARPService = 0;
919
920 cdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
921}
922
923/**
924 * hdd_roam_deregister_sta() - deregister station
925 * @pAdapter: pointer to adapter
926 * @staId: station identifier
927 *
928 * Return: CDF_STATUS enumeration
929 */
930static CDF_STATUS
931hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
932{
933 CDF_STATUS cdf_status;
934 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
935
936 if (eConnectionState_IbssDisconnected ==
937 pHddStaCtx->conn_info.connState) {
938 /*
939 * Do not set the carrier off when the last peer leaves.
940 * We will set the carrier off while stopping the IBSS.
941 */
942 }
943
944 cdf_status = ol_txrx_clear_peer(staId);
945 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
946 hddLog(LOGE,
947 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
948 staId, cdf_status, cdf_status);
949 }
950 return cdf_status;
951}
952
953/**
954 * hdd_dis_connect_handler() - disconnect event handler
955 * @pAdapter: pointer to adapter
956 * @pRoamInfo: pointer to roam info
957 * @roamId: roam identifier
958 * @roamStatus: roam status
959 * @roamResult: roam result
960 *
961 * This function handles disconnect event:
962 * 1. Disable transmit queues;
963 * 2. Clean up internal connection states and data structures;
964 * 3. Send disconnect indication to supplicant.
965 *
966 * Return: CDF_STATUS enumeration
967 */
968static CDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
969 tCsrRoamInfo *pRoamInfo,
970 uint32_t roamId,
971 eRoamCmdStatus roamStatus,
972 eCsrRoamResult roamResult)
973{
974 CDF_STATUS status = CDF_STATUS_SUCCESS;
975 CDF_STATUS vstatus;
976 struct net_device *dev = pAdapter->dev;
977 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
979 uint8_t sta_id;
980 bool sendDisconInd = true;
981
982 if (dev == NULL) {
983 hddLog(LOGE, FL("net_dev is released return"));
984 return CDF_STATUS_E_FAILURE;
985 }
986 /* notify apps that we can't pass traffic anymore */
987 hddLog(LOG1, FL("Disabling queues"));
988 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
989 WLAN_CONTROL_PATH);
990
991 if (hdd_ipa_is_enabled(pHddCtx))
992 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
993 WLAN_STA_DISCONNECT,
994 pHddStaCtx->conn_info.bssId.bytes);
995
996#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
997 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
998#endif
999
1000#ifdef QCA_PKT_PROTO_TRACE
1001 /* STA disconnected, update into trace buffer */
1002 if (pHddCtx->config->gEnableDebugLog)
1003 cds_pkt_trace_buf_update("ST:DISASC");
1004#endif /* QCA_PKT_PROTO_TRACE */
1005
1006 /* HDD has initiated disconnect, do not send disconnect indication
1007 * to kernel. Sending disconnected event to kernel for userspace
1008 * initiated disconnect will be handled by hdd_DisConnectHandler call
1009 * to cfg80211_disconnected.
1010 */
1011 if ((eConnectionState_Disconnecting ==
1012 pHddStaCtx->conn_info.connState) ||
1013 (eConnectionState_NotConnected ==
1014 pHddStaCtx->conn_info.connState)) {
1015 hddLog(LOG1,
1016 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1017 sendDisconInd = false;
1018 }
1019
1020 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1021 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1022 hddLog(LOG1,
1023 FL("Set HDD connState to eConnectionState_Disconnecting"));
1024 hdd_conn_set_connection_state(pAdapter,
1025 eConnectionState_Disconnecting);
1026 }
1027
1028 hdd_clear_roam_profile_ie(pAdapter);
1029 hdd_wmm_init(pAdapter);
1030
1031 /* indicate 'disconnect' status to wpa_supplicant... */
1032 hdd_send_association_event(dev, pRoamInfo);
1033 /* indicate disconnected event to nl80211 */
1034 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1035 /*
1036 * Only send indication to kernel if not initiated
1037 * by kernel
1038 */
1039 if (sendDisconInd) {
1040 /*
1041 * To avoid wpa_supplicant sending "HANGED" CMD
1042 * to ICS UI.
1043 */
1044 if (eCSR_ROAM_LOSTLINK == roamStatus)
1045 cfg80211_disconnected(dev, pRoamInfo->
1046 reasonCode, NULL,
1047 0, GFP_KERNEL);
1048 else
1049 cfg80211_disconnected(dev,
1050 WLAN_REASON_UNSPECIFIED,
1051 NULL, 0,
1052 GFP_KERNEL);
1053
1054 hdd_info("sent disconnected event to nl80211, rssi: %d",
1055 pAdapter->rssi);
1056 }
1057 /*
1058 * During the WLAN uninitialization,supplicant is stopped
1059 * before the driver so not sending the status of the
1060 * connection to supplicant.
1061 */
1062 if ((pHddCtx->isLoadInProgress != true) &&
1063 (pHddCtx->isUnloadInProgress != true)) {
1064#ifdef WLAN_FEATURE_P2P_DEBUG
1065 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1066 if (global_p2p_connection_status ==
1067 P2P_CLIENT_CONNECTED_STATE_1) {
1068 global_p2p_connection_status =
1069 P2P_CLIENT_DISCONNECTED_STATE;
1070 hddLog(LOGE,
1071 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1072 } else if (global_p2p_connection_status ==
1073 P2P_CLIENT_COMPLETED_STATE) {
1074 global_p2p_connection_status =
1075 P2P_NOT_ACTIVE;
1076 hddLog(LOGE,
1077 "[P2P State] P2P Client is removed and moved to inactive state");
1078 }
1079 }
1080#endif
1081
1082 }
1083 }
1084
1085 hdd_wmm_adapter_clear(pAdapter);
1086#if defined(WLAN_FEATURE_VOWIFI_11R)
1087 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
1088#endif
1089 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
1090 sta_id = IBSS_BROADCAST_STAID;
1091 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
1092 if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
1093 hddLog(LOGE,
1094 FL("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]"),
1095 sta_id, status, status);
1096 status = CDF_STATUS_E_FAILURE;
1097 }
1098 pHddCtx->sta_to_adapter[sta_id] = NULL;
1099 }
1100 sta_id = pHddStaCtx->conn_info.staId[0];
1101
1102 /* We should clear all sta register with TL, for now, only one. */
1103 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
1104 if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
1105 hddLog(LOGE,
1106 "hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]",
1107 sta_id, status, status);
1108 status = CDF_STATUS_E_FAILURE;
1109 }
1110
1111 pHddCtx->sta_to_adapter[sta_id] = NULL;
1112 /* Clear saved connection information in HDD */
1113 hdd_conn_remove_connect_info(pHddStaCtx);
1114 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1115 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1116#ifdef WLAN_FEATURE_GTK_OFFLOAD
1117 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1118 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1119 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1120 sizeof(tSirGtkOffloadParams));
1121 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1122 }
1123#endif
1124
1125#ifdef FEATURE_WLAN_TDLS
1126 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1127 wlan_hdd_tdls_disconnection_callback(pAdapter);
1128#endif
1129
1130 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1131 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1132 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1133 (pAdapter),
1134 pAdapter->sessionId);
1135 }
1136 /* Unblock anyone waiting for disconnect to complete */
1137 complete(&pAdapter->disconnect_comp_var);
1138 return status;
1139}
1140
1141/**
1142 * hdd_set_peer_authorized_event() - set peer_authorized_event
1143 * @vdev_id: vdevid
1144 *
1145 * Return: None
1146 */
1147void hdd_set_peer_authorized_event(uint32_t vdev_id)
1148{
1149 hdd_context_t *hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
1150 hdd_adapter_t *adapter = NULL;
1151
1152 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1153 if (adapter == NULL) {
1154 hddLog(LOGE,
1155 "%s: Invalid vdev_id", __func__);
1156 }
1157 complete(&adapter->sta_authorized_event);
1158}
1159
1160/**
1161 * hdd_change_peer_state() - change peer state
1162 * @pAdapter: HDD adapter
1163 * @sta_state: peer state
1164 * @roam_synch_in_progress: roam synch in progress
1165 *
1166 * Return: CDF status
1167 */
1168CDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
1169 uint8_t sta_id,
1170 enum ol_txrx_peer_state sta_state,
1171 bool roam_synch_in_progress)
1172{
1173 struct ol_txrx_peer_t *peer;
1174 CDF_STATUS err;
1175 struct ol_txrx_pdev_t *pdev = cds_get_context(CDF_MODULE_ID_TXRX);
1176
1177 if (!pdev) {
1178 hdd_err("Failed to get txrx context");
1179 return CDF_STATUS_E_FAULT;
1180 }
1181
1182 if (sta_id >= WLAN_MAX_STA_COUNT) {
1183 hddLog(LOGE, "Invalid sta id :%d", sta_id);
1184 return CDF_STATUS_E_INVAL;
1185 }
1186
1187 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1188 if (!peer)
1189 return CDF_STATUS_E_FAULT;
1190
1191 err = ol_txrx_peer_state_update(pdev,
1192 (u_int8_t *) peer->mac_addr.raw, sta_state);
1193 if (err != CDF_STATUS_SUCCESS) {
1194 hddLog(LOGE, "peer state update failed");
1195 return CDF_STATUS_E_FAULT;
1196 }
1197#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1198 if (roam_synch_in_progress)
1199 return CDF_STATUS_SUCCESS;
1200#endif
1201
1202 if (sta_state == ol_txrx_peer_state_auth) {
1203#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1204 /* make sure event is reset */
1205 INIT_COMPLETION(pAdapter->sta_authorized_event);
1206#endif
1207
1208 err = sme_set_peer_authorized(peer->mac_addr.raw,
1209 hdd_set_peer_authorized_event,
1210 pAdapter->sessionId);
1211 if (err != CDF_STATUS_SUCCESS) {
1212 hddLog(LOGE, "Failed to set the peer state to authorized");
1213 return CDF_STATUS_E_FAULT;
1214 }
1215
1216 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1217 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1218#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1219 unsigned long rc;
1220
1221 /* wait for event from firmware to set the event */
1222 rc = wait_for_completion_timeout(
1223 &pAdapter->sta_authorized_event,
1224 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1225 if (!rc) {
1226 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1227 __func__);
1228 }
1229 ol_txrx_vdev_unpause(peer->vdev,
1230 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
1231#endif
1232 }
1233 }
1234 return CDF_STATUS_SUCCESS;
1235}
1236
1237/**
1238 * hdd_roam_register_sta() - register station
1239 * @pAdapter: pointer to adapter
1240 * @pRoamInfo: pointer to roam info
1241 * @staId: station identifier
1242 * @pPeerMacAddress: peer MAC address
1243 * @pBssDesc: pointer to BSS description
1244 *
1245 * Return: CDF_STATUS enumeration
1246 */
1247static CDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
1248 tCsrRoamInfo *pRoamInfo,
1249 uint8_t staId,
1250 struct cdf_mac_addr *pPeerMacAddress,
1251 tSirBssDescription *pBssDesc)
1252{
1253 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1254 struct ol_txrx_desc_type staDesc = { 0 };
1255 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1256
1257 if (NULL == pBssDesc)
1258 return CDF_STATUS_E_FAILURE;
1259
1260 /* Get the Station ID from the one saved during the association */
1261 staDesc.sta_id = staId;
1262
1263 /* set the QoS field appropriately */
1264 if (hdd_wmm_is_active(pAdapter))
1265 staDesc.is_qos_enabled = 1;
1266 else
1267 staDesc.is_qos_enabled = 0;
1268
1269#ifdef FEATURE_WLAN_WAPI
1270 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1271 pAdapter->wapi_info.fIsWapiSta);
1272 if (pAdapter->wapi_info.fIsWapiSta)
1273 staDesc.is_wapi_supported = 1;
1274 else
1275 staDesc.is_wapi_supported = 0;
1276#endif /* FEATURE_WLAN_WAPI */
1277
1278 cdf_status = ol_txrx_register_peer(hdd_rx_packet_cbk,
1279 &staDesc);
1280 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1281 hddLog(LOGW,
1282 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
1283 cdf_status, cdf_status);
1284 return cdf_status;
1285 }
1286
1287 if (!pRoamInfo->fAuthRequired) {
1288 /*
1289 * Connections that do not need Upper layer auth, transition
1290 * TLSHIM directly to 'Authenticated' state
1291 */
1292 cdf_status =
1293 hdd_change_peer_state(pAdapter, staDesc.sta_id,
1294 ol_txrx_peer_state_auth,
1295#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1296 pRoamInfo->roamSynchInProgress
1297#else
1298 false
1299#endif
1300 );
1301
1302 hdd_conn_set_authenticated(pAdapter, true);
1303 } else {
1304 hddLog(LOG3,
1305 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1306 pHddStaCtx->conn_info.staId[0]);
1307 cdf_status =
1308 hdd_change_peer_state(pAdapter, staDesc.sta_id,
1309 ol_txrx_peer_state_conn,
1310#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1311 pRoamInfo->roamSynchInProgress
1312#else
1313 false
1314#endif
1315 );
1316 hdd_conn_set_authenticated(pAdapter, false);
1317 }
1318 return cdf_status;
1319}
1320
1321/**
1322 * hdd_send_re_assoc_event() - send reassoc event
1323 * @dev: pointer to net device
1324 * @pAdapter: pointer to adapter
1325 * @pCsrRoamInfo: pointer to roam info
1326 * @reqRsnIe: pointer to RSN Information element
1327 * @reqRsnLength: length of RSN IE
1328 *
1329 * Return: none
1330 */
1331static void hdd_send_re_assoc_event(struct net_device *dev,
1332 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1333 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1334{
1335 unsigned int len = 0;
1336 u8 *pFTAssocRsp = NULL;
1337 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1338 uint32_t rspRsnLength = 0;
1339 struct ieee80211_channel *chan;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1342 uint8_t *buf_ptr, ssid_ie_len;
1343 struct cfg80211_bss *bss = NULL;
1344 uint8_t *final_req_ie = NULL;
1345 tCsrRoamConnectedProfile roam_profile;
1346 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1347
1348 if (!rspRsnIe) {
1349 hddLog(LOGE, FL("Unable to allocate RSN IE"));
1350 return;
1351 }
1352
1353 if (pCsrRoamInfo == NULL) {
1354 hddLog(LOGE, FL("Invalid CSR roam info"));
1355 goto done;
1356 }
1357
1358 if (pCsrRoamInfo->nAssocRspLength == 0) {
1359 hddLog(LOGE, FL("Invalid assoc response length"));
1360 goto done;
1361 }
1362
1363 pFTAssocRsp =
1364 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1365 pCsrRoamInfo->nAssocReqLength);
1366 if (pFTAssocRsp == NULL)
1367 goto done;
1368
1369 /* pFTAssocRsp needs to point to the IEs */
1370 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1371 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1372 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1373
1374 /*
1375 * Active session count is decremented upon disconnection, but during
1376 * roaming, there is no disconnect indication and hence active session
1377 * count is not decremented.
1378 * After roaming is completed, active session count is incremented
1379 * as a part of connect indication but effectively after roaming the
1380 * active session count should still be the same and hence upon
1381 * successful reassoc decrement the active session count here.
1382 */
1383 cds_decr_session_set_pcl(
1384 pHddCtx, pAdapter->device_mode,
1385 pAdapter->sessionId);
1386
1387 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1388 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1389 rspRsnLength = len;
1390 cdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1391 cdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
1392
1393 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1394 (int)pCsrRoamInfo->pBssDesc->channelId);
1395 cdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
1396 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1397 &roam_profile);
1398 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1399 pCsrRoamInfo->bssid.bytes,
1400 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
1401 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1402
1403 if (bss == NULL)
1404 hddLog(LOGE, FL("Get BSS returned NULL"));
1405 buf_ptr = buf_ssid_ie;
1406 *buf_ptr = SIR_MAC_SSID_EID;
1407 buf_ptr++;
1408 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1409 buf_ptr++;
1410 cdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
1411 roam_profile.SSID.length);
1412 ssid_ie_len = 2 + roam_profile.SSID.length;
1413 hddLog(LOG2, FL("SSIDIE:"));
1414 hddLog(CDF_TRACE_LEVEL_DEBUG, buf_ssid_ie, ssid_ie_len);
1415 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1416 if (final_req_ie == NULL)
1417 goto done;
1418 buf_ptr = final_req_ie;
1419 cdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
1420 buf_ptr += ssid_ie_len;
1421 cdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1422 cdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1423 cdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
1424 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
1425 hddLog(LOG2, FL("Req RSN IE:"));
1426 hddLog(CDF_TRACE_LEVEL_DEBUG, final_req_ie,
1427 (ssid_ie_len + reqRsnLength));
1428 cfg80211_roamed_bss(dev, bss,
1429 final_req_ie, (ssid_ie_len + reqRsnLength),
1430 rspRsnIe, rspRsnLength, GFP_KERNEL);
1431
1432 if (pHddCtx->config->isRoamOffloadEnabled &&
1433 pCsrRoamInfo->roamSynchInProgress)
1434 wlan_hdd_send_roam_auth_event(pHddCtx,
1435 pCsrRoamInfo->bssid.bytes,
1436 reqRsnIe, reqRsnLength, rspRsnIe,
1437 rspRsnLength, pCsrRoamInfo);
1438done:
1439 sme_roam_free_connect_profile(hal_handle, &roam_profile);
1440 if (final_req_ie)
1441 kfree(final_req_ie);
1442 kfree(rspRsnIe);
1443}
1444
1445/**
1446 * hdd_roam_set_key_complete_handler() - Update the security parameters
1447 * @pAdapter: pointer to adapter
1448 * @pRoamInfo: pointer to roam info
1449 * @roamId: roam id
1450 * @roamStatus: roam status
1451 * @roamResult: roam result
1452 *
1453 * Return: CDF_STATUS enumeration
1454 */
1455static CDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
1456 tCsrRoamInfo *pRoamInfo,
1457 uint32_t roamId,
1458 eRoamCmdStatus roamStatus,
1459 eCsrRoamResult roamResult)
1460{
1461 eCsrEncryptionType connectedCipherAlgo;
1462 bool fConnected = false;
1463 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1464 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1465 ENTER();
1466
1467 if (NULL == pRoamInfo) {
1468 hddLog(LOG2, FL("pRoamInfo is NULL"));
1469 return CDF_STATUS_E_FAILURE;
1470 }
1471 /*
1472 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1473 * then go to 'authenticated'. For all other authentication types
1474 * (those that do not require upper layer authentication) we can put TL
1475 * directly into 'authenticated' state.
1476 */
1477 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1478 MAC_ADDRESS_STR, roamStatus, roamResult,
1479 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1480
1481 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1482 &connectedCipherAlgo);
1483 if (fConnected) {
1484 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
1485 uint8_t staId;
1486
1487 if (cdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
1488 pHddStaCtx->roam_info.roamingState =
1489 HDD_ROAM_STATE_NONE;
1490 } else {
1491 cdf_status = hdd_ibss_get_sta_id(
1492 pHddStaCtx,
1493 &pRoamInfo->peerMac,
1494 &staId);
1495 if (CDF_STATUS_SUCCESS == cdf_status) {
1496 hddLog(LOG2,
1497 "WLAN TL STA Ptk Installed for STAID=%d",
1498 staId);
1499 pHddStaCtx->roam_info.roamingState =
1500 HDD_ROAM_STATE_NONE;
1501 }
1502 }
1503 } else {
1504 /*
1505 * TODO: Considering getting a state machine in
1506 * HDD later. This routine is invoked twice.
1507 * 1)set PTK 2)set GTK.
1508 * The following if statement will be true when
1509 * setting GTK. At this time we don't handle the state
1510 * in detail. Related CR: 174048 - TL not in
1511 * authenticated state
1512 */
1513 cdf_status =
1514 hdd_change_peer_state(pAdapter, pHddStaCtx->conn_info.staId[0],
1515 ol_txrx_peer_state_auth,
1516#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1517 pRoamInfo->roamSynchInProgress
1518#else
1519 false
1520#endif
1521 );
1522 hdd_conn_set_authenticated(pAdapter, true);
1523 if ((eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) &&
1524 (pRoamInfo != NULL) && !pRoamInfo->fAuthRequired) {
1525 hddLog(LOG3,
1526 "Key set for StaId= %d. Changing TL state to AUTHENTICATED",
1527 pHddStaCtx->conn_info.staId[0]);
1528
1529 /*
1530 * Connections that do not need Upper layer
1531 * authentication, transition TL to
1532 * 'Authenticated' state after the keys are set.
1533 */
1534 cdf_status =
1535 hdd_change_peer_state(pAdapter,
1536 pHddStaCtx->conn_info.staId[0],
1537 ol_txrx_peer_state_auth,
1538#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1539 pRoamInfo->roamSynchInProgress
1540#else
1541 false
1542#endif
1543 );
1544
1545 hdd_conn_set_authenticated(pAdapter, true);
1546 if ((WLAN_HDD_INFRA_STATION ==
1547 pAdapter->device_mode) ||
1548 (WLAN_HDD_P2P_CLIENT ==
1549 pAdapter->device_mode)) {
1550 sme_ps_enable_auto_ps_timer
1551 (WLAN_HDD_GET_HAL_CTX(pAdapter),
1552 pAdapter->sessionId,
1553 pHddStaCtx->hdd_ReassocScenario);
1554 }
1555 }
1556
1557 pHddStaCtx->roam_info.roamingState =
1558 HDD_ROAM_STATE_NONE;
1559 }
1560 } else {
1561 /*
1562 * possible disassoc after issuing set key and waiting
1563 * set key complete.
1564 */
1565 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1566 }
1567
1568 EXIT();
1569 return CDF_STATUS_SUCCESS;
1570}
1571
1572/**
1573 * hdd_perform_roam_set_key_complete() - perform set key complete
1574 * @pAdapter: pointer to adapter
1575 *
1576 * Return: none
1577 */
1578void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1579{
1580 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
1581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1582 tCsrRoamInfo roamInfo;
1583 roamInfo.fAuthRequired = false;
1584 cdf_mem_copy(roamInfo.bssid.bytes,
1585 pHddStaCtx->roam_info.bssid, CDF_MAC_ADDR_SIZE);
1586 cdf_mem_copy(roamInfo.peerMac.bytes,
1587 pHddStaCtx->roam_info.peerMac, CDF_MAC_ADDR_SIZE);
1588
1589 cdf_ret_status =
1590 hdd_roam_set_key_complete_handler(pAdapter,
1591 &roamInfo,
1592 pHddStaCtx->roam_info.roamId,
1593 pHddStaCtx->roam_info.roamStatus,
1594 eCSR_ROAM_RESULT_AUTHENTICATED);
1595 if (cdf_ret_status != CDF_STATUS_SUCCESS)
1596 hddLog(LOGE, FL("Set Key complete failure"));
1597
1598 pHddStaCtx->roam_info.deferKeyComplete = false;
1599}
1600
1601/**
1602 * hdd_association_completion_handler() - association completion handler
1603 * @pAdapter: pointer to adapter
1604 * @pRoamInfo: pointer to roam info
1605 * @roamId: roam id
1606 * @roamStatus: roam status
1607 * @roamResult: roam result
1608 *
1609 * Return: CDF_STATUS enumeration
1610 */
1611static CDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
1612 tCsrRoamInfo *pRoamInfo,
1613 uint32_t roamId,
1614 eRoamCmdStatus roamStatus,
1615 eCsrRoamResult roamResult)
1616{
1617 struct net_device *dev = pAdapter->dev;
1618 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1619 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1620 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1621 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1622 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
1623#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || \
1624defined(WLAN_FEATURE_VOWIFI_11R)
1625 int ft_carrier_on = false;
1626#endif
1627 bool hddDisconInProgress = false;
1628 unsigned long rc;
1629
1630 if (!pHddCtx) {
1631 hdd_err("HDD context is NULL");
1632 return CDF_STATUS_E_FAILURE;
1633 }
1634
1635#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1636 if (pRoamInfo && pRoamInfo->roamSynchInProgress) {
1637 /* change logging before release */
1638 hddLog(LOG3, "LFR3:hdd_association_completion_handler");
1639 }
1640#endif
1641
1642 /* HDD has initiated disconnect, do not send connect result indication
1643 * to kernel as it will be handled by __cfg80211_disconnect.
1644 */
1645 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1646 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1647 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1648 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1649 hddDisconInProgress = true;
1650 }
1651
1652 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1653 if (NULL == pRoamInfo) {
1654 hddLog(LOGE, FL("pRoamInfo is NULL"));
1655 return CDF_STATUS_E_FAILURE;
1656 }
1657 if (!hddDisconInProgress) {
1658 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1659 hdd_conn_set_connection_state(pAdapter,
1660 eConnectionState_Associated);
1661 }
1662 /* Save the connection info from CSR... */
1663 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1664 eCSR_BSS_TYPE_INFRASTRUCTURE);
1665#ifdef FEATURE_WLAN_WAPI
1666 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1667 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1668 || pRoamInfo->u.pConnectedProfile->AuthType ==
1669 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1670 pAdapter->wapi_info.fIsWapiSta = 1;
1671 } else {
1672 pAdapter->wapi_info.fIsWapiSta = 0;
1673 }
1674#endif /* FEATURE_WLAN_WAPI */
1675
1676 /* Indicate 'connect' status to user space */
1677 hdd_send_association_event(dev, pRoamInfo);
1678
1679 if (cds_is_mcc_in_24G(pHddCtx)) {
1680 if (pHddCtx->miracast_value)
1681 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1682 }
1683
1684 /* Initialize the Linkup event completion variable */
1685 INIT_COMPLETION(pAdapter->linkup_event_var);
1686
1687 /*
1688 * Sometimes Switching ON the Carrier is taking time to activate
1689 * the device properly. Before allowing any packet to go up to
1690 * the application, device activation has to be ensured for
1691 * proper queue mapping by the kernel. we have registered net
1692 * device notifier for device change notification. With this we
1693 * will come to know that the device is getting
1694 * activated properly.
1695 */
1696#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
1697defined(FEATURE_WLAN_LFR)
1698 if (pHddStaCtx->ft_carrier_on == false) {
1699#endif
1700 /*
1701 * Enable Linkup Event Servicing which allows the net device
1702 * notifier to set the linkup event variable.
1703 */
1704 pAdapter->isLinkUpSvcNeeded = true;
1705
1706 /*
1707 * Enable Linkup Event Servicing which allows the net device
1708 * notifier to set the linkup event variable.
1709 */
1710 pAdapter->isLinkUpSvcNeeded = true;
1711
1712 /* Switch on the Carrier to activate the device */
1713 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_CARRIER_ON,
1714 WLAN_CONTROL_PATH);
1715
1716 /*
1717 * Wait for the Link to up to ensure all the queues are set
1718 * properly by the kernel.
1719 */
1720 rc = wait_for_completion_timeout(&pAdapter->
1721 linkup_event_var,
1722 msecs_to_jiffies
1723 (ASSOC_LINKUP_TIMEOUT));
1724 if (!rc)
1725 hddLog(LOGW, FL("Warning:ASSOC_LINKUP_TIMEOUT"));
1726
1727 /*
1728 * Disable Linkup Event Servicing - no more service required
1729 * from the net device notifier call.
1730 */
1731 pAdapter->isLinkUpSvcNeeded = false;
1732#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
1733defined(FEATURE_WLAN_LFR)
1734 } else {
1735 pHddStaCtx->ft_carrier_on = false;
1736 ft_carrier_on = true;
1737 }
1738#endif
1739 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1740 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1741 else
1742 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1743 pRoamInfo->staId);
1744
1745 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1746
1747 if (hdd_ipa_is_enabled(pHddCtx))
1748 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1749 WLAN_STA_CONNECT,
1750 pRoamInfo->bssid.bytes);
1751
1752#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1753 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1754#endif
1755
1756 cds_check_concurrent_intf_and_restart_sap(pHddCtx,
1757 pHddStaCtx,
1758 pAdapter);
1759
1760#ifdef FEATURE_WLAN_TDLS
1761 wlan_hdd_tdls_connection_callback(pAdapter);
1762#endif
1763
1764#ifdef QCA_PKT_PROTO_TRACE
1765 /* STA Associated, update into trace buffer */
1766 if (pHddCtx->config->gEnableDebugLog)
1767 cds_pkt_trace_buf_update("ST:ASSOC");
1768#endif /* QCA_PKT_PROTO_TRACE */
1769 /*
1770 * For reassoc, the station is already registered, all we need
1771 * is to change the state of the STA in TL.
1772 * If authentication is required (WPA/WPA2/DWEP), change TL to
1773 * CONNECTED instead of AUTHENTICATED.
1774 */
1775 if (!pRoamInfo->fReassocReq) {
1776 struct cfg80211_bss *bss;
1777#ifdef WLAN_FEATURE_VOWIFI_11R
1778 u8 *pFTAssocRsp = NULL;
1779 unsigned int assocRsplen = 0;
1780 u8 *pFTAssocReq = NULL;
1781 unsigned int assocReqlen = 0;
1782 struct ieee80211_channel *chan;
1783#endif
1784 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1785 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1786
1787 /* add bss_id to cfg80211 data base */
1788 bss =
1789 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1790 pRoamInfo);
1791 if (NULL == bss) {
1792 pr_err("wlan: Not able to create BSS entry\n");
1793 wlan_hdd_netif_queue_control(pAdapter,
1794 WLAN_NETIF_CARRIER_OFF,
1795 WLAN_CONTROL_PATH);
1796 return CDF_STATUS_E_FAILURE;
1797 }
1798#ifdef WLAN_FEATURE_VOWIFI_11R
1799 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1800 eCSR_AUTH_TYPE_FT_RSN
1801 || pRoamInfo->u.pConnectedProfile->AuthType ==
1802 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1803
1804 /* Association Response */
1805 pFTAssocRsp =
1806 (u8 *) (pRoamInfo->pbFrames +
1807 pRoamInfo->nBeaconLength +
1808 pRoamInfo->nAssocReqLength);
1809 if (pFTAssocRsp != NULL) {
1810 /*
1811 * pFTAssocRsp needs to point to the IEs
1812 */
1813 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1814 hddLog(LOG1,
1815 FL("AssocRsp is now at %02x%02x"),
1816 (unsigned int)pFTAssocRsp[0],
1817 (unsigned int)pFTAssocRsp[1]);
1818 assocRsplen =
1819 pRoamInfo->nAssocRspLength -
1820 FT_ASSOC_RSP_IES_OFFSET;
1821 } else {
1822 hddLog(LOGE, FL("AssocRsp is NULL"));
1823 assocRsplen = 0;
1824 }
1825
1826 /* Association Request */
1827 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1828 pRoamInfo->nBeaconLength);
1829 if (pFTAssocReq != NULL) {
1830 if (!ft_carrier_on) {
1831 /*
1832 * pFTAssocReq needs to point to
1833 * the IEs
1834 */
1835 pFTAssocReq +=
1836 FT_ASSOC_REQ_IES_OFFSET;
1837 hddLog(LOG1,
1838 FL("pFTAssocReq is now at %02x%02x"),
1839 (unsigned int)
1840 pFTAssocReq[0],
1841 (unsigned int)
1842 pFTAssocReq[1]);
1843 assocReqlen =
1844 pRoamInfo->nAssocReqLength -
1845 FT_ASSOC_REQ_IES_OFFSET;
1846 } else {
1847 /*
1848 * This should contain only the
1849 * FTIEs
1850 */
1851 assocReqlen =
1852 pRoamInfo->nAssocReqLength;
1853 }
1854 } else {
1855 hddLog(LOGE, FL("AssocReq is NULL"));
1856 assocReqlen = 0;
1857 }
1858
1859 if (ft_carrier_on) {
1860 if (!hddDisconInProgress) {
1861 /*
1862 * After roaming is completed,
1863 * active session count is
1864 * incremented as a part of
1865 * connect indication but
1866 * effectively the active
1867 * session count should still
1868 * be the same and hence upon
1869 * successful reassoc
1870 * decrement the active session
1871 * count here.
1872 */
1873 cds_decr_session_set_pcl
1874 (pHddCtx,
1875 pAdapter->device_mode,
1876 pAdapter->sessionId);
1877 hddLog(LOG1,
1878 FL("ft_carrier_on is %d, sending roamed indication"),
1879 ft_carrier_on);
1880 chan =
1881 ieee80211_get_channel
1882 (pAdapter->wdev.wiphy,
1883 (int)pRoamInfo->pBssDesc->
1884 channelId);
1885 hddLog(LOG1,
1886 "assocReqlen %d assocRsplen %d",
1887 assocReqlen,
1888 assocRsplen);
1889 cfg80211_roamed(dev, chan,
1890 pRoamInfo->
1891 bssid.bytes,
1892 pFTAssocReq,
1893 assocReqlen,
1894 pFTAssocRsp,
1895 assocRsplen,
1896 GFP_KERNEL);
1897 if (pRoamInfo->roamSynchInProgress)
1898 wlan_hdd_send_roam_auth_event(
1899 pHddCtx,
1900 pRoamInfo->bssid.bytes,
1901 pFTAssocReq,
1902 assocReqlen,
1903 pFTAssocRsp,
1904 assocRsplen,
1905 pRoamInfo);
1906 }
1907 if (sme_get_ftptk_state
1908 (WLAN_HDD_GET_HAL_CTX(pAdapter),
1909 pAdapter->sessionId)) {
1910 sme_set_ftptk_state
1911 (WLAN_HDD_GET_HAL_CTX
1912 (pAdapter),
1913 pAdapter->sessionId,
1914 false);
1915 pRoamInfo->fAuthRequired =
1916 false;
1917
1918 cdf_mem_copy(pHddStaCtx->
1919 roam_info.bssid,
1920 pRoamInfo->bssid.bytes,
1921 CDF_MAC_ADDR_SIZE);
1922 cdf_mem_copy(pHddStaCtx->
1923 roam_info.peerMac,
1924 pRoamInfo->peerMac.bytes,
1925 CDF_MAC_ADDR_SIZE);
1926 pHddStaCtx->roam_info.roamId =
1927 roamId;
1928 pHddStaCtx->roam_info.
1929 roamStatus = roamStatus;
1930 pHddStaCtx->roam_info.
1931 deferKeyComplete = true;
1932 }
1933 } else if (!hddDisconInProgress) {
1934 hddLog(LOG1,
1935 FL("ft_carrier_on is %d, sending connect indication"),
1936 ft_carrier_on);
1937 cfg80211_connect_result(dev,
1938 pRoamInfo->
1939 bssid.bytes,
1940 pFTAssocReq,
1941 assocReqlen,
1942 pFTAssocRsp,
1943 assocRsplen,
1944 WLAN_STATUS_SUCCESS,
1945 GFP_KERNEL);
1946 }
1947 } else
1948#endif
1949 {
1950 /*
1951 * wpa supplicant expecting WPA/RSN IE in
1952 * connect result.
1953 */
1954 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
1955 (pAdapter),
1956 pAdapter->sessionId,
1957 &reqRsnLength,
1958 reqRsnIe);
1959
1960 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
1961 (pAdapter),
1962 pAdapter->sessionId,
1963 &rspRsnLength,
1964 rspRsnIe);
1965 if (!hddDisconInProgress) {
1966#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
1967 if (ft_carrier_on)
1968 hdd_send_re_assoc_event(dev,
1969 pAdapter,
1970 pRoamInfo,
1971 reqRsnIe,
1972 reqRsnLength);
1973 else
1974#endif /* FEATURE_WLAN_ESE */
1975
1976 {
1977 hddLog(LOG1,
1978 FL("sending connect indication to nl80211:for bssid "
1979 MAC_ADDRESS_STR
1980 " reason:%d and Status:%d"),
1981 MAC_ADDR_ARRAY
1982 (pRoamInfo->bssid.bytes),
1983 roamResult, roamStatus);
1984
1985 /* inform connect result to nl80211 */
1986 cfg80211_connect_result(dev,
1987 pRoamInfo->
1988 bssid.bytes,
1989 reqRsnIe,
1990 reqRsnLength,
1991 rspRsnIe,
1992 rspRsnLength,
1993 WLAN_STATUS_SUCCESS,
1994 GFP_KERNEL);
1995 }
1996 }
1997 }
1998 if (!hddDisconInProgress) {
1999 cfg80211_put_bss(
2000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2001 pHddCtx->wiphy,
2002#endif
2003 bss);
2004
2005 /*
2006 * Perform any WMM-related association
2007 * processing.
2008 */
2009 hdd_wmm_assoc(pAdapter, pRoamInfo,
2010 eCSR_BSS_TYPE_INFRASTRUCTURE);
2011
2012 /*
2013 * Start the Queue - Start tx queues before
2014 * hdd_roam_register_sta, since
2015 * hdd_roam_register_sta will flush any cached
2016 * data frames immediately.
2017 */
2018 hddLog(LOG1, FL("Enabling queues"));
2019 wlan_hdd_netif_queue_control(pAdapter,
2020 WLAN_WAKE_ALL_NETIF_QUEUE,
2021 WLAN_CONTROL_PATH);
2022
2023 /*
2024 * Register the Station with TL after associated
2025 */
2026 cdf_status = hdd_roam_register_sta(pAdapter,
2027 pRoamInfo,
2028 pHddStaCtx->
2029 conn_info.
2030 staId[0],
2031 NULL,
2032 pRoamInfo->
2033 pBssDesc);
2034 }
2035 } else {
2036 /*
2037 * wpa supplicant expecting WPA/RSN IE in connect result
2038 * in case of reassociation also need to indicate it to
2039 * supplicant.
2040 */
2041 csr_roam_get_wpa_rsn_req_ie(
2042 WLAN_HDD_GET_HAL_CTX(pAdapter),
2043 pAdapter->sessionId,
2044 &reqRsnLength, reqRsnIe);
2045
2046 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2047 reqRsnIe, reqRsnLength);
2048 /* Reassoc successfully */
2049 if (pRoamInfo->fAuthRequired) {
2050 cdf_status =
2051 hdd_change_peer_state(pAdapter,
2052 pHddStaCtx->conn_info.staId[0],
2053 ol_txrx_peer_state_conn,
2054#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2055 pRoamInfo->roamSynchInProgress
2056#else
2057 false
2058#endif
2059 );
2060 hdd_conn_set_authenticated(pAdapter, false);
2061 } else {
2062 hddLog(LOG2,
2063 FL("staId: %d Changing TL state to AUTHENTICATED"),
2064 pHddStaCtx->conn_info.staId[0]);
2065 cdf_status =
2066 hdd_change_peer_state(pAdapter,
2067 pHddStaCtx->conn_info.staId[0],
2068 ol_txrx_peer_state_auth,
2069#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2070 pRoamInfo->roamSynchInProgress
2071#else
2072 false
2073#endif
2074 );
2075 hdd_conn_set_authenticated(pAdapter, true);
2076 }
2077
2078 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
2079 /*
2080 * Perform any WMM-related association
2081 * processing
2082 */
2083 hdd_wmm_assoc(pAdapter, pRoamInfo,
2084 eCSR_BSS_TYPE_INFRASTRUCTURE);
2085 }
2086
2087 /* Start the tx queues */
2088#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2089 if (pRoamInfo->roamSynchInProgress)
2090 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2091#endif
2092 hddLog(LOG1, FL("Enabling queues"));
2093 wlan_hdd_netif_queue_control(pAdapter,
2094 WLAN_WAKE_ALL_NETIF_QUEUE,
2095 WLAN_CONTROL_PATH);
2096 }
2097
2098 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2099 hddLog(LOGE,
2100 "STA register with TL failed. status(=%d) [%08X]",
2101 cdf_status, cdf_status);
2102 }
2103#ifdef WLAN_FEATURE_11W
2104 cdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
2105 sizeof(pAdapter->hdd_stats.hddPmfStats));
2106#endif
2107 } else {
2108 hdd_wext_state_t *pWextState =
2109 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2110 if (pRoamInfo)
2111 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
2112 " reason:%d and Status:%d\n",
2113 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2114 roamResult, roamStatus);
2115 else
2116 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
2117 " reason:%d and Status:%d\n",
2118 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2119 roamResult, roamStatus);
2120
2121 /*
2122 * CR465478: Only send up a connection failure result when CSR
2123 * has completed operation - with a ASSOCIATION_FAILURE status.
2124 */
2125 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2126 && !hddDisconInProgress) {
2127 if (pRoamInfo)
2128 hddLog(LOGE,
2129 FL("send connect failure to nl80211: for bssid "
2130 MAC_ADDRESS_STR
2131 " reason:%d and Status:%d "),
2132 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2133 roamResult, roamStatus);
2134 else
2135 hddLog(LOGE,
2136 FL("connect failed: for bssid "
2137 MAC_ADDRESS_STR
2138 " reason:%d and Status:%d "),
2139 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2140 roamResult, roamStatus);
2141
2142 hdd_clear_roam_profile_ie(pAdapter);
2143
2144 /* inform association failure event to nl80211 */
2145 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2146 roamResult) {
2147 if (pRoamInfo)
2148 cfg80211_connect_result(dev,
2149 pRoamInfo->bssid.bytes,
2150 NULL, 0, NULL, 0,
2151 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2152 GFP_KERNEL);
2153 else
2154 cfg80211_connect_result(dev,
2155 pWextState->req_bssId.bytes,
2156 NULL, 0, NULL, 0,
2157 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2158 GFP_KERNEL);
2159 } else {
2160 if (pRoamInfo) {
2161 eCsrAuthType authType =
2162 pWextState->roamProfile.AuthType.
2163 authType[0];
2164 bool isWep =
2165 (authType ==
2166 eCSR_AUTH_TYPE_OPEN_SYSTEM)
2167 || (authType ==
2168 eCSR_AUTH_TYPE_SHARED_KEY);
2169
2170 /*
2171 * In case of OPEN-WEP or SHARED-WEP
2172 * authentication, send exact protocol
2173 * reason code. This enables user
2174 * applications to reconnect the station
2175 * with correct configuration.
2176 */
2177 cfg80211_connect_result(dev,
2178 pRoamInfo->bssid.bytes, NULL, 0,
2179 NULL, 0,
2180 isWep ? pRoamInfo->reasonCode :
2181 WLAN_STATUS_UNSPECIFIED_FAILURE,
2182 GFP_KERNEL);
2183 } else
2184 cfg80211_connect_result(dev,
2185 pWextState->req_bssId.bytes,
2186 NULL, 0, NULL, 0,
2187 WLAN_STATUS_UNSPECIFIED_FAILURE,
2188 GFP_KERNEL);
2189 }
2190 }
2191
2192 if (pRoamInfo) {
2193 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2194 pRoamInfo->statusCode)
2195 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2196 pRoamInfo->statusCode)
2197 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2198 pRoamInfo->statusCode)) {
2199 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2200 pRoamInfo);
2201 }
2202 }
2203
2204 /*
2205 * Set connection state to eConnectionState_NotConnected only
2206 * when CSR has completed operation - with a
2207 * ASSOCIATION_FAILURE status.
2208 */
2209 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2210 && !hddDisconInProgress) {
2211 hddLog(LOG1,
2212 FL("state to eConnectionState_NotConnected"));
2213 hdd_conn_set_connection_state(pAdapter,
2214 eConnectionState_NotConnected);
2215 }
2216 hdd_wmm_init(pAdapter);
2217
2218 hddLog(LOG1, FL("Disabling queues"));
2219 wlan_hdd_netif_queue_control(pAdapter,
2220 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2221 WLAN_CONTROL_PATH);
2222 }
2223
2224 if (CDF_STATUS_SUCCESS != cds_check_and_restart_sap(pHddCtx,
2225 roamResult, pHddStaCtx))
2226 return CDF_STATUS_E_FAILURE;
2227
2228 cds_force_sap_on_scc(pHddCtx, roamResult);
2229
2230 return CDF_STATUS_SUCCESS;
2231}
2232
2233/**
2234 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2235 * @pAdapter: pointer to adapter
2236 * @pRoamInfo: pointer to roam info
2237 * @roamId: roam id
2238 * @roamStatus: roam status
2239 * @roamResult: roam result
2240 *
2241 * Here we update the status of the Ibss when we receive information that we
2242 * have started/joined an ibss session.
2243 *
2244 * Return: none
2245 */
2246static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2247 tCsrRoamInfo *pRoamInfo,
2248 uint32_t roamId,
2249 eRoamCmdStatus roamStatus,
2250 eCsrRoamResult roamResult)
2251{
2252 hddLog(LOG1, "%s: id %d, status %d, result %d",
2253 pAdapter->dev->name, roamId, roamStatus, roamResult);
2254
2255 switch (roamResult) {
2256 /* both IBSS Started and IBSS Join should come in here. */
2257 case eCSR_ROAM_RESULT_IBSS_STARTED:
2258 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2259 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2260 {
2261 hdd_context_t *pHddCtx =
2262 (hdd_context_t *) pAdapter->pHddCtx;
2263 struct cdf_mac_addr broadcastMacAddr =
2264 CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2265
2266 if (NULL == pRoamInfo) {
2267 CDF_ASSERT(0);
2268 return;
2269 }
2270
2271 /* When IBSS Started comes from CSR, we need to move
2272 * connection state to IBSS Disconnected (meaning no peers
2273 * are in the IBSS).
2274 */
2275 hddLog(LOG1,
2276 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2277 hdd_conn_set_connection_state(pAdapter,
2278 eConnectionState_IbssDisconnected);
2279 /* notify wmm */
2280 hdd_wmm_connect(pAdapter, pRoamInfo,
2281 eCSR_BSS_TYPE_IBSS);
2282 pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] =
2283 pAdapter;
2284 hdd_roam_register_sta(pAdapter, pRoamInfo,
2285 IBSS_BROADCAST_STAID,
2286 &broadcastMacAddr,
2287 pRoamInfo->pBssDesc);
2288
2289 if (pRoamInfo->pBssDesc) {
2290 struct cfg80211_bss *bss;
2291#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2292 struct ieee80211_channel *chan;
2293 int chan_no;
2294 unsigned int freq;
2295#endif
2296 /* we created the IBSS, notify supplicant */
2297 hddLog(LOG1,
2298 FL("%s: created ibss " MAC_ADDRESS_STR),
2299 pAdapter->dev->name,
2300 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2301
2302 /* we must first give cfg80211 the BSS information */
2303 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2304 pRoamInfo);
2305 if (NULL == bss) {
2306 hddLog(LOGE,
2307 FL("%s: unable to create IBSS entry"),
2308 pAdapter->dev->name);
2309 return;
2310 }
2311 hddLog(LOG1, FL("Enabling queues"));
2312 wlan_hdd_netif_queue_control(pAdapter,
2313 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2314 WLAN_CONTROL_PATH);
2315
2316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2317 chan_no = pRoamInfo->pBssDesc->channelId;
2318
2319 if (chan_no <= 14)
2320 freq = ieee80211_channel_to_frequency(chan_no,
2321 IEEE80211_BAND_2GHZ);
2322 else
2323 freq = ieee80211_channel_to_frequency(chan_no,
2324 IEEE80211_BAND_5GHZ);
2325
2326 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2327
2328 if (chan)
2329 cfg80211_ibss_joined(pAdapter->dev,
2330 bss->bssid, chan,
2331 GFP_KERNEL);
2332 else
2333 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2334 pAdapter->dev->name,
2335 (int)pRoamInfo->pBssDesc->channelId);
2336#else
2337 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2338 GFP_KERNEL);
2339#endif
2340 cfg80211_put_bss(
2341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2342 pHddCtx->wiphy,
2343#endif
2344 bss);
2345 }
2346
2347 break;
2348 }
2349
2350 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2351 {
2352 hddLog(LOGE,
2353 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2354 break;
2355 }
2356
2357 default:
2358 hddLog(LOGE, FL("%s: unexpected result %d"),
2359 pAdapter->dev->name, (int)roamResult);
2360 break;
2361 }
2362
2363 return;
2364}
2365
2366/**
2367 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2368 * @pHddStaCtx: pointer to global HDD station context
2369 * @staId: station id
2370 * @peerMacAddress: pointer to peer MAC address
2371 *
2372 * This information is passed to iwconfig later. The peer that joined
2373 * last is passed as information to iwconfig.
2374 *
2375 * Return:
2376 * true if we add MAX_IBSS_PEERS or less STA
2377 * false otherwise.
2378 */
2379static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
2380 struct cdf_mac_addr *peerMacAddress)
2381{
2382 bool fSuccess = false;
2383 int idx = 0;
2384
2385 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2386 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2387 pHddStaCtx->conn_info.staId[idx] = staId;
2388
2389 cdf_copy_macaddr(&pHddStaCtx->conn_info.
2390 peerMacAddress[idx], peerMacAddress);
2391
2392 fSuccess = true;
2393 break;
2394 }
2395 }
2396
2397 return fSuccess;
2398}
2399
2400/**
2401 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2402 * @pAdapter: pointer to adapter
2403 * @staId: station id
2404 *
2405 * Return:
2406 * true if we remove MAX_IBSS_PEERS or less STA
2407 * false otherwise.
2408 */
2409static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2410{
2411 bool fSuccess = false;
2412 int idx = 0;
2413 uint8_t valid_idx = 0;
2414 uint8_t del_idx = 0;
2415 uint8_t empty_slots = 0;
2416 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2417
2418 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2419 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2420 pHddStaCtx->conn_info.staId[idx] = 0;
2421
2422 cdf_zero_macaddr(&pHddStaCtx->conn_info.
2423 peerMacAddress[idx]);
2424
2425 fSuccess = true;
2426
2427 /*
2428 * Note the deleted Index, if its 0 we need special
2429 * handling.
2430 */
2431 del_idx = idx;
2432
2433 empty_slots++;
2434 } else {
2435 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2436 valid_idx = idx;
2437 } else {
2438 /* Found an empty slot */
2439 empty_slots++;
2440 }
2441 }
2442 }
2443
2444 if (MAX_IBSS_PEERS == empty_slots) {
2445 /* Last peer departed, set the IBSS state appropriately */
2446 pHddStaCtx->conn_info.connState =
2447 eConnectionState_IbssDisconnected;
2448 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2449 }
2450 /* Find next active staId, to have a valid sta trigger for TL. */
2451 if (fSuccess == true) {
2452 if (del_idx == 0) {
2453 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2454 pHddStaCtx->conn_info.staId[0] =
2455 pHddStaCtx->conn_info.staId[valid_idx];
2456 cdf_copy_macaddr(&pHddStaCtx->conn_info.
2457 peerMacAddress[0],
2458 &pHddStaCtx->conn_info.
2459 peerMacAddress[valid_idx]);
2460
2461 pHddStaCtx->conn_info.staId[valid_idx] = 0;
2462 cdf_zero_macaddr(&pHddStaCtx->conn_info.
2463 peerMacAddress[valid_idx]);
2464 }
2465 }
2466 }
2467 return fSuccess;
2468}
2469
2470/**
2471 * roam_ibss_connect_handler() - IBSS connection handler
2472 * @pAdapter: pointer to adapter
2473 * @pRoamInfo: pointer to roam info
2474 *
2475 * We update the status of the IBSS to connected in this function.
2476 *
2477 * Return: CDF_STATUS enumeration
2478 */
2479static CDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
2480 tCsrRoamInfo *pRoamInfo)
2481{
2482 struct cfg80211_bss *bss;
2483 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2484 /*
2485 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2486 * a partner stations).
2487 */
2488 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2489
2490 /* Save the connection info from CSR... */
2491 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2492
2493 /* Send the bssid address to the wext. */
2494 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2495 /* add bss_id to cfg80211 data base */
2496 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2497 if (NULL == bss) {
2498 hddLog(LOGE,
2499 FL("%s: unable to create IBSS entry"),
2500 pAdapter->dev->name);
2501 return CDF_STATUS_E_FAILURE;
2502 }
2503 cfg80211_put_bss(
2504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2505 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
2506#endif
2507 bss);
2508
2509 return CDF_STATUS_SUCCESS;
2510}
2511
2512/**
2513 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2514 * @pAdapter: pointer to adapter
2515 * @pRoamInfo: pointer to roam info
2516 * @roamId: roam id
2517 * @roamStatus: roam status
2518 * @roamResult: roam result
2519 *
2520 * This function indicates the Mic failure to the supplicant
2521 *
2522 * Return: CDF_STATUS enumeration
2523 */
2524static CDF_STATUS
2525hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2526 tCsrRoamInfo *pRoamInfo,
2527 uint32_t roamId,
2528 eRoamCmdStatus roamStatus,
2529 eCsrRoamResult roamResult)
2530{
2531 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2532
2533 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2534 TKIP_COUNTER_MEASURE_STOPED ==
2535 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2536 struct iw_michaelmicfailure msg;
2537 union iwreq_data wreq;
2538 memset(&msg, '\0', sizeof(msg));
2539 msg.src_addr.sa_family = ARPHRD_ETHER;
2540 memcpy(msg.src_addr.sa_data,
2541 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2542 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2543 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2544 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2545
2546 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2547 msg.flags = IW_MICFAILURE_GROUP;
2548 else
2549 msg.flags = IW_MICFAILURE_PAIRWISE;
2550 memset(&wreq, 0, sizeof(wreq));
2551 wreq.data.length = sizeof(msg);
2552 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2553 (char *)&msg);
2554 /* inform mic failure to nl80211 */
2555 cfg80211_michael_mic_failure(pAdapter->dev,
2556 pRoamInfo->u.pMICFailureInfo->
2557 taMacAddr,
2558 ((pRoamInfo->u.pMICFailureInfo->
2559 multicast ==
2560 eSIR_TRUE) ?
2561 NL80211_KEYTYPE_GROUP :
2562 NL80211_KEYTYPE_PAIRWISE),
2563 pRoamInfo->u.pMICFailureInfo->
2564 keyId,
2565 pRoamInfo->u.pMICFailureInfo->TSC,
2566 GFP_KERNEL);
2567
2568 }
2569
2570 return CDF_STATUS_SUCCESS;
2571}
2572
2573/**
2574 * roam_roam_connect_status_update_handler() - IBSS connect status update
2575 * @pAdapter: pointer to adapter
2576 * @pRoamInfo: pointer to roam info
2577 * @roamId: roam id
2578 * @roamStatus: roam status
2579 * @roamResult: roam result
2580 *
2581 * The Ibss connection status is updated regularly here in this function.
2582 *
2583 * Return: CDF_STATUS enumeration
2584 */
2585static CDF_STATUS
2586roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2587 tCsrRoamInfo *pRoamInfo,
2588 uint32_t roamId,
2589 eRoamCmdStatus roamStatus,
2590 eCsrRoamResult roamResult)
2591{
2592 CDF_STATUS cdf_status;
2593
2594 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2595 switch (roamResult) {
2596 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2597 {
2598 hdd_station_ctx_t *pHddStaCtx =
2599 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2600 struct station_info staInfo;
2601
2602 pr_info("IBSS New Peer indication from SME "
2603 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2604 MAC_ADDRESS_STR " and stationID= %d",
2605 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2606 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2607 pRoamInfo->staId);
2608
2609 if (!roam_save_ibss_station
2610 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2611 pRoamInfo->staId,
2612 &pRoamInfo->peerMac)) {
2613 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2614 break;
2615 }
2616
2617 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2618
2619 pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] =
2620 pAdapter;
2621
2622 /* Register the Station with TL for the new peer. */
2623 cdf_status = hdd_roam_register_sta(pAdapter,
2624 pRoamInfo,
2625 pRoamInfo->staId,
2626 &pRoamInfo->peerMac,
2627 pRoamInfo->pBssDesc);
2628 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2629 hddLog(LOGE,
2630 "Cannot register STA with TL for IBSS. Failed with cdf_status = %d [%08X]",
2631 cdf_status, cdf_status);
2632 }
2633 pHddStaCtx->ibss_sta_generation++;
2634 memset(&staInfo, 0, sizeof(staInfo));
2635 staInfo.filled = 0;
2636 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2637
2638 cfg80211_new_sta(pAdapter->dev,
2639 (const u8 *)pRoamInfo->peerMac.bytes,
2640 &staInfo, GFP_KERNEL);
2641
2642 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2643 pHddStaCtx->ibss_enc_key.encType
2644 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2645 pHddStaCtx->ibss_enc_key.encType
2646 || eCSR_ENCRYPT_TYPE_TKIP ==
2647 pHddStaCtx->ibss_enc_key.encType
2648 || eCSR_ENCRYPT_TYPE_AES ==
2649 pHddStaCtx->ibss_enc_key.encType) {
2650 pHddStaCtx->ibss_enc_key.keyDirection =
2651 eSIR_TX_RX;
2652 cdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
2653 &pRoamInfo->peerMac);
2654
2655 hddLog(LOG2, "New peer joined set PTK encType=%d",
2656 pHddStaCtx->ibss_enc_key.encType);
2657
2658 cdf_status =
2659 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2660 (pAdapter),
2661 pAdapter->sessionId,
2662 &pHddStaCtx->ibss_enc_key,
2663 &roamId);
2664
2665 if (CDF_STATUS_SUCCESS != cdf_status) {
2666 hddLog(LOGE,
2667 FL("sme_roam_set_key failed, status=%d"),
2668 cdf_status);
2669 return CDF_STATUS_E_FAILURE;
2670 }
2671 }
2672 hddLog(LOG1, FL("Enabling queues"));
2673 wlan_hdd_netif_queue_control(pAdapter,
2674 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2675 WLAN_CONTROL_PATH);
2676 break;
2677 }
2678
2679 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2680 {
2681
2682 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2683
2684 break;
2685 }
2686 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2687 {
2688 hdd_station_ctx_t *pHddStaCtx =
2689 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2690
2691 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2692 hddLog(LOGW,
2693 "IBSS peer departed by cannot find peer in our registration table with TL");
2694
2695 pr_info("IBSS Peer Departed from SME "
2696 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2697 MAC_ADDRESS_STR " and stationID= %d",
2698 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2699 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2700 pRoamInfo->staId);
2701
2702 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2703
2704 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2705 pHddStaCtx->ibss_sta_generation++;
2706
2707 cfg80211_del_sta(pAdapter->dev,
2708 (const u8 *)&pRoamInfo->peerMac.bytes,
2709 GFP_KERNEL);
2710 break;
2711 }
2712 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2713 {
2714 hddLog(LOG3,
2715 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2716 /* Stop only when we are inactive */
2717 hddLog(LOG1, FL("Disabling queues"));
2718 wlan_hdd_netif_queue_control(pAdapter,
2719 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2720 WLAN_CONTROL_PATH);
2721 hddLog(LOG1,
2722 FL("Set HDD connState to eConnectionState_NotConnected"));
2723 hdd_conn_set_connection_state(pAdapter,
2724 eConnectionState_NotConnected);
2725
2726 /* Send the bssid address to the wext. */
2727 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2728 break;
2729 }
2730 default:
2731 break;
2732
2733 }
2734
2735 return CDF_STATUS_SUCCESS;
2736}
2737
2738#ifdef FEATURE_WLAN_TDLS
2739/**
2740 * hdd_roam_register_tdlssta() - register new TDLS station
2741 * @pAdapter: pointer to adapter
2742 * @peerMac: pointer to peer MAC address
2743 * @staId: station identifier
2744 * @ucastSig: unicast signature
2745 *
2746 * Construct the staDesc and register with TL the new STA.
2747 * This is called as part of ADD_STA in the TDLS setup.
2748 *
2749 * Return: CDF_STATUS enumeration
2750 */
2751CDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
2752 const uint8_t *peerMac, uint16_t staId,
2753 uint8_t ucastSig)
2754{
2755 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
2756 struct ol_txrx_desc_type staDesc = { 0 };
2757
2758 /*
2759 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2760 * be peer MAC, here we are working on direct Link
2761 */
2762 staDesc.sta_id = staId;
2763
2764 /* set the QoS field appropriately .. */
2765 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2766 : (staDesc.is_qos_enabled = 0);
2767
2768
2769 /* Register the Station with TL... */
2770 cdf_status = ol_txrx_register_peer(hdd_rx_packet_cbk,
2771 &staDesc);
2772 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2773 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
2774 cdf_status, cdf_status);
2775 return cdf_status;
2776 }
2777
2778 return cdf_status;
2779}
2780
2781/**
2782 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2783 * @pAdapter: pointer to adapter
2784 * @staId: station identifier
2785 *
2786 * Return: CDF_STATUS enumeration
2787 */
2788static CDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
2789 uint8_t staId)
2790{
2791 CDF_STATUS cdf_status;
2792 cdf_status = ol_txrx_clear_peer(staId);
2793 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2794 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
2795 staId, cdf_status, cdf_status);
2796 }
2797 return cdf_status;
2798}
2799
2800/**
2801 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2802 * @pAdapter: pointer to adapter
2803 * @pRoamInfo: pointer to roam info
2804 * @roamId: roam id
2805 * @roamStatus: roam status
2806 * @roamResult: roam result
2807 *
2808 * HDD interface between SME and TL to ensure TDLS client registration with
2809 * TL in case of new TDLS client is added and deregistration at the time
2810 * TDLS client is deleted.
2811 *
2812 * Return: CDF_STATUS enumeration
2813 */
2814static CDF_STATUS
2815hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
2816 tCsrRoamInfo *pRoamInfo,
2817 uint32_t roamId,
2818 eRoamCmdStatus roamStatus,
2819 eCsrRoamResult roamResult)
2820{
2821 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2822 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2823 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
2824 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2825 uint8_t staIdx;
2826 hddTdlsPeer_t *curr_peer;
2827 uint32_t reason;
2828
2829 hddLog(LOG2,
2830 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
2831 roamResult ==
2832 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
2833 ==
2834 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
2835 roamResult ==
2836 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
2837 : roamResult ==
2838 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
2839 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
2840 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
2841 roamResult ==
2842 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
2843 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
2844 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
2845 : roamResult ==
2846 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
2847 : roamResult ==
2848 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
2849 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
2850 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
2851
2852 if (!pHddTdlsCtx) {
2853 hddLog(LOG1,
2854 FL("TDLS ctx is null, ignore roamResult (%d)"),
2855 roamResult);
2856 return status;
2857 }
2858
2859 switch (roamResult) {
2860 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
2861 {
2862 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2863 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
2864 pRoamInfo->statusCode);
2865 } else {
2866 /*
2867 * Check if there is available index for this new TDLS
2868 * STA.
2869 */
2870 for (staIdx = 0;
2871 staIdx < pHddCtx->max_num_tdls_sta;
2872 staIdx++) {
2873 if (0 ==
2874 pHddCtx->tdlsConnInfo[staIdx].
2875 staId) {
2876 pHddCtx->tdlsConnInfo[staIdx].
2877 sessionId =
2878 pRoamInfo->sessionId;
2879 pHddCtx->tdlsConnInfo[staIdx].
2880 staId = pRoamInfo->staId;
2881
2882 hddLog(LOGW,
2883 ("TDLS: STA IDX at %d is %d "
2884 "of mac "
2885 MAC_ADDRESS_STR),
2886 staIdx,
2887 pHddCtx->
2888 tdlsConnInfo[staIdx].
2889 staId,
2890 MAC_ADDR_ARRAY
2891 (pRoamInfo->peerMac.bytes));
2892
2893 cdf_copy_macaddr(&pHddCtx->
2894 tdlsConnInfo
2895 [staIdx].
2896 peerMac,
2897 &pRoamInfo->
2898 peerMac);
2899 status = CDF_STATUS_SUCCESS;
2900 break;
2901 }
2902 }
2903 if (staIdx < pHddCtx->max_num_tdls_sta) {
2904 if (-1 ==
2905 wlan_hdd_tdls_set_sta_id(pAdapter,
2906 pRoamInfo->
2907 peerMac.bytes,
2908 pRoamInfo->
2909 staId)) {
2910 hddLog(LOGE,
2911 "wlan_hdd_tdls_set_sta_id() failed");
2912 return CDF_STATUS_E_FAILURE;
2913 }
2914
2915 (WLAN_HDD_GET_CTX(pAdapter))->
2916 sta_to_adapter[pRoamInfo->staId] =
2917 pAdapter;
2918 /*
2919 * store the ucast signature,
2920 * if required for further reference.
2921 */
2922
2923 wlan_hdd_tdls_set_signature(pAdapter,
2924 pRoamInfo->
2925 peerMac.bytes,
2926 pRoamInfo->
2927 ucastSig);
2928 } else {
2929 status = CDF_STATUS_E_FAILURE;
2930 hddLog(LOGE,
2931 FL("no available slot in conn_info. staId %d cannot be stored"),
2932 pRoamInfo->staId);
2933 }
2934 pAdapter->tdlsAddStaStatus = status;
2935 }
2936 complete(&pAdapter->tdls_add_station_comp);
2937 break;
2938 }
2939 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
2940 {
2941 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2942 hddLog(LOGE,
2943 FL("Add Sta failed. status code(=%d)"),
2944 pRoamInfo->statusCode);
2945 }
2946 /* store the ucast signature which will be used later when
2947 * registering to TL
2948 */
2949 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
2950 complete(&pAdapter->tdls_add_station_comp);
2951 break;
2952 }
2953 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
2954 {
2955 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2956 hddLog(LOGE,
2957 FL("Link Establish Request failed. status(=%d)"),
2958 pRoamInfo->statusCode);
2959 }
2960 complete(&pAdapter->tdls_link_establish_req_comp);
2961 break;
2962 }
2963 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
2964 {
2965 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
2966 staIdx++) {
2967 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
2968 pRoamInfo->sessionId)
2969 && pRoamInfo->staId ==
2970 pHddCtx->tdlsConnInfo[staIdx].staId) {
2971 hddLog(LOGW,
2972 ("HDD: del STA IDX = %x"),
2973 pRoamInfo->staId);
2974
2975 curr_peer =
2976 wlan_hdd_tdls_find_peer(pAdapter,
2977 pRoamInfo->
2978 peerMac.bytes,
2979 true);
2980 if (NULL != curr_peer
2981 && TDLS_IS_CONNECTED(curr_peer)) {
2982 hdd_roam_deregister_tdlssta
2983 (pAdapter,
2984 pRoamInfo->staId);
2985 wlan_hdd_tdls_decrement_peer_count
2986 (pAdapter);
2987 }
2988 wlan_hdd_tdls_reset_peer(pAdapter,
2989 pRoamInfo->
2990 peerMac.bytes);
2991
2992 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
2993 pHddCtx->tdlsConnInfo[staIdx].
2994 sessionId = 255;
2995 cdf_mem_zero(&pHddCtx->
2996 tdlsConnInfo[staIdx].
2997 peerMac,
2998 CDF_MAC_ADDR_SIZE);
2999 status = CDF_STATUS_SUCCESS;
3000 break;
3001 }
3002 }
3003 complete(&pAdapter->tdls_del_station_comp);
3004 }
3005 break;
3006 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3007 {
3008 hddLog(LOGE,
3009 FL("Sending teardown to supplicant with reason code %u"),
3010 pRoamInfo->reasonCode);
3011
3012 curr_peer =
3013 wlan_hdd_tdls_find_peer(pAdapter,
3014 pRoamInfo->peerMac.bytes, true);
3015 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3016 pRoamInfo->reasonCode);
3017 status = CDF_STATUS_SUCCESS;
3018 break;
3019 }
3020 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3021 {
3022 /* 0 staIdx is assigned to AP we dont want to touch that */
3023 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3024 staIdx++) {
3025 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3026 pRoamInfo->sessionId)
3027 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3028 hddLog(LOGW,
3029 ("hdd_tdlsStatusUpdate: staIdx %d "
3030 MAC_ADDRESS_STR),
3031 pHddCtx->tdlsConnInfo[staIdx].
3032 staId,
3033 MAC_ADDR_ARRAY(pHddCtx->
3034 tdlsConnInfo
3035 [staIdx].
3036 peerMac.
3037 bytes));
3038 wlan_hdd_tdls_reset_peer(pAdapter,
3039 pHddCtx->
3040 tdlsConnInfo
3041 [staIdx].
3042 peerMac.bytes);
3043 hdd_roam_deregister_tdlssta(pAdapter,
3044 pHddCtx->
3045 tdlsConnInfo
3046 [staIdx].
3047 staId);
3048 cdf_mem_zero(&smeTdlsPeerStateParams,
3049 sizeof
3050 (smeTdlsPeerStateParams));
3051 smeTdlsPeerStateParams.vdevId =
3052 pHddCtx->tdlsConnInfo[staIdx].
3053 sessionId;
3054 cdf_mem_copy(&smeTdlsPeerStateParams.
3055 peerMacAddr,
3056 &pHddCtx->
3057 tdlsConnInfo[staIdx].
3058 peerMac.bytes,
3059 CDF_MAC_ADDR_SIZE);
3060 smeTdlsPeerStateParams.peerState =
3061 eSME_TDLS_PEER_STATE_TEARDOWN;
3062
3063 hddLog(LOG1,
3064 FL("calling sme_update_tdls_peer_state for staIdx %d "
3065 MAC_ADDRESS_STR),
3066 pHddCtx->tdlsConnInfo[staIdx].
3067 staId,
3068 MAC_ADDR_ARRAY(pHddCtx->
3069 tdlsConnInfo
3070 [staIdx].
3071 peerMac.
3072 bytes));
3073 status =
3074 sme_update_tdls_peer_state(
3075 pHddCtx->hHal,
3076 &smeTdlsPeerStateParams);
3077 if (CDF_STATUS_SUCCESS != status) {
3078 hddLog(LOGE,
3079 FL("sme_update_tdls_peer_state failed for "
3080 MAC_ADDRESS_STR),
3081 MAC_ADDR_ARRAY
3082 (pHddCtx->
3083 tdlsConnInfo[staIdx].
3084 peerMac.bytes));
3085 }
3086 wlan_hdd_tdls_decrement_peer_count
3087 (pAdapter);
3088
3089 cdf_mem_zero(&pHddCtx->
3090 tdlsConnInfo[staIdx].
3091 peerMac,
3092 CDF_MAC_ADDR_SIZE);
3093 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3094 pHddCtx->tdlsConnInfo[staIdx].
3095 sessionId = 255;
3096
3097 status = CDF_STATUS_SUCCESS;
3098 }
3099 }
3100 break;
3101 }
3102 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3103 {
3104 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
3105 if (((1 << CDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3106 (pHddCtx->no_of_active_sessions[CDF_STA_MODE] > 1)) {
3107 hddLog(LOG2,
3108 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3109 pHddCtx->concurrency_mode,
3110 pHddCtx->no_of_active_sessions[CDF_STA_MODE]);
3111 status = CDF_STATUS_E_FAILURE;
3112 break;
3113 }
3114
3115 curr_peer =
3116 wlan_hdd_tdls_get_peer(pAdapter,
3117 pRoamInfo->peerMac.bytes);
3118 if (!curr_peer) {
3119 hddLog(LOGE, FL("curr_peer is null"));
3120 status = CDF_STATUS_E_FAILURE;
3121 } else {
3122 if (eTDLS_LINK_CONNECTED ==
3123 curr_peer->link_status) {
3124 hddLog(LOGE,
3125 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3126 } else {
3127 /*
3128 * If external control is enabled then initiate
3129 * TDLS only if forced peer is set otherwise
3130 * ignore should Discover trigger from fw.
3131 */
3132 if (pHddCtx->config->
3133 fTDLSExternalControl
3134 && (false ==
3135 curr_peer->isForcedPeer)) {
3136 hddLog(LOG2,
3137 FL
3138 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
3139 status = CDF_STATUS_SUCCESS;
3140 break;
3141 } else {
3142 hddLog(LOG2,
3143 FL
3144 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3145 pHddCtx->config->
3146 fTDLSExternalControl,
3147 curr_peer->isForcedPeer,
3148 pRoamInfo->reasonCode);
3149 }
3150 wlan_hdd_tdls_pre_setup_init_work
3151 (pHddTdlsCtx, curr_peer);
3152 }
3153 status = CDF_STATUS_SUCCESS;
3154 }
3155 break;
3156 }
3157
3158 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3159 {
3160 curr_peer =
3161 wlan_hdd_tdls_find_peer(pAdapter,
3162 pRoamInfo->peerMac.bytes, true);
3163 if (!curr_peer) {
3164 hddLog(LOGE, FL("curr_peer is null"));
3165 status = CDF_STATUS_E_FAILURE;
3166 } else {
3167 if (eTDLS_LINK_CONNECTED ==
3168 curr_peer->link_status) {
3169 hddLog(LOGE,
3170 FL
3171 ("Received SHOULD_TEARDOWN for peer "
3172 MAC_ADDRESS_STR
3173 " staId: %d, reason: %d"),
3174 MAC_ADDR_ARRAY(pRoamInfo->
3175 peerMac.bytes),
3176 pRoamInfo->staId,
3177 pRoamInfo->reasonCode);
3178
3179 if (pRoamInfo->reasonCode ==
3180 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3181 pRoamInfo->reasonCode ==
3182 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3183 pRoamInfo->reasonCode ==
3184 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3185 pRoamInfo->reasonCode ==
3186 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3187 reason =
3188 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3189 } else
3190 reason =
3191 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3192
3193 wlan_hdd_tdls_indicate_teardown
3194 (pHddTdlsCtx->pAdapter, curr_peer,
3195 reason);
3196 } else {
3197 hddLog(LOGE,
3198 FL
3199 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3200 pRoamInfo->reasonCode);
3201 }
3202 status = CDF_STATUS_SUCCESS;
3203 }
3204 break;
3205 }
3206
3207 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3208 {
3209 curr_peer =
3210 wlan_hdd_tdls_find_peer(pAdapter,
3211 pRoamInfo->peerMac.bytes, true);
3212 if (!curr_peer) {
3213 hddLog(LOGE, FL("curr_peer is null"));
3214 status = CDF_STATUS_E_FAILURE;
3215 } else {
3216 if (eTDLS_LINK_CONNECTED ==
3217 curr_peer->link_status) {
3218 hddLog(LOGE,
3219 FL
3220 ("Received SHOULD_PEER_DISCONNECTED for peer "
3221 MAC_ADDRESS_STR
3222 " staId: %d, reason: %d"),
3223 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3224 pRoamInfo->staId,
3225 pRoamInfo->reasonCode);
3226
3227 if (pRoamInfo->reasonCode ==
3228 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3229 pRoamInfo->reasonCode ==
3230 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3231 pRoamInfo->reasonCode ==
3232 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3233 pRoamInfo->reasonCode ==
3234 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3235 reason =
3236 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3237 } else
3238 reason =
3239 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3240
3241 wlan_hdd_tdls_indicate_teardown
3242 (pHddTdlsCtx->pAdapter, curr_peer,
3243 reason);
3244 } else {
3245 hddLog(LOGE,
3246 FL
3247 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3248 pRoamInfo->reasonCode);
3249 }
3250 status = CDF_STATUS_SUCCESS;
3251 }
3252 break;
3253 }
3254 default:
3255 {
3256 break;
3257 }
3258 }
3259
3260 return status;
3261}
3262#endif
3263
3264#ifdef WLAN_FEATURE_11W
3265/**
3266 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3267 * @pAdapter: pointer to the adapter
3268 * @nFrameLength: Length of the unprotected frame being passed
3269 * @pbFrames: Pointer to the frame buffer
3270 * @frameType: 802.11 frame type
3271 *
3272 * This function forwards the unprotected management frame to the supplicant.
3273 *
3274 * Return: nothing
3275 */
3276static void
3277hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3278 uint8_t *pbFrames, uint8_t frameType)
3279{
3280 uint8_t type = 0;
3281 uint8_t subType = 0;
3282
3283 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3284 frameType, nFrameLength);
3285
3286 /* Sanity Checks */
3287 if (NULL == pAdapter) {
3288 hddLog(LOGE, FL("pAdapter is NULL"));
3289 return;
3290 }
3291
3292 if (NULL == pAdapter->dev) {
3293 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3294 return;
3295 }
3296
3297 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3298 hddLog(LOGE, FL("pAdapter has invalid magic"));
3299 return;
3300 }
3301
3302 if (!nFrameLength) {
3303 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3304 return;
3305 }
3306
3307 if (NULL == pbFrames) {
3308 hddLog(LOGE, FL("pbFrames is NULL"));
3309 return;
3310 }
3311
3312 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3313 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3314
3315 /* Get pAdapter from Destination mac address of the frame */
3316 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3318 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3319 nFrameLength);
3320#else
3321 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3322 nFrameLength);
3323#endif
3324 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3325 } else if (type == SIR_MAC_MGMT_FRAME &&
3326 subType == SIR_MAC_MGMT_DEAUTH) {
3327#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3328 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3329 nFrameLength);
3330#else
3331 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3332 nFrameLength);
3333#endif
3334 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3335 } else {
3336 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3337 type, subType);
3338 return;
3339 }
3340}
3341#endif
3342
3343#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
3344/**
3345 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3346 * @pAdapter: pointer to adapter
3347 * @tid: traffic identifier
3348 * @state: state
3349 * @measInterval: measurement interval
3350 *
3351 * This function sends traffic stream metrics IE information to
3352 * the supplicant via wireless event.
3353 *
3354 * Return: none
3355 */
3356static void
3357hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3358 uint8_t state, uint16_t measInterval)
3359{
3360 union iwreq_data wrqu;
3361 char buf[IW_CUSTOM_MAX + 1];
3362 int nBytes = 0;
3363
3364 if (NULL == pAdapter)
3365 return;
3366
3367 /* create the event */
3368 memset(&wrqu, '\0', sizeof(wrqu));
3369 memset(buf, '\0', sizeof(buf));
3370
3371 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3372 tid, state, measInterval);
3373
3374 nBytes =
3375 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3376 measInterval);
3377
3378 wrqu.data.pointer = buf;
3379 wrqu.data.length = nBytes;
3380 /* send the event */
3381 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3382}
3383
3384/**
3385 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3386 * @pAdapter: pointer to adapter
3387 * @pRoamInfo: pointer to roam info
3388 *
3389 * This function sends cckm preauth indication to the supplicant
3390 * via wireless custom event.
3391 *
3392 * Return: none
3393 */
3394static void
3395hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3396{
3397 union iwreq_data wrqu;
3398 char buf[IW_CUSTOM_MAX + 1];
3399 char *pos = buf;
3400 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3401
3402 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3403 return;
3404
3405 /* create the event */
3406 memset(&wrqu, '\0', sizeof(wrqu));
3407 memset(buf, '\0', sizeof(buf));
3408
3409 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3410 hddLog(LOG1,
3411 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3412 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3413 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3414
3415 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3416 pos += nBytes;
3417 freeBytes -= nBytes;
3418
3419 cdf_mem_copy(pos, pRoamInfo->bssid.bytes, CDF_MAC_ADDR_SIZE);
3420 pos += CDF_MAC_ADDR_SIZE;
3421 freeBytes -= CDF_MAC_ADDR_SIZE;
3422
3423 nBytes = snprintf(pos, freeBytes, " %u:%u",
3424 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3425 freeBytes -= nBytes;
3426
3427 wrqu.data.pointer = buf;
3428 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3429
3430 /* send the event */
3431 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3432}
3433
3434/**
3435 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3436 * @pAdapter: pointer to adapter
3437 * @pRoamInfo: pointer to roam info
3438 *
3439 * Return: none
3440 */
3441static void
3442hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3443 tCsrRoamInfo *pRoamInfo)
3444{
3445 union iwreq_data wrqu;
3446 char buf[IW_CUSTOM_MAX + 1];
3447 int nBytes = 0;
3448
3449 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3450 return;
3451
3452 /* create the event */
3453 memset(&wrqu, '\0', sizeof(wrqu));
3454 memset(buf, '\0', sizeof(buf));
3455
3456 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3457
3458 nBytes =
3459 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3460 pRoamInfo->tsmRoamDelay);
3461
3462 wrqu.data.pointer = buf;
3463 wrqu.data.length = nBytes;
3464
3465 /* send the event */
3466 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3467}
3468
3469/**
3470 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3471 * @pAdapter: pointer to adapter
3472 * @measurementToken: measurement token
3473 * @flag: flag
3474 * @numBss: number of bss
3475 *
3476 * If the measurement is none and no scan results found,
3477 * indicate the supplicant about measurement done.
3478 *
3479 * Return: none
3480 */
3481void
3482hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3483 const uint16_t measurementToken,
3484 const bool flag, const uint8_t numBss)
3485{
3486 union iwreq_data wrqu;
3487 char buf[IW_CUSTOM_MAX];
3488 char *pos = buf;
3489 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3490
3491 memset(&wrqu, '\0', sizeof(wrqu));
3492 memset(buf, '\0', sizeof(buf));
3493
3494 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3495 flag, numBss);
3496
3497 nBytes =
3498 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3499 flag, numBss);
3500
3501 wrqu.data.pointer = buf;
3502 wrqu.data.length = nBytes;
3503 /* send the event */
3504 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3505}
3506
3507/**
3508 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3509 * @pAdapter: pointer to adapter
3510 * @pRoamInfo: pointer to roam info
3511 *
3512 * If the measurement is none and no scan results found,
3513 * indicate the supplicant about measurement done.
3514 *
3515 * Return: none
3516 */
3517static void
3518hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3519 const tCsrRoamInfo *pRoamInfo)
3520{
3521 union iwreq_data wrqu;
3522 char buf[IW_CUSTOM_MAX];
3523 char *pos = buf;
3524 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3525 uint8_t i = 0, len = 0;
3526 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3527 uint8_t lastSent = 0, sendBss = 0;
3528 int bcnRepFieldSize =
3529 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3530 bcnReportFields);
3531 uint8_t ieLenByte = 1;
3532 /*
3533 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3534 */
3535#define ESEBCNREPHEADER_LEN (18)
3536
3537 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3538 return;
3539
3540 /*
3541 * Custom event can pass maximum of 256 bytes of data,
3542 * based on the IE len we need to identify how many BSS info can
3543 * be filled in to custom event data.
3544 */
3545 /*
3546 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3547 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3548 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3549 */
3550
3551 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3552 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3553 hddLog(LOG1,
3554 "Measurement Done but no scan results");
3555 /* If the measurement is none and no scan results found,
3556 indicate the supplicant about measurement done */
3557 hdd_indicate_ese_bcn_report_no_results(
3558 pAdapter,
3559 pRoamInfo->pEseBcnReportRsp->
3560 measurementToken,
3561 pRoamInfo->pEseBcnReportRsp->flag,
3562 pRoamInfo->pEseBcnReportRsp->numBss);
3563 } else {
3564 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3565 memset(&wrqu, '\0', sizeof(wrqu));
3566 memset(buf, '\0', sizeof(buf));
3567 tot_bcn_ieLen = 0;
3568 sendBss = 0;
3569 pos = buf;
3570 freeBytes = IW_CUSTOM_MAX;
3571
3572 for (i = lastSent;
3573 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3574 len =
3575 bcnRepFieldSize + ieLenByte +
3576 pRoamInfo->pEseBcnReportRsp->
3577 bcnRepBssInfo[i].ieLen;
3578 if ((len + tot_bcn_ieLen) >
3579 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3580 break;
3581 }
3582 tot_bcn_ieLen += len;
3583 sendBss++;
3584 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3585 i, bcnRepFieldSize, 1,
3586 pRoamInfo->pEseBcnReportRsp->
3587 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3588 }
3589
3590 hddLog(LOG1, "Sending %d BSS Info",
3591 sendBss);
3592 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3593 pRoamInfo->pEseBcnReportRsp->measurementToken,
3594 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3595 tot_bcn_ieLen);
3596
3597 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3598 pRoamInfo->pEseBcnReportRsp->
3599 measurementToken,
3600 pRoamInfo->pEseBcnReportRsp->flag,
3601 sendBss);
3602 pos += nBytes;
3603 freeBytes -= nBytes;
3604
3605 /* Copy total Beacon report data length */
3606 cdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
3607 sizeof(tot_bcn_ieLen));
3608 pos += sizeof(tot_bcn_ieLen);
3609 freeBytes -= sizeof(tot_bcn_ieLen);
3610
3611 for (i = 0; i < sendBss; i++) {
3612 hddLog(LOG1,
3613 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3614 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3615 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3616 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3617 pRoamInfo->pEseBcnReportRsp->
3618 bcnRepBssInfo[i +
3619 lastSent].bcnReportFields.
3620 ChanNum,
3621 pRoamInfo->pEseBcnReportRsp->
3622 bcnRepBssInfo[i +
3623 lastSent].bcnReportFields.
3624 Spare,
3625 pRoamInfo->pEseBcnReportRsp->
3626 bcnRepBssInfo[i +
3627 lastSent].bcnReportFields.
3628 MeasDuration,
3629 pRoamInfo->pEseBcnReportRsp->
3630 bcnRepBssInfo[i +
3631 lastSent].bcnReportFields.
3632 PhyType,
3633 pRoamInfo->pEseBcnReportRsp->
3634 bcnRepBssInfo[i +
3635 lastSent].bcnReportFields.
3636 RecvSigPower,
3637 pRoamInfo->pEseBcnReportRsp->
3638 bcnRepBssInfo[i +
3639 lastSent].bcnReportFields.
3640 ParentTsf,
3641 pRoamInfo->pEseBcnReportRsp->
3642 bcnRepBssInfo[i +
3643 lastSent].bcnReportFields.
3644 TargetTsf[0],
3645 pRoamInfo->pEseBcnReportRsp->
3646 bcnRepBssInfo[i +
3647 lastSent].bcnReportFields.
3648 TargetTsf[1],
3649 pRoamInfo->pEseBcnReportRsp->
3650 bcnRepBssInfo[i +
3651 lastSent].bcnReportFields.
3652 BcnInterval,
3653 pRoamInfo->pEseBcnReportRsp->
3654 bcnRepBssInfo[i +
3655 lastSent].bcnReportFields.
3656 CapabilityInfo,
3657 pRoamInfo->pEseBcnReportRsp->
3658 bcnRepBssInfo[i +
3659 lastSent].bcnReportFields.
3660 Bssid[0],
3661 pRoamInfo->pEseBcnReportRsp->
3662 bcnRepBssInfo[i +
3663 lastSent].bcnReportFields.
3664 Bssid[1],
3665 pRoamInfo->pEseBcnReportRsp->
3666 bcnRepBssInfo[i +
3667 lastSent].bcnReportFields.
3668 Bssid[2],
3669 pRoamInfo->pEseBcnReportRsp->
3670 bcnRepBssInfo[i +
3671 lastSent].bcnReportFields.
3672 Bssid[3],
3673 pRoamInfo->pEseBcnReportRsp->
3674 bcnRepBssInfo[i +
3675 lastSent].bcnReportFields.
3676 Bssid[4],
3677 pRoamInfo->pEseBcnReportRsp->
3678 bcnRepBssInfo[i +
3679 lastSent].bcnReportFields.
3680 Bssid[5]);
3681
3682 /* bcn report fields are copied */
3683 len =
3684 sizeof(pRoamInfo->pEseBcnReportRsp->
3685 bcnRepBssInfo[i +
3686 lastSent].
3687 bcnReportFields);
3688 cdf_mem_copy(pos,
3689 (char *)&pRoamInfo->
3690 pEseBcnReportRsp->bcnRepBssInfo[i +
3691 lastSent].
3692 bcnReportFields, len);
3693 pos += len;
3694 freeBytes -= len;
3695
3696 /* Add 1 byte of ie len */
3697 len =
3698 pRoamInfo->pEseBcnReportRsp->
3699 bcnRepBssInfo[i + lastSent].ieLen;
3700 cdf_mem_copy(pos, (char *)&len, sizeof(len));
3701 pos += sizeof(len);
3702 freeBytes -= sizeof(len);
3703
3704 /* copy IE from scan results */
3705 cdf_mem_copy(pos,
3706 (char *)pRoamInfo->
3707 pEseBcnReportRsp->bcnRepBssInfo[i +
3708 lastSent].
3709 pBuf, len);
3710 pos += len;
3711 freeBytes -= len;
3712 }
3713
3714 wrqu.data.pointer = buf;
3715 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3716
3717 /* send the event */
3718 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3719 buf);
3720 lastSent += sendBss;
3721 }
3722 }
3723}
3724
3725#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
3726
3727/**
3728 * hdd_sme_roam_callback() - hdd sme roam callback
3729 * @pContext: pointer to adapter context
3730 * @pRoamInfo: pointer to roam info
3731 * @roamId: roam id
3732 * @roamStatus: roam status
3733 * @roamResult: roam result
3734 *
3735 * Return: CDF_STATUS enumeration
3736 */
3737CDF_STATUS
3738hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3739 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3740{
3741 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
3742 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3743 hdd_wext_state_t *pWextState = NULL;
3744 hdd_station_ctx_t *pHddStaCtx = NULL;
3745 CDF_STATUS status = CDF_STATUS_SUCCESS;
3746 hdd_context_t *pHddCtx = NULL;
3747
3748 hddLog(LOG2,
3749 "CSR Callback: status= %d result= %d roamID=%d",
3750 roamStatus, roamResult, roamId);
3751
3752 /* Sanity check */
3753 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3754 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
3755 return CDF_STATUS_E_FAILURE;
3756 }
3757
3758 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3759 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3760
3761 switch (roamStatus) {
3762 case eCSR_ROAM_SESSION_OPENED:
3763 if (pAdapter != NULL) {
3764 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3765 complete(&pAdapter->session_open_comp_var);
3766 }
3767 break;
3768
3769#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3770defined(FEATURE_WLAN_LFR)
3771 /*
3772 * We did pre-auth,then we attempted a 11r or ese reassoc.
3773 * reassoc failed due to failure, timeout, reject from ap
3774 * in any case tell the OS, our carrier is off and mark
3775 * interface down.
3776 */
3777 case eCSR_ROAM_FT_REASSOC_FAILED:
3778 hddLog(LOGE,
3779 FL
3780 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3781 roamStatus, roamResult, pAdapter->sessionId);
3782 cdf_ret_status =
3783 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3784 roamStatus, roamResult);
3785 /*
3786 * Check if Mcast/Bcast Filters are set, if yes
3787 * clear the filters here.
3788 */
3789 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
3790 true) {
3791 (WLAN_HDD_GET_CTX(pAdapter))->
3792 hdd_mcastbcast_filter_set = false;
3793 }
3794 pHddStaCtx->ft_carrier_on = false;
3795 pHddStaCtx->hdd_ReassocScenario = false;
3796 hddLog(LOG1,
3797 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
3798 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3799 break;
3800
3801 case eCSR_ROAM_FT_START:
3802 /*
3803 * When we roam for ESE and 11r, we dont want the OS to be
3804 * informed that the link is down. So mark the link ready for
3805 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
3806 * be received. Where in we will not mark the link down
3807 * Also we want to stop tx at this point when we will be
3808 * doing disassoc at this time. This saves 30-60 msec
3809 * after reassoc.
3810 */
3811 {
3812 hddLog(LOG1, FL("Disabling queues"));
3813 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
3814 WLAN_CONTROL_PATH);
3815 status =
3816 hdd_roam_deregister_sta(pAdapter,
3817 pHddStaCtx->conn_info.
3818 staId[0]);
3819 if (!CDF_IS_STATUS_SUCCESS(status)) {
3820 hddLog(LOGW,
3821 FL
3822 ("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
3823 pHddStaCtx->conn_info.staId[0],
3824 status, status);
3825 cdf_ret_status = CDF_STATUS_E_FAILURE;
3826 }
3827 }
3828 pHddStaCtx->ft_carrier_on = true;
3829 pHddStaCtx->hdd_ReassocScenario = true;
3830 hddLog(LOG1,
3831 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
3832 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3833 break;
3834#endif
3835
3836 case eCSR_ROAM_SHOULD_ROAM:
3837 /* Dont need to do anything */
3838 {
3839 hdd_station_ctx_t *pHddStaCtx =
3840 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3841 /* notify apps that we can't pass traffic anymore */
3842 hddLog(LOG1, FL("Disabling queues"));
3843 wlan_hdd_netif_queue_control(pAdapter,
3844 WLAN_NETIF_TX_DISABLE,
3845 WLAN_CONTROL_PATH);
3846#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3847defined(FEATURE_WLAN_LFR)
3848 if (pHddStaCtx->ft_carrier_on == false) {
3849#endif
3850 wlan_hdd_netif_queue_control(pAdapter,
3851 WLAN_NETIF_CARRIER_OFF,
3852 WLAN_CONTROL_PATH);
3853#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3854defined(FEATURE_WLAN_LFR)
3855 }
3856#endif
3857
3858#if !(defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3859defined(FEATURE_WLAN_LFR))
3860 /*
3861 * We should clear all sta register with TL, for now, only one.
3862 */
3863 status =
3864 hdd_roam_deregister_sta(pAdapter,
3865 pHddStaCtx->conn_info.
3866 staId[0]);
3867 if (!CDF_IS_STATUS_SUCCESS(status)) {
3868 hddLog(LOGW,
3869 FL
3870 ("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
3871 pHddStaCtx->conn_info.staId[0],
3872 status, status);
3873 cdf_ret_status = CDF_STATUS_E_FAILURE;
3874 }
3875#endif
3876 }
3877 break;
3878 case eCSR_ROAM_LOSTLINK:
3879 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
3880 hddLog(LOG2, "Roaming started due to connection lost");
3881 hddLog(LOG1, FL("Disabling queues"));
3882 wlan_hdd_netif_queue_control(pAdapter,
3883 WLAN_NETIF_TX_DISABLE_N_CARRIER,
3884 WLAN_CONTROL_PATH);
3885 break;
3886 }
3887 case eCSR_ROAM_DISASSOCIATED:
3888 {
3889 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
3890 cdf_ret_status =
3891 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3892 roamStatus, roamResult);
3893 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
3894 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3895 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
3896 hdd_conf_mcastbcast_filter(pHddCtx, false);
3897
3898 if (true ==
3899 pHddCtx->sus_res_mcastbcast_filter_valid) {
3900 pHddCtx->configuredMcastBcastFilter =
3901 pHddCtx->sus_res_mcastbcast_filter;
3902 pHddCtx->
3903 sus_res_mcastbcast_filter_valid =
3904 false;
3905 }
3906
3907 hddLog(LOG1,
3908 "offload: disassociation happening, restoring configuredMcastBcastFilter");
3909 hddLog(LOG1,
3910 "McastBcastFilter = %d",
3911 pHddCtx->configuredMcastBcastFilter);
3912 hddLog(LOG1,
3913 "offload: already called mcastbcast filter");
3914 (WLAN_HDD_GET_CTX(pAdapter))->
3915 hdd_mcastbcast_filter_set = false;
3916 }
3917 /* Call to clear any MC Addr List filter applied after
3918 * successful connection.
3919 */
3920 wlan_hdd_set_mc_addr_list(pAdapter, false);
3921 }
3922 break;
3923 case eCSR_ROAM_IBSS_LEAVE:
3924 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
3925 cdf_ret_status =
3926 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3927 roamStatus, roamResult);
3928 break;
3929 case eCSR_ROAM_ASSOCIATION_COMPLETION:
3930 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
3931 /*
3932 * To Do - address probable memory leak with WEP encryption upon
3933 * successful association.
3934 */
3935 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
3936 /* Clear saved connection information in HDD */
3937 hdd_conn_remove_connect_info(
3938 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
3939 }
3940 cdf_ret_status =
3941 hdd_association_completion_handler(pAdapter, pRoamInfo,
3942 roamId, roamStatus,
3943 roamResult);
3944#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3945 if (pRoamInfo)
3946 pRoamInfo->roamSynchInProgress = false;
3947#endif
3948 break;
3949 case eCSR_ROAM_ASSOCIATION_FAILURE:
3950 cdf_ret_status = hdd_association_completion_handler(pAdapter,
3951 pRoamInfo,
3952 roamId,
3953 roamStatus,
3954 roamResult);
3955 break;
3956 case eCSR_ROAM_IBSS_IND:
3957 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
3958 roamStatus, roamResult);
3959 break;
3960
3961 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
3962 cdf_ret_status =
3963 roam_roam_connect_status_update_handler(pAdapter,
3964 pRoamInfo,
3965 roamId,
3966 roamStatus,
3967 roamResult);
3968 break;
3969
3970 case eCSR_ROAM_MIC_ERROR_IND:
3971 cdf_ret_status =
3972 hdd_roam_mic_error_indication_handler(pAdapter,
3973 pRoamInfo,
3974 roamId,
3975 roamStatus,
3976 roamResult);
3977 break;
3978
3979 case eCSR_ROAM_SET_KEY_COMPLETE:
3980 {
3981 cdf_ret_status =
3982 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
3983 roamId, roamStatus,
3984 roamResult);
3985 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
3986 pHddStaCtx->hdd_ReassocScenario = false;
3987 hddLog(LOG1,
3988 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
3989 pHddStaCtx->hdd_ReassocScenario,
3990 pAdapter->sessionId);
3991 }
3992 }
3993#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3994 if (pRoamInfo != NULL)
3995 pRoamInfo->roamSynchInProgress = false;
3996#endif
3997 break;
3998#ifdef WLAN_FEATURE_VOWIFI_11R
3999 case eCSR_ROAM_FT_RESPONSE:
4000 hdd_send_ft_event(pAdapter);
4001 break;
4002#endif
4003#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
4004 case eCSR_ROAM_PMK_NOTIFY:
4005 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType ||
4006 eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
4007 pHddStaCtx->conn_info.authType) {
4008 /* notify the supplicant of a new candidate */
4009 cdf_ret_status =
4010 wlan_hdd_cfg80211_pmksa_candidate_notify(
4011 pAdapter, pRoamInfo, 1, false);
4012 }
4013 break;
4014#endif
4015
4016#ifdef FEATURE_WLAN_LFR_METRICS
4017 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4018 /* This event is to notify pre-auth initiation */
4019 if (CDF_STATUS_SUCCESS !=
4020 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4021 pRoamInfo)) {
4022 cdf_ret_status = CDF_STATUS_E_FAILURE;
4023 }
4024 break;
4025 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4026 /*
4027 * This event will notify pre-auth completion in case of success
4028 */
4029 if (CDF_STATUS_SUCCESS !=
4030 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4031 pRoamInfo, 1)) {
4032 cdf_ret_status = CDF_STATUS_E_FAILURE;
4033 }
4034 break;
4035 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4036 /*
4037 * This event will notify pre-auth completion incase of failure.
4038 */
4039 if (CDF_STATUS_SUCCESS !=
4040 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4041 pRoamInfo, 0)) {
4042 cdf_ret_status = CDF_STATUS_E_FAILURE;
4043 }
4044 break;
4045 case eCSR_ROAM_HANDOVER_SUCCESS:
4046 /* This event is to notify handover success.
4047 It will be only invoked on success */
4048 if (CDF_STATUS_SUCCESS !=
4049 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4050 pRoamInfo)) {
4051 cdf_ret_status = CDF_STATUS_E_FAILURE;
4052 }
4053 break;
4054#endif
4055
4056 case eCSR_ROAM_INDICATE_MGMT_FRAME:
4057 hdd_indicate_mgmt_frame(pAdapter,
4058 pRoamInfo->nFrameLength,
4059 pRoamInfo->pbFrames,
4060 pRoamInfo->frameType,
4061 pRoamInfo->rxChan, pRoamInfo->rxRssi);
4062 break;
4063 case eCSR_ROAM_REMAIN_CHAN_READY:
4064 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4065 break;
4066 case eCSR_ROAM_SEND_ACTION_CNF:
4067 hdd_send_action_cnf(pAdapter,
4068 (roamResult ==
4069 eCSR_ROAM_RESULT_NONE) ? true : false);
4070 break;
4071#ifdef FEATURE_WLAN_TDLS
4072 case eCSR_ROAM_TDLS_STATUS_UPDATE:
4073 cdf_ret_status =
4074 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4075 roamId,
4076 roamStatus,
4077 roamResult);
4078 break;
4079 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4080 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4081 pRoamInfo->reasonCode);
4082 break;
4083#endif
4084#ifdef WLAN_FEATURE_11W
4085 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4086 hdd_indicate_unprot_mgmt_frame(pAdapter,
4087 pRoamInfo->nFrameLength,
4088 pRoamInfo->pbFrames,
4089 pRoamInfo->frameType);
4090 break;
4091#endif
4092#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4093 case eCSR_ROAM_TSM_IE_IND:
4094 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4095 pRoamInfo->tsmIe.state,
4096 pRoamInfo->tsmIe.msmt_interval);
4097 break;
4098
4099 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4100 {
4101 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4102 pHddStaCtx->conn_info.authType
4103 || eCSR_AUTH_TYPE_CCKM_RSN ==
4104 pHddStaCtx->conn_info.authType) {
4105 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4106 }
4107 break;
4108 }
4109
4110 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4111 {
4112 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4113 break;
4114 }
4115
4116 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4117 {
4118 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4119 break;
4120 }
4121#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4122 default:
4123 break;
4124 }
4125 return cdf_ret_status;
4126}
4127
4128/**
4129 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4130 * @auth_suite: auth suite
4131 *
4132 * Return: eCsrAuthType enumeration
4133 */
4134eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4135{
4136 eCsrAuthType auth_type;
4137 /* is the auth type supported? */
4138 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4139 auth_type = eCSR_AUTH_TYPE_RSN;
4140 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4141 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
4142 } else
4143#ifdef WLAN_FEATURE_VOWIFI_11R
4144 if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
4145 /* Check for 11r FT Authentication with PSK */
4146 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4147 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4148 /* Check for 11R FT Authentication with 802.1X */
4149 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4150 } else
4151#endif
4152#ifdef FEATURE_WLAN_ESE
4153 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4154 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4155 } else
4156#endif /* FEATURE_WLAN_ESE */
4157#ifdef WLAN_FEATURE_11W
4158 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4159 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4160 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4161 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4162 } else
4163#endif
4164 {
4165 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4166 }
4167 return auth_type;
4168}
4169
4170/**
4171 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4172 * @auth_suite: auth suite
4173 *
4174 * Return: eCsrAuthType enumeration
4175 */
4176eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4177{
4178 eCsrAuthType auth_type;
4179 /* is the auth type supported? */
4180 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4181 auth_type = eCSR_AUTH_TYPE_WPA;
4182 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4183 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4184 } else
4185#ifdef FEATURE_WLAN_ESE
4186 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4187 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4188 } else
4189#endif /* FEATURE_WLAN_ESE */
4190 {
4191 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4192 }
4193 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4194 return auth_type;
4195}
4196
4197/**
4198 * hdd_translate_rsn_to_csr_encryption_type() -
4199 * Translate RSN to CSR encryption type
4200 * @cipher_suite: cipher suite
4201 *
4202 * Return: eCsrEncryptionType enumeration
4203 */
4204eCsrEncryptionType
4205hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4206{
4207 eCsrEncryptionType cipher_type;
4208
4209 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4210 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4211 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4212 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4213 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4214 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4215 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4216 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4217 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4218 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4219 else
4220 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4221
4222 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4223 return cipher_type;
4224}
4225
4226/**
4227 * hdd_translate_wpa_to_csr_encryption_type() -
4228 * Translate WPA to CSR encryption type
4229 * @cipher_suite: cipher suite
4230 *
4231 * Return: eCsrEncryptionType enumeration
4232 */
4233eCsrEncryptionType
4234hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4235{
4236 eCsrEncryptionType cipher_type;
4237
4238 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4239 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4240 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4241 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4242 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4243 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4244 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4245 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4246 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4247 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4248 else
4249 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4250
4251 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4252 return cipher_type;
4253}
4254
4255/**
4256 * hdd_process_genie() - process gen ie
4257 * @pAdapter: pointer to adapter
4258 * @bssid: pointer to mac address
4259 * @pEncryptType: pointer to encryption type
4260 * @mcEncryptType: pointer to multicast encryption type
4261 * @pAuthType: pointer to auth type
4262 *
4263 * Return: 0 on success, error number otherwise
4264 */
4265static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4266 u8 *bssid,
4267 eCsrEncryptionType *pEncryptType,
4268 eCsrEncryptionType *mcEncryptType,
4269 eCsrAuthType *pAuthType,
4270#ifdef WLAN_FEATURE_11W
4271 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4272#endif
4273 uint16_t gen_ie_len, uint8_t *gen_ie)
4274{
4275 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
4276 CDF_STATUS result;
4277 tDot11fIERSN dot11RSNIE;
4278 tDot11fIEWPA dot11WPAIE;
4279 uint32_t i;
4280 uint8_t *pRsnIe;
4281 uint16_t RSNIeLen;
4282 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4283 bool updatePMKCache = false;
4284
4285 /*
4286 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4287 * setting present flag to 0.
4288 */
4289 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4290 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4291
4292 /* Type check */
4293 if (gen_ie[0] == DOT11F_EID_RSN) {
4294 /* Validity checks */
4295 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4296 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4297 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4298 gen_ie_len);
4299 return -EINVAL;
4300 }
4301 /* Skip past the EID byte and length byte */
4302 pRsnIe = gen_ie + 2;
4303 RSNIeLen = gen_ie_len - 2;
4304 /* Unpack the RSN IE */
4305 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4306 pRsnIe, RSNIeLen, &dot11RSNIE);
4307 /* Copy out the encryption and authentication types */
4308 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4309 dot11RSNIE.pwise_cipher_suite_count);
4310 hddLog(LOG1, FL("authentication suite count: %d"),
4311 dot11RSNIE.akm_suite_count);
4312 /*Here we have followed the apple base code,
4313 but probably I suspect we can do something different */
4314 /* dot11RSNIE.akm_suite_count */
4315 /* Just translate the FIRST one */
4316 *pAuthType =
4317 hdd_translate_rsn_to_csr_auth_type(
4318 dot11RSNIE.akm_suites[0]);
4319 /* dot11RSNIE.pwise_cipher_suite_count */
4320 *pEncryptType =
4321 hdd_translate_rsn_to_csr_encryption_type(
4322 dot11RSNIE.pwise_cipher_suites[0]);
4323 /* dot11RSNIE.gp_cipher_suite_count */
4324 *mcEncryptType =
4325 hdd_translate_rsn_to_csr_encryption_type(
4326 dot11RSNIE.gp_cipher_suite);
4327#ifdef WLAN_FEATURE_11W
4328 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4329 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4330#endif
4331 /* Set the PMKSA ID Cache for this interface */
4332 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4333 if (is_zero_ether_addr(bssid)) {
4334 hddLog(LOGE, FL("MAC address is all zeroes"));
4335 break;
4336 }
4337 updatePMKCache = true;
4338 /*
4339 * For right now, I assume setASSOCIATE() has passed
4340 * in the bssid.
4341 */
4342 cdf_mem_copy(PMKIDCache[i].BSSID.bytes,
4343 bssid, ETHER_ADDR_LEN);
4344 cdf_mem_copy(PMKIDCache[i].PMKID,
4345 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4346 }
4347
4348 if (updatePMKCache) {
4349 /*
4350 * Calling csr_roam_set_pmkid_cache to configure the
4351 * PMKIDs into the cache.
4352 */
4353 hddLog(LOG1,
4354 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4355 i);
4356 /* Finally set the PMKSA ID Cache in CSR */
4357 result =
4358 sme_roam_set_pmkid_cache(halHandle,
4359 pAdapter->sessionId,
4360 PMKIDCache,
4361 dot11RSNIE.pmkid_count,
4362 false);
4363 }
4364 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4365 /* Validity checks */
4366 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4367 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4368 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4369 gen_ie_len);
4370 return -EINVAL;
4371 }
4372 /* Skip past the EID and length byte - and four byte WiFi OUI */
4373 pRsnIe = gen_ie + 2 + 4;
4374 RSNIeLen = gen_ie_len - (2 + 4);
4375 /* Unpack the WPA IE */
4376 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4377 pRsnIe, RSNIeLen, &dot11WPAIE);
4378 /* Copy out the encryption and authentication types */
4379 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4380 dot11WPAIE.unicast_cipher_count);
4381 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4382 dot11WPAIE.auth_suite_count);
4383 /* dot11WPAIE.auth_suite_count */
4384 /* Just translate the FIRST one */
4385 *pAuthType =
4386 hdd_translate_wpa_to_csr_auth_type(
4387 dot11WPAIE.auth_suites[0]);
4388 /* dot11WPAIE.unicast_cipher_count */
4389 *pEncryptType =
4390 hdd_translate_wpa_to_csr_encryption_type(
4391 dot11WPAIE.unicast_ciphers[0]);
4392 /* dot11WPAIE.unicast_cipher_count */
4393 *mcEncryptType =
4394 hdd_translate_wpa_to_csr_encryption_type(
4395 dot11WPAIE.multicast_cipher);
4396 } else {
4397 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4398 return -EINVAL;
4399 }
4400 return 0;
4401}
4402
4403/**
4404 * hdd_set_genie_to_csr() - set genie to csr
4405 * @pAdapter: pointer to adapter
4406 * @RSNAuthType: pointer to auth type
4407 *
4408 * Return: 0 on success, error number otherwise
4409 */
4410int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4411{
4412 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4413 uint32_t status = 0;
4414 eCsrEncryptionType RSNEncryptType;
4415 eCsrEncryptionType mcRSNEncryptType;
4416#ifdef WLAN_FEATURE_11W
4417 uint8_t RSNMfpRequired = 0;
4418 uint8_t RSNMfpCapable = 0;
4419#endif
4420 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4421 /* MAC address of assoc peer */
4422 /* But, this routine is only called when we are NOT associated. */
4423 cdf_mem_copy(bssid,
4424 pWextState->roamProfile.BSSIDs.bssid,
4425 sizeof(bssid));
4426 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4427 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4428 /* continue */
4429 } else {
4430 return 0;
4431 }
4432 /* The actual processing may eventually be more extensive than this. */
4433 /* Right now, just consume any PMKIDs that are sent in by the app. */
4434 status = hdd_process_genie(pAdapter, bssid,
4435 &RSNEncryptType,
4436 &mcRSNEncryptType, RSNAuthType,
4437#ifdef WLAN_FEATURE_11W
4438 &RSNMfpRequired, &RSNMfpCapable,
4439#endif
4440 pWextState->WPARSNIE[1] + 2,
4441 pWextState->WPARSNIE);
4442 if (status == 0) {
4443 /*
4444 * Now copy over all the security attributes
4445 * you have parsed out.
4446 */
4447 pWextState->roamProfile.EncryptionType.numEntries = 1;
4448 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4449
4450 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4451 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4452 mcRSNEncryptType;
4453
4454 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
4455 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4456 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4457 /*
4458 * For wpa none supplicant sends the WPA IE with unicast
4459 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4460 * multicast cipher as either AES/TKIP based on group
4461 * cipher configuration mentioned in the
4462 * wpa_supplicant.conf.
4463 */
4464
4465 /* Set the unicast cipher same as multicast cipher */
4466 pWextState->roamProfile.EncryptionType.encryptionType[0]
4467 = mcRSNEncryptType;
4468 }
4469#ifdef WLAN_FEATURE_11W
4470 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4471 RSNMfpRequired, RSNMfpCapable);
4472 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4473 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4474#endif
4475 hddLog(LOG1,
4476 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4477 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4478 }
4479 return 0;
4480}
4481
4482/**
4483 * hdd_set_csr_auth_type() - set csr auth type
4484 * @pAdapter: pointer to adapter
4485 * @RSNAuthType: auth type
4486 *
4487 * Return: 0 on success, error number otherwise
4488 */
4489int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4490{
4491 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4492 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4493 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4494 ENTER();
4495
4496 pRoamProfile->AuthType.numEntries = 1;
4497 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4498 pHddStaCtx->conn_info.authType);
4499
4500 switch (pHddStaCtx->conn_info.authType) {
4501 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4502#ifdef FEATURE_WLAN_ESE
4503 case eCSR_AUTH_TYPE_CCKM_WPA:
4504 case eCSR_AUTH_TYPE_CCKM_RSN:
4505#endif
4506 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4507
4508 pRoamProfile->AuthType.authType[0] =
4509 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4510 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4511
4512#ifdef FEATURE_WLAN_ESE
4513 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4514 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4515 == IW_AUTH_KEY_MGMT_802_1X)) {
4516 hddLog(LOG1,
4517 FL("set authType to CCKM WPA. AKM also 802.1X."));
4518 pRoamProfile->AuthType.authType[0] =
4519 eCSR_AUTH_TYPE_CCKM_WPA;
4520 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4521 hddLog(LOG1,
4522 FL("Last chance to set authType to CCKM WPA."));
4523 pRoamProfile->AuthType.authType[0] =
4524 eCSR_AUTH_TYPE_CCKM_WPA;
4525 } else
4526#endif
4527 if ((pWextState->
4528 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4529 == IW_AUTH_KEY_MGMT_802_1X) {
4530 pRoamProfile->AuthType.authType[0] =
4531 eCSR_AUTH_TYPE_WPA;
4532 } else
4533 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4534 == IW_AUTH_KEY_MGMT_PSK) {
4535 pRoamProfile->AuthType.authType[0] =
4536 eCSR_AUTH_TYPE_WPA_PSK;
4537 } else {
4538 pRoamProfile->AuthType.authType[0] =
4539 eCSR_AUTH_TYPE_WPA_NONE;
4540 }
4541 }
4542 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4543#ifdef FEATURE_WLAN_ESE
4544 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4545 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4546 == IW_AUTH_KEY_MGMT_802_1X)) {
4547 hddLog(LOG1,
4548 FL("set authType to CCKM RSN. AKM also 802.1X."));
4549 pRoamProfile->AuthType.authType[0] =
4550 eCSR_AUTH_TYPE_CCKM_RSN;
4551 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4552 hddLog(LOG1,
4553 FL("Last chance to set authType to CCKM RSN."));
4554 pRoamProfile->AuthType.authType[0] =
4555 eCSR_AUTH_TYPE_CCKM_RSN;
4556 } else
4557#endif
4558
4559#ifdef WLAN_FEATURE_VOWIFI_11R
4560 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4561 ((pWextState->
4562 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4563 == IW_AUTH_KEY_MGMT_802_1X)) {
4564 pRoamProfile->AuthType.authType[0] =
4565 eCSR_AUTH_TYPE_FT_RSN;
4566 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4567 &&
4568 ((pWextState->
4569 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4570 == IW_AUTH_KEY_MGMT_PSK)) {
4571 pRoamProfile->AuthType.authType[0] =
4572 eCSR_AUTH_TYPE_FT_RSN_PSK;
4573 } else
4574#endif
4575
4576#ifdef WLAN_FEATURE_11W
4577 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4578 pRoamProfile->AuthType.authType[0] =
4579 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4580 } else if (RSNAuthType ==
4581 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4582 pRoamProfile->AuthType.authType[0] =
4583 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4584 } else
4585#endif
4586
4587 if ((pWextState->
4588 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4589 == IW_AUTH_KEY_MGMT_802_1X) {
4590 pRoamProfile->AuthType.authType[0] =
4591 eCSR_AUTH_TYPE_RSN;
4592 } else
4593 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4594 == IW_AUTH_KEY_MGMT_PSK) {
4595 pRoamProfile->AuthType.authType[0] =
4596 eCSR_AUTH_TYPE_RSN_PSK;
4597 } else {
4598 pRoamProfile->AuthType.authType[0] =
4599 eCSR_AUTH_TYPE_UNKNOWN;
4600 }
4601 }
4602 break;
4603
4604 case eCSR_AUTH_TYPE_SHARED_KEY:
4605
4606 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4607 break;
4608 default:
4609
4610#ifdef FEATURE_WLAN_ESE
4611 hddLog(LOG1, FL("In default, unknown auth type."));
4612#endif /* FEATURE_WLAN_ESE */
4613 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4614 break;
4615 }
4616
4617 hddLog(LOG1, FL("Set roam Authtype to %d"),
4618 pWextState->roamProfile.AuthType.authType[0]);
4619
4620 EXIT();
4621 return 0;
4622}
4623
4624/**
4625 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4626 * to the CSR roam profile.
4627 *
4628 * @dev: Pointer to the net device.
4629 * @info: Pointer to the iw_request_info.
4630 * @wrqu: Pointer to the iwreq_data.
4631 * @extra: Pointer to the data.
4632 *
4633 * Return: 0 for success, error number on failure
4634 */
4635static int __iw_set_essid(struct net_device *dev,
4636 struct iw_request_info *info,
4637 union iwreq_data *wrqu, char *extra)
4638{
4639 unsigned long rc;
4640 uint32_t status = 0;
4641 hdd_wext_state_t *pWextState;
4642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4643 hdd_context_t *hdd_ctx;
4644 uint32_t roamId;
4645 tCsrRoamProfile *pRoamProfile;
4646 eMib_dot11DesiredBssType connectedBssType;
4647 eCsrAuthType RSNAuthType;
4648 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4649 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4650 int ret;
4651
4652 ENTER();
4653
4654 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4655 ret = wlan_hdd_validate_context(hdd_ctx);
4656 if (0 != ret)
4657 return ret;
4658
4659 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
4660 pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
4661 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4662 hdd_device_mode_to_string(pAdapter->device_mode),
4663 pAdapter->device_mode);
4664 return -EINVAL;
4665 }
4666
4667 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4668
4669 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4670 hddLog(LOG2, FL("Counter measure is in progress"));
4671 return -EBUSY;
4672 }
4673 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4674 return -EINVAL;
4675
4676 pRoamProfile = &pWextState->roamProfile;
4677 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4678 (eMib_dot11DesiredBssType_independent ==
4679 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
4680 CDF_STATUS cdf_status;
4681
4682 /* Need to issue a disconnect to CSR. */
4683 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4684 cdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
4685 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4686
4687 if (CDF_STATUS_SUCCESS == cdf_status) {
4688 rc = wait_for_completion_timeout(&pAdapter->
4689 disconnect_comp_var,
4690 msecs_to_jiffies
4691 (WLAN_WAIT_TIME_DISCONNECT));
4692 if (!rc)
4693 hddLog(LOGE, FL("Disconnect event timed out"));
4694 }
4695 }
4696
4697 /*
4698 * when cfg80211 defined, wpa_supplicant wext driver uses
4699 * zero-length, null-string ssid for force disconnection.
4700 * after disconnection (if previously connected) and cleaning ssid,
4701 * driver MUST return success.
4702 */
4703 if (0 == wrqu->essid.length)
4704 return 0;
4705
4706 status = hdd_wmm_get_uapsd_mask(pAdapter,
4707 &pWextState->roamProfile.uapsd_mask);
4708 if (CDF_STATUS_SUCCESS != status)
4709 pWextState->roamProfile.uapsd_mask = 0;
4710
4711 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4712
4713 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4714 wrqu->essid.length;
4715
4716 cdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
4717 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
4718 cdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
4719 ssId), extra, wrqu->essid.length);
4720 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4721 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4722
4723 /* set gen ie */
4724 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4725
4726 /* set auth */
4727 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4728 }
4729#ifdef FEATURE_WLAN_WAPI
4730 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4731 if (pAdapter->wapi_info.nWapiMode) {
4732 switch (pAdapter->wapi_info.wapiAuthMode) {
4733 case WAPI_AUTH_MODE_PSK:
4734 {
4735 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4736 pAdapter->wapi_info.wapiAuthMode);
4737 pRoamProfile->AuthType.numEntries = 1;
4738 pRoamProfile->AuthType.authType[0] =
4739 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4740 break;
4741 }
4742 case WAPI_AUTH_MODE_CERT:
4743 {
4744 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4745 pAdapter->wapi_info.wapiAuthMode);
4746 pRoamProfile->AuthType.numEntries = 1;
4747 pRoamProfile->AuthType.authType[0] =
4748 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4749 break;
4750 }
4751 } /* End of switch */
4752 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4753 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4754 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4755 pRoamProfile->EncryptionType.numEntries = 1;
4756 pRoamProfile->EncryptionType.encryptionType[0] =
4757 eCSR_ENCRYPT_TYPE_WPI;
4758 pRoamProfile->mcEncryptionType.numEntries = 1;
4759 pRoamProfile->mcEncryptionType.encryptionType[0] =
4760 eCSR_ENCRYPT_TYPE_WPI;
4761 }
4762 }
4763#endif /* FEATURE_WLAN_WAPI */
4764 /* if previous genIE is not NULL, update AssocIE */
4765 if (0 != pWextState->genIE.length) {
4766 memset(&pWextState->assocAddIE, 0,
4767 sizeof(pWextState->assocAddIE));
4768 memcpy(pWextState->assocAddIE.addIEdata,
4769 pWextState->genIE.addIEdata, pWextState->genIE.length);
4770 pWextState->assocAddIE.length = pWextState->genIE.length;
4771 pWextState->roamProfile.pAddIEAssoc =
4772 pWextState->assocAddIE.addIEdata;
4773 pWextState->roamProfile.nAddIEAssocLength =
4774 pWextState->assocAddIE.length;
4775
4776 /* clear previous genIE after use it */
4777 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4778 }
4779
4780 /*
4781 * Assumes it is not WPS Association by default, except when
4782 * pAddIEAssoc has WPS IE.
4783 */
4784 pWextState->roamProfile.bWPSAssociation = false;
4785
4786 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4787 pWextState->roamProfile.
4788 nAddIEAssocLength))
4789 pWextState->roamProfile.bWPSAssociation = true;
4790
4791 /* Disable auto BMPS entry by PMC until DHCP is done */
4792 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4793 true);
4794
4795 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4796
4797 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4798 hdd_select_cbmode(pAdapter,
4799 (WLAN_HDD_GET_CTX(pAdapter))->config->
4800 AdHocChannel5G);
4801 }
4802 status = sme_roam_connect(hHal, pAdapter->sessionId,
4803 &(pWextState->roamProfile), &roamId);
4804 pRoamProfile->ChannelInfo.ChannelList = NULL;
4805 pRoamProfile->ChannelInfo.numOfChannels = 0;
4806
4807 EXIT();
4808 return status;
4809}
4810
4811/**
4812 * iw_set_essid() - set essid handler function
4813 * @dev: Pointer to the net device.
4814 * @info: Pointer to the iw_request_info.
4815 * @wrqu: Pointer to the iwreq_data.
4816 * @extra: Pointer to the data.
4817 *
4818 * Return: 0 for success, error number on failure
4819 */
4820int iw_set_essid(struct net_device *dev,
4821 struct iw_request_info *info,
4822 union iwreq_data *wrqu, char *extra)
4823{
4824 int ret;
4825
4826 cds_ssr_protect(__func__);
4827 ret = __iw_set_essid(dev, info, wrqu, extra);
4828 cds_ssr_unprotect(__func__);
4829
4830 return ret;
4831}
4832
4833/**
4834 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4835 * @dev: pointer to the net device
4836 * @info: pointer to the iw request info
4837 * @dwrq: pointer to iw_point
4838 * @extra: pointer to the data
4839 *
4840 * Return: 0 on success, error number otherwise
4841 */
4842static int __iw_get_essid(struct net_device *dev,
4843 struct iw_request_info *info,
4844 struct iw_point *dwrq, char *extra)
4845{
4846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4847 hdd_context_t *hdd_ctx;
4848 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4849 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4850 int ret;
4851
4852 ENTER();
4853
4854 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4855 ret = wlan_hdd_validate_context(hdd_ctx);
4856 if (0 != ret)
4857 return ret;
4858
4859 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
4860 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
4861 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
4862 || pHddStaCtx->conn_info.connState ==
4863 eConnectionState_IbssDisconnected)
4864 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
4865 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
4866 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
4867 dwrq->length);
4868 dwrq->flags = 1;
4869 } else {
4870 memset(extra, 0, dwrq->length);
4871 dwrq->length = 0;
4872 dwrq->flags = 0;
4873 }
4874 EXIT();
4875 return 0;
4876}
4877
4878/**
4879 * iw_get_essid() - get essid handler function
4880 * @dev: Pointer to the net device.
4881 * @info: Pointer to the iw_request_info.
4882 * @wrqu: Pointer to the iwreq_data.
4883 * @extra: Pointer to the data.
4884 *
4885 * Return: 0 for success, error number on failure
4886 */
4887int iw_get_essid(struct net_device *dev,
4888 struct iw_request_info *info,
4889 struct iw_point *wrqu, char *extra)
4890{
4891 int ret;
4892
4893 cds_ssr_protect(__func__);
4894 ret = __iw_get_essid(dev, info, wrqu, extra);
4895 cds_ssr_unprotect(__func__);
4896
4897 return ret;
4898}
4899
4900/**
4901 * __iw_set_auth() -
4902 * This function sets the auth type received from the wpa_supplicant
4903 * @dev: pointer to the net device
4904 * @info: pointer to the iw request info
4905 * @wrqu: pointer to iwreq_data
4906 * @extra: pointer to the data
4907 *
4908 * Return: 0 on success, error number otherwise
4909 */
4910static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
4911 union iwreq_data *wrqu, char *extra)
4912{
4913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4914 hdd_context_t *hdd_ctx;
4915 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4916 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4917 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4918 eCsrEncryptionType mcEncryptionType;
4919 eCsrEncryptionType ucEncryptionType;
4920 int ret;
4921
4922 ENTER();
4923
4924 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4925 ret = wlan_hdd_validate_context(hdd_ctx);
4926 if (0 != ret)
4927 return ret;
4928
4929 switch (wrqu->param.flags & IW_AUTH_INDEX) {
4930 case IW_AUTH_WPA_VERSION:
4931 pWextState->wpaVersion = wrqu->param.value;
4932 break;
4933
4934 case IW_AUTH_CIPHER_PAIRWISE:
4935 {
4936 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
4937 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
4938 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
4939 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4940 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
4941 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
4942 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
4943 if ((IW_AUTH_KEY_MGMT_802_1X
4944 ==
4945 (pWextState->
4946 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
4947 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4948 pHddStaCtx->conn_info.authType))
4949 /*Dynamic WEP key */
4950 ucEncryptionType =
4951 eCSR_ENCRYPT_TYPE_WEP40;
4952 else
4953 /*Static WEP key */
4954 ucEncryptionType =
4955 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4956 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
4957 if ((IW_AUTH_KEY_MGMT_802_1X
4958 ==
4959 (pWextState->
4960 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
4961 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4962 pHddStaCtx->conn_info.authType))
4963 /*Dynamic WEP key */
4964 ucEncryptionType =
4965 eCSR_ENCRYPT_TYPE_WEP104;
4966 else
4967 /*Static WEP key */
4968 ucEncryptionType =
4969 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4970 } else {
4971 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
4972 wrqu->param.value);
4973 return -EINVAL;
4974 }
4975
4976 pRoamProfile->EncryptionType.numEntries = 1;
4977 pRoamProfile->EncryptionType.encryptionType[0] =
4978 ucEncryptionType;
4979 }
4980 break;
4981 case IW_AUTH_CIPHER_GROUP:
4982 {
4983 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
4984 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
4985 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
4986 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
4987 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
4988 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
4989 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
4990 if ((IW_AUTH_KEY_MGMT_802_1X
4991 ==
4992 (pWextState->
4993 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
4994 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4995 pHddStaCtx->conn_info.authType))
4996 mcEncryptionType =
4997 eCSR_ENCRYPT_TYPE_WEP40;
4998 else
4999 mcEncryptionType =
5000 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5001 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5002 /* Dynamic WEP keys won't work with shared keys */
5003 if ((IW_AUTH_KEY_MGMT_802_1X
5004 ==
5005 (pWextState->
5006 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5007 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5008 pHddStaCtx->conn_info.authType)) {
5009 mcEncryptionType =
5010 eCSR_ENCRYPT_TYPE_WEP104;
5011 } else {
5012 mcEncryptionType =
5013 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5014 }
5015 } else {
5016 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5017 wrqu->param.value);
5018 return -EINVAL;
5019 }
5020
5021 pRoamProfile->mcEncryptionType.numEntries = 1;
5022 pRoamProfile->mcEncryptionType.encryptionType[0] =
5023 mcEncryptionType;
5024 }
5025 break;
5026
5027 case IW_AUTH_80211_AUTH_ALG:
5028 {
5029 /* Save the auth algo here and set auth type to SME Roam profile
5030 in the iw_set_ap_address */
5031 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5032 pHddStaCtx->conn_info.authType =
5033 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5034
5035 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5036 pHddStaCtx->conn_info.authType =
5037 eCSR_AUTH_TYPE_SHARED_KEY;
5038
5039 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5040 /*Not supported */
5041 pHddStaCtx->conn_info.authType =
5042 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5043 pWextState->roamProfile.AuthType.authType[0] =
5044 pHddStaCtx->conn_info.authType;
5045 }
5046 break;
5047
5048 case IW_AUTH_KEY_MGMT:
5049 {
5050#ifdef FEATURE_WLAN_ESE
5051#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5052 /*Check for CCKM AKM type */
5053 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5054 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5055 /* Set the CCKM bit in authKeyMgmt */
5056 /*
5057 * Right now, this breaks all ref to authKeyMgmt because
5058 * our code doesn't realize it is a "bitfield"
5059 */
5060 pWextState->authKeyMgmt |=
5061 IW_AUTH_KEY_MGMT_CCKM;
5062 /* Set the key management to 802.1X */
5063 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5064 pWextState->isESEConnection = true;
5065 /*
5066 * This is test code. I need to actually KNOW whether
5067 * this is an RSN Assoc or WPA.
5068 */
5069 pWextState->collectedAuthType =
5070 eCSR_AUTH_TYPE_CCKM_RSN;
5071 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5072 /* Save the key management */
5073 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5074 pWextState->collectedAuthType =
5075 eCSR_AUTH_TYPE_RSN;
5076 } else
5077 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5078 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5079 /* Save the key management anyway */
5080 pWextState->authKeyMgmt = wrqu->param.value;
5081 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5082 /* Save the key management */
5083 pWextState->authKeyMgmt |=
5084 IW_AUTH_KEY_MGMT_802_1X;
5085 pWextState->collectedAuthType =
5086 eCSR_AUTH_TYPE_RSN;
5087 }
5088#else
5089 /* Save the key management */
5090 pWextState->authKeyMgmt = wrqu->param.value;
5091#endif /* FEATURE_WLAN_ESE */
5092 }
5093 break;
5094
5095 case IW_AUTH_TKIP_COUNTERMEASURES:
5096 {
5097 if (wrqu->param.value) {
5098 hddLog(LOG2,
5099 "Counter Measure started %d",
5100 wrqu->param.value);
5101 pWextState->mTKIPCounterMeasures =
5102 TKIP_COUNTER_MEASURE_STARTED;
5103 } else {
5104 hddLog(LOG2,
5105 "Counter Measure stopped=%d",
5106 wrqu->param.value);
5107 pWextState->mTKIPCounterMeasures =
5108 TKIP_COUNTER_MEASURE_STOPED;
5109 }
5110 }
5111 break;
5112 case IW_AUTH_DROP_UNENCRYPTED:
5113 case IW_AUTH_WPA_ENABLED:
5114 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5115 case IW_AUTH_ROAMING_CONTROL:
5116 case IW_AUTH_PRIVACY_INVOKED:
5117
5118 default:
5119
5120 hddLog(LOGW, FL("called with unsupported auth type %d"),
5121 wrqu->param.flags & IW_AUTH_INDEX);
5122 break;
5123 }
5124
5125 EXIT();
5126 return 0;
5127}
5128
5129/**
5130 * iw_set_auth() - set auth callback function
5131 * @dev: Pointer to the net device.
5132 * @info: Pointer to the iw_request_info.
5133 * @wrqu: Pointer to the iwreq_data.
5134 * @extra: Pointer to the data.
5135 *
5136 * Return: 0 for success, error number on failure.
5137 */
5138int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5139 union iwreq_data *wrqu, char *extra)
5140{
5141 int ret;
5142
5143 cds_ssr_protect(__func__);
5144 ret = __iw_set_auth(dev, info, wrqu, extra);
5145 cds_ssr_unprotect(__func__);
5146
5147 return ret;
5148}
5149
5150/**
5151 * __iw_get_auth() -
5152 * This function returns the auth type to the wpa_supplicant
5153 * @dev: pointer to the net device
5154 * @info: pointer to the iw request info
5155 * @wrqu: pointer to iwreq_data
5156 * @extra: pointer to the data
5157 *
5158 * Return: 0 on success, error number otherwise
5159 */
5160static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5161 union iwreq_data *wrqu, char *extra)
5162{
5163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5164 hdd_context_t *hdd_ctx;
5165 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5166 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5167 int ret;
5168
5169 ENTER();
5170
5171 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5172 ret = wlan_hdd_validate_context(hdd_ctx);
5173 if (0 != ret)
5174 return ret;
5175
5176 switch (pRoamProfile->negotiatedAuthType) {
5177 case eCSR_AUTH_TYPE_WPA_NONE:
5178 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5179 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5180 break;
5181 case eCSR_AUTH_TYPE_WPA:
5182 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5183 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5184 break;
5185#ifdef WLAN_FEATURE_VOWIFI_11R
5186 case eCSR_AUTH_TYPE_FT_RSN:
5187#endif
5188 case eCSR_AUTH_TYPE_RSN:
5189 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5190 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5191 break;
5192 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5193 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5194 break;
5195 case eCSR_AUTH_TYPE_SHARED_KEY:
5196 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5197 break;
5198 case eCSR_AUTH_TYPE_UNKNOWN:
5199 hddLog(LOG1, FL("called with unknown auth type"));
5200 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5201 break;
5202 case eCSR_AUTH_TYPE_AUTOSWITCH:
5203 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5204 break;
5205 case eCSR_AUTH_TYPE_WPA_PSK:
5206 hddLog(LOG1, FL("called with WPA PSK auth type"));
5207 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5208 return -EIO;
5209#ifdef WLAN_FEATURE_VOWIFI_11R
5210 case eCSR_AUTH_TYPE_FT_RSN_PSK:
5211#endif
5212 case eCSR_AUTH_TYPE_RSN_PSK:
5213#ifdef WLAN_FEATURE_11W
5214 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5215 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5216#endif
5217 hddLog(LOG1, FL("called with RSN PSK auth type"));
5218 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5219 return -EIO;
5220 default:
5221 hddLog(LOGE, FL("called with unknown auth type"));
5222 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5223 return -EIO;
5224 }
5225 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5226 switch (pRoamProfile->negotiatedUCEncryptionType) {
5227 case eCSR_ENCRYPT_TYPE_NONE:
5228 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5229 break;
5230 case eCSR_ENCRYPT_TYPE_WEP40:
5231 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5232 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5233 break;
5234 case eCSR_ENCRYPT_TYPE_TKIP:
5235 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5236 break;
5237 case eCSR_ENCRYPT_TYPE_WEP104:
5238 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5239 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5240 break;
5241 case eCSR_ENCRYPT_TYPE_AES:
5242 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5243 break;
5244 default:
5245 hddLog(LOG1, FL("called with unknown auth type %d"),
5246 pRoamProfile->negotiatedUCEncryptionType);
5247 return -EIO;
5248 }
5249 }
5250
5251 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5252 switch (pRoamProfile->negotiatedMCEncryptionType) {
5253 case eCSR_ENCRYPT_TYPE_NONE:
5254 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5255 break;
5256 case eCSR_ENCRYPT_TYPE_WEP40:
5257 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5258 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5259 break;
5260 case eCSR_ENCRYPT_TYPE_TKIP:
5261 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5262 break;
5263 case eCSR_ENCRYPT_TYPE_WEP104:
5264 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5265 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5266 break;
5267 case eCSR_ENCRYPT_TYPE_AES:
5268 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5269 break;
5270 default:
5271 hddLog(LOG1, FL("called with unknown auth type %d"),
5272 pRoamProfile->negotiatedMCEncryptionType);
5273 return -EIO;
5274 }
5275 }
5276
5277 hddLog(LOG1, FL("called with auth type %d"),
5278 pRoamProfile->AuthType.authType[0]);
5279 EXIT();
5280 return 0;
5281}
5282
5283/**
5284 * iw_get_auth() - get auth callback function
5285 * @dev: Pointer to the net device.
5286 * @info: Pointer to the iw_request_info.
5287 * @wrqu: Pointer to the iwreq_data.
5288 * @extra: Pointer to the data.
5289 *
5290 * Return: 0 for success, error number on failure.
5291 */
5292int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5293 union iwreq_data *wrqu, char *extra)
5294{
5295 int ret;
5296
5297 cds_ssr_protect(__func__);
5298 ret = __iw_get_auth(dev, info, wrqu, extra);
5299 cds_ssr_unprotect(__func__);
5300
5301 return ret;
5302}
5303
5304/**
5305 * __iw_set_ap_address() - set ap address
5306 * @dev: pointer to the net device
5307 * @info: pointer to the iw request info
5308 * @wrqu: pointer to iwreq_data
5309 * @extra: pointer to the data
5310 *
5311 * This function updates the HDD global station context connection info
5312 * BSSID with the MAC address received from the wpa_supplicant.
5313 *
5314 * Return: 0 on success, error number otherwise
5315 */
5316static int __iw_set_ap_address(struct net_device *dev,
5317 struct iw_request_info *info,
5318 union iwreq_data *wrqu, char *extra)
5319{
5320
5321 hdd_adapter_t *adapter;
5322 hdd_context_t *hdd_ctx;
5323 hdd_station_ctx_t *pHddStaCtx =
5324 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5325 uint8_t *pMacAddress = NULL;
5326 int ret;
5327
5328 ENTER();
5329
5330 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5331
5332 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5333 ret = wlan_hdd_validate_context(hdd_ctx);
5334 if (0 != ret)
5335 return ret;
5336
5337 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5338 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
5339 cdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
5340 sizeof(struct cdf_mac_addr));
5341 EXIT();
5342
5343 return 0;
5344}
5345
5346/**
5347 * iw_set_ap_address() - set ap addresses callback function
5348 * @dev: Pointer to the net device.
5349 * @info: Pointer to the iw_request_info.
5350 * @wrqu: Pointer to the iwreq_data.
5351 * @extra: Pointer to the data.
5352 *
5353 * Return: 0 for success, error number on failure.
5354 */
5355int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5356 union iwreq_data *wrqu, char *extra)
5357{
5358 int ret;
5359
5360 cds_ssr_protect(__func__);
5361 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5362 cds_ssr_unprotect(__func__);
5363
5364 return ret;
5365}
5366
5367/**
5368 * __iw_get_ap_address() - get ap address
5369 * @dev: pointer to the net device
5370 * @info: pointer to the iw request info
5371 * @wrqu: pointer to iwreq_data
5372 * @extra: pointer to the data
5373 *
5374 * This function returns currently associated BSSID.
5375 *
5376 * Return: 0 on success, error number otherwise
5377 */
5378static int __iw_get_ap_address(struct net_device *dev,
5379 struct iw_request_info *info,
5380 union iwreq_data *wrqu, char *extra)
5381{
5382 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5383 hdd_context_t *hdd_ctx;
5384 hdd_station_ctx_t *pHddStaCtx =
5385 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5386 int ret;
5387
5388 ENTER();
5389
5390 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5391 ret = wlan_hdd_validate_context(hdd_ctx);
5392 if (0 != ret)
5393 return ret;
5394
5395 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5396 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
5397 cdf_mem_copy(wrqu->ap_addr.sa_data,
5398 pHddStaCtx->conn_info.bssId.bytes,
5399 CDF_MAC_ADDR_SIZE);
5400 } else {
5401 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5402 }
5403 EXIT();
5404 return 0;
5405}
5406
5407/**
5408 * iw_get_ap_address() - get ap addresses callback function
5409 * @dev: Pointer to the net device.
5410 * @info: Pointer to the iw_request_info.
5411 * @wrqu: Pointer to the iwreq_data.
5412 * @extra: Pointer to the data.
5413 *
5414 * Return: 0 for success, error number on failure.
5415 */
5416int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5417 union iwreq_data *wrqu, char *extra)
5418{
5419 int ret;
5420
5421 cds_ssr_protect(__func__);
5422 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5423 cds_ssr_unprotect(__func__);
5424
5425 return ret;
5426}