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