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