blob: 9074f37cae7c9686a89f5269183d7c4fddd4c472 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/** ------------------------------------------------------------------------- *
29 ------------------------------------------------------------------------- *
30
31 \file csr_api_roam.c
32
33 Implementation for the Common Roaming interfaces.
34 ========================================================================== */
35#include "ani_global.h" /* for tpAniSirGlobal */
36#include "wma_types.h"
37#include "wma_if.h" /* for STA_INVALID_IDX. */
38#include "lim_utils.h"
39#include "cds_mq.h"
40#include "csr_inside_api.h"
41#include "sms_debug.h"
42#include "sme_qos_internal.h"
43#include "sme_inside.h"
44#include "host_diag_core_event.h"
45#include "host_diag_core_log.h"
46#include "csr_api.h"
47#include "csr_internal.h"
48#include "cds_reg_service.h"
49#include "mac_trace.h"
50#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
51#include "csr_neighbor_roam.h"
52#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
53#include "cds_regdomain_common.h"
54#include "cds_utils.h"
55#include "sir_types.h"
56#include "cfg_api.h"
57#include "sme_power_save_api.h"
58#include "wma.h"
59#include "cds_concurrency.h"
60
61#define CSR_NUM_IBSS_START_CHANNELS_50 4
62#define CSR_NUM_IBSS_START_CHANNELS_24 3
63/* 5 seconds, for WPA, WPA2, CCKM */
64#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (5 * CDF_MC_TIMER_TO_SEC_UNIT)
65/* 120 seconds, for WPS */
66#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * CDF_MC_TIMER_TO_SEC_UNIT)
67
68/*---------------------------------------------------------------------------
69 OBIWAN recommends [8 10]% : pick 9%
70 ---------------------------------------------------------------------------*/
71#define CSR_VCC_UL_MAC_LOSS_THRESHOLD 9
72/*---------------------------------------------------------------------------
73 OBIWAN recommends -85dBm
74 ---------------------------------------------------------------------------*/
75#define CSR_VCC_RSSI_THRESHOLD 80
76#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD 500 /* ms */
77#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS 2000 /* ms */
78#define CSR_MIN_TL_STAT_QUERY_PERIOD 500 /* ms */
79/* Flag to send/do not send disassoc frame over the air */
80#define CSR_DONT_SEND_DISASSOC_OVER_THE_AIR 1
81#define RSSI_HACK_BMPS (-40)
82#define MAX_CB_VALUE_IN_INI (2)
83
84#define MAX_SOCIAL_CHANNELS 3
85/* Choose the largest possible value that can be accomodates in 8 bit signed */
86/* variable. */
87#define SNR_HACK_BMPS (127)
88
89static bool b_roam_scan_offload_started;
90
91/*--------------------------------------------------------------------------
92 Static Type declarations
93 ------------------------------------------------------------------------*/
94static tCsrRoamSession csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
95
96/*--------------------------------------------------------------------------
97 Type declarations
98 ------------------------------------------------------------------------*/
99#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
100int diag_auth_type_from_csr_type(eCsrAuthType authType)
101{
102 int n = AUTH_OPEN;
103 switch (authType) {
104 case eCSR_AUTH_TYPE_SHARED_KEY:
105 n = AUTH_SHARED;
106 break;
107 case eCSR_AUTH_TYPE_WPA:
108 n = AUTH_WPA_EAP;
109 break;
110 case eCSR_AUTH_TYPE_WPA_PSK:
111 n = AUTH_WPA_PSK;
112 break;
113 case eCSR_AUTH_TYPE_RSN:
114#ifdef WLAN_FEATURE_11W
115 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
116#endif
117 n = AUTH_WPA2_EAP;
118 break;
119 case eCSR_AUTH_TYPE_RSN_PSK:
120#ifdef WLAN_FEATURE_11W
121 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
122#endif
123 n = AUTH_WPA2_PSK;
124 break;
125#ifdef FEATURE_WLAN_WAPI
126 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
127 n = AUTH_WAPI_CERT;
128 break;
129 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
130 n = AUTH_WAPI_PSK;
131 break;
132#endif /* FEATURE_WLAN_WAPI */
133 default:
134 break;
135 }
136 return n;
137}
138
139int diag_enc_type_from_csr_type(eCsrEncryptionType encType)
140{
141 int n = ENC_MODE_OPEN;
142 switch (encType) {
143 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
144 case eCSR_ENCRYPT_TYPE_WEP40:
145 n = ENC_MODE_WEP40;
146 break;
147 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
148 case eCSR_ENCRYPT_TYPE_WEP104:
149 n = ENC_MODE_WEP104;
150 break;
151 case eCSR_ENCRYPT_TYPE_TKIP:
152 n = ENC_MODE_TKIP;
153 break;
154 case eCSR_ENCRYPT_TYPE_AES:
155 n = ENC_MODE_AES;
156 break;
157#ifdef FEATURE_WLAN_WAPI
158 case eCSR_ENCRYPT_TYPE_WPI:
159 n = ENC_MODE_SMS4;
160 break;
161#endif /* FEATURE_WLAN_WAPI */
162 default:
163 break;
164 }
165 return n;
166}
167#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
168static const uint8_t
169 csr_start_ibss_channels50[CSR_NUM_IBSS_START_CHANNELS_50] = { 36, 40, 44, 48 };
170static const uint8_t
171 csr_start_ibss_channels24[CSR_NUM_IBSS_START_CHANNELS_24] = { 1, 6, 11 };
172static void init_config_param(tpAniSirGlobal pMac);
173static bool csr_roam_process_results(tpAniSirGlobal pMac, tSmeCmd *pCommand,
174 eCsrRoamCompleteResult Result,
175 void *Context);
176static CDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
177 tCsrRoamProfile *pProfile,
178 bool *pfSameIbss);
179static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
180 uint32_t sessionId,
181 tSirSmeNewBssInfo *
182 pNewBss);
183static void csr_roam_prepare_bss_params(tpAniSirGlobal pMac, uint32_t sessionId,
184 tCsrRoamProfile *pProfile,
185 tSirBssDescription *pBssDesc,
186 tBssConfigParam *pBssConfig,
187 tDot11fBeaconIEs *pIes);
188static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
189 uint8_t primaryChn,
190 tDot11fBeaconIEs *pIes);
191
192static void csr_roaming_state_config_cnf_processor(tpAniSirGlobal pMac,
193 uint32_t result);
194CDF_STATUS csr_roam_open(tpAniSirGlobal pMac);
195CDF_STATUS csr_roam_close(tpAniSirGlobal pMac);
196void csr_roamMICErrorTimerHandler(void *pv);
197void csr_roamTKIPCounterMeasureTimerHandler(void *pv);
198bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
199 tCsrRoamConnectedProfile *pConnProfile,
200 tCsrRoamProfile *pProfile2);
201
202static CDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac,
203 uint32_t sessionId,
204 uint32_t interval);
205static CDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac,
206 uint32_t sessionId);
207static void csr_roam_roaming_timer_handler(void *pv);
208CDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval);
209CDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac);
210static void csr_roam_wait_for_key_time_out_handler(void *pv);
211static CDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
212static CDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac,
213 tCsr11dinfo *ps11dinfo);
214static CDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
215 tCsrRoamConnectedInfo *
216 pConnectedInfo);
217CDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
218 tSirMacAddr peerMacAddr, uint8_t numKeys,
219 tAniEdType edType, bool fUnicast,
220 tAniKeyDirection aniKeyDirection,
221 uint8_t keyId, uint8_t keyLength,
222 uint8_t *pKey, uint8_t paeRole,
223 uint8_t *pKeyRsc);
224static CDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
225 uint32_t sessionId,
226 tSirBssDescription *pSirBssDesc,
227 tDot11fBeaconIEs *pIes,
228 tCsrRoamProfile *pProfile);
229void csr_roamStatisticsTimerHandler(void *pv);
230void csr_roamStatsGlobalClassDTimerHandler(void *pv);
231static void csr_roam_link_up(tpAniSirGlobal pMac, struct cdf_mac_addr bssid);
232static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId);
233void csr_roam_vcc_trigger(tpAniSirGlobal pMac);
234CDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
235 uint8_t staId, uint8_t sessionId);
236/*
237 pStaEntry is no longer invalid upon the return of this function.
238 */
239static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac, tListElem *pEntry);
240static eCsrCfgDot11Mode csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal pMac,
241 tCsrRoamProfile *pProfile,
242 uint8_t operationChn,
243 eCsrBand *pBand);
244static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
245 tSirBssDescription *pBssDesc);
246tCsrStatsClientReqInfo *csr_roam_insert_entry_into_list(tpAniSirGlobal pMac,
247 tDblLinkList *pStaList,
248 tCsrStatsClientReqInfo *
249 pStaEntry);
250void csr_roam_stats_client_timer_handler(void *pv);
251tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
252 uint32_t statsMask,
253 uint32_t periodicity,
254 bool *pFound, uint8_t staId,
255 uint8_t sessionId);
256void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
257 tCsrStatsCallback callback, uint8_t staId,
258 void *pContext);
259void csr_roam_tl_stats_timer_handler(void *pv);
260void csr_roam_pe_stats_timer_handler(void *pv);
261tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac, uint32_t statsMask);
262void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
263 tCsrPeStatsReqInfo *pPeStaEntry);
264tListElem *csr_roam_find_in_pe_stats_req_list(tpAniSirGlobal pMac, uint32_t statsMask);
265CDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac);
266static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac);
267static uint32_t csr_find_session_by_type(tpAniSirGlobal, tCDF_CON_MODE);
268static bool csr_is_conn_allow_2g_band(tpAniSirGlobal pMac, uint32_t chnl);
269static bool csr_is_conn_allow_5g_band(tpAniSirGlobal pMac, uint32_t chnl);
270static CDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac, uint32_t sessionId,
271 tCsrRoamProfile *pProfile,
272 tSirBssDescription *pBssDesc);
273static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId);
274static CDF_STATUS csr_roam_issue_set_key_command(tpAniSirGlobal pMac,
275 uint32_t sessionId,
276 tCsrRoamSetKey *pSetKey,
277 uint32_t roamId);
278static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
279 tSirBssDescription *pBssDesc);
280void csr_roam_reissue_roam_command(tpAniSirGlobal pMac);
281static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf,
282 tSirSmeDisassocRsp *pRsp);
283void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
284void csr_init_operating_classes(tHalHandle hHal);
285
286/* Initialize global variables */
287static void csr_roam_init_globals(tpAniSirGlobal pMac)
288{
289 if (pMac) {
290 cdf_mem_zero(&csr_roam_roam_session, sizeof(csr_roam_roam_session));
291 pMac->roam.roamSession = csr_roam_roam_session;
292 }
293 return;
294}
295
296static void csr_roam_de_init_globals(tpAniSirGlobal pMac)
297{
298 if (pMac) {
299 pMac->roam.roamSession = NULL;
300 }
301 return;
302}
303
304CDF_STATUS csr_open(tpAniSirGlobal pMac)
305{
306 CDF_STATUS status = CDF_STATUS_SUCCESS;
307 uint32_t i;
308
309 do {
310 /* Initialize CSR Roam Globals */
311 csr_roam_init_globals(pMac);
312 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
313 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, i);
314
315 init_config_param(pMac);
316 status = csr_scan_open(pMac);
317 if (!CDF_IS_STATUS_SUCCESS(status))
318 break;
319 status = csr_roam_open(pMac);
320 if (!CDF_IS_STATUS_SUCCESS(status))
321 break;
322 pMac->roam.nextRoamId = 1; /* Must not be 0 */
323 if (!CDF_IS_STATUS_SUCCESS
324 (csr_ll_open(pMac->hHdd,
325 &pMac->roam.statsClientReqList)))
326 break;
327 if (!CDF_IS_STATUS_SUCCESS
328 (csr_ll_open(pMac->hHdd,
329 &pMac->roam.peStatsReqList)))
330 break;
331 if (!CDF_IS_STATUS_SUCCESS
332 (csr_ll_open(pMac->hHdd,
333 &pMac->roam.roamCmdPendingList)))
334 break;
335 } while (0);
336
337 return status;
338}
339
340CDF_STATUS csr_init_chan_list(tpAniSirGlobal mac, uint8_t *alpha2)
341{
342 CDF_STATUS status;
343 v_REGDOMAIN_t reg_id;
344 v_CountryInfoSource_t source = COUNTRY_INIT;
345
346 mac->scan.countryCodeDefault[0] = alpha2[0];
347 mac->scan.countryCodeDefault[1] = alpha2[1];
348 mac->scan.countryCodeDefault[2] = alpha2[2];
349
350 sms_log(mac, LOGE, FL("init time country code %.2s"),
351 mac->scan.countryCodeDefault);
352
353 status = csr_get_regulatory_domain_for_country(mac,
354 mac->scan.countryCodeDefault,
355 &reg_id, source);
356 if (status != CDF_STATUS_SUCCESS) {
357 sms_log(mac, LOGE,
358 FL("csr_get_regulatory_domain_for_country failed"));
359 return status;
360 }
361
362 if (cds_set_reg_domain(mac, reg_id) != CDF_STATUS_SUCCESS) {
363 sms_log(mac, LOGE, FL("cds_set_reg_domain failed"));
364 return CDF_STATUS_E_FAILURE;
365 }
366 mac->scan.domainIdDefault = reg_id;
367 mac->scan.domainIdCurrent = mac->scan.domainIdDefault;
368 cdf_mem_copy(mac->scan.countryCodeCurrent,
369 mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
370 cdf_mem_copy(mac->scan.countryCodeElected,
371 mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
372 status = csr_get_channel_and_power_list(mac);
373 csr_clear_votes_for_country_info(mac);
374 return status;
375}
376
377CDF_STATUS csr_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode)
378{
379 CDF_STATUS status = CDF_STATUS_SUCCESS;
380 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
381 v_REGDOMAIN_t regId;
382 uint8_t cntryCodeLength;
383 if (NULL == apCntryCode) {
384 sms_log(pMac, LOGE, FL(" Invalid country Code Pointer"));
385 return CDF_STATUS_E_FAILURE;
386 }
387 sms_log(pMac, LOG1, FL(" country Code %.2s"), apCntryCode);
388
389 cntryCodeLength = WNI_CFG_COUNTRY_CODE_LEN;
390 status = csr_get_regulatory_domain_for_country(pMac, apCntryCode, &regId,
391 COUNTRY_USER);
392 if (status != CDF_STATUS_SUCCESS) {
393 sms_log(pMac, LOGE,
394 FL(" fail to get regId for country Code %.2s"),
395 apCntryCode);
396 return status;
397 }
398 status = wma_set_reg_domain(hHal, regId);
399 if (status != CDF_STATUS_SUCCESS) {
400 sms_log(pMac, LOGE,
401 FL(" fail to get regId for country Code %.2s"),
402 apCntryCode);
403 return status;
404 }
405 pMac->scan.domainIdDefault = regId;
406 pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
407 /* Clear CC field */
408 cdf_mem_set(pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN, 0);
409
410 /* Copy 2 or 3 bytes country code */
411 cdf_mem_copy(pMac->scan.countryCodeDefault, apCntryCode,
412 cntryCodeLength);
413
414 /* If 2 bytes country code, 3rd byte must be filled with space */
415 if ((WNI_CFG_COUNTRY_CODE_LEN - 1) == cntryCodeLength) {
416 cdf_mem_set(pMac->scan.countryCodeDefault + 2, 1, 0x20);
417 }
418 cdf_mem_copy(pMac->scan.countryCodeCurrent,
419 pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
420 status = csr_get_channel_and_power_list(pMac);
421 return status;
422}
423
424CDF_STATUS csr_set_channels(tHalHandle hHal, tCsrConfigParam *pParam)
425{
426 CDF_STATUS status = CDF_STATUS_SUCCESS;
427 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
428 uint8_t index = 0;
429 cdf_mem_copy(pParam->Csr11dinfo.countryCode,
430 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
431 for (index = 0; index < pMac->scan.base_channels.numChannels;
432 index++) {
433 pParam->Csr11dinfo.Channels.channelList[index] =
434 pMac->scan.base_channels.channelList[index];
435 pParam->Csr11dinfo.ChnPower[index].firstChannel =
436 pMac->scan.base_channels.channelList[index];
437 pParam->Csr11dinfo.ChnPower[index].numChannels = 1;
438 pParam->Csr11dinfo.ChnPower[index].maxtxPower =
439 pMac->scan.defaultPowerTable[index].pwr;
440 }
441 pParam->Csr11dinfo.Channels.numChannels =
442 pMac->scan.base_channels.numChannels;
443
444 return status;
445}
446
447CDF_STATUS csr_close(tpAniSirGlobal pMac)
448{
449 CDF_STATUS status = CDF_STATUS_SUCCESS;
450
451 csr_roam_close(pMac);
452 csr_scan_close(pMac);
453 csr_ll_close(&pMac->roam.statsClientReqList);
454 csr_ll_close(&pMac->roam.peStatsReqList);
455 csr_ll_close(&pMac->roam.roamCmdPendingList);
456 /* DeInit Globals */
457 csr_roam_de_init_globals(pMac);
458 return status;
459}
460
461static tPowerdBm csr_find_channel_pwr(tChannelListWithPower *
462 pdefaultPowerTable,
463 uint8_t ChannelNum)
464{
465 uint8_t i;
466 /* TODO: if defaultPowerTable is guaranteed to be in ascending */
467 /* order of channel numbers, we can employ binary search */
468 for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
469 if (pdefaultPowerTable[i].chanId == ChannelNum)
470 return pdefaultPowerTable[i].pwr;
471 }
472 /* could not find the channel list in default list */
473 /* this should not have occured */
474 CDF_ASSERT(0);
475 return 0;
476}
477
478CDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
479{
480 tSirUpdateChanList *pChanList;
481 tCsrScanStruct *pScan = &pMac->scan;
482 uint8_t numChan = pScan->base_channels.numChannels;
483 uint8_t num_channel = 0;
484 uint32_t bufLen;
485 cds_msg_t msg;
486 uint8_t i, j, social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 };
487 uint8_t channel_state;
488
489 if (CSR_IS_5G_BAND_ONLY(pMac)) {
490 for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
491 if (cds_get_channel_state(social_channel[i])
492 == CHANNEL_STATE_ENABLE)
493 numChan++;
494 }
495 }
496
497 bufLen = sizeof(tSirUpdateChanList) +
498 (sizeof(tSirUpdateChanParam) * (numChan));
499
500 csr_init_operating_classes((tHalHandle) pMac);
501 pChanList = (tSirUpdateChanList *) cdf_mem_malloc(bufLen);
502 if (!pChanList) {
503 CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
504 "Failed to allocate memory for tSirUpdateChanList");
505 return CDF_STATUS_E_NOMEM;
506 }
507 cdf_mem_zero(pChanList, bufLen);
508
509 for (i = 0; i < pScan->base_channels.numChannels; i++) {
510 /* Scan is not performed on DSRC channels*/
511 if (pScan->base_channels.channelList[i] >= MIN_11P_CHANNEL)
512 continue;
513 if (pScan->fcc_constraint) {
514 if (pScan->base_channels.channelList[i] == 12)
515 continue;
516 if (pScan->base_channels.channelList[i] == 13)
517 continue;
518 }
519 channel_state =
520 cds_get_channel_state(
521 pScan->base_channels.channelList[i]);
522 if ((CHANNEL_STATE_ENABLE == channel_state) ||
523 pMac->scan.fEnableDFSChnlScan) {
524 pChanList->chanParam[num_channel].chanId =
525 pScan->base_channels.channelList[i];
526 pChanList->chanParam[num_channel].pwr =
527 csr_find_channel_pwr(pScan->defaultPowerTable,
528 pChanList->chanParam[num_channel].chanId);
529 if (CHANNEL_STATE_ENABLE == channel_state)
530 pChanList->chanParam[num_channel].dfsSet =
531 false;
532 else
533 pChanList->chanParam[num_channel].dfsSet =
534 true;
535 num_channel++;
536 }
537 }
538
539 if (CSR_IS_5G_BAND_ONLY(pMac)) {
540 for (j = 0; j < MAX_SOCIAL_CHANNELS; j++) {
541 if (cds_get_channel_state(social_channel[j])
542 == CHANNEL_STATE_ENABLE) {
543 pChanList->chanParam[num_channel].chanId =
544 social_channel[j];
545 pChanList->chanParam[num_channel].pwr =
546 csr_find_channel_pwr(pScan->defaultPowerTable,
547 social_channel[j]);
548 pChanList->chanParam[num_channel].dfsSet = false;
549 num_channel++;
550 }
551 }
552 }
553
554 msg.type = WMA_UPDATE_CHAN_LIST_REQ;
555 msg.reserved = 0;
556 msg.bodyptr = pChanList;
557 pChanList->numChan = num_channel;
558
559 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
560 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
561 "%s: Failed to post msg to WMA", __func__);
562 cdf_mem_free(pChanList);
563 return CDF_STATUS_E_FAILURE;
564 }
565
566 return CDF_STATUS_SUCCESS;
567}
568
569CDF_STATUS csr_start(tpAniSirGlobal pMac)
570{
571 CDF_STATUS status = CDF_STATUS_SUCCESS;
572 uint32_t i;
573
574 do {
575 /* save the global cds context */
576 pMac->roam.g_cds_context = cds_get_global_context();
577 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
578 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_IDLE, i);
579
580 status = csr_roam_start(pMac);
581 if (!CDF_IS_STATUS_SUCCESS(status))
582 break;
583
584 pMac->roam.sPendingCommands = 0;
585 csr_scan_enable(pMac);
586#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
587 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
588 status = csr_neighbor_roam_init(pMac, i);
589#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
590 pMac->roam.tlStatsReqInfo.numClient = 0;
591 pMac->roam.tlStatsReqInfo.periodicity = 0;
592 pMac->roam.tlStatsReqInfo.timerRunning = false;
593 /* init the link quality indication also */
594 pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND;
595 if (!CDF_IS_STATUS_SUCCESS(status)) {
596 sms_log(pMac, LOGW,
597 " csr_start: Couldn't Init HO control blk ");
598 break;
599 }
600
601 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
602 "Scan offload is enabled, update default chan list");
603 status = csr_update_channel_list(pMac);
604
605 } while (0);
606 return status;
607}
608
609CDF_STATUS csr_stop(tpAniSirGlobal pMac, tHalStopType stopType)
610{
611 uint32_t sessionId;
612
613 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
614 csr_roam_close_session(pMac, sessionId, true, NULL, NULL);
615 }
616 csr_scan_disable(pMac);
617 pMac->scan.fCancelIdleScan = false;
618 pMac->scan.fRestartIdleScan = false;
619 csr_ll_purge(&pMac->roam.roamCmdPendingList, true);
620
621#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
622 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
623 csr_neighbor_roam_close(pMac, sessionId);
624#endif
625 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
626 if (CSR_IS_SESSION_VALID(pMac, sessionId))
627 csr_scan_flush_result(pMac);
628
629 /* Reset the domain back to the deault */
630 pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
631
632 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
633 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, sessionId);
634 pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE;
635 }
636
637 /* When HAL resets all the context information
638 * in HAL is lost, so we might need to send the
639 * scan offload request again when it comes
640 * out of reset for scan offload to be functional
641 */
642 if (HAL_STOP_TYPE_SYS_RESET == stopType) {
643 b_roam_scan_offload_started = false;
644 }
645
646 return CDF_STATUS_SUCCESS;
647}
648
649CDF_STATUS csr_ready(tpAniSirGlobal pMac)
650{
651 CDF_STATUS status = CDF_STATUS_SUCCESS;
652 /* If the gScanAgingTime is set to '0' then scan results aging timeout
653 based on timer feature is not enabled */
654
655 if (0 != pMac->scan.scanResultCfgAgingTime) {
656 csr_scan_start_result_cfg_aging_timer(pMac);
657 }
658 status = csr_apply_channel_and_power_list(pMac);
659 if (!CDF_IS_STATUS_SUCCESS(status)) {
660 sms_log(pMac, LOGE,
661 "csr_apply_channel_and_power_list failed during csr_ready with status=%d",
662 status);
663 }
664 return status;
665}
666
667void csr_set_default_dot11_mode(tpAniSirGlobal pMac)
668{
669 uint32_t wniDot11mode = 0;
670 wniDot11mode =
671 csr_translate_to_wni_cfg_dot11_mode(pMac,
672 pMac->roam.configParam.uCfgDot11Mode);
673 cfg_set_int(pMac, WNI_CFG_DOT11_MODE, wniDot11mode);
674}
675
676void csr_set_global_cfgs(tpAniSirGlobal pMac)
677{
678
679 cfg_set_int(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD,
680 csr_get_frag_thresh(pMac));
681 cfg_set_int(pMac, WNI_CFG_RTS_THRESHOLD, csr_get_rts_thresh(pMac));
682 cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
683 ((pMac->roam.configParam.Is11hSupportEnabled) ? pMac->roam.
684 configParam.Is11dSupportEnabled : pMac->roam.configParam.
685 Is11dSupportEnabled));
686 cfg_set_int(pMac, WNI_CFG_11H_ENABLED,
687 pMac->roam.configParam.Is11hSupportEnabled);
688 /* For now we will just use the 5GHz CB mode ini parameter to decide whether CB supported or not in Probes when there is no session
689 * Once session is established we will use the session related params stored in PE session for CB mode
690 */
691 cfg_set_int(pMac, WNI_CFG_CHANNEL_BONDING_MODE,
692 !!(pMac->roam.configParam.channelBondingMode5GHz));
693 cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
694 pMac->roam.configParam.HeartbeatThresh24);
695
696 /* Update the operating mode to configured value during initialization, */
697 /* So that client can advertise full capabilities in Probe request frame. */
698 csr_set_default_dot11_mode(pMac);
699}
700
701CDF_STATUS csr_roam_open(tpAniSirGlobal pMac)
702{
703 CDF_STATUS status = CDF_STATUS_SUCCESS;
704 uint32_t i;
705 tCsrRoamSession *pSession;
706 do {
707 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
708 pSession = CSR_GET_SESSION(pMac, i);
709 pSession->roamingTimerInfo.pMac = pMac;
710 pSession->roamingTimerInfo.sessionId =
711 CSR_SESSION_ID_INVALID;
712 }
713 pMac->roam.WaitForKeyTimerInfo.pMac = pMac;
714 pMac->roam.WaitForKeyTimerInfo.sessionId =
715 CSR_SESSION_ID_INVALID;
716 status =
717 cdf_mc_timer_init(&pMac->roam.hTimerWaitForKey,
718 CDF_TIMER_TYPE_SW,
719 csr_roam_wait_for_key_time_out_handler,
720 &pMac->roam.WaitForKeyTimerInfo);
721 if (!CDF_IS_STATUS_SUCCESS(status)) {
722 sms_log(pMac, LOGE,
723 FL
724 ("cannot allocate memory for WaitForKey time out timer"));
725 break;
726 }
727 status =
728 cdf_mc_timer_init(&pMac->roam.tlStatsReqInfo.hTlStatsTimer,
729 CDF_TIMER_TYPE_SW,
730 csr_roam_tl_stats_timer_handler, pMac);
731 if (!CDF_IS_STATUS_SUCCESS(status)) {
732 sms_log(pMac, LOGE,
733 FL
734 ("cannot allocate memory for summary Statistics timer"));
735 return CDF_STATUS_E_FAILURE;
736 }
737 } while (0);
738 return status;
739}
740
741CDF_STATUS csr_roam_close(tpAniSirGlobal pMac)
742{
743 uint32_t sessionId;
744 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
745 csr_roam_close_session(pMac, sessionId, true, NULL, NULL);
746 }
747 cdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
748 cdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey);
749 cdf_mc_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
750 cdf_mc_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
751 return CDF_STATUS_SUCCESS;
752}
753
754CDF_STATUS csr_roam_start(tpAniSirGlobal pMac)
755{
756 (void)pMac;
757 return CDF_STATUS_SUCCESS;
758}
759
760void csr_roam_stop(tpAniSirGlobal pMac, uint32_t sessionId)
761{
762 csr_roam_stop_roaming_timer(pMac, sessionId);
763 /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers */
764 csr_roam_dereg_statistics_req(pMac);
765}
766
767CDF_STATUS csr_roam_get_connect_state(tpAniSirGlobal pMac, uint32_t sessionId,
768 eCsrConnectState *pState)
769{
770 CDF_STATUS status = CDF_STATUS_E_INVAL;
771 if (CSR_IS_SESSION_VALID(pMac, sessionId) && (NULL != pState)) {
772 status = CDF_STATUS_SUCCESS;
773 *pState = pMac->roam.roamSession[sessionId].connectState;
774 }
775 return status;
776}
777
778CDF_STATUS csr_roam_copy_connect_profile(tpAniSirGlobal pMac,
779 uint32_t sessionId, tCsrRoamConnectedProfile *pProfile)
780{
781 CDF_STATUS status = CDF_STATUS_E_FAILURE;
782 uint32_t size = 0;
783 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
784 tCsrRoamConnectedProfile *connected_prof;
785
786 if (!pSession) {
787 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
788 return CDF_STATUS_E_FAILURE;
789 }
790 if (!pProfile) {
791 sms_log(pMac, LOGE, FL("profile not found"));
792 return CDF_STATUS_E_FAILURE;
793 }
794
795 if (pSession->pConnectBssDesc) {
796 size = pSession->pConnectBssDesc->length +
797 sizeof(pSession->pConnectBssDesc->length);
798 if (size) {
799 pProfile->pBssDesc = cdf_mem_malloc(size);
800 if (NULL != pProfile->pBssDesc) {
801 cdf_mem_copy(pProfile->pBssDesc,
802 pSession->pConnectBssDesc,
803 size);
804 status = CDF_STATUS_SUCCESS;
805 } else {
806 return CDF_STATUS_E_FAILURE;
807 }
808 } else {
809 pProfile->pBssDesc = NULL;
810 }
811 connected_prof = &(pSession->connectedProfile);
812 pProfile->AuthType = connected_prof->AuthType;
813 pProfile->EncryptionType = connected_prof->EncryptionType;
814 pProfile->mcEncryptionType = connected_prof->mcEncryptionType;
815 pProfile->BSSType = connected_prof->BSSType;
816 pProfile->operationChannel = connected_prof->operationChannel;
817 pProfile->CBMode = connected_prof->CBMode;
818 cdf_mem_copy(&pProfile->bssid, &connected_prof->bssid,
819 sizeof(struct cdf_mac_addr));
820 cdf_mem_copy(&pProfile->SSID, &connected_prof->SSID,
821 sizeof(tSirMacSSid));
822#ifdef WLAN_FEATURE_VOWIFI_11R
823 if (connected_prof->MDID.mdiePresent) {
824 pProfile->MDID.mdiePresent = 1;
825 pProfile->MDID.mobilityDomain =
826 connected_prof->MDID.mobilityDomain;
827 } else {
828 pProfile->MDID.mdiePresent = 0;
829 pProfile->MDID.mobilityDomain = 0;
830 }
831#endif
832#ifdef FEATURE_WLAN_ESE
833 pProfile->isESEAssoc = connected_prof->isESEAssoc;
834 if (csr_is_auth_type_ese(connected_prof->AuthType)) {
835 cdf_mem_copy(pProfile->eseCckmInfo.krk,
836 connected_prof->eseCckmInfo.krk,
837 SIR_KRK_KEY_LEN);
838#ifdef WLAN_FEATURE_ROAM_OFFLOAD
839 cdf_mem_copy(pProfile->eseCckmInfo.btk,
840 connected_prof->eseCckmInfo.btk,
841 SIR_BTK_KEY_LEN);
842#endif
843 pProfile->eseCckmInfo.reassoc_req_num =
844 connected_prof->eseCckmInfo.reassoc_req_num;
845 pProfile->eseCckmInfo.krk_plumbed =
846 connected_prof->eseCckmInfo.krk_plumbed;
847 }
848#endif
849 }
850 return status;
851}
852
853CDF_STATUS csr_roam_get_connect_profile(tpAniSirGlobal pMac, uint32_t sessionId,
854 tCsrRoamConnectedProfile *pProfile)
855{
856 CDF_STATUS status = CDF_STATUS_E_FAILURE;
857
858 if ((csr_is_conn_state_connected(pMac, sessionId)) ||
859 (csr_is_conn_state_ibss(pMac, sessionId))) {
860 if (pProfile) {
861 status =
862 csr_roam_copy_connect_profile(pMac, sessionId,
863 pProfile);
864 }
865 }
866 return status;
867}
868
869CDF_STATUS csr_roam_free_connect_profile(tpAniSirGlobal pMac,
870 tCsrRoamConnectedProfile *pProfile)
871{
872 CDF_STATUS status = CDF_STATUS_SUCCESS;
873
874 if (pProfile->pBssDesc) {
875 cdf_mem_free(pProfile->pBssDesc);
876 }
877 if (pProfile->pAddIEAssoc) {
878 cdf_mem_free(pProfile->pAddIEAssoc);
879 }
880 cdf_mem_set(pProfile, sizeof(tCsrRoamConnectedProfile), 0);
881
882 pProfile->AuthType = eCSR_AUTH_TYPE_UNKNOWN;
883 return status;
884}
885
886static CDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
887 tCsrRoamConnectedInfo *
888 pConnectedInfo)
889{
890 CDF_STATUS status = CDF_STATUS_SUCCESS;
891 if (pConnectedInfo->pbFrames) {
892 cdf_mem_free(pConnectedInfo->pbFrames);
893 pConnectedInfo->pbFrames = NULL;
894 }
895 pConnectedInfo->nBeaconLength = 0;
896 pConnectedInfo->nAssocReqLength = 0;
897 pConnectedInfo->nAssocRspLength = 0;
898 pConnectedInfo->staId = 0;
899#ifdef WLAN_FEATURE_VOWIFI_11R
900 pConnectedInfo->nRICRspLength = 0;
901#endif
902#ifdef FEATURE_WLAN_ESE
903 pConnectedInfo->nTspecIeLength = 0;
904#endif
905 return status;
906}
907
908void csr_release_command_preauth(tpAniSirGlobal pMac, tSmeCmd *pCommand)
909{
910 csr_reinit_preauth_cmd(pMac, pCommand);
911 csr_release_command(pMac, pCommand);
912}
913
914void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
915{
916 csr_reinit_roam_cmd(pMac, pCommand);
917 csr_release_command(pMac, pCommand);
918}
919
920void csr_release_command_scan(tpAniSirGlobal pMac, tSmeCmd *pCommand)
921{
922 cdf_mc_timer_stop(&pCommand->u.scanCmd.csr_scan_timer);
923 cdf_mc_timer_destroy(&pCommand->u.scanCmd.csr_scan_timer);
924 csr_reinit_scan_cmd(pMac, pCommand);
925 csr_release_command(pMac, pCommand);
926}
927
928void csr_release_command_wm_status_change(tpAniSirGlobal pMac, tSmeCmd *pCommand)
929{
930 csr_reinit_wm_status_change_cmd(pMac, pCommand);
931 csr_release_command(pMac, pCommand);
932}
933
934void csr_reinit_set_key_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
935{
936 cdf_mem_set(&pCommand->u.setKeyCmd, sizeof(tSetKeyCmd), 0);
937}
938
939void csr_release_command_set_key(tpAniSirGlobal pMac, tSmeCmd *pCommand)
940{
941 csr_reinit_set_key_cmd(pMac, pCommand);
942 csr_release_command(pMac, pCommand);
943}
944
945/**
946 * csr_release_roc_req_cmd() - Release the command
947 * @mac_ctx: Global MAC Context
948 *
949 * Release the remain on channel request command from the queue
950 *
951 * Return: None
952 */
953void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx)
954{
955 tListElem *entry;
956 tSmeCmd *cmd = NULL;
957
958 entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
959 LL_ACCESS_LOCK);
960 if (entry) {
961 cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
962 if (eSmeCommandRemainOnChannel == cmd->command) {
963 remainOnChanCallback callback =
964 cmd->u.remainChlCmd.callback;
965 /* process the msg */
966 if (callback)
967 callback(mac_ctx,
968 cmd->u.remainChlCmd.callbackCtx, 0,
969 cmd->u.remainChlCmd.scan_id);
970 sms_log(mac_ctx, LOGE,
971 FL("Remove RoC Request from Active Cmd List"));
972 /* Put this cmd back on the available command list */
973 if (csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList,
974 entry, LL_ACCESS_LOCK))
975 sme_release_command(mac_ctx, cmd);
976 }
977 }
978}
979
980void csr_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand, bool fStopping)
981{
982
983 if (eSmeCsrCommandMask & pCommand->command) {
984 switch (pCommand->command) {
985 case eSmeCommandScan:
986 /* We need to inform the requester before dropping the scan command */
987 sms_log(pMac, LOGW,
988 "%s: Drop scan reason %d callback %p", __func__,
989 pCommand->u.scanCmd.reason,
990 pCommand->u.scanCmd.callback);
991 if (NULL != pCommand->u.scanCmd.callback) {
992 sms_log(pMac, LOGW, "%s callback scan requester",
993 __func__);
994 csr_scan_call_callback(pMac, pCommand,
995 eCSR_SCAN_ABORT);
996 }
997 csr_release_command_scan(pMac, pCommand);
998 break;
999 case eSmeCommandRoam:
1000 csr_release_command_roam(pMac, pCommand);
1001 break;
1002
1003 case eSmeCommandWmStatusChange:
1004 csr_release_command_wm_status_change(pMac, pCommand);
1005 break;
1006
1007 case eSmeCommandSetKey:
1008 csr_release_command_set_key(pMac, pCommand);
1009 break;
1010
1011 default:
1012 sms_log(pMac, LOGW, " CSR abort standard command %d",
1013 pCommand->command);
1014 csr_release_command(pMac, pCommand);
1015 break;
1016 }
1017 }
1018}
1019
1020void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate,
1021 uint32_t sessionId)
1022{
1023 sms_log(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"),
1024 mac_trace_getcsr_roam_sub_state(NewSubstate),
1025 mac_trace_getcsr_roam_sub_state(pMac->roam.curSubState[sessionId]));
1026 if (pMac->roam.curSubState[sessionId] == NewSubstate) {
1027 return;
1028 }
1029 pMac->roam.curSubState[sessionId] = NewSubstate;
1030}
1031
1032eCsrRoamState csr_roam_state_change(tpAniSirGlobal pMac,
1033 eCsrRoamState NewRoamState, uint8_t sessionId)
1034{
1035 eCsrRoamState PreviousState;
1036
1037 sms_log(pMac, LOG1, FL("CSR RoamState[%hu]: [ %s <== %s ]"), sessionId,
1038 mac_trace_getcsr_roam_state(NewRoamState),
1039 mac_trace_getcsr_roam_state(pMac->roam.curState[sessionId]));
1040 PreviousState = pMac->roam.curState[sessionId];
1041
1042 if (NewRoamState != pMac->roam.curState[sessionId]) {
1043 /* Whenever we transition OUT of the Roaming state, clear the Roaming substate... */
1044 if (CSR_IS_ROAM_JOINING(pMac, sessionId)) {
1045 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
1046 sessionId);
1047 }
1048
1049 pMac->roam.curState[sessionId] = NewRoamState;
1050 }
1051 return PreviousState;
1052}
1053
1054void csr_assign_rssi_for_category(tpAniSirGlobal pMac, int8_t bestApRssi,
1055 uint8_t catOffset)
1056{
1057 int i;
1058 if (catOffset) {
1059 pMac->roam.configParam.bCatRssiOffset = catOffset;
1060 for (i = 0; i < CSR_NUM_RSSI_CAT; i++) {
1061 pMac->roam.configParam.RSSICat[CSR_NUM_RSSI_CAT - i -
1062 1] =
1063 (int)bestApRssi -
1064 pMac->roam.configParam.nSelect5GHzMargin -
1065 (int)(i * catOffset);
1066 }
1067 }
1068}
1069
1070static void init_config_param(tpAniSirGlobal pMac)
1071{
1072 int i;
1073 pMac->roam.configParam.agingCount = CSR_AGING_COUNT;
1074 pMac->roam.configParam.channelBondingMode24GHz =
1075 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
1076 pMac->roam.configParam.channelBondingMode5GHz =
1077 WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
1078
1079 pMac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO;
1080 pMac->roam.configParam.eBand = eCSR_BAND_ALL;
1081 pMac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
1082 pMac->roam.configParam.FragmentationThreshold =
1083 eCSR_DOT11_FRAG_THRESH_DEFAULT;
1084 pMac->roam.configParam.HeartbeatThresh24 = 40;
1085 pMac->roam.configParam.HeartbeatThresh50 = 40;
1086 pMac->roam.configParam.Is11dSupportEnabled = false;
1087 pMac->roam.configParam.Is11dSupportEnabledOriginal = false;
1088 pMac->roam.configParam.Is11eSupportEnabled = true;
1089 pMac->roam.configParam.Is11hSupportEnabled = true;
1090 pMac->roam.configParam.RTSThreshold = 2346;
1091 pMac->roam.configParam.shortSlotTime = true;
1092 pMac->roam.configParam.WMMSupportMode = eCsrRoamWmmAuto;
1093 pMac->roam.configParam.ProprietaryRatesEnabled = true;
1094 pMac->roam.configParam.TxRate = eCSR_TX_RATE_AUTO;
1095 pMac->roam.configParam.scanAgeTimeNCNPS =
1096 CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS;
1097 pMac->roam.configParam.scanAgeTimeNCPS =
1098 CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS;
1099 pMac->roam.configParam.scanAgeTimeCNPS =
1100 CSR_SCAN_AGING_TIME_CONNECT_NO_PS;
1101 pMac->roam.configParam.scanAgeTimeCPS =
1102 CSR_SCAN_AGING_TIME_CONNECT_W_PS;
1103 for (i = 0; i < CSR_NUM_RSSI_CAT; i++) {
1104 pMac->roam.configParam.BssPreferValue[i] = i;
1105 }
1106 csr_assign_rssi_for_category(pMac, CSR_BEST_RSSI_VALUE,
1107 CSR_DEFAULT_RSSI_DB_GAP);
1108 pMac->roam.configParam.nRoamingTime = CSR_DEFAULT_ROAMING_TIME;
1109 pMac->roam.configParam.fSupplicantCountryCodeHasPriority = false;
1110 pMac->roam.configParam.nActiveMaxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME;
1111 pMac->roam.configParam.nActiveMinChnTime = CSR_ACTIVE_MIN_CHANNEL_TIME;
1112 pMac->roam.configParam.nPassiveMaxChnTime =
1113 CSR_PASSIVE_MAX_CHANNEL_TIME;
1114 pMac->roam.configParam.nPassiveMinChnTime =
1115 CSR_PASSIVE_MIN_CHANNEL_TIME;
1116#ifdef WLAN_AP_STA_CONCURRENCY
1117 pMac->roam.configParam.nActiveMaxChnTimeConc =
1118 CSR_ACTIVE_MAX_CHANNEL_TIME_CONC;
1119 pMac->roam.configParam.nActiveMinChnTimeConc =
1120 CSR_ACTIVE_MIN_CHANNEL_TIME_CONC;
1121 pMac->roam.configParam.nPassiveMaxChnTimeConc =
1122 CSR_PASSIVE_MAX_CHANNEL_TIME_CONC;
1123 pMac->roam.configParam.nPassiveMinChnTimeConc =
1124 CSR_PASSIVE_MIN_CHANNEL_TIME_CONC;
1125 pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC;
1126 pMac->roam.configParam.nNumStaChanCombinedConc =
1127 CSR_NUM_STA_CHAN_COMBINED_CONC;
1128 pMac->roam.configParam.nNumP2PChanCombinedConc =
1129 CSR_NUM_P2P_CHAN_COMBINED_CONC;
1130#endif
1131 pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER;
1132 pMac->roam.configParam.statsReqPeriodicity =
1133 CSR_MIN_GLOBAL_STAT_QUERY_PERIOD;
1134 pMac->roam.configParam.statsReqPeriodicityInPS =
1135 CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS;
1136#ifdef WLAN_FEATURE_VOWIFI_11R
1137 pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported = 0;
1138#endif
1139#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
1140 pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries = 3;
1141 pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold =
1142 120;
1143 pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff =
1144 30;
1145 pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff = 5;
1146 pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = 20;
1147 pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = 40;
1148 pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod =
1149 200;
1150 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
1151 numChannels = 3;
1152 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
1153 channelList[0] = 1;
1154 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
1155 channelList[1] = 6;
1156 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
1157 channelList[2] = 11;
1158 pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = 20000; /* 20 seconds */
1159 pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0;
1160 pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt = 10;
1161 pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt = 10;
1162 pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight = 14;
1163#endif
1164#ifdef WLAN_FEATURE_11AC
1165 pMac->roam.configParam.nVhtChannelWidth =
1166 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
1167#endif
1168
1169 pMac->roam.configParam.addTSWhenACMIsOff = 0;
1170 pMac->roam.configParam.fScanTwice = false;
1171
1172 /* Remove this code once SLM_Sessionization is supported */
1173 /* BMPS_WORKAROUND_NOT_NEEDED */
1174 pMac->roam.configParam.doBMPSWorkaround = 0;
1175
1176 pMac->roam.configParam.nInitialDwellTime = 0;
1177 pMac->roam.configParam.initial_scan_no_dfs_chnl = 0;
1178}
1179
1180eCsrBand csr_get_current_band(tHalHandle hHal)
1181{
1182 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1183 return pMac->roam.configParam.bandCapability;
1184}
1185
1186#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
1187/*
1188 This function flushes the roam scan cache
1189 */
1190CDF_STATUS csr_flush_roam_scan_roam_channel_list(tpAniSirGlobal pMac,
1191 uint8_t sessionId)
1192{
1193 CDF_STATUS status = CDF_STATUS_SUCCESS;
1194 tpCsrNeighborRoamControlInfo pNeighborRoamInfo
1195 = &pMac->roam.neighborRoamInfo[sessionId];
1196 /* Free up the memory first (if required) */
1197 if (NULL !=
1198 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
1199 ChannelList) {
1200 cdf_mem_free(pNeighborRoamInfo->roamChannelInfo.
1201 currentChannelListInfo.ChannelList);
1202 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
1203 ChannelList = NULL;
1204 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
1205 numOfChannels = 0;
1206 }
1207 return status;
1208}
1209#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
1210
1211#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
1212/*
1213 This function flushes the roam scan cache
1214 */
1215CDF_STATUS csr_flush_cfg_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
1216 uint8_t sessionId)
1217{
1218 CDF_STATUS status = CDF_STATUS_SUCCESS;
1219 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
1220 &pMac->roam.neighborRoamInfo[sessionId];
1221
1222 /* Free up the memory first (if required) */
1223 if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
1224 cdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
1225 ChannelList);
1226 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
1227 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
1228 }
1229 return status;
1230}
1231
1232/*
1233 This function flushes the roam scan cache and creates fresh cache
1234 based on the input channel list
1235 */
1236CDF_STATUS csr_create_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
1237 uint8_t sessionId,
1238 const uint8_t *pChannelList,
1239 const uint8_t numChannels)
1240{
1241 CDF_STATUS status = CDF_STATUS_SUCCESS;
1242 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
1243 &pMac->roam.neighborRoamInfo[sessionId];
1244
1245 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = numChannels;
1246
1247 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
1248 cdf_mem_malloc(pNeighborRoamInfo->cfgParams.channelInfo.
1249 numOfChannels);
1250
1251 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
1252 sms_log(pMac, LOGE,
1253 FL("Memory Allocation for CFG Channel List failed"));
1254 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
1255 return CDF_STATUS_E_NOMEM;
1256 }
1257
1258 /* Update the roam global structure */
1259 cdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
1260 pChannelList,
1261 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
1262 return status;
1263}
1264
1265#endif
1266
1267#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
1268/*
1269 * This function modifies the roam scan channel list as per AP neighbor
1270 * report; AP neighbor report may be empty or may include only other AP
1271 * channels; in any case, we merge the channel list with the learned occupied
1272 * channels list.
1273 * if the band is 2.4G, then make sure channel list contains only 2.4G
1274 * valid channels if the band is 5G, then make sure channel list contains
1275 * only 5G valid channels
1276 */
1277CDF_STATUS csr_create_roam_scan_channel_list(tpAniSirGlobal pMac,
1278 uint8_t sessionId,
1279 uint8_t *pChannelList,
1280 uint8_t numChannels,
1281 const eCsrBand eBand)
1282{
1283 CDF_STATUS status = CDF_STATUS_SUCCESS;
1284 tpCsrNeighborRoamControlInfo pNeighborRoamInfo
1285 = &pMac->roam.neighborRoamInfo[sessionId];
1286 uint8_t outNumChannels = 0;
1287 uint8_t inNumChannels = numChannels;
1288 uint8_t *inPtr = pChannelList;
1289 uint8_t i = 0;
1290 uint8_t ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
1291 uint8_t tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
1292 uint8_t mergedOutputNumOfChannels = 0;
1293 tpCsrChannelInfo currChannelListInfo
1294 = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
1295 /*
1296 * Create a Union of occupied channel list learnt by the DUT along
1297 * with the Neighbor report Channels. This increases the chances of
1298 * the DUT to get a candidate AP while roaming even if the Neighbor
1299 * Report is not able to provide sufficient information.
1300 */
1301 if (pMac->scan.occupiedChannels[sessionId].numChannels) {
1302 csr_neighbor_roam_merge_channel_lists(pMac,
1303 &pMac->scan.
1304 occupiedChannels[sessionId].
1305 channelList[0],
1306 pMac->scan.
1307 occupiedChannels[sessionId].
1308 numChannels, inPtr,
1309 inNumChannels,
1310 &mergedOutputNumOfChannels);
1311 inNumChannels = mergedOutputNumOfChannels;
1312 }
1313 if (eCSR_BAND_24 == eBand) {
1314 for (i = 0; i < inNumChannels; i++) {
1315 if (CDS_IS_CHANNEL_24GHZ(inPtr[i])
1316 && csr_roam_is_channel_valid(pMac, inPtr[i])) {
1317 ChannelList[outNumChannels++] = inPtr[i];
1318 }
1319 }
1320 } else if (eCSR_BAND_5G == eBand) {
1321 for (i = 0; i < inNumChannels; i++) {
1322 /* Add 5G Non-DFS channel */
1323 if (CDS_IS_CHANNEL_5GHZ(inPtr[i]) &&
1324 csr_roam_is_channel_valid(pMac, inPtr[i]) &&
1325 !CDS_IS_DFS_CH(inPtr[i])) {
1326 ChannelList[outNumChannels++] = inPtr[i];
1327 }
1328 }
1329 } else if (eCSR_BAND_ALL == eBand) {
1330 for (i = 0; i < inNumChannels; i++) {
1331 if (csr_roam_is_channel_valid(pMac, inPtr[i]) &&
1332 !CDS_IS_DFS_CH(inPtr[i])) {
1333 ChannelList[outNumChannels++] = inPtr[i];
1334 }
1335 }
1336 } else {
1337 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_WARN,
1338 "Invalid band, No operation carried out (Band %d)",
1339 eBand);
1340 return CDF_STATUS_E_INVAL;
1341 }
1342 /*
1343 * if roaming within band is enabled, then select only the
1344 * in band channels .
1345 * This is required only if the band capability is set to ALL,
1346 * E.g., if band capability is only 2.4G then all the channels in the
1347 * list are already filtered for 2.4G channels, hence ignore this check
1348 */
1349 if ((eCSR_BAND_ALL == eBand) && CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) {
1350 csr_neighbor_roam_channels_filter_by_current_band(pMac,
1351 sessionId,
1352 ChannelList,
1353 outNumChannels,
1354 tmpChannelList,
1355 &outNumChannels);
1356 cdf_mem_copy(ChannelList, tmpChannelList, outNumChannels);
1357 }
1358 /* Prepare final roam scan channel list */
1359 if (outNumChannels) {
1360 /* Clear the channel list first */
1361 if (NULL != currChannelListInfo->ChannelList) {
1362 cdf_mem_free(currChannelListInfo->ChannelList);
1363 currChannelListInfo->ChannelList = NULL;
1364 currChannelListInfo->numOfChannels = 0;
1365 }
1366 currChannelListInfo->ChannelList
1367 = cdf_mem_malloc(outNumChannels * sizeof(uint8_t));
1368 if (NULL == currChannelListInfo->ChannelList) {
1369 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
1370 "Failed to allocate memory for roam scan channel list");
1371 currChannelListInfo->numOfChannels = 0;
1372 return CDF_STATUS_E_NOMEM;
1373 }
1374 cdf_mem_copy(currChannelListInfo->ChannelList,
1375 ChannelList, outNumChannels);
1376 }
1377 return status;
1378}
1379#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
1380
1381CDF_STATUS csr_set_band(tHalHandle hHal, uint8_t sessionId, eCsrBand eBand)
1382{
1383 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1384 CDF_STATUS status = CDF_STATUS_SUCCESS;
1385 if (CSR_IS_PHY_MODE_A_ONLY(pMac) && (eBand == eCSR_BAND_24)) {
1386 /* DOT11 mode configured to 11a only and received
1387 request to change the band to 2.4 GHz */
1388 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1389 "failed to set band cfg80211 = %u, band = %u",
1390 pMac->roam.configParam.uCfgDot11Mode, eBand);
1391 return CDF_STATUS_E_INVAL;
1392 }
1393 if ((CSR_IS_PHY_MODE_B_ONLY(pMac) ||
1394 CSR_IS_PHY_MODE_G_ONLY(pMac)) && (eBand == eCSR_BAND_5G)) {
1395 /* DOT11 mode configured to 11b/11g only and received
1396 request to change the band to 5 GHz */
1397 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1398 "failed to set band dot11mode = %u, band = %u",
1399 pMac->roam.configParam.uCfgDot11Mode, eBand);
1400 return CDF_STATUS_E_INVAL;
1401 }
1402 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
1403 "Band changed to %u (0 - ALL, 1 - 2.4 GHZ, 2 - 5GHZ)", eBand);
1404 pMac->roam.configParam.eBand = eBand;
1405 pMac->roam.configParam.bandCapability = eBand;
1406
1407 status = csr_get_channel_and_power_list(pMac);
1408 if (CDF_STATUS_SUCCESS == status)
1409 csr_apply_channel_and_power_list(pMac);
1410 return status;
1411}
1412
1413/* The funcns csr_convert_cb_ini_value_to_phy_cb_state and csr_convert_phy_cb_state_to_ini_value have been
1414 * introduced to convert the ini value to the ENUM used in csr and MAC for CB state
1415 * Ideally we should have kept the ini value and enum value same and representing the same
1416 * cb values as in 11n standard i.e.
1417 * Set to 1 (SCA) if the secondary channel is above the primary channel
1418 * Set to 3 (SCB) if the secondary channel is below the primary channel
1419 * Set to 0 (SCN) if no secondary channel is present
1420 * However, since our driver is already distributed we will keep the ini definition as it is which is:
1421 * 0 - secondary none
1422 * 1 - secondary LOW
1423 * 2 - secondary HIGH
1424 * and convert to enum value used within the driver in csr_change_default_config_param using this funcn
1425 * The enum values are as follows:
1426 * PHY_SINGLE_CHANNEL_CENTERED = 0
1427 * PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1
1428 * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3
1429 */
1430ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)
1431{
1432
1433 ePhyChanBondState phyCbState;
1434 switch (cbIniValue) {
1435 /* secondary none */
1436 case eCSR_INI_SINGLE_CHANNEL_CENTERED:
1437 phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1438 break;
1439 /* secondary LOW */
1440 case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
1441 phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1442 break;
1443 /* secondary HIGH */
1444 case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
1445 phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1446 break;
1447#ifdef WLAN_FEATURE_11AC
1448 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1449 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1450 break;
1451 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1452 phyCbState =
1453 PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1454 break;
1455 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1456 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1457 break;
1458 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1459 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1460 break;
1461 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1462 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1463 break;
1464 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1465 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1466 break;
1467 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1468 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1469 break;
1470#endif
1471 default:
1472 /* If an invalid value is passed, disable CHANNEL BONDING */
1473 phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1474 break;
1475 }
1476 return phyCbState;
1477}
1478
1479uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)
1480{
1481
1482 uint32_t cbIniValue;
1483 switch (phyCbState) {
1484 /* secondary none */
1485 case PHY_SINGLE_CHANNEL_CENTERED:
1486 cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED;
1487 break;
1488 /* secondary LOW */
1489 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1490 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
1491 break;
1492 /* secondary HIGH */
1493 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1494 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
1495 break;
1496#ifdef WLAN_FEATURE_11AC
1497 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1498 cbIniValue =
1499 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1500 break;
1501 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1502 cbIniValue =
1503 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1504 break;
1505 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1506 cbIniValue =
1507 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1508 break;
1509 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1510 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1511 break;
1512 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1513 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1514 break;
1515 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1516 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1517 break;
1518 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1519 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1520 break;
1521#endif
1522 default:
1523 /* return some invalid value */
1524 cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX;
1525 break;
1526 }
1527 return cbIniValue;
1528}
1529
1530CDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
1531 tCsrConfigParam *pParam)
1532{
1533 CDF_STATUS status = CDF_STATUS_SUCCESS;
1534
1535 if (pParam) {
1536 pMac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode;
1537 cfg_set_int(pMac, WNI_CFG_WME_ENABLED,
1538 (pParam->WMMSupportMode == eCsrRoamWmmNoQos) ? 0 : 1);
1539 pMac->roam.configParam.Is11eSupportEnabled =
1540 pParam->Is11eSupportEnabled;
1541 pMac->roam.configParam.FragmentationThreshold =
1542 pParam->FragmentationThreshold;
1543 pMac->roam.configParam.Is11dSupportEnabled =
1544 pParam->Is11dSupportEnabled;
1545 pMac->roam.configParam.Is11dSupportEnabledOriginal =
1546 pParam->Is11dSupportEnabled;
1547 pMac->roam.configParam.Is11hSupportEnabled =
1548 pParam->Is11hSupportEnabled;
1549
1550 pMac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode;
1551 pMac->roam.configParam.mcc_rts_cts_prot_enable =
1552 pParam->mcc_rts_cts_prot_enable;
1553 pMac->roam.configParam.mcc_bcast_prob_resp_enable =
1554 pParam->mcc_bcast_prob_resp_enable;
1555 pMac->roam.configParam.fAllowMCCGODiffBI =
1556 pParam->fAllowMCCGODiffBI;
1557
1558 /* channelBondingMode5GHz plays a dual role right now
1559 * INFRA STA will use this non zero value as CB enabled and SOFTAP will use this non-zero value to determine the secondary channel offset
1560 * This is how channelBondingMode5GHz works now and this is kept intact to avoid any cfg.ini change
1561 */
1562 if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI) {
1563 sms_log(pMac, LOGW,
1564 "Invalid CB value from ini in 2.4GHz band %d, CB DISABLED",
1565 pParam->channelBondingMode24GHz);
1566 }
1567 pMac->roam.configParam.channelBondingMode24GHz =
1568 csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1569 channelBondingMode24GHz);
1570 if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI) {
1571 sms_log(pMac, LOGW,
1572 "Invalid CB value from ini in 5GHz band %d, CB DISABLED",
1573 pParam->channelBondingMode5GHz);
1574 }
1575 pMac->roam.configParam.channelBondingMode5GHz =
1576 csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1577 channelBondingMode5GHz);
1578 pMac->roam.configParam.RTSThreshold = pParam->RTSThreshold;
1579 pMac->roam.configParam.phyMode = pParam->phyMode;
1580 pMac->roam.configParam.shortSlotTime = pParam->shortSlotTime;
1581 pMac->roam.configParam.HeartbeatThresh24 =
1582 pParam->HeartbeatThresh24;
1583 pMac->roam.configParam.HeartbeatThresh50 =
1584 pParam->HeartbeatThresh50;
1585 pMac->roam.configParam.ProprietaryRatesEnabled =
1586 pParam->ProprietaryRatesEnabled;
1587 pMac->roam.configParam.TxRate = pParam->TxRate;
1588 pMac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24;
1589 pMac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G;
1590 pMac->roam.configParam.bandCapability = pParam->bandCapability;
1591 pMac->roam.configParam.cbChoice = pParam->cbChoice;
1592 pMac->roam.configParam.neighborRoamConfig.
1593 delay_before_vdev_stop =
1594 pParam->neighborRoamConfig.delay_before_vdev_stop;
1595
1596 /* if HDD passed down non zero values then only update, */
1597 /* otherwise keep using the defaults */
1598 if (pParam->initial_scan_no_dfs_chnl) {
1599 pMac->roam.configParam.initial_scan_no_dfs_chnl =
1600 pParam->initial_scan_no_dfs_chnl;
1601 }
1602 if (pParam->nInitialDwellTime) {
1603 pMac->roam.configParam.nInitialDwellTime =
1604 pParam->nInitialDwellTime;
1605 }
1606 if (pParam->nActiveMaxChnTime) {
1607 pMac->roam.configParam.nActiveMaxChnTime =
1608 pParam->nActiveMaxChnTime;
1609 cfg_set_int(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
1610 pParam->nActiveMaxChnTime);
1611 }
1612 if (pParam->nActiveMinChnTime) {
1613 pMac->roam.configParam.nActiveMinChnTime =
1614 pParam->nActiveMinChnTime;
1615 cfg_set_int(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
1616 pParam->nActiveMinChnTime);
1617 }
1618 if (pParam->nPassiveMaxChnTime) {
1619 pMac->roam.configParam.nPassiveMaxChnTime =
1620 pParam->nPassiveMaxChnTime;
1621 cfg_set_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
1622 pParam->nPassiveMaxChnTime);
1623 }
1624 if (pParam->nPassiveMinChnTime) {
1625 pMac->roam.configParam.nPassiveMinChnTime =
1626 pParam->nPassiveMinChnTime;
1627 cfg_set_int(pMac, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME,
1628 pParam->nPassiveMinChnTime);
1629 }
1630#ifdef WLAN_AP_STA_CONCURRENCY
1631 if (pParam->nActiveMaxChnTimeConc) {
1632 pMac->roam.configParam.nActiveMaxChnTimeConc =
1633 pParam->nActiveMaxChnTimeConc;
1634 }
1635 if (pParam->nActiveMinChnTimeConc) {
1636 pMac->roam.configParam.nActiveMinChnTimeConc =
1637 pParam->nActiveMinChnTimeConc;
1638 }
1639 if (pParam->nPassiveMaxChnTimeConc) {
1640 pMac->roam.configParam.nPassiveMaxChnTimeConc =
1641 pParam->nPassiveMaxChnTimeConc;
1642 }
1643 if (pParam->nPassiveMinChnTimeConc) {
1644 pMac->roam.configParam.nPassiveMinChnTimeConc =
1645 pParam->nPassiveMinChnTimeConc;
1646 }
1647 if (pParam->nRestTimeConc) {
1648 pMac->roam.configParam.nRestTimeConc =
1649 pParam->nRestTimeConc;
1650 }
1651 if (pParam->nNumStaChanCombinedConc) {
1652 pMac->roam.configParam.nNumStaChanCombinedConc =
1653 pParam->nNumStaChanCombinedConc;
1654 }
1655 if (pParam->nNumP2PChanCombinedConc) {
1656 pMac->roam.configParam.nNumP2PChanCombinedConc =
1657 pParam->nNumP2PChanCombinedConc;
1658 }
1659#endif
1660 pMac->roam.configParam.eBand = pParam->eBand;
1661 pMac->roam.configParam.uCfgDot11Mode =
1662 csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
1663 pMac->roam.configParam.
1664 phyMode,
1665 pMac->roam.configParam.
1666 ProprietaryRatesEnabled);
1667 /* if HDD passed down non zero values for age params, then only update, */
1668 /* otherwise keep using the defaults */
1669 if (pParam->nScanResultAgeCount) {
1670 pMac->roam.configParam.agingCount =
1671 pParam->nScanResultAgeCount;
1672 }
1673 if (pParam->scanAgeTimeNCNPS) {
1674 pMac->roam.configParam.scanAgeTimeNCNPS =
1675 pParam->scanAgeTimeNCNPS;
1676 }
1677 if (pParam->scanAgeTimeNCPS) {
1678 pMac->roam.configParam.scanAgeTimeNCPS =
1679 pParam->scanAgeTimeNCPS;
1680 }
1681 if (pParam->scanAgeTimeCNPS) {
1682 pMac->roam.configParam.scanAgeTimeCNPS =
1683 pParam->scanAgeTimeCNPS;
1684 }
1685 if (pParam->scanAgeTimeCPS) {
1686 pMac->roam.configParam.scanAgeTimeCPS =
1687 pParam->scanAgeTimeCPS;
1688 }
1689
1690 csr_assign_rssi_for_category(pMac, CSR_BEST_RSSI_VALUE,
1691 pParam->bCatRssiOffset);
1692 pMac->roam.configParam.nRoamingTime = pParam->nRoamingTime;
1693 pMac->roam.configParam.fSupplicantCountryCodeHasPriority =
1694 pParam->fSupplicantCountryCodeHasPriority;
1695 pMac->roam.configParam.vccRssiThreshold =
1696 pParam->vccRssiThreshold;
1697 pMac->roam.configParam.vccUlMacLossThreshold =
1698 pParam->vccUlMacLossThreshold;
1699 pMac->roam.configParam.statsReqPeriodicity =
1700 pParam->statsReqPeriodicity;
1701 pMac->roam.configParam.statsReqPeriodicityInPS =
1702 pParam->statsReqPeriodicityInPS;
1703 /* Assign this before calling csr_init11d_info */
1704 pMac->roam.configParam.nTxPowerCap = pParam->nTxPowerCap;
1705 if (csr_is11d_supported(pMac)) {
1706 status = csr_init11d_info(pMac, &pParam->Csr11dinfo);
1707 } else {
1708 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
1709 }
1710
1711 /* Initialize the power + channel information if 11h is enabled.
1712 If 11d is enabled this information has already been initialized */
1713 if (csr_is11h_supported(pMac) && !csr_is11d_supported(pMac)) {
1714 csr_init_channel_power_list(pMac, &pParam->Csr11dinfo);
1715 }
1716
1717#ifdef WLAN_FEATURE_VOWIFI_11R
1718 cdf_mem_copy(&pMac->roam.configParam.csr11rConfig,
1719 &pParam->csr11rConfig,
1720 sizeof(tCsr11rConfigParams));
1721 sms_log(pMac, LOG1, "IsFTResourceReqSupp = %d",
1722 pMac->roam.configParam.csr11rConfig.
1723 IsFTResourceReqSupported);
1724#endif
1725#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
1726 pMac->roam.configParam.isFastTransitionEnabled =
1727 pParam->isFastTransitionEnabled;
1728 pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff;
1729 pMac->roam.configParam.nRoamPrefer5GHz =
1730 pParam->nRoamPrefer5GHz;
1731 pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand;
1732 pMac->roam.configParam.isWESModeEnabled =
1733 pParam->isWESModeEnabled;
1734 pMac->roam.configParam.nProbes = pParam->nProbes;
1735 pMac->roam.configParam.nRoamScanHomeAwayTime =
1736 pParam->nRoamScanHomeAwayTime;
1737#endif
1738 pMac->roam.configParam.isRoamOffloadScanEnabled =
1739 pParam->isRoamOffloadScanEnabled;
1740 pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
1741 pParam->bFastRoamInConIniFeatureEnabled;
1742#ifdef FEATURE_WLAN_LFR
1743 pMac->roam.configParam.isFastRoamIniFeatureEnabled =
1744 pParam->isFastRoamIniFeatureEnabled;
1745 pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled;
1746#endif
1747
1748#ifdef FEATURE_WLAN_ESE
1749 pMac->roam.configParam.isEseIniFeatureEnabled =
1750 pParam->isEseIniFeatureEnabled;
1751#endif
1752#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
1753 cdf_mem_copy(&pMac->roam.configParam.neighborRoamConfig,
1754 &pParam->neighborRoamConfig,
1755 sizeof(tCsrNeighborRoamConfigParams));
1756 sms_log(pMac, LOG1, "nNeighborScanTimerPerioid = %d",
1757 pMac->roam.configParam.neighborRoamConfig.
1758 nNeighborScanTimerPeriod);
1759 sms_log(pMac, LOG1, "nNeighborLookupRssiThreshold = %d",
1760 pMac->roam.configParam.neighborRoamConfig.
1761 nNeighborLookupRssiThreshold);
1762 sms_log(pMac, LOG1, "nOpportunisticThresholdDiff = %d",
1763 pMac->roam.configParam.neighborRoamConfig.
1764 nOpportunisticThresholdDiff);
1765 sms_log(pMac, LOG1, "nRoamRescanRssiDiff = %d",
1766 pMac->roam.configParam.neighborRoamConfig.
1767 nRoamRescanRssiDiff);
1768 sms_log(pMac, LOG1, "nNeighborScanMinChanTime = %d",
1769 pMac->roam.configParam.neighborRoamConfig.
1770 nNeighborScanMinChanTime);
1771 sms_log(pMac, LOG1, "nNeighborScanMaxChanTime = %d",
1772 pMac->roam.configParam.neighborRoamConfig.
1773 nNeighborScanMaxChanTime);
1774 sms_log(pMac, LOG1, "nMaxNeighborRetries = %d",
1775 pMac->roam.configParam.neighborRoamConfig.
1776 nMaxNeighborRetries);
1777 sms_log(pMac, LOG1, "nNeighborResultsRefreshPeriod = %d",
1778 pMac->roam.configParam.neighborRoamConfig.
1779 nNeighborResultsRefreshPeriod);
1780 sms_log(pMac, LOG1, "nEmptyScanRefreshPeriod = %d",
1781 pMac->roam.configParam.neighborRoamConfig.
1782 nEmptyScanRefreshPeriod);
1783 {
1784 int i;
1785 sms_log(pMac, LOG1,
1786 FL("Num of Channels in CFG Channel List: %d"),
1787 pMac->roam.configParam.neighborRoamConfig.
1788 neighborScanChanList.numChannels);
1789 for (i = 0;
1790 i <
1791 pMac->roam.configParam.neighborRoamConfig.
1792 neighborScanChanList.numChannels; i++) {
1793 sms_log(pMac, LOG1, "%d ",
1794 pMac->roam.configParam.
1795 neighborRoamConfig.neighborScanChanList.
1796 channelList[i]);
1797 }
1798 }
1799 sms_log(pMac, LOG1, "nRoamBmissFirstBcnt = %d",
1800 pMac->roam.configParam.neighborRoamConfig.
1801 nRoamBmissFirstBcnt);
1802 sms_log(pMac, LOG1, "nRoamBmissFinalBcnt = %d",
1803 pMac->roam.configParam.neighborRoamConfig.
1804 nRoamBmissFinalBcnt);
1805 sms_log(pMac, LOG1, "nRoamBeaconRssiWeight = %d",
1806 pMac->roam.configParam.neighborRoamConfig.
1807 nRoamBeaconRssiWeight);
1808#endif
1809 pMac->roam.configParam.addTSWhenACMIsOff =
1810 pParam->addTSWhenACMIsOff;
1811 pMac->scan.fValidateList = pParam->fValidateList;
1812 pMac->scan.fEnableBypass11d = pParam->fEnableBypass11d;
1813 pMac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan;
1814 pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime;
1815 pMac->roam.configParam.fScanTwice = pParam->fScanTwice;
1816 pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl;
1817 pMac->scan.max_scan_count = pParam->max_scan_count;
1818 /* This parameter is not available in cfg and not passed from upper layers. Instead it is initialized here
1819 * This paramtere is used in concurrency to determine if there are concurrent active sessions.
1820 * Is used as a temporary fix to disconnect all active sessions when BMPS enabled so the active session if Infra STA
1821 * will automatically connect back and resume BMPS since resume BMPS is not working when moving from concurrent to
1822 * single session
1823 */
1824 /* Remove this code once SLM_Sessionization is supported */
1825 /* BMPS_WORKAROUND_NOT_NEEDED */
1826 pMac->roam.configParam.doBMPSWorkaround = 0;
1827
1828#ifdef WLAN_FEATURE_11AC
1829 pMac->roam.configParam.nVhtChannelWidth =
1830 pParam->nVhtChannelWidth;
1831 pMac->roam.configParam.txBFEnable = pParam->enableTxBF;
1832 pMac->roam.configParam.txBFCsnValue = pParam->txBFCsnValue;
1833 pMac->roam.configParam.enable2x2 = pParam->enable2x2;
1834 pMac->roam.configParam.enableVhtFor24GHz =
1835 pParam->enableVhtFor24GHz;
1836 pMac->roam.configParam.txMuBformee = pParam->enableMuBformee;
1837 pMac->roam.configParam.enableVhtpAid = pParam->enableVhtpAid;
1838 pMac->roam.configParam.enableVhtGid = pParam->enableVhtGid;
1839#endif
1840 pMac->roam.configParam.enableAmpduPs = pParam->enableAmpduPs;
1841 pMac->roam.configParam.enableHtSmps = pParam->enableHtSmps;
1842 pMac->roam.configParam.htSmps = pParam->htSmps;
1843 pMac->roam.configParam.txLdpcEnable = pParam->enableTxLdpc;
1844 pMac->roam.configParam.ignore_peer_erp_info =
1845 pParam->ignore_peer_erp_info;
1846 pMac->roam.configParam.isAmsduSupportInAMPDU =
1847 pParam->isAmsduSupportInAMPDU;
1848 pMac->roam.configParam.nSelect5GHzMargin =
1849 pParam->nSelect5GHzMargin;
1850 pMac->roam.configParam.isCoalesingInIBSSAllowed =
1851 pParam->isCoalesingInIBSSAllowed;
1852#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1853 pMac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode;
1854#endif
1855 pMac->roam.configParam.allowDFSChannelRoam =
1856 pParam->allowDFSChannelRoam;
1857#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1858 pMac->roam.configParam.isRoamOffloadEnabled =
1859 pParam->isRoamOffloadEnabled;
1860#endif
1861 pMac->roam.configParam.obssEnabled = pParam->obssEnabled;
1862 pMac->roam.configParam.conc_custom_rule1 =
1863 pParam->conc_custom_rule1;
1864 pMac->roam.configParam.conc_custom_rule2 =
1865 pParam->conc_custom_rule2;
1866 pMac->roam.configParam.is_sta_connection_in_5gz_enabled =
1867 pParam->is_sta_connection_in_5gz_enabled;
1868 pMac->roam.configParam.sendDeauthBeforeCon =
1869 pParam->sendDeauthBeforeCon;
1870
1871 pMac->enable_dot11p = pParam->enable_dot11p;
1872 }
1873
1874 return status;
1875}
1876
1877CDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
1878{
1879 int i;
1880 tCsrConfig *cfg_params = &pMac->roam.configParam;
1881
1882 if (!pParam)
1883 return CDF_STATUS_E_INVAL;
1884
1885 pParam->WMMSupportMode = cfg_params->WMMSupportMode;
1886 pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled;
1887 pParam->FragmentationThreshold = cfg_params->FragmentationThreshold;
1888 pParam->Is11dSupportEnabled = cfg_params->Is11dSupportEnabled;
1889 pParam->Is11dSupportEnabledOriginal =
1890 cfg_params->Is11dSupportEnabledOriginal;
1891 pParam->Is11hSupportEnabled = cfg_params->Is11hSupportEnabled;
1892 pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value(
1893 cfg_params->channelBondingMode24GHz);
1894 pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value(
1895 cfg_params->channelBondingMode5GHz);
1896 pParam->RTSThreshold = cfg_params->RTSThreshold;
1897 pParam->phyMode = cfg_params->phyMode;
1898 pParam->shortSlotTime = cfg_params->shortSlotTime;
1899 pParam->HeartbeatThresh24 = cfg_params->HeartbeatThresh24;
1900 pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50;
1901 pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled;
1902 pParam->TxRate = cfg_params->TxRate;
1903 pParam->AdHocChannel24 = cfg_params->AdHocChannel24;
1904 pParam->AdHocChannel5G = cfg_params->AdHocChannel5G;
1905 pParam->bandCapability = cfg_params->bandCapability;
1906 pParam->cbChoice = cfg_params->cbChoice;
1907 pParam->nActiveMaxChnTime = cfg_params->nActiveMaxChnTime;
1908 pParam->nActiveMinChnTime = cfg_params->nActiveMinChnTime;
1909 pParam->nPassiveMaxChnTime = cfg_params->nPassiveMaxChnTime;
1910 pParam->nPassiveMinChnTime = cfg_params->nPassiveMinChnTime;
1911#ifdef WLAN_AP_STA_CONCURRENCY
1912 pParam->nActiveMaxChnTimeConc = cfg_params->nActiveMaxChnTimeConc;
1913 pParam->nActiveMinChnTimeConc = cfg_params->nActiveMinChnTimeConc;
1914 pParam->nPassiveMaxChnTimeConc = cfg_params->nPassiveMaxChnTimeConc;
1915 pParam->nPassiveMinChnTimeConc = cfg_params->nPassiveMinChnTimeConc;
1916 pParam->nRestTimeConc = cfg_params->nRestTimeConc;
1917 pParam->nNumStaChanCombinedConc = cfg_params->nNumStaChanCombinedConc;
1918 pParam->nNumP2PChanCombinedConc = cfg_params->nNumP2PChanCombinedConc;
1919#endif
1920 pParam->eBand = cfg_params->eBand;
1921 pParam->nScanResultAgeCount = cfg_params->agingCount;
1922 pParam->scanAgeTimeNCNPS = cfg_params->scanAgeTimeNCNPS;
1923 pParam->scanAgeTimeNCPS = cfg_params->scanAgeTimeNCPS;
1924 pParam->scanAgeTimeCNPS = cfg_params->scanAgeTimeCNPS;
1925 pParam->scanAgeTimeCPS = cfg_params->scanAgeTimeCPS;
1926 pParam->bCatRssiOffset = cfg_params->bCatRssiOffset;
1927 pParam->nRoamingTime = cfg_params->nRoamingTime;
1928 pParam->fSupplicantCountryCodeHasPriority =
1929 cfg_params->fSupplicantCountryCodeHasPriority;
1930 pParam->vccRssiThreshold = cfg_params->vccRssiThreshold;
1931 pParam->vccUlMacLossThreshold = cfg_params->vccUlMacLossThreshold;
1932 pParam->nTxPowerCap = cfg_params->nTxPowerCap;
1933 pParam->statsReqPeriodicity = cfg_params->statsReqPeriodicity;
1934 pParam->statsReqPeriodicityInPS = cfg_params->statsReqPeriodicityInPS;
1935 pParam->addTSWhenACMIsOff = cfg_params->addTSWhenACMIsOff;
1936 pParam->fValidateList = cfg_params->fValidateList;
1937 pParam->fEnableBypass11d = pMac->scan.fEnableBypass11d;
1938 pParam->fEnableDFSChnlScan = pMac->scan.fEnableDFSChnlScan;
1939 pParam->fScanTwice = cfg_params->fScanTwice;
1940 pParam->fFirstScanOnly2GChnl = pMac->scan.fFirstScanOnly2GChnl;
1941 pParam->fEnableMCCMode = cfg_params->fenableMCCMode;
1942 pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI;
1943 pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime;
1944#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
1945 cdf_mem_copy(&pParam->neighborRoamConfig,
1946 &cfg_params->neighborRoamConfig,
1947 sizeof(tCsrNeighborRoamConfigParams));
1948#endif
1949#ifdef WLAN_FEATURE_11AC
1950 pParam->nVhtChannelWidth = cfg_params->nVhtChannelWidth;
1951 pParam->enableTxBF = cfg_params->txBFEnable;
1952 pParam->txBFCsnValue = cfg_params->txBFCsnValue;
1953 pParam->enableMuBformee = cfg_params->txMuBformee;
1954 pParam->enableVhtFor24GHz = cfg_params->enableVhtFor24GHz;
1955 pParam->ignore_peer_erp_info = cfg_params->ignore_peer_erp_info;
1956 pParam->enable2x2 = cfg_params->enable2x2;
1957#endif
1958#ifdef WLAN_FEATURE_VOWIFI_11R
1959 cdf_mem_copy(&cfg_params->csr11rConfig, &pParam->csr11rConfig,
1960 sizeof(tCsr11rConfigParams));
1961#endif
1962#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
1963 pParam->isFastTransitionEnabled = cfg_params->isFastTransitionEnabled;
1964 pParam->RoamRssiDiff = cfg_params->RoamRssiDiff;
1965 pParam->nRoamPrefer5GHz = cfg_params->nRoamPrefer5GHz;
1966 pParam->nRoamIntraBand = cfg_params->nRoamIntraBand;
1967 pParam->isWESModeEnabled = cfg_params->isWESModeEnabled;
1968 pParam->nProbes = cfg_params->nProbes;
1969 pParam->nRoamScanHomeAwayTime = cfg_params->nRoamScanHomeAwayTime;
1970#endif
1971 pParam->isRoamOffloadScanEnabled = cfg_params->isRoamOffloadScanEnabled;
1972 pParam->bFastRoamInConIniFeatureEnabled =
1973 cfg_params->bFastRoamInConIniFeatureEnabled;
1974#ifdef FEATURE_WLAN_LFR
1975 pParam->isFastRoamIniFeatureEnabled =
1976 cfg_params->isFastRoamIniFeatureEnabled;
1977#endif
1978#ifdef FEATURE_WLAN_ESE
1979 pParam->isEseIniFeatureEnabled = cfg_params->isEseIniFeatureEnabled;
1980#endif
1981#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
1982 cdf_mem_copy(&pParam->neighborRoamConfig,
1983 &cfg_params->neighborRoamConfig,
1984 sizeof(tCsrNeighborRoamConfigParams));
1985 sms_log(pMac, LOG1,
1986 FL("Num of Channels in CFG Channel List: %d"),
1987 cfg_params->neighborRoamConfig.
1988 neighborScanChanList.numChannels);
1989 for (i = 0; i < cfg_params->neighborRoamConfig.
1990 neighborScanChanList.numChannels; i++) {
1991 sms_log(pMac, LOG1, "%d ",
1992 cfg_params->neighborRoamConfig.
1993 neighborScanChanList.channelList[i]);
1994 }
1995#endif
1996
1997#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1998 pParam->cc_switch_mode = cfg_params->cc_switch_mode;
1999#endif
2000 pParam->enableTxLdpc = cfg_params->txLdpcEnable;
2001 pParam->isAmsduSupportInAMPDU = cfg_params->isAmsduSupportInAMPDU;
2002 pParam->nSelect5GHzMargin = cfg_params->nSelect5GHzMargin;
2003 pParam->isCoalesingInIBSSAllowed = cfg_params->isCoalesingInIBSSAllowed;
2004 pParam->allowDFSChannelRoam = cfg_params->allowDFSChannelRoam;
2005 pParam->nInitialDwellTime = cfg_params->nInitialDwellTime;
2006 pParam->initial_scan_no_dfs_chnl = cfg_params->initial_scan_no_dfs_chnl;
2007#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2008 pParam->isRoamOffloadEnabled = cfg_params->isRoamOffloadEnabled;
2009#endif
2010 pParam->enable_dot11p = pMac->enable_dot11p;
2011 csr_set_channels(pMac, pParam);
2012 pParam->obssEnabled = cfg_params->obssEnabled;
2013 pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
2014 pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
2015 pParam->is_sta_connection_in_5gz_enabled =
2016 cfg_params->is_sta_connection_in_5gz_enabled;
2017 pParam->sendDeauthBeforeCon =
2018 cfg_params->sendDeauthBeforeCon;
2019 pParam->max_scan_count = pMac->scan.max_scan_count;
2020 return CDF_STATUS_SUCCESS;
2021}
2022
2023CDF_STATUS csr_set_phy_mode(tHalHandle hHal, uint32_t phyMode, eCsrBand eBand,
2024 bool *pfRestartNeeded)
2025{
2026 CDF_STATUS status = CDF_STATUS_E_INVAL;
2027 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2028 bool fRestartNeeded = false;
2029 eCsrPhyMode newPhyMode = eCSR_DOT11_MODE_AUTO;
2030 if (eCSR_BAND_24 == eBand) {
2031 if (CSR_IS_RADIO_A_ONLY(pMac))
2032 goto end;
2033 if (eCSR_DOT11_MODE_11a & phyMode)
2034 goto end;
2035 }
2036 if (eCSR_BAND_5G == eBand) {
2037 if (CSR_IS_RADIO_BG_ONLY(pMac))
2038 goto end;
2039 if ((eCSR_DOT11_MODE_11b & phyMode)
2040 || (eCSR_DOT11_MODE_11b_ONLY & phyMode)
2041 || (eCSR_DOT11_MODE_11g & phyMode)
2042 || (eCSR_DOT11_MODE_11g_ONLY & phyMode))
2043 goto end;
2044 }
2045 if (eCSR_DOT11_MODE_AUTO & phyMode)
2046 newPhyMode = eCSR_DOT11_MODE_AUTO;
2047 else {
2048 /* Check for dual band and higher capability first */
2049 if (eCSR_DOT11_MODE_11n_ONLY & phyMode) {
2050 if (eCSR_DOT11_MODE_11n_ONLY != phyMode)
2051 goto end;
2052 newPhyMode = eCSR_DOT11_MODE_11n_ONLY;
2053 } else if (eCSR_DOT11_MODE_11g_ONLY & phyMode) {
2054 if (eCSR_DOT11_MODE_11g_ONLY != phyMode)
2055 goto end;
2056 if (eCSR_BAND_5G == eBand)
2057 goto end;
2058 newPhyMode = eCSR_DOT11_MODE_11g_ONLY;
2059 eBand = eCSR_BAND_24;
2060 } else if (eCSR_DOT11_MODE_11b_ONLY & phyMode) {
2061 if (eCSR_DOT11_MODE_11b_ONLY != phyMode)
2062 goto end;
2063 if (eCSR_BAND_5G == eBand)
2064 goto end;
2065 newPhyMode = eCSR_DOT11_MODE_11b_ONLY;
2066 eBand = eCSR_BAND_24;
2067 } else if (eCSR_DOT11_MODE_11n & phyMode) {
2068 newPhyMode = eCSR_DOT11_MODE_11n;
2069 } else if (eCSR_DOT11_MODE_abg & phyMode) {
2070 newPhyMode = eCSR_DOT11_MODE_abg;
2071 } else if (eCSR_DOT11_MODE_11a & phyMode) {
2072 if ((eCSR_DOT11_MODE_11g & phyMode)
2073 || (eCSR_DOT11_MODE_11b & phyMode)) {
2074 if (eCSR_BAND_ALL == eBand)
2075 newPhyMode = eCSR_DOT11_MODE_abg;
2076 else
2077 goto end;
2078 } else {
2079 newPhyMode = eCSR_DOT11_MODE_11a;
2080 eBand = eCSR_BAND_5G;
2081 }
2082 } else if (eCSR_DOT11_MODE_11g & phyMode) {
2083 newPhyMode = eCSR_DOT11_MODE_11g;
2084 eBand = eCSR_BAND_24;
2085 } else if (eCSR_DOT11_MODE_11b & phyMode) {
2086 newPhyMode = eCSR_DOT11_MODE_11b;
2087 eBand = eCSR_BAND_24;
2088 } else {
2089 /* We will never be here */
2090 sms_log(pMac, LOGE,
2091 FL("can't recognize phymode 0x%08X"),
2092 phyMode);
2093 newPhyMode = eCSR_DOT11_MODE_AUTO;
2094 }
2095 }
2096 /* Done validating */
2097 status = CDF_STATUS_SUCCESS;
2098 /* Now we need to check whether a restart is needed. */
2099 if (eBand != pMac->roam.configParam.eBand) {
2100 fRestartNeeded = true;
2101 goto end;
2102 }
2103 if (newPhyMode != pMac->roam.configParam.phyMode) {
2104 fRestartNeeded = true;
2105 goto end;
2106 }
2107end:
2108 if (CDF_IS_STATUS_SUCCESS(status)) {
2109 pMac->roam.configParam.eBand = eBand;
2110 pMac->roam.configParam.phyMode = newPhyMode;
2111 if (pfRestartNeeded)
2112 *pfRestartNeeded = fRestartNeeded;
2113 }
2114 return status;
2115}
2116
2117/**
2118 * csr_prune_ch_list() - prunes the channel list to keep only a type of channels
2119 * @ch_lst: existing channel list
2120 * @is_24_GHz: indicates if 2.5 GHz or 5 GHz channels are required
2121 *
2122 * Return: void
2123 */
2124void csr_prune_ch_list(tCsrChannel *ch_lst, bool is_24_GHz)
2125{
2126 uint8_t idx = 0, num_channels = 0;
2127 for ( ; idx < ch_lst->numChannels; idx++) {
2128 if (is_24_GHz) {
2129 if (CDS_IS_CHANNEL_24GHZ(ch_lst->channelList[idx])) {
2130 ch_lst->channelList[num_channels] =
2131 ch_lst->channelList[idx];
2132 num_channels++;
2133 }
2134 } else {
2135 if (CDS_IS_CHANNEL_5GHZ(ch_lst->channelList[idx])) {
2136 ch_lst->channelList[num_channels] =
2137 ch_lst->channelList[idx];
2138 num_channels++;
2139 }
2140 }
2141 }
2142 /*
2143 * Cleanup the rest of channels. Note we only need to clean up the
2144 * channels if we had to trim the list. Calling cdf_mem_set() with a 0
2145 * size is going to throw asserts on the debug builds so let's be a bit
2146 * smarter about that. Zero out the reset of the channels only if we
2147 * need to. The amount of memory to clear is the number of channesl that
2148 * we trimmed (ch_lst->numChannels - num_channels) times the size of a
2149 * channel in the structure.
2150 */
2151 if (ch_lst->numChannels > num_channels) {
2152 cdf_mem_set(&ch_lst->channelList[num_channels],
2153 sizeof(ch_lst->channelList[0]) *
2154 (ch_lst->numChannels - num_channels), 0);
2155 }
2156 ch_lst->numChannels = num_channels;
2157}
2158
2159/**
2160 * csr_prune_channel_list_for_mode() - prunes the channel list
2161 * @mac_ctx: global mac context
2162 * @ch_lst: existing channel list
2163 *
2164 * Prunes the channel list according to band stored in mac_ctx
2165 *
2166 * Return: void
2167 */
2168void csr_prune_channel_list_for_mode(tpAniSirGlobal mac_ctx,
2169 tCsrChannel *ch_lst)
2170{
2171 /* for dual band NICs, don't need to trim the channel list.... */
2172 if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx))
2173 return;
2174 /*
2175 * 2.4 GHz band operation requires the channel list to be trimmed to
2176 * the 2.4 GHz channels only
2177 */
2178 if (CSR_IS_24_BAND_ONLY(mac_ctx))
2179 csr_prune_ch_list(ch_lst, true);
2180 else if (CSR_IS_5G_BAND_ONLY(mac_ctx))
2181 csr_prune_ch_list(ch_lst, false);
2182}
2183
2184#define INFRA_AP_DEFAULT_CHANNEL 6
2185CDF_STATUS csr_is_valid_channel(tpAniSirGlobal pMac, uint8_t chnNum)
2186{
2187 uint8_t index = 0;
2188 CDF_STATUS status = CDF_STATUS_E_NOSUPPORT;
2189
2190 /* regulatory check */
2191 for (index = 0; index < pMac->scan.base_channels.numChannels;
2192 index++) {
2193 if (pMac->scan.base_channels.channelList[index] == chnNum) {
2194 status = CDF_STATUS_SUCCESS;
2195 break;
2196 }
2197 }
2198
2199 if (status == CDF_STATUS_SUCCESS) {
2200 /* dfs nol */
2201 for (index = 0;
2202 index <
2203 pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
2204 index++) {
2205 tSapDfsNolInfo *dfsChan =
2206 &pMac->sap.SapDfsInfo.sapDfsChannelNolList[index];
2207 if ((dfsChan->dfs_channel_number == chnNum)
2208 && (dfsChan->radar_status_flag ==
2209 eSAP_DFS_CHANNEL_UNAVAILABLE)) {
2210 CDF_TRACE(CDF_MODULE_ID_SME,
2211 CDF_TRACE_LEVEL_ERROR,
2212 FL("channel %d is in dfs nol"),
2213 chnNum);
2214 status = CDF_STATUS_E_FAILURE;
2215 break;
2216 }
2217 }
2218 }
2219
2220 if (CDF_STATUS_SUCCESS != status) {
2221 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
2222 FL("channel %d is not available"), chnNum);
2223 }
2224
2225 return status;
2226}
2227
2228CDF_STATUS csr_get_channel_and_power_list(tpAniSirGlobal pMac)
2229{
2230 CDF_STATUS status = CDF_STATUS_SUCCESS;
2231 uint8_t num20MHzChannelsFound = 0;
2232 CDF_STATUS cdf_status;
2233 uint8_t Index = 0;
2234 uint8_t num40MHzChannelsFound = 0;
2235
2236 /* TODO: this interface changed to include the 40MHz channel list */
2237 /* this needs to be tied into the adapter structure somehow and referenced appropriately for CB operation */
2238 /* Read the scan channel list (including the power limit) from EEPROM */
2239 cdf_status =
2240 cds_get_channel_list_with_power(pMac->scan.defaultPowerTable,
2241 &num20MHzChannelsFound,
2242 pMac->scan.defaultPowerTable40MHz,
2243 &num40MHzChannelsFound);
2244 if ((CDF_STATUS_SUCCESS != cdf_status) || (num20MHzChannelsFound == 0)) {
2245 sms_log(pMac, LOGE, FL("failed to get channels "));
2246 status = CDF_STATUS_E_FAILURE;
2247 } else {
2248 if (num20MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
2249 num20MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN;
2250 }
2251 pMac->scan.numChannelsDefault = num20MHzChannelsFound;
2252 /* Move the channel list to the global data */
2253 /* structure -- this will be used as the scan list */
2254 for (Index = 0; Index < num20MHzChannelsFound; Index++) {
2255 pMac->scan.base_channels.channelList[Index] =
2256 pMac->scan.defaultPowerTable[Index].chanId;
2257 }
2258 pMac->scan.base_channels.numChannels =
2259 num20MHzChannelsFound;
2260 if (num40MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
2261 num40MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN;
2262 }
2263 for (Index = 0; Index < num40MHzChannelsFound; Index++) {
2264 pMac->scan.base40MHzChannels.channelList[Index] =
2265 pMac->scan.defaultPowerTable40MHz[Index].chanId;
2266 }
2267 pMac->scan.base40MHzChannels.numChannels =
2268 num40MHzChannelsFound;
2269 }
2270 return status;
2271}
2272
2273CDF_STATUS csr_apply_channel_and_power_list(tpAniSirGlobal pMac)
2274{
2275 CDF_STATUS status = CDF_STATUS_SUCCESS;
2276
2277 csr_prune_channel_list_for_mode(pMac, &pMac->scan.base_channels);
2278 csr_save_channel_power_for_band(pMac, false);
2279 csr_save_channel_power_for_band(pMac, true);
2280 /* Apply the base channel list, power info, and set the Country code... */
2281 csr_apply_channel_power_info_to_fw(pMac,
2282 &pMac->scan.base_channels,
2283 pMac->scan.countryCodeCurrent);
2284
2285 csr_init_operating_classes((tHalHandle) pMac);
2286 return status;
2287}
2288
2289CDF_STATUS csr_change_config_params(tpAniSirGlobal pMac,
2290 tCsrUpdateConfigParam *pUpdateConfigParam)
2291{
2292 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2293 tCsr11dinfo *ps11dinfo = NULL;
2294 ps11dinfo = &pUpdateConfigParam->Csr11dinfo;
2295 status = csr_init11d_info(pMac, ps11dinfo);
2296 return status;
2297}
2298
2299static CDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo)
2300{
2301 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2302 uint8_t index;
2303 uint32_t count = 0;
2304 tSirMacChanInfo *pChanInfo;
2305 tSirMacChanInfo *pChanInfoStart;
2306 bool applyConfig = true;
2307
2308 pMac->scan.currentCountryRSSI = -128;
2309 if (!ps11dinfo) {
2310 return status;
2311 }
2312 if (ps11dinfo->Channels.numChannels
2313 && (WNI_CFG_VALID_CHANNEL_LIST_LEN >=
2314 ps11dinfo->Channels.numChannels)) {
2315 pMac->scan.base_channels.numChannels =
2316 ps11dinfo->Channels.numChannels;
2317 cdf_mem_copy(pMac->scan.base_channels.channelList,
2318 ps11dinfo->Channels.channelList,
2319 ps11dinfo->Channels.numChannels);
2320 } else {
2321 /* No change */
2322 return CDF_STATUS_SUCCESS;
2323 }
2324 /* legacy maintenance */
2325
2326 cdf_mem_copy(pMac->scan.countryCodeDefault, ps11dinfo->countryCode,
2327 WNI_CFG_COUNTRY_CODE_LEN);
2328
2329 /* Tush: at csropen get this initialized with default, during csr reset if this */
2330 /* already set with some value no need initilaize with default again */
2331 if (0 == pMac->scan.countryCodeCurrent[0]) {
2332 cdf_mem_copy(pMac->scan.countryCodeCurrent,
2333 ps11dinfo->countryCode, WNI_CFG_COUNTRY_CODE_LEN);
2334 }
2335 /* need to add the max power channel list */
2336 pChanInfo =
2337 cdf_mem_malloc(sizeof(tSirMacChanInfo) *
2338 WNI_CFG_VALID_CHANNEL_LIST_LEN);
2339 if (pChanInfo != NULL) {
2340 cdf_mem_set(pChanInfo,
2341 sizeof(tSirMacChanInfo) *
2342 WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
2343
2344 pChanInfoStart = pChanInfo;
2345 for (index = 0; index < ps11dinfo->Channels.numChannels;
2346 index++) {
2347 pChanInfo->firstChanNum =
2348 ps11dinfo->ChnPower[index].firstChannel;
2349 pChanInfo->numChannels =
2350 ps11dinfo->ChnPower[index].numChannels;
2351 pChanInfo->maxTxPower =
2352 CDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
2353 pMac->roam.configParam.nTxPowerCap);
2354 pChanInfo++;
2355 count++;
2356 }
2357 if (count) {
2358 csr_save_to_channel_power2_g_5_g(pMac,
2359 count *
2360 sizeof(tSirMacChanInfo),
2361 pChanInfoStart);
2362 }
2363 cdf_mem_free(pChanInfoStart);
2364 }
2365 /* Only apply them to CFG when not in STOP state. Otherwise they will be applied later */
2366 if (CDF_IS_STATUS_SUCCESS(status)) {
2367 for (index = 0; index < CSR_ROAM_SESSION_MAX; index++) {
2368 if ((CSR_IS_SESSION_VALID(pMac, index))
2369 && CSR_IS_ROAM_STOP(pMac, index)) {
2370 applyConfig = false;
2371 }
2372 }
2373
2374 if (true == applyConfig) {
2375 /* Apply the base channel list, power info, and set the Country code... */
2376 csr_apply_channel_power_info_to_fw(pMac,
2377 &pMac->scan.
2378 base_channels,
2379 pMac->scan.
2380 countryCodeCurrent);
2381 }
2382 }
2383 return status;
2384}
2385
2386/* Initialize the Channel + Power List in the local cache and in the CFG */
2387CDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo)
2388{
2389 uint8_t index;
2390 uint32_t count = 0;
2391 tSirMacChanInfo *pChanInfo;
2392 tSirMacChanInfo *pChanInfoStart;
2393
2394 if (!ps11dinfo || !pMac) {
2395 return CDF_STATUS_E_FAILURE;
2396 }
2397
2398 pChanInfo =
2399 cdf_mem_malloc(sizeof(tSirMacChanInfo) *
2400 WNI_CFG_VALID_CHANNEL_LIST_LEN);
2401 if (pChanInfo != NULL) {
2402 cdf_mem_set(pChanInfo,
2403 sizeof(tSirMacChanInfo) *
2404 WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
2405 pChanInfoStart = pChanInfo;
2406
2407 for (index = 0; index < ps11dinfo->Channels.numChannels;
2408 index++) {
2409 pChanInfo->firstChanNum =
2410 ps11dinfo->ChnPower[index].firstChannel;
2411 pChanInfo->numChannels =
2412 ps11dinfo->ChnPower[index].numChannels;
2413 pChanInfo->maxTxPower =
2414 CDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
2415 pMac->roam.configParam.nTxPowerCap);
2416 pChanInfo++;
2417 count++;
2418 }
2419 if (count) {
2420 csr_save_to_channel_power2_g_5_g(pMac,
2421 count *
2422 sizeof(tSirMacChanInfo),
2423 pChanInfoStart);
2424 }
2425 cdf_mem_free(pChanInfoStart);
2426 }
2427
2428 return CDF_STATUS_SUCCESS;
2429}
2430
2431/* pCommand may be NULL */
2432/* Pass in sessionId in case pCommand is NULL. sessionId is not used in case pCommand is not NULL. */
2433void csr_roam_remove_duplicate_command(tpAniSirGlobal pMac, uint32_t sessionId,
2434 tSmeCmd *pCommand,
2435 eCsrRoamReason eRoamReason)
2436{
2437 tListElem *pEntry, *pNextEntry;
2438 tSmeCmd *pDupCommand;
2439 tDblLinkList localList;
2440
2441 cdf_mem_zero(&localList, sizeof(tDblLinkList));
2442 if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
2443 sms_log(pMac, LOGE, FL(" failed to open list"));
2444 return;
2445 }
2446 csr_ll_lock(&pMac->sme.smeCmdPendingList);
2447 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
2448 while (pEntry) {
2449 pNextEntry =
2450 csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
2451 LL_ACCESS_NOLOCK);
2452 pDupCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
2453 /* Remove the previous command if.. */
2454 /* - the new roam command is for the same RoamReason... */
2455 /* - the new roam command is a NewProfileList. */
2456 /* - the new roam command is a Forced Dissoc */
2457 /* - the new roam command is from an 802.11 OID (OID_SSID or OID_BSSID). */
2458 if ((pCommand && (pCommand->sessionId == pDupCommand->sessionId)
2459 && ((pCommand->command == pDupCommand->command) &&
2460 /*
2461 * This peermac check is requried for Softap/GO
2462 * scenarios. For STA scenario below OR check will
2463 * suffice as pCommand will always be NULL for STA
2464 * scenarios
2465 */
2466 (cdf_mem_compare
2467 (pDupCommand->u.roamCmd.peerMac,
2468 pCommand->u.roamCmd.peerMac,
2469 CDF_MAC_ADDR_SIZE))
2470 && (pCommand->u.roamCmd.roamReason ==
2471 pDupCommand->u.roamCmd.roamReason
2472 || eCsrForcedDisassoc ==
2473 pCommand->u.roamCmd.roamReason
2474 || eCsrHddIssued ==
2475 pCommand->u.roamCmd.roamReason)))
2476 ||
2477 /* below the pCommand is NULL */
2478 ((sessionId == pDupCommand->sessionId) &&
2479 (eSmeCommandRoam == pDupCommand->command) &&
2480 ((eCsrForcedDisassoc == eRoamReason) ||
2481 (eCsrHddIssued == eRoamReason))
2482 )
2483 ) {
2484 sms_log(pMac, LOGW, FL(" roamReason = %d"),
2485 pDupCommand->u.roamCmd.roamReason);
2486 /* Remove the 'stale' roam command from the pending list... */
2487 if (csr_ll_remove_entry
2488 (&pMac->sme.smeCmdPendingList, pEntry,
2489 LL_ACCESS_NOLOCK)) {
2490 csr_ll_insert_tail(&localList, pEntry,
2491 LL_ACCESS_NOLOCK);
2492 }
2493 }
2494 pEntry = pNextEntry;
2495 }
2496 csr_ll_unlock(&pMac->sme.smeCmdPendingList);
2497
2498 while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
2499 pDupCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
2500 /* Tell caller that the command is cancelled */
2501 csr_roam_call_callback(pMac, pDupCommand->sessionId, NULL,
2502 pDupCommand->u.roamCmd.roamId,
2503 eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE);
2504 csr_release_command_roam(pMac, pDupCommand);
2505 }
2506 csr_ll_close(&localList);
2507}
2508
2509/**
2510 * csr_roam_populate_channels() - Helper function to populate channels
2511 * @beacon_ies: pointer to beacon ie
2512 * @roam_info: Roaming related information
2513 * @chan1: center freq 1
2514 * @chan2: center freq2
2515 *
2516 * This function will issue populate chan1 and chan2 based on beacon ie
2517 *
2518 * Return: none.
2519 */
2520static void csr_roam_populate_channels(tDot11fBeaconIEs *beacon_ies,
2521 tCsrRoamInfo *roam_info,
2522 uint8_t *chan1, uint8_t *chan2)
2523{
2524 ePhyChanBondState phy_state;
2525 if (beacon_ies->VHTOperation.present) {
2526 *chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1;
2527 *chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2;
2528 roam_info->chan_info.info = MODE_11AC_VHT80;
2529 } else if (beacon_ies->HTInfo.present) {
2530 if (beacon_ies->HTInfo.recommendedTxWidthSet ==
2531 eHT_CHANNEL_WIDTH_40MHZ) {
2532 phy_state = beacon_ies->HTInfo.secondaryChannelOffset;
2533 if (phy_state == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
2534 *chan1 = beacon_ies->HTInfo.primaryChannel +
2535 CSR_CB_CENTER_CHANNEL_OFFSET;
2536 else if (phy_state == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
2537 *chan1 = beacon_ies->HTInfo.primaryChannel -
2538 CSR_CB_CENTER_CHANNEL_OFFSET;
2539 else
2540 *chan1 = beacon_ies->HTInfo.primaryChannel;
2541
2542 roam_info->chan_info.info = MODE_11NA_HT40;
2543 } else {
2544 *chan1 = beacon_ies->HTInfo.primaryChannel;
2545 roam_info->chan_info.info = MODE_11NA_HT20;
2546 }
2547 *chan2 = 0;
2548 } else {
2549 *chan1 = 0;
2550 *chan2 = 0;
2551 roam_info->chan_info.info = MODE_11A;
2552 }
2553}
2554
2555CDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
2556 tCsrRoamInfo *pRoamInfo, uint32_t roamId,
2557 eRoamCmdStatus u1, eCsrRoamResult u2)
2558{
2559 CDF_STATUS status = CDF_STATUS_SUCCESS;
2560#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2561 uint32_t rssi = 0;
2562 WLAN_HOST_DIAG_EVENT_DEF(connectionStatus,
2563 host_event_wlan_status_payload_type);
2564#endif
2565 tCsrRoamSession *pSession;
2566 tDot11fBeaconIEs *beacon_ies = NULL;
2567 uint8_t chan1, chan2;
2568
2569 if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
2570 sms_log(pMac, LOGE, "Session ID:%d is not valid", sessionId);
2571 CDF_ASSERT(0);
2572 return CDF_STATUS_E_FAILURE;
2573 }
2574 pSession = CSR_GET_SESSION(pMac, sessionId);
2575
2576 if (false == pSession->sessionActive) {
2577 sms_log(pMac, LOG1, "%s Session is not Active", __func__);
2578 return CDF_STATUS_E_FAILURE;
2579 }
2580
2581 sms_log(pMac, LOG4, "Received RoamCmdStatus %d with Roam Result %d", u1,
2582 u2);
2583
2584 if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1 &&
2585 eCSR_ROAM_RESULT_ASSOCIATED == u2 && pRoamInfo) {
2586 sms_log(pMac, LOGW,
2587 FL("Assoc complete result=%d status=%d reason=%d"),
2588 u2, pRoamInfo->statusCode, pRoamInfo->reasonCode);
2589 beacon_ies = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
2590 if ((NULL != beacon_ies) && (NULL != pRoamInfo->pBssDesc)) {
2591 status = csr_parse_bss_description_ies(
2592 (tHalHandle) pMac, pRoamInfo->pBssDesc,
2593 beacon_ies);
2594 csr_roam_populate_channels(beacon_ies, pRoamInfo,
2595 &chan1, &chan2);
2596 if (0 != chan1)
2597 pRoamInfo->chan_info.band_center_freq1 =
2598 cds_chan_to_freq(chan1);
2599 else
2600 pRoamInfo->chan_info.band_center_freq1 = 0;
2601 if (0 != chan2)
2602 pRoamInfo->chan_info.band_center_freq2 =
2603 cds_chan_to_freq(chan2);
2604 else
2605 pRoamInfo->chan_info.band_center_freq2 = 0;
2606 } else {
2607 pRoamInfo->chan_info.band_center_freq1 = 0;
2608 pRoamInfo->chan_info.band_center_freq2 = 0;
2609 pRoamInfo->chan_info.info = 0;
2610 }
2611 pRoamInfo->chan_info.chan_id =
2612 pRoamInfo->u.pConnectedProfile->operationChannel;
2613 pRoamInfo->chan_info.mhz =
2614 cds_chan_to_freq(pRoamInfo->chan_info.chan_id);
2615 pRoamInfo->chan_info.reg_info_1 =
2616 (csr_get_cfg_max_tx_power(pMac,
2617 pRoamInfo->chan_info.chan_id) << 16);
2618 pRoamInfo->chan_info.reg_info_2 =
2619 (csr_get_cfg_max_tx_power(pMac,
2620 pRoamInfo->chan_info.chan_id) << 8);
2621 cdf_mem_free(beacon_ies);
2622 } else if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED)
2623 && (pSession->bRefAssocStartCnt)) {
2624 /*
2625 * Decrement bRefAssocStartCnt for FT reassoc failure.
2626 * Reason: For FT reassoc failures, we first call
2627 * csr_roam_call_callback before notifying a failed roam
2628 * completion through csr_roam_complete. The latter in
2629 * turn calls csr_roam_process_results which tries to
2630 * once again call csr_roam_call_callback if bRefAssocStartCnt
2631 * is non-zero. Since this is redundant for FT reassoc
2632 * failure, decrement bRefAssocStartCnt.
2633 */
2634 pSession->bRefAssocStartCnt--;
2635 } else if (u1 == eCSR_ROAM_SET_CHANNEL_RSP && u2 ==
2636 eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS)
2637 pSession->connectedProfile.operationChannel =
2638 pRoamInfo->channelChangeRespEvent->newChannelNumber;
2639
2640 if (NULL != pSession->callback) {
2641 if (pRoamInfo) {
2642 pRoamInfo->sessionId = (uint8_t) sessionId;
2643 /*
2644 * the reasonCode will be passed to supplicant by
2645 * cfg80211_disconnected. Based on the document,
2646 * the reason code passed to supplicant needs to set
2647 * to 0 if unknow. eSIR_BEACON_MISSED reason code is not
2648 * recognizable so that we set to 0 instead.
2649 */
2650 pRoamInfo->reasonCode =
2651 (pRoamInfo->reasonCode == eSIR_BEACON_MISSED) ?
2652 0 : pRoamInfo->reasonCode;
2653 }
2654 status = pSession->callback(pSession->pContext, pRoamInfo,
2655 roamId, u1, u2);
2656 }
2657 /*
2658 * EVENT_WLAN_STATUS: eCSR_ROAM_ASSOCIATION_COMPLETION,
2659 * eCSR_ROAM_LOSTLINK,
2660 * eCSR_ROAM_DISASSOCIATED,
2661 */
2662#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2663 cdf_mem_set(&connectionStatus,
2664 sizeof(host_event_wlan_status_payload_type), 0);
2665
2666 if ((eCSR_ROAM_ASSOCIATION_COMPLETION == u1)
2667 && (eCSR_ROAM_RESULT_ASSOCIATED == u2) && pRoamInfo) {
2668 connectionStatus.eventId = eCSR_WLAN_STATUS_CONNECT;
2669 connectionStatus.bssType =
2670 pRoamInfo->u.pConnectedProfile->BSSType;
2671
2672 if (NULL != pRoamInfo->pBssDesc) {
2673 connectionStatus.rssi =
2674 pRoamInfo->pBssDesc->rssi * (-1);
2675 connectionStatus.channel =
2676 pRoamInfo->pBssDesc->channelId;
2677 }
2678 if (cfg_set_int(pMac, WNI_CFG_CURRENT_RSSI,
2679 connectionStatus.rssi) == eSIR_FAILURE)
2680 sms_log(pMac, LOGE,
2681 FL("Can't pass WNI_CFG_CURRENT_RSSI to cfg"));
2682
2683 connectionStatus.qosCapability =
2684 pRoamInfo->u.pConnectedProfile->qosConnection;
2685 connectionStatus.authType =
2686 (uint8_t) diag_auth_type_from_csr_type(
2687 pRoamInfo->u.pConnectedProfile->AuthType);
2688 connectionStatus.encryptionType =
2689 (uint8_t) diag_enc_type_from_csr_type(
2690 pRoamInfo->u.pConnectedProfile->EncryptionType);
2691 cdf_mem_copy(connectionStatus.ssid,
2692 pRoamInfo->u.pConnectedProfile->SSID.ssId, 6);
2693
2694 connectionStatus.reason = eCSR_REASON_UNSPECIFIED;
2695 cdf_mem_copy(&pMac->sme.eventPayload, &connectionStatus,
2696 sizeof(host_event_wlan_status_payload_type));
2697 WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
2698 EVENT_WLAN_STATUS);
2699 }
2700 if ((eCSR_ROAM_MIC_ERROR_IND == u1)
2701 || (eCSR_ROAM_RESULT_MIC_FAILURE == u2)) {
2702 cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
2703 sizeof(host_event_wlan_status_payload_type));
2704 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
2705 WNI_CFG_CURRENT_RSSI, &rssi)))
2706 connectionStatus.rssi = rssi;
2707
2708 connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
2709 connectionStatus.reason = eCSR_REASON_MIC_ERROR;
2710 WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
2711 EVENT_WLAN_STATUS);
2712 }
2713 if (eCSR_ROAM_RESULT_FORCED == u2) {
2714 cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
2715 sizeof(host_event_wlan_status_payload_type));
2716 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
2717 WNI_CFG_CURRENT_RSSI, &rssi)))
2718 connectionStatus.rssi = rssi;
2719
2720 connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
2721 connectionStatus.reason = eCSR_REASON_USER_REQUESTED;
2722 WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
2723 EVENT_WLAN_STATUS);
2724 }
2725 if (eCSR_ROAM_RESULT_DISASSOC_IND == u2) {
2726 cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
2727 sizeof(host_event_wlan_status_payload_type));
2728 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
2729 WNI_CFG_CURRENT_RSSI, &rssi)))
2730 connectionStatus.rssi = rssi;
2731
2732 connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
2733 connectionStatus.reason = eCSR_REASON_DISASSOC;
2734 if (pRoamInfo)
2735 connectionStatus.reasonDisconnect =
2736 pRoamInfo->reasonCode;
2737
2738 WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
2739 EVENT_WLAN_STATUS);
2740 }
2741 if (eCSR_ROAM_RESULT_DEAUTH_IND == u2) {
2742 cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
2743 sizeof(host_event_wlan_status_payload_type));
2744 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
2745 WNI_CFG_CURRENT_RSSI, &rssi)))
2746 connectionStatus.rssi = rssi;
2747
2748 connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
2749 connectionStatus.reason = eCSR_REASON_DEAUTH;
2750 if (pRoamInfo)
2751 connectionStatus.reasonDisconnect =
2752 pRoamInfo->reasonCode;
2753 WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
2754 EVENT_WLAN_STATUS);
2755 }
2756#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
2757 return status;
2758}
2759
2760/* Returns whether handoff is currently in progress or not */
2761bool csr_roam_is_handoff_in_progress(tpAniSirGlobal pMac, uint8_t sessionId)
2762{
2763#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2764 return csr_neighbor_roam_is_handoff_in_progress(pMac, sessionId);
2765#else
2766 return false;
2767#endif
2768}
2769
2770CDF_STATUS csr_roam_issue_disassociate(tpAniSirGlobal pMac, uint32_t sessionId,
2771 eCsrRoamSubState NewSubstate,
2772 bool fMICFailure)
2773{
2774 CDF_STATUS status = CDF_STATUS_SUCCESS;
2775 struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2776 uint16_t reasonCode;
2777 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2778
2779 if (!pSession) {
2780 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
2781 return CDF_STATUS_E_FAILURE;
2782 }
2783
2784 if (fMICFailure) {
2785 reasonCode = eSIR_MAC_MIC_FAILURE_REASON;
2786 } else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) {
2787 reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON;
2788 } else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) {
2789 reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
2790 NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
2791 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2792 FL
2793 ("set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON"
2794 " and set back NewSubstate"));
2795 } else {
2796 reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
2797 }
2798#ifdef WLAN_FEATURE_VOWIFI_11R
2799 if ((csr_roam_is_handoff_in_progress(pMac, sessionId)) &&
2800 (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) {
2801 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
2802 &pMac->roam.neighborRoamInfo[sessionId];
2803 cdf_copy_macaddr(&bssId,
2804 pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.
2805 bssid);
2806 } else
2807#endif
2808 if (pSession->pConnectBssDesc) {
2809 cdf_mem_copy(&bssId.bytes, pSession->pConnectBssDesc->bssId,
2810 sizeof(struct cdf_mac_addr));
2811 }
2812
2813 sms_log(pMac, LOG2,
2814 FL("CSR Attempting to Disassociate Bssid=" MAC_ADDRESS_STR
2815 " subState = %s reason=%d"), MAC_ADDR_ARRAY(bssId.bytes),
2816 mac_trace_getcsr_roam_sub_state(NewSubstate), reasonCode);
2817
2818 csr_roam_substate_change(pMac, NewSubstate, sessionId);
2819
2820 status = csr_send_mb_disassoc_req_msg(pMac, sessionId, bssId.bytes,
2821 reasonCode);
2822
2823 if (CDF_IS_STATUS_SUCCESS(status)) {
2824 csr_roam_link_down(pMac, sessionId);
2825#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2826 /* no need to tell QoS that we are disassociating, it will be taken care off in assoc req for HO */
2827 if (eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) {
2828 /* notify QoS module that disassoc happening */
2829 sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
2830 SME_QOS_CSR_DISCONNECT_REQ, NULL);
2831 }
2832#endif
2833 } else {
2834 sms_log(pMac, LOGW,
2835 FL("csr_send_mb_disassoc_req_msg failed with status %d"),
2836 status);
2837 }
2838
2839 return status;
2840}
2841
2842/* ---------------------------------------------------------------------------
2843 \fn csr_roam_issue_disassociate_sta_cmd
2844 \brief csr function that HDD calls to disassociate a associated station
2845 \param sessionId - session Id for Soft AP
2846 \param pPeerMacAddr - MAC of associated station to delete
2847 \param reason - reason code, be one of the tSirMacReasonCodes
2848 \return CDF_STATUS
2849 ---------------------------------------------------------------------------*/
2850CDF_STATUS csr_roam_issue_disassociate_sta_cmd(tpAniSirGlobal pMac,
2851 uint32_t sessionId,
2852 const uint8_t *pPeerMacAddr,
2853 uint32_t reason)
2854{
2855 CDF_STATUS status = CDF_STATUS_SUCCESS;
2856 tSmeCmd *pCommand;
2857
2858 do {
2859 pCommand = csr_get_command_buffer(pMac);
2860 if (!pCommand) {
2861 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
2862 status = CDF_STATUS_E_RESOURCES;
2863 break;
2864 }
2865 pCommand->command = eSmeCommandRoam;
2866 pCommand->sessionId = (uint8_t) sessionId;
2867 pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta;
2868 cdf_mem_copy(pCommand->u.roamCmd.peerMac, pPeerMacAddr, 6);
2869 pCommand->u.roamCmd.reason = (tSirMacReasonCodes) reason;
2870 status = csr_queue_sme_command(pMac, pCommand, false);
2871 if (!CDF_IS_STATUS_SUCCESS(status)) {
2872 sms_log(pMac, LOGE,
2873 FL(" fail to send message status = %d"), status);
2874 csr_release_command_roam(pMac, pCommand);
2875 }
2876 } while (0);
2877
2878 return status;
2879}
2880
2881/**
2882 * csr_roam_issue_deauthSta() - delete a associated station
2883 * @sessionId: Session Id for Soft AP
2884 * @pDelStaParams: Pointer to parameters of the station to deauthenticate
2885 *
2886 * CSR function that HDD calls to delete a associated station
2887 *
2888 * Return: CDF_STATUS_SUCCESS on success or another CDF_STATUS_* on error
2889 */
2890CDF_STATUS csr_roam_issue_deauth_sta_cmd(tpAniSirGlobal pMac,
2891 uint32_t sessionId,
2892 struct tagCsrDelStaParams *pDelStaParams)
2893{
2894 CDF_STATUS status = CDF_STATUS_SUCCESS;
2895 tSmeCmd *pCommand;
2896
2897 do {
2898 pCommand = csr_get_command_buffer(pMac);
2899 if (!pCommand) {
2900 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
2901 status = CDF_STATUS_E_RESOURCES;
2902 break;
2903 }
2904 pCommand->command = eSmeCommandRoam;
2905 pCommand->sessionId = (uint8_t) sessionId;
2906 pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta;
2907 cdf_mem_copy(pCommand->u.roamCmd.peerMac,
2908 pDelStaParams->peerMacAddr.bytes,
2909 sizeof(tSirMacAddr));
2910 pCommand->u.roamCmd.reason =
2911 (tSirMacReasonCodes)pDelStaParams->reason_code;
2912 status = csr_queue_sme_command(pMac, pCommand, false);
2913 if (!CDF_IS_STATUS_SUCCESS(status)) {
2914 sms_log(pMac, LOGE,
2915 FL(" fail to send message status = %d"), status);
2916 csr_release_command_roam(pMac, pCommand);
2917 }
2918 } while (0);
2919
2920 return status;
2921}
2922
2923CDF_STATUS
2924csr_roam_issue_tkip_counter_measures(tpAniSirGlobal pMac, uint32_t sessionId,
2925 bool bEnable)
2926{
2927 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2928 struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2929 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2930 if (!pSession) {
2931 sms_log(pMac, LOGE,
2932 "csr_roam_issue_tkip_counter_measures:CSR Session not found");
2933 return status;
2934 }
2935 if (pSession->pConnectBssDesc) {
2936 cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
2937 sizeof(struct cdf_mac_addr));
2938 } else {
2939 sms_log(pMac, LOGE,
2940 "csr_roam_issue_tkip_counter_measures:Connected BSS Description in CSR Session not found");
2941 return status;
2942 }
2943 sms_log(pMac, LOG2,
2944 "CSR issuing tkip counter measures for Bssid = " MAC_ADDRESS_STR
2945 ", Enable = %d", MAC_ADDR_ARRAY(bssId.bytes), bEnable);
2946 status =
2947 csr_send_mb_tkip_counter_measures_req_msg(pMac, sessionId,
2948 bEnable, bssId.bytes);
2949 return status;
2950}
2951
2952CDF_STATUS
2953csr_roam_get_associated_stas(tpAniSirGlobal pMac, uint32_t sessionId,
2954 CDF_MODULE_ID modId, void *pUsrContext,
2955 void *pfnSapEventCallback, uint8_t *pAssocStasBuf)
2956{
2957 CDF_STATUS status = CDF_STATUS_SUCCESS;
2958 struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2959 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2960 if (!pSession) {
2961 sms_log(pMac, LOGE,
2962 "csr_roam_get_associated_stas:CSR Session not found");
2963 return status;
2964 }
2965 if (pSession->pConnectBssDesc) {
2966 cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
2967 sizeof(struct cdf_mac_addr));
2968 } else {
2969 sms_log(pMac, LOGE,
2970 "csr_roam_get_associated_stas:Connected BSS Description in CSR Session not found");
2971 return status;
2972 }
2973 sms_log(pMac, LOG2,
2974 "CSR getting associated stations for Bssid = " MAC_ADDRESS_STR,
2975 MAC_ADDR_ARRAY(bssId.bytes));
2976 status =
2977 csr_send_mb_get_associated_stas_req_msg(pMac, sessionId, modId,
2978 bssId.bytes,
2979 pUsrContext,
2980 pfnSapEventCallback,
2981 pAssocStasBuf);
2982 return status;
2983}
2984
2985CDF_STATUS
2986csr_roam_get_wps_session_overlap(tpAniSirGlobal pMac, uint32_t sessionId,
2987 void *pUsrContext, void *pfnSapEventCallback,
2988 struct cdf_mac_addr pRemoveMac)
2989{
2990 CDF_STATUS status = CDF_STATUS_SUCCESS;
2991 struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2992 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2993
2994 if (!pSession) {
2995 sms_log(pMac, LOGE,
2996 "csr_roam_get_wps_session_overlap:CSR Session not found");
2997 return status;
2998 }
2999 if (pSession->pConnectBssDesc) {
3000 cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
3001 sizeof(struct cdf_mac_addr));
3002 } else {
3003 sms_log(pMac, LOGE,
3004 "csr_roam_get_wps_session_overlap:Connected BSS Description in CSR Session not found");
3005 return status;
3006 }
3007 sms_log(pMac, LOG2,
3008 "CSR getting WPS Session Overlap for Bssid = " MAC_ADDRESS_STR,
3009 MAC_ADDR_ARRAY(bssId.bytes));
3010
3011 status =
3012 csr_send_mb_get_wpspbc_sessions(pMac, sessionId, bssId.bytes, pUsrContext,
3013 pfnSapEventCallback, pRemoveMac);
3014
3015 return status;
3016}
3017
3018CDF_STATUS csr_roam_issue_deauth(tpAniSirGlobal pMac, uint32_t sessionId,
3019 eCsrRoamSubState NewSubstate)
3020{
3021 CDF_STATUS status = CDF_STATUS_SUCCESS;
3022 struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
3023 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
3024
3025 if (!pSession) {
3026 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
3027 return CDF_STATUS_E_FAILURE;
3028 }
3029
3030 if (pSession->pConnectBssDesc) {
3031 cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
3032 sizeof(struct cdf_mac_addr));
3033 }
3034 sms_log(pMac, LOG2, "CSR Attempting to Deauth Bssid= " MAC_ADDRESS_STR,
3035 MAC_ADDR_ARRAY(bssId.bytes));
3036 csr_roam_substate_change(pMac, NewSubstate, sessionId);
3037
3038 status =
3039 csr_send_mb_deauth_req_msg(pMac, sessionId, bssId.bytes,
3040 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
3041 if (CDF_IS_STATUS_SUCCESS(status))
3042 csr_roam_link_down(pMac, sessionId);
3043 else {
3044 sms_log(pMac, LOGE,
3045 FL
3046 ("csr_send_mb_deauth_req_msg failed with status %d Session ID: %d"
3047 MAC_ADDRESS_STR), status, sessionId,
3048 MAC_ADDR_ARRAY(bssId.bytes));
3049 }
3050
3051 return status;
3052}
3053
3054CDF_STATUS csr_roam_save_connected_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId,
3055 tSirBssDescription *pBssDesc)
3056{
3057 CDF_STATUS status = CDF_STATUS_SUCCESS;
3058 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
3059 uint32_t size;
3060
3061 if (!pSession) {
3062 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
3063 return CDF_STATUS_E_FAILURE;
3064 }
3065 /* If no BSS description was found in this connection (happens with start IBSS), then */
3066 /* nix the BSS description that we keep around for the connected BSS) and get out... */
3067 if (NULL == pBssDesc) {
3068 csr_free_connect_bss_desc(pMac, sessionId);
3069 } else {
3070 size = pBssDesc->length + sizeof(pBssDesc->length);
3071 if (NULL != pSession->pConnectBssDesc) {
3072 if (((pSession->pConnectBssDesc->length) +
3073 sizeof(pSession->pConnectBssDesc->length)) <
3074 size) {
3075 /* not enough room for the new BSS, pMac->roam.pConnectBssDesc is freed inside */
3076 csr_free_connect_bss_desc(pMac, sessionId);
3077 }
3078 }
3079 if (NULL == pSession->pConnectBssDesc) {
3080 pSession->pConnectBssDesc = cdf_mem_malloc(size);
3081 }
3082 if (NULL == pSession->pConnectBssDesc)
3083 status = CDF_STATUS_E_NOMEM;
3084 else
3085 cdf_mem_copy(pSession->pConnectBssDesc, pBssDesc, size);
3086 }
3087 return status;
3088}
3089
3090CDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac,
3091 tCsrRoamProfile *pProfile,
3092 tSirBssDescription *pBssDesc,
3093 tBssConfigParam *pBssConfig,
3094 tDot11fBeaconIEs *pIes)
3095{
3096 eCsrCfgDot11Mode cfgDot11Mode;
3097 CDF_ASSERT(pIes != NULL);
3098 if (pIes == NULL)
3099 return CDF_STATUS_E_FAILURE;
3100
3101 cdf_mem_copy(&pBssConfig->BssCap, &pBssDesc->capabilityInfo,
3102 sizeof(tSirMacCapabilityInfo));
3103 /* get qos */
3104 pBssConfig->qosType = csr_get_qo_s_from_bss_desc(pMac, pBssDesc, pIes);
3105 /* get SSID */
3106 if (pIes->SSID.present) {
3107 cdf_mem_copy(&pBssConfig->SSID.ssId, pIes->SSID.ssid,
3108 pIes->SSID.num_ssid);
3109 pBssConfig->SSID.length = pIes->SSID.num_ssid;
3110 } else
3111 pBssConfig->SSID.length = 0;
3112 if (csr_is_nullssid(pBssConfig->SSID.ssId, pBssConfig->SSID.length)) {
3113 sms_log(pMac, LOGW, FL("BSS desc SSID is a wild card"));
3114 /* Return failed if profile doesn't have an SSID either. */
3115 if (pProfile->SSIDs.numOfSSIDs == 0) {
3116 sms_log(pMac, LOGW,
3117 FL("BSS desc and profile doesn't have SSID"));
3118 return CDF_STATUS_E_FAILURE;
3119 }
3120 }
3121 if (CDS_IS_CHANNEL_5GHZ(pBssDesc->channelId))
3122 pBssConfig->eBand = eCSR_BAND_5G;
3123 else
3124 pBssConfig->eBand = eCSR_BAND_24;
3125 /* phymode */
3126 if (csr_is_phy_mode_match(pMac, pProfile->phyMode, pBssDesc,
3127 pProfile, &cfgDot11Mode, pIes)) {
3128 pBssConfig->uCfgDot11Mode = cfgDot11Mode;
3129 } else {
3130 sms_log(pMac, LOGW, "Can not find match phy mode");
3131 /* force it */
3132 if (eCSR_BAND_24 == pBssConfig->eBand)
3133 pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
3134 else
3135 pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
3136 }
3137 /* Qos */
3138 if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
3139 (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos)) {
3140 /*
3141 * Joining BSS is not 11n capable and WMM is disabled on client.
3142 * Disable QoS and WMM
3143 */
3144 pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
3145 }
3146
3147 if (((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N)
3148 || (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC))
3149 && ((pBssConfig->qosType != eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP)
3150 || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_HCF)
3151 || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_eDCF))) {
3152 /* Joining BSS is 11n capable and WMM is disabled on AP. */
3153 /* Assume all HT AP's are QOS AP's and enable WMM */
3154 pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
3155 }
3156 /* auth type */
3157 switch (pProfile->negotiatedAuthType) {
3158 default:
3159 case eCSR_AUTH_TYPE_WPA:
3160 case eCSR_AUTH_TYPE_WPA_PSK:
3161 case eCSR_AUTH_TYPE_WPA_NONE:
3162 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
3163 pBssConfig->authType = eSIR_OPEN_SYSTEM;
3164 break;
3165 case eCSR_AUTH_TYPE_SHARED_KEY:
3166 pBssConfig->authType = eSIR_SHARED_KEY;
3167 break;
3168 case eCSR_AUTH_TYPE_AUTOSWITCH:
3169 pBssConfig->authType = eSIR_AUTO_SWITCH;
3170 break;
3171 }
3172 /* short slot time */
3173 if (eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode)
3174 pBssConfig->uShortSlotTime =
3175 pMac->roam.configParam.shortSlotTime;
3176 else
3177 pBssConfig->uShortSlotTime = 0;
3178
3179 if (pBssConfig->BssCap.ibss)
3180 /* We don't support 11h on IBSS */
3181 pBssConfig->f11hSupport = false;
3182 else
3183 pBssConfig->f11hSupport =
3184 pMac->roam.configParam.Is11hSupportEnabled;
3185 /* power constraint */
3186 pBssConfig->uPowerLimit =
3187 csr_get11h_power_constraint(pMac, &pIes->PowerConstraints);
3188 /* heartbeat */
3189 if (CSR_IS_11A_BSS(pBssDesc))
3190 pBssConfig->uHeartBeatThresh =
3191 pMac->roam.configParam.HeartbeatThresh50;
3192 else
3193 pBssConfig->uHeartBeatThresh =
3194 pMac->roam.configParam.HeartbeatThresh24;
3195
3196 /*
3197 * Join timeout: if we find a BeaconInterval in the BssDescription,
3198 * then set the Join Timeout to be 10 x the BeaconInterval.
3199 */
3200 if (pBssDesc->beaconInterval)
3201 /* Make sure it is bigger than the minimal */
3202 pBssConfig->uJoinTimeOut =
3203 CDF_MAX(10 * pBssDesc->beaconInterval,
3204 CSR_JOIN_FAILURE_TIMEOUT_MIN);
3205 else
3206 pBssConfig->uJoinTimeOut =
3207 CSR_JOIN_FAILURE_TIMEOUT_DEFAULT;
3208 /* validate CB */
3209 pBssConfig->cbMode = csr_get_cb_mode_from_ies(pMac, pBssDesc->channelId,
3210 pIes);
3211
3212 return CDF_STATUS_SUCCESS;
3213}
3214
3215static CDF_STATUS csr_roam_prepare_bss_config_from_profile(tpAniSirGlobal pMac,
3216 tCsrRoamProfile *pProfile,
3217 tBssConfigParam *
3218 pBssConfig,
3219 tSirBssDescription *
3220 pBssDesc)
3221{
3222 CDF_STATUS status = CDF_STATUS_SUCCESS;
3223 uint8_t operationChannel = 0;
3224 uint8_t qAPisEnabled = false;
3225 /* SSID */
3226 pBssConfig->SSID.length = 0;
3227 if (pProfile->SSIDs.numOfSSIDs) {
3228 /* only use the first one */
3229 cdf_mem_copy(&pBssConfig->SSID,
3230 &pProfile->SSIDs.SSIDList[0].SSID,
3231 sizeof(tSirMacSSid));
3232 } else {
3233 /* SSID must present */
3234 return CDF_STATUS_E_FAILURE;
3235 }
3236 /* Settomg up the capabilities */
3237 if (csr_is_bss_type_ibss(pProfile->BSSType)) {
3238 pBssConfig->BssCap.ibss = 1;
3239 } else {
3240 pBssConfig->BssCap.ess = 1;
3241 }
3242 if (eCSR_ENCRYPT_TYPE_NONE !=
3243 pProfile->EncryptionType.encryptionType[0]) {
3244 pBssConfig->BssCap.privacy = 1;
3245 }
3246 pBssConfig->eBand = pMac->roam.configParam.eBand;
3247 /* phymode */
3248 if (pProfile->ChannelInfo.ChannelList) {
3249 operationChannel = pProfile->ChannelInfo.ChannelList[0];
3250 }
3251 pBssConfig->uCfgDot11Mode =
3252 csr_roam_get_phy_mode_band_for_bss(pMac, pProfile, operationChannel,
3253 &pBssConfig->eBand);
3254 /* QOS */
3255 /* Is this correct to always set to this // *** */
3256 if (pBssConfig->BssCap.ess == 1) {
3257 /*For Softap case enable WMM */
3258 if (CSR_IS_INFRA_AP(pProfile)
3259 && (eCsrRoamWmmNoQos !=
3260 pMac->roam.configParam.WMMSupportMode)) {
3261 qAPisEnabled = true;
3262 } else
3263 if (csr_roam_get_qos_info_from_bss(pMac, pBssDesc) ==
3264 CDF_STATUS_SUCCESS) {
3265 qAPisEnabled = true;
3266 } else {
3267 qAPisEnabled = false;
3268 }
3269 } else {
3270 qAPisEnabled = true;
3271 }
3272 if ((eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode &&
3273 qAPisEnabled) ||
3274 ((eCSR_CFG_DOT11_MODE_11N == pBssConfig->uCfgDot11Mode &&
3275 qAPisEnabled))) {
3276 pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
3277 } else {
3278 pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
3279 }
3280
3281 /* auth type */
3282 /* Take the preferred Auth type. */
3283 switch (pProfile->AuthType.authType[0]) {
3284 default:
3285 case eCSR_AUTH_TYPE_WPA:
3286 case eCSR_AUTH_TYPE_WPA_PSK:
3287 case eCSR_AUTH_TYPE_WPA_NONE:
3288 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
3289 pBssConfig->authType = eSIR_OPEN_SYSTEM;
3290 break;
3291 case eCSR_AUTH_TYPE_SHARED_KEY:
3292 pBssConfig->authType = eSIR_SHARED_KEY;
3293 break;
3294 case eCSR_AUTH_TYPE_AUTOSWITCH:
3295 pBssConfig->authType = eSIR_AUTO_SWITCH;
3296 break;
3297 }
3298 /* short slot time */
3299 if (WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode) {
3300 pBssConfig->uShortSlotTime =
3301 pMac->roam.configParam.shortSlotTime;
3302 } else {
3303 pBssConfig->uShortSlotTime = 0;
3304 }
3305 /* power constraint. We don't support 11h on IBSS */
3306 pBssConfig->f11hSupport = false;
3307 pBssConfig->uPowerLimit = 0;
3308 /* heartbeat */
3309 if (eCSR_BAND_5G == pBssConfig->eBand) {
3310 pBssConfig->uHeartBeatThresh =
3311 pMac->roam.configParam.HeartbeatThresh50;
3312 } else {
3313 pBssConfig->uHeartBeatThresh =
3314 pMac->roam.configParam.HeartbeatThresh24;
3315 }
3316 /* Join timeout */
3317 pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT;
3318
3319 return status;
3320}
3321
3322static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
3323 tSirBssDescription *pBssDesc)
3324{
3325 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3326 tDot11fBeaconIEs *pIes = NULL;
3327
3328 do {
3329 if (!CDF_IS_STATUS_SUCCESS(
3330 csr_get_parsed_bss_description_ies(
3331 pMac, pBssDesc, &pIes))) {
3332 /* err msg */
3333 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3334 "csr_roam_get_qos_info_from_bss() failed");
3335 break;
3336 }
3337 /* check if the AP is QAP & it supports APSD */
3338 if (CSR_IS_QOS_BSS(pIes)) {
3339 status = CDF_STATUS_SUCCESS;
3340 }
3341 } while (0);
3342
3343 if (NULL != pIes) {
3344 cdf_mem_free(pIes);
3345 }
3346
3347 return status;
3348}
3349
3350void csr_set_cfg_privacy(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile,
3351 bool fPrivacy)
3352{
3353 /*
3354 * the only difference between this function and
3355 * the csr_set_cfg_privacyFromProfile() is the setting of the privacy
3356 * CFG based on the advertised privacy setting from the AP for WPA
3357 * associations. See note below in this function...
3358 */
3359 uint32_t PrivacyEnabled = 0, RsnEnabled = 0, WepDefaultKeyId = 0;
3360 uint32_t WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5;
3361 uint32_t Key0Length = 0, Key1Length = 0, Key2Length = 0, Key3Length = 0;
3362
3363 /* Reserve for the biggest key */
3364 uint8_t Key0[WNI_CFG_WEP_DEFAULT_KEY_1_LEN];
3365 uint8_t Key1[WNI_CFG_WEP_DEFAULT_KEY_2_LEN];
3366 uint8_t Key2[WNI_CFG_WEP_DEFAULT_KEY_3_LEN];
3367 uint8_t Key3[WNI_CFG_WEP_DEFAULT_KEY_4_LEN];
3368
3369 switch (pProfile->negotiatedUCEncryptionType) {
3370 case eCSR_ENCRYPT_TYPE_NONE:
3371 /* for NO encryption, turn off Privacy and Rsn. */
3372 PrivacyEnabled = 0;
3373 RsnEnabled = 0;
3374 /* clear out the WEP keys that may be hanging around. */
3375 Key0Length = 0;
3376 Key1Length = 0;
3377 Key2Length = 0;
3378 Key3Length = 0;
3379 break;
3380
3381 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3382 case eCSR_ENCRYPT_TYPE_WEP40:
3383
3384 /* Privacy is ON. NO RSN for Wep40 static key. */
3385 PrivacyEnabled = 1;
3386 RsnEnabled = 0;
3387 /* Set the Wep default key ID. */
3388 WepDefaultKeyId = pProfile->Keys.defaultIndex;
3389 /* Wep key size if 5 bytes (40 bits). */
3390 WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5;
3391 /*
3392 * set encryption keys in the CFG database or
3393 * clear those that are not present in this profile.
3394 */
3395 if (pProfile->Keys.KeyLength[0]) {
3396 cdf_mem_copy(Key0,
3397 pProfile->Keys.KeyMaterial[0],
3398 WNI_CFG_WEP_KEY_LENGTH_5);
3399 Key0Length = WNI_CFG_WEP_KEY_LENGTH_5;
3400 } else {
3401 Key0Length = 0;
3402 }
3403
3404 if (pProfile->Keys.KeyLength[1]) {
3405 cdf_mem_copy(Key1,
3406 pProfile->Keys.KeyMaterial[1],
3407 WNI_CFG_WEP_KEY_LENGTH_5);
3408 Key1Length = WNI_CFG_WEP_KEY_LENGTH_5;
3409 } else {
3410 Key1Length = 0;
3411 }
3412
3413 if (pProfile->Keys.KeyLength[2]) {
3414 cdf_mem_copy(Key2,
3415 pProfile->Keys.KeyMaterial[2],
3416 WNI_CFG_WEP_KEY_LENGTH_5);
3417 Key2Length = WNI_CFG_WEP_KEY_LENGTH_5;
3418 } else {
3419 Key2Length = 0;
3420 }
3421
3422 if (pProfile->Keys.KeyLength[3]) {
3423 cdf_mem_copy(Key3,
3424 pProfile->Keys.KeyMaterial[3],
3425 WNI_CFG_WEP_KEY_LENGTH_5);
3426 Key3Length = WNI_CFG_WEP_KEY_LENGTH_5;
3427 } else {
3428 Key3Length = 0;
3429 }
3430 break;
3431
3432 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3433 case eCSR_ENCRYPT_TYPE_WEP104:
3434
3435 /* Privacy is ON. NO RSN for Wep40 static key. */
3436 PrivacyEnabled = 1;
3437 RsnEnabled = 0;
3438 /* Set the Wep default key ID. */
3439 WepDefaultKeyId = pProfile->Keys.defaultIndex;
3440 /* Wep key size if 13 bytes (104 bits). */
3441 WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_13;
3442 /*
3443 * set encryption keys in the CFG database or clear
3444 * those that are not present in this profile.
3445 */
3446 if (pProfile->Keys.KeyLength[0]) {
3447 cdf_mem_copy(Key0,
3448 pProfile->Keys.KeyMaterial[0],
3449 WNI_CFG_WEP_KEY_LENGTH_13);
3450 Key0Length = WNI_CFG_WEP_KEY_LENGTH_13;
3451 } else {
3452 Key0Length = 0;
3453 }
3454
3455 if (pProfile->Keys.KeyLength[1]) {
3456 cdf_mem_copy(Key1,
3457 pProfile->Keys.KeyMaterial[1],
3458 WNI_CFG_WEP_KEY_LENGTH_13);
3459 Key1Length = WNI_CFG_WEP_KEY_LENGTH_13;
3460 } else {
3461 Key1Length = 0;
3462 }
3463
3464 if (pProfile->Keys.KeyLength[2]) {
3465 cdf_mem_copy(Key2,
3466 pProfile->Keys.KeyMaterial[2],
3467 WNI_CFG_WEP_KEY_LENGTH_13);
3468 Key2Length = WNI_CFG_WEP_KEY_LENGTH_13;
3469 } else {
3470 Key2Length = 0;
3471 }
3472
3473 if (pProfile->Keys.KeyLength[3]) {
3474 cdf_mem_copy(Key3,
3475 pProfile->Keys.KeyMaterial[3],
3476 WNI_CFG_WEP_KEY_LENGTH_13);
3477 Key3Length = WNI_CFG_WEP_KEY_LENGTH_13;
3478 } else {
3479 Key3Length = 0;
3480 }
3481 break;
3482
3483 case eCSR_ENCRYPT_TYPE_TKIP:
3484 case eCSR_ENCRYPT_TYPE_AES:
3485#ifdef FEATURE_WLAN_WAPI
3486 case eCSR_ENCRYPT_TYPE_WPI:
3487#endif /* FEATURE_WLAN_WAPI */
3488 /*
3489 * this is the only difference between this function and
3490 * the csr_set_cfg_privacyFromProfile().
3491 * (setting of the privacy CFG based on the advertised
3492 * privacy setting from AP for WPA/WAPI associations).
3493 */
3494 PrivacyEnabled = (0 != fPrivacy);
3495 /* turn on RSN enabled for WPA associations */
3496 RsnEnabled = 1;
3497 /* clear static WEP keys that may be hanging around. */
3498 Key0Length = 0;
3499 Key1Length = 0;
3500 Key2Length = 0;
3501 Key3Length = 0;
3502 break;
3503 default:
3504 PrivacyEnabled = 0;
3505 RsnEnabled = 0;
3506 break;
3507 }
3508
3509 cfg_set_int(pMac, WNI_CFG_PRIVACY_ENABLED, PrivacyEnabled);
3510 cfg_set_int(pMac, WNI_CFG_RSN_ENABLED, RsnEnabled);
3511 cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0, Key0Length);
3512 cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1, Key1Length);
3513 cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2, Key2Length);
3514 cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3, Key3Length);
3515 cfg_set_int(pMac, WNI_CFG_WEP_KEY_LENGTH, WepKeyLength);
3516 cfg_set_int(pMac, WNI_CFG_WEP_DEFAULT_KEYID, WepDefaultKeyId);
3517}
3518
3519static void csr_set_cfg_ssid(tpAniSirGlobal pMac, tSirMacSSid *pSSID)
3520{
3521 uint32_t len = 0;
3522 if (pSSID->length <= WNI_CFG_SSID_LEN) {
3523 len = pSSID->length;
3524 }
3525 cfg_set_str(pMac, WNI_CFG_SSID, (uint8_t *) pSSID->ssId, len);
3526}
3527
3528CDF_STATUS csr_set_qos_to_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
3529 eCsrMediaAccessType qosType)
3530{
3531 CDF_STATUS status = CDF_STATUS_SUCCESS;
3532 uint32_t QoSEnabled;
3533 uint32_t WmeEnabled;
3534 /* set the CFG enable/disable variables based on the qosType being configured... */
3535 switch (qosType) {
3536 case eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p:
3537 QoSEnabled = false;
3538 WmeEnabled = true;
3539 break;
3540 case eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP:
3541 QoSEnabled = false;
3542 WmeEnabled = true;
3543 break;
3544 case eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify:
3545 QoSEnabled = false;
3546 WmeEnabled = true;
3547 break;
3548 case eCSR_MEDIUM_ACCESS_11e_eDCF:
3549 QoSEnabled = true;
3550 WmeEnabled = false;
3551 break;
3552 case eCSR_MEDIUM_ACCESS_11e_HCF:
3553 QoSEnabled = true;
3554 WmeEnabled = false;
3555 break;
3556 default:
3557 case eCSR_MEDIUM_ACCESS_DCF:
3558 QoSEnabled = false;
3559 WmeEnabled = false;
3560 break;
3561 }
3562 /* save the WMM setting for later use */
3563 pMac->roam.roamSession[sessionId].fWMMConnection = (bool) WmeEnabled;
3564 pMac->roam.roamSession[sessionId].fQOSConnection = (bool) QoSEnabled;
3565 return status;
3566}
3567
3568static CDF_STATUS csr_get_rate_set(tpAniSirGlobal pMac,
3569 tCsrRoamProfile *pProfile, eCsrPhyMode phyMode,
3570 tSirBssDescription *pBssDesc,
3571 tDot11fBeaconIEs *pIes,
3572 tSirMacRateSet *pOpRateSet,
3573 tSirMacRateSet *pExRateSet)
3574{
3575 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3576 int i;
3577 eCsrCfgDot11Mode cfgDot11Mode;
3578 uint8_t *pDstRate;
3579 uint16_t rateBitmap = 0;
3580 cdf_mem_set(pOpRateSet, sizeof(tSirMacRateSet), 0);
3581 cdf_mem_set(pExRateSet, sizeof(tSirMacRateSet), 0);
3582 CDF_ASSERT(pIes != NULL);
3583
3584 if (NULL == pIes) {
3585 sms_log(pMac, LOGE, FL("failed to parse BssDesc"));
3586 return status;
3587 }
3588
3589 csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
3590 &cfgDot11Mode, pIes);
3591 /*
3592 * Originally, we thought that for 11a networks, the 11a rates
3593 * are always in the Operational Rate set & for 11b and 11g
3594 * networks, the 11b rates appear in the Operational Rate set.
3595 * Consequently, in either case, we would blindly put the rates
3596 * we support into our Operational Rate set.
3597 * (including the basic rates, which we've already verified are
3598 * supported earlier in the roaming decision).
3599 * However, it turns out that this is not always the case.
3600 * Some AP's (e.g. D-Link DI-784) ram 11g rates into the
3601 * Operational Rate set too. Now, we're a little more careful.
3602 */
3603 pDstRate = pOpRateSet->rate;
3604 if (pIes->SuppRates.present) {
3605 for (i = 0; i < pIes->SuppRates.num_rates; i++) {
3606 if (csr_rates_is_dot11_rate_supported(pMac,
3607 pIes->SuppRates.rates[i]) &&
3608 !csr_check_rate_bitmap(
3609 pIes->SuppRates.rates[i],
3610 rateBitmap)) {
3611 csr_add_rate_bitmap(pIes->SuppRates.
3612 rates[i], &rateBitmap);
3613 *pDstRate++ = pIes->SuppRates.rates[i];
3614 pOpRateSet->numRates++;
3615 }
3616 }
3617 }
3618 if ((eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode ||
3619 eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode ||
3620 eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode
3621#ifdef WLAN_FEATURE_11AC
3622 || eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode
3623#endif
3624 ) && pIes->ExtSuppRates.present) {
3625 /*
3626 * If there are extended rates in the beacon,
3627 * we will reflect those extended rates that we support in our
3628 * extended operational rate
3629 */
3630 pDstRate = pExRateSet->rate;
3631 for (i = 0; i < pIes->ExtSuppRates.num_rates; i++) {
3632 if (csr_rates_is_dot11_rate_supported(pMac,
3633 pIes->ExtSuppRates.rates[i]) &&
3634 !csr_check_rate_bitmap(
3635 pIes->ExtSuppRates.rates[i],
3636 rateBitmap)) {
3637 *pDstRate++ = pIes->ExtSuppRates.rates[i];
3638 pExRateSet->numRates++;
3639 }
3640 }
3641 }
3642 if (pOpRateSet->numRates > 0 || pExRateSet->numRates > 0)
3643 status = CDF_STATUS_SUCCESS;
3644 return status;
3645}
3646
3647static void csr_set_cfg_rate_set(tpAniSirGlobal pMac, eCsrPhyMode phyMode,
3648 tCsrRoamProfile *pProfile,
3649 tSirBssDescription *pBssDesc,
3650 tDot11fBeaconIEs *pIes)
3651{
3652 int i;
3653 uint8_t *pDstRate;
3654 eCsrCfgDot11Mode cfgDot11Mode;
3655 uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX]; /* leave enough room for the max number of rates */
3656 uint32_t OperationalRatesLength = 0;
3657 uint8_t ExtendedOperationalRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; /* leave enough room for the max number of rates */
3658 uint32_t ExtendedOperationalRatesLength = 0;
3659 uint8_t MCSRateIdxSet[SIZE_OF_SUPPORTED_MCS_SET];
3660 uint32_t MCSRateLength = 0;
3661 CDF_ASSERT(pIes != NULL);
3662 if (NULL != pIes) {
3663 csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
3664 &cfgDot11Mode, pIes);
3665 /* Originally, we thought that for 11a networks, the 11a rates are always */
3666 /* in the Operational Rate set & for 11b and 11g networks, the 11b rates */
3667 /* appear in the Operational Rate set. Consequently, in either case, we */
3668 /* would blindly put the rates we support into our Operational Rate set */
3669 /* (including the basic rates, which we have already verified are */
3670 /* supported earlier in the roaming decision). */
3671 /* However, it turns out that this is not always the case. Some AP's */
3672 /* (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, */
3673 /* too. Now, we're a little more careful: */
3674 pDstRate = OperationalRates;
3675 if (pIes->SuppRates.present) {
3676 for (i = 0; i < pIes->SuppRates.num_rates; i++) {
3677 if (csr_rates_is_dot11_rate_supported
3678 (pMac, pIes->SuppRates.rates[i])
3679 && (OperationalRatesLength <
3680 CSR_DOT11_SUPPORTED_RATES_MAX)) {
3681 *pDstRate++ = pIes->SuppRates.rates[i];
3682 OperationalRatesLength++;
3683 }
3684 }
3685 }
3686 if (eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode ||
3687 eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode ||
3688 eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode) {
3689 /* If there are Extended Rates in the beacon, we will reflect those */
3690 /* extended rates that we support in out Extended Operational Rate */
3691 /* set: */
3692 pDstRate = ExtendedOperationalRates;
3693 if (pIes->ExtSuppRates.present) {
3694 for (i = 0; i < pIes->ExtSuppRates.num_rates;
3695 i++) {
3696 if (csr_rates_is_dot11_rate_supported
3697 (pMac, pIes->ExtSuppRates.rates[i])
3698 && (ExtendedOperationalRatesLength <
3699 CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX)) {
3700 *pDstRate++ =
3701 pIes->ExtSuppRates.rates[i];
3702 ExtendedOperationalRatesLength++;
3703 }
3704 }
3705 }
3706 }
3707 /* Enable proprietary MAC features if peer node is Airgo node and STA */
3708 /* user wants to use them */
3709 /* For ANI network companions, we need to populate the proprietary rate */
3710 /* set with any proprietary rates we found in the beacon, only if user */
3711 /* allows them... */
3712 /* No proprietary modes... */
3713 /* Get MCS Rate */
3714 pDstRate = MCSRateIdxSet;
3715 if (pIes->HTCaps.present) {
3716 for (i = 0; i < VALID_MAX_MCS_INDEX; i++) {
3717 if ((unsigned int)pIes->HTCaps.
3718 supportedMCSSet[0] & (1 << i)) {
3719 MCSRateLength++;
3720 *pDstRate++ = i;
3721 }
3722 }
3723 }
3724 /* Set the operational rate set CFG variables... */
3725 cfg_set_str(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
3726 OperationalRates, OperationalRatesLength);
3727 cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
3728 ExtendedOperationalRates,
3729 ExtendedOperationalRatesLength);
3730 cfg_set_str(pMac, WNI_CFG_CURRENT_MCS_SET, MCSRateIdxSet,
3731 MCSRateLength);
3732 } /* Parsing BSSDesc */
3733 else {
3734 sms_log(pMac, LOGE, FL("failed to parse BssDesc"));
3735 }
3736}
3737
3738static void csr_set_cfg_rate_set_from_profile(tpAniSirGlobal pMac,
3739 tCsrRoamProfile *pProfile)
3740{
3741 tSirMacRateSetIE DefaultSupportedRates11a = { SIR_MAC_RATESET_EID,
3742 {8,
3743 {SIR_MAC_RATE_6,
3744 SIR_MAC_RATE_9,
3745 SIR_MAC_RATE_12,
3746 SIR_MAC_RATE_18,
3747 SIR_MAC_RATE_24,
3748 SIR_MAC_RATE_36,
3749 SIR_MAC_RATE_48,
3750 SIR_MAC_RATE_54} } };
3751 tSirMacRateSetIE DefaultSupportedRates11b = { SIR_MAC_RATESET_EID,
3752 {4,
3753 {SIR_MAC_RATE_1,
3754 SIR_MAC_RATE_2,
3755 SIR_MAC_RATE_5_5,
3756 SIR_MAC_RATE_11} } };
3757
3758 tSirMacPropRateSet DefaultSupportedPropRates = { 3,
3759 {SIR_MAC_RATE_72,
3760 SIR_MAC_RATE_96,
3761 SIR_MAC_RATE_108} };
3762 eCsrCfgDot11Mode cfgDot11Mode;
3763 eCsrBand eBand;
3764 /* leave enough room for the max number of rates */
3765 uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
3766 uint32_t OperationalRatesLength = 0;
3767 /* leave enough room for the max number of rates */
3768 uint8_t ExtendedOperationalRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
3769 uint32_t ExtendedOperationalRatesLength = 0;
3770 /* leave enough room for the max number of proprietary rates */
3771 uint8_t ProprietaryOperationalRates[4];
3772 uint32_t ProprietaryOperationalRatesLength = 0;
3773 uint32_t PropRatesEnable = 0;
3774 uint8_t operationChannel = 0;
3775 if (pProfile->ChannelInfo.ChannelList) {
3776 operationChannel = pProfile->ChannelInfo.ChannelList[0];
3777 }
3778 cfgDot11Mode =
3779 csr_roam_get_phy_mode_band_for_bss(pMac, pProfile, operationChannel,
3780 &eBand);
3781 /* For 11a networks, the 11a rates go into the Operational Rate set. For 11b and 11g */
3782 /* networks, the 11b rates appear in the Operational Rate set. In either case, */
3783 /* we can blindly put the rates we support into our Operational Rate set */
3784 /* (including the basic rates, which we have already verified are supported */
3785 /* earlier in the roaming decision). */
3786 if (eCSR_BAND_5G == eBand) {
3787 /* 11a rates into the Operational Rate Set. */
3788 OperationalRatesLength =
3789 DefaultSupportedRates11a.supportedRateSet.numRates *
3790 sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
3791 cdf_mem_copy(OperationalRates,
3792 DefaultSupportedRates11a.supportedRateSet.rate,
3793 OperationalRatesLength);
3794
3795 /* Nothing in the Extended rate set. */
3796 ExtendedOperationalRatesLength = 0;
3797 /* populate proprietary rates if user allows them */
3798 if (pMac->roam.configParam.ProprietaryRatesEnabled) {
3799 ProprietaryOperationalRatesLength =
3800 DefaultSupportedPropRates.numPropRates *
3801 sizeof(*DefaultSupportedPropRates.propRate);
3802 cdf_mem_copy(ProprietaryOperationalRates,
3803 DefaultSupportedPropRates.propRate,
3804 ProprietaryOperationalRatesLength);
3805 } else {
3806 /* No proprietary modes */
3807 ProprietaryOperationalRatesLength = 0;
3808 }
3809 } else if (eCSR_CFG_DOT11_MODE_11B == cfgDot11Mode) {
3810 /* 11b rates into the Operational Rate Set. */
3811 OperationalRatesLength =
3812 DefaultSupportedRates11b.supportedRateSet.numRates *
3813 sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
3814 cdf_mem_copy(OperationalRates,
3815 DefaultSupportedRates11b.supportedRateSet.rate,
3816 OperationalRatesLength);
3817 /* Nothing in the Extended rate set. */
3818 ExtendedOperationalRatesLength = 0;
3819 /* No proprietary modes */
3820 ProprietaryOperationalRatesLength = 0;
3821 } else {
3822 /* 11G */
3823
3824 /* 11b rates into the Operational Rate Set. */
3825 OperationalRatesLength =
3826 DefaultSupportedRates11b.supportedRateSet.numRates *
3827 sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
3828 cdf_mem_copy(OperationalRates,
3829 DefaultSupportedRates11b.supportedRateSet.rate,
3830 OperationalRatesLength);
3831
3832 /* 11a rates go in the Extended rate set. */
3833 ExtendedOperationalRatesLength =
3834 DefaultSupportedRates11a.supportedRateSet.numRates *
3835 sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
3836 cdf_mem_copy(ExtendedOperationalRates,
3837 DefaultSupportedRates11a.supportedRateSet.rate,
3838 ExtendedOperationalRatesLength);
3839
3840 /* populate proprietary rates if user allows them */
3841 if (pMac->roam.configParam.ProprietaryRatesEnabled) {
3842 ProprietaryOperationalRatesLength =
3843 DefaultSupportedPropRates.numPropRates *
3844 sizeof(*DefaultSupportedPropRates.propRate);
3845 cdf_mem_copy(ProprietaryOperationalRates,
3846 DefaultSupportedPropRates.propRate,
3847 ProprietaryOperationalRatesLength);
3848 } else {
3849 /* No proprietary modes */
3850 ProprietaryOperationalRatesLength = 0;
3851 }
3852 }
3853 /* set this to 1 if prop. rates need to be advertised in to the IBSS beacon and user wants to use them */
3854 if (ProprietaryOperationalRatesLength
3855 && pMac->roam.configParam.ProprietaryRatesEnabled) {
3856 PropRatesEnable = 1;
3857 } else {
3858 PropRatesEnable = 0;
3859 }
3860
3861 /* Set the operational rate set CFG variables... */
3862 cfg_set_str(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates,
3863 OperationalRatesLength);
3864 cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
3865 ExtendedOperationalRates, ExtendedOperationalRatesLength);
3866 cfg_set_str(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET,
3867 ProprietaryOperationalRates,
3868 ProprietaryOperationalRatesLength);
3869}
3870
3871void csr_roam_ccm_cfg_set_callback(tpAniSirGlobal pMac, int32_t result)
3872{
3873 tListElem *pEntry =
3874 csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
3875 uint32_t sessionId;
3876 tSmeCmd *pCommand = NULL;
3877#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3878 tCsrRoamSession *pSession = NULL;
3879#endif
3880 if (NULL == pEntry) {
3881 sms_log(pMac, LOGW, "CFG_CNF with active list empty");
3882 return;
3883 }
3884 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
3885 sessionId = pCommand->sessionId;
3886#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3887 pSession = &pMac->roam.roamSession[sessionId];
3888 if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
3889 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
3890 "LFR3:csr_roam_cfg_set_callback");
3891 }
3892#endif
3893
3894 if (CSR_IS_ROAM_JOINING(pMac, sessionId)
3895 && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
3896 csr_roaming_state_config_cnf_processor(pMac, (uint32_t) result);
3897 }
3898}
3899
3900/* This function is very dump. It is here because PE still need WNI_CFG_PHY_MODE */
3901uint32_t csr_roam_get_phy_mode_from_dot11_mode(eCsrCfgDot11Mode dot11Mode,
3902 eCsrBand band)
3903{
3904 if (eCSR_CFG_DOT11_MODE_11B == dot11Mode) {
3905 return WNI_CFG_PHY_MODE_11B;
3906 } else {
3907 if (eCSR_BAND_24 == band)
3908 return WNI_CFG_PHY_MODE_11G;
3909 }
3910 return WNI_CFG_PHY_MODE_11A;
3911}
3912
3913#ifdef WLAN_FEATURE_11AC
3914ePhyChanBondState csr_get_htcb_state_from_vhtcb_state(ePhyChanBondState aniCBMode)
3915{
3916 switch (aniCBMode) {
3917 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
3918 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
3919 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
3920 return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
3921 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
3922 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
3923 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
3924 return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
3925 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
3926 default:
3927 return PHY_SINGLE_CHANNEL_CENTERED;
3928 }
3929}
3930#endif
3931
3932/* pIes may be NULL */
3933CDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
3934 tCsrRoamProfile *pProfile,
3935 tSirBssDescription *pBssDesc,
3936 tBssConfigParam *pBssConfig,
3937 tDot11fBeaconIEs *pIes, bool resetCountry)
3938{
3939 tSirRetStatus status;
3940 uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
3941 uint8_t channel = 0;
3942 /* Make sure we have the domain info for the BSS we try to connect to. */
3943 /* Do we need to worry about sequence for OSs that are not Windows?? */
3944 if (pBssDesc) {
3945 if (csr_learn_11dcountry_information(pMac, pBssDesc, pIes, true)) {
3946 csr_apply_country_information(pMac);
3947 }
3948 if ((csr_is11d_supported(pMac)) && pIes) {
3949 if (!pIes->Country.present) {
3950 csr_apply_channel_power_info_wrapper(pMac);
3951 } else {
3952 /* Let's also update the below to make sure we don't update CC while */
3953 /* connected to an AP which is advertising some CC */
3954 cdf_mem_copy(pMac->scan.currentCountryBssid.bytes,
3955 pBssDesc->bssId,
3956 sizeof(tSirMacAddr));
3957 }
3958 }
3959 }
3960 /* Qos */
3961 csr_set_qos_to_cfg(pMac, sessionId, pBssConfig->qosType);
3962 /* SSID */
3963 csr_set_cfg_ssid(pMac, &pBssConfig->SSID);
3964
3965 /* Auth type */
3966 cfg_set_int(pMac, WNI_CFG_AUTHENTICATION_TYPE, pBssConfig->authType);
3967 /* encryption type */
3968 csr_set_cfg_privacy(pMac, pProfile, (bool) pBssConfig->BssCap.privacy);
3969 /* short slot time */
3970 cfg_set_int(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
3971 pBssConfig->uShortSlotTime);
3972 /* 11d */
3973 cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
3974 ((pBssConfig->f11hSupport) ? pBssConfig->f11hSupport :
3975 pProfile->ieee80211d));
3976 cfg_set_int(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
3977 pBssConfig->uPowerLimit);
3978 /* CB */
3979
3980 if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_WDS_AP(pProfile)
3981 || CSR_IS_IBSS(pProfile)) {
3982 channel = pProfile->operationChannel;
3983 } else {
3984 if (pBssDesc) {
3985 channel = pBssDesc->channelId;
3986 }
3987 }
3988 if (0 != channel) {
3989 if (CDS_IS_CHANNEL_24GHZ(channel)) { /* for now if we are on 2.4 Ghz, CB will be always disabled */
3990 cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
3991 } else {
3992 cfgCb = pBssConfig->cbMode;
3993 }
3994 }
3995 /* Rate */
3996 /* Fixed Rate */
3997 if (pBssDesc) {
3998 csr_set_cfg_rate_set(pMac, (eCsrPhyMode) pProfile->phyMode,
3999 pProfile, pBssDesc, pIes);
4000 } else {
4001 csr_set_cfg_rate_set_from_profile(pMac, pProfile);
4002 }
4003 /* Make this the last CFG to set. The callback will trigger a join_req */
4004 /* Join time out */
4005 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId);
4006
4007 status = cfg_set_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
4008 pBssConfig->uJoinTimeOut);
4009 csr_roam_ccm_cfg_set_callback(pMac, status);
4010 return CDF_STATUS_SUCCESS;
4011}
4012
4013CDF_STATUS csr_roam_stop_network(tpAniSirGlobal pMac, uint32_t sessionId,
4014 tCsrRoamProfile *pProfile,
4015 tSirBssDescription *pBssDesc,
4016 tDot11fBeaconIEs *pIes)
4017{
4018 CDF_STATUS status;
4019 tBssConfigParam *pBssConfig;
4020 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
4021
4022 if (!pSession) {
4023 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
4024 return CDF_STATUS_E_FAILURE;
4025 }
4026
4027 pBssConfig = cdf_mem_malloc(sizeof(tBssConfigParam));
4028 if (NULL == pBssConfig)
4029 return CDF_STATUS_E_NOMEM;
4030
4031 cdf_mem_set(pBssConfig, sizeof(tBssConfigParam), 0);
4032 status = csr_roam_prepare_bss_config(pMac, pProfile, pBssDesc,
4033 pBssConfig, pIes);
4034 if (CDF_IS_STATUS_SUCCESS(status)) {
4035 eCsrRoamSubState substate;
4036 substate = eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING;
4037 pSession->bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
4038 /* This will allow to pass cbMode during join req */
4039 pSession->bssParams.cbMode = pBssConfig->cbMode;
4040 /* For IBSS, we need to prepare some more information */
4041 if (csr_is_bss_type_ibss(pProfile->BSSType) ||
4042 CSR_IS_WDS(pProfile) ||
4043 CSR_IS_INFRA_AP(pProfile))
4044 csr_roam_prepare_bss_params(pMac, sessionId, pProfile,
4045 pBssDesc, pBssConfig, pIes);
4046
4047 /*
4048 * If we are in an IBSS, then stop the IBSS...
4049 * Not worry about WDS connection for now
4050 */
4051 if (csr_is_conn_state_ibss(pMac, sessionId)) {
4052 status = csr_roam_issue_stop_bss(pMac, sessionId,
4053 substate);
4054 } else if (csr_is_conn_state_infra(pMac, sessionId)) {
4055 /*
4056 * the new Bss is an Ibss OR we are roaming from
4057 * Infra to Infra across SSIDs
4058 * (roaming to a new SSID)...
4059 * Not worry about WDS connection for now
4060 */
4061 if (pBssDesc && (csr_is_ibss_bss_desc(pBssDesc) ||
4062 !csr_is_ssid_equal(pMac,
4063 pSession->pConnectBssDesc,
4064 pBssDesc, pIes)))
4065 status = csr_roam_issue_disassociate(pMac,
4066 sessionId, substate, false);
4067 else if (pBssDesc)
4068 /*
4069 * In an infra & going to an infra network with
4070 * the same SSID. This calls for a reassoc seq.
4071 * So issue the CFG sets for this new AP. Set
4072 * parameters for this Bss.
4073 */
4074 status = csr_roam_set_bss_config_cfg(pMac,
4075 sessionId, pProfile, pBssDesc,
4076 pBssConfig, pIes, false);
4077 } else if (pBssDesc || CSR_IS_WDS_AP(pProfile) ||
4078 CSR_IS_INFRA_AP(pProfile)) {
4079 /*
4080 * Neither in IBSS nor in Infra. We can go ahead and set
4081 * the cfg for tne new network... nothing to stop.
4082 */
4083 bool is11rRoamingFlag = false;
4084 is11rRoamingFlag = csr_roam_is11r_assoc(pMac,
4085 sessionId);
4086 /* Set parameters for this Bss. */
4087 status = csr_roam_set_bss_config_cfg(pMac, sessionId,
4088 pProfile, pBssDesc, pBssConfig, pIes,
4089 is11rRoamingFlag);
4090 }
4091 } /* Success getting BSS config info */
4092 cdf_mem_free(pBssConfig);
4093 return status;
4094}
4095
4096/**
4097 * csr_roam_state_for_same_profile() - Determine roam state for same profile
4098 * @mac_ctx: pointer to mac context
4099 * @profile: Roam profile
4100 * @session: Roam session
4101 * @session_id: session id
4102 * @ies_local: local ies
4103 * @bss_descr: bss description
4104 *
4105 * This function will determine the roam state for same profile
4106 *
4107 * Return: Roaming state.
4108 */
4109static eCsrJoinState csr_roam_state_for_same_profile(tpAniSirGlobal mac_ctx,
4110 tCsrRoamProfile *profile, tCsrRoamSession *session,
4111 uint32_t session_id, tDot11fBeaconIEs *ies_local,
4112 tSirBssDescription *bss_descr)
4113{
4114 CDF_STATUS status;
4115 tBssConfigParam bssConfig;
4116 if (csr_roam_is_same_profile_keys(mac_ctx, &session->connectedProfile,
4117 profile))
4118 return eCsrReassocToSelfNoCapChange;
4119 /* The key changes */
4120 cdf_mem_set(&bssConfig, sizeof(bssConfig), 0);
4121 status = csr_roam_prepare_bss_config(mac_ctx, profile, bss_descr,
4122 &bssConfig, ies_local);
4123 if (CDF_IS_STATUS_SUCCESS(status)) {
4124 session->bssParams.uCfgDot11Mode =
4125 bssConfig.uCfgDot11Mode;
4126 session->bssParams.cbMode =
4127 bssConfig.cbMode;
4128 /* reapply the cfg including keys so reassoc happens. */
4129 status = csr_roam_set_bss_config_cfg(mac_ctx, session_id,
4130 profile, bss_descr, &bssConfig,
4131 ies_local, false);
4132 if (CDF_IS_STATUS_SUCCESS(status))
4133 return eCsrContinueRoaming;
4134 }
4135
4136 return eCsrStopRoaming;
4137
4138}
4139
4140eCsrJoinState csr_roam_join(tpAniSirGlobal pMac, uint32_t sessionId,
4141 tCsrScanResultInfo *pScanResult,
4142 tCsrRoamProfile *pProfile)
4143{
4144 eCsrJoinState eRoamState = eCsrContinueRoaming;
4145 tSirBssDescription *pBssDesc = &pScanResult->BssDescriptor;
4146 tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *) (pScanResult->pvIes);
4147 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
4148
4149 if (!pSession) {
4150 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
4151 return eCsrStopRoaming;
4152 }
4153
4154 if (CSR_IS_WDS_STA(pProfile) &&
4155 !CDF_IS_STATUS_SUCCESS(csr_roam_start_wds(pMac, sessionId,
4156 pProfile, pBssDesc)))
4157 return eCsrStopRoaming;
4158 if (!pIesLocal &&
4159 !CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(pMac,
4160 pBssDesc, &pIesLocal))) {
4161 sms_log(pMac, LOGE, FL("fail to parse IEs"));
4162 return eCsrStopRoaming;
4163 }
4164 if (csr_is_infra_bss_desc(pBssDesc)) {
4165 /*
4166 * If we are connected in infra mode and the join bss descr is
4167 * for the same BssID, then we are attempting to join the AP we
4168 * are already connected with. In that case, see if the Bss or
4169 * sta capabilities have changed and handle the changes
4170 * without disturbing the current association
4171 */
4172
4173 if (csr_is_conn_state_connected_infra(pMac, sessionId) &&
4174 csr_is_bss_id_equal(pMac,
4175 pBssDesc, pSession->pConnectBssDesc) &&
4176 csr_is_ssid_equal(pMac, pSession->pConnectBssDesc,
4177 pBssDesc, pIesLocal)) {
4178 /*
4179 * Check to see if the Auth type has changed in the
4180 * profile. If so, we don't want to reassociate with
4181 * authenticating first. To force this, stop the
4182 * current association (Disassociate) and then re 'Join'
4183 * the AP, wihch will force an Authentication (with the
4184 * new Auth type) followed by a new Association.
4185 */
4186 if (csr_is_same_profile(pMac,
4187 &pSession->connectedProfile, pProfile)) {
4188 sms_log(pMac, LOGW,
4189 FL("detect same profile"));
4190 eRoamState =
4191 csr_roam_state_for_same_profile(pMac,
4192 pProfile, pSession, sessionId,
4193 pIesLocal, pBssDesc);
4194 } else if (!CDF_IS_STATUS_SUCCESS(
4195 csr_roam_issue_disassociate(pMac,
4196 sessionId,
4197 eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
4198 false))) {
4199 sms_log(pMac, LOGE,
4200 FL("fail disassoc session %d"),
4201 sessionId);
4202 eRoamState = eCsrStopRoaming;
4203 }
4204 } else if (!CDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac,
4205 sessionId, pProfile, pBssDesc, pIesLocal))) {
4206 /* we used to pre-auth here with open auth
4207 * networks but that wasn't working so well.
4208 * stop the existing network before attempting
4209 * to join the new network... */
4210 eRoamState = eCsrStopRoaming;
4211 }
4212 } else if (!CDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac, sessionId,
4213 pProfile, pBssDesc,
4214 pIesLocal))) {
4215 eRoamState = eCsrStopRoaming;
4216 }
4217
4218 if (pIesLocal && !pScanResult->pvIes)
4219 cdf_mem_free(pIesLocal);
4220 return eRoamState;
4221}
4222
4223CDF_STATUS csr_roam_should_roam(tpAniSirGlobal pMac, uint32_t sessionId,
4224 tSirBssDescription *pBssDesc, uint32_t roamId)
4225{
4226 CDF_STATUS status = CDF_STATUS_SUCCESS;
4227 tCsrRoamInfo roamInfo;
4228 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
4229 roamInfo.pBssDesc = pBssDesc;
4230 status =
4231 csr_roam_call_callback(pMac, sessionId, &roamInfo, roamId,
4232 eCSR_ROAM_SHOULD_ROAM, eCSR_ROAM_RESULT_NONE);
4233 return status;
4234}
4235
4236/* In case no matching BSS is found, use whatever default we can find */
4237static void csr_roam_assign_default_param(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4238{
4239 /* Need to get all negotiated types in place first */
4240 /* auth type */
4241 /* Take the preferred Auth type. */
4242 switch (pCommand->u.roamCmd.roamProfile.AuthType.authType[0]) {
4243 default:
4244 case eCSR_AUTH_TYPE_WPA:
4245 case eCSR_AUTH_TYPE_WPA_PSK:
4246 case eCSR_AUTH_TYPE_WPA_NONE:
4247 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4248 pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
4249 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4250 break;
4251
4252 case eCSR_AUTH_TYPE_SHARED_KEY:
4253 pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
4254 eCSR_AUTH_TYPE_SHARED_KEY;
4255 break;
4256
4257 case eCSR_AUTH_TYPE_AUTOSWITCH:
4258 pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
4259 eCSR_AUTH_TYPE_AUTOSWITCH;
4260 break;
4261 }
4262 pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
4263 pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0];
4264 /* In this case, the multicast encryption needs to follow the uncast ones. */
4265 pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
4266 pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0];
4267}
4268
4269static void csr_set_abort_roaming_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4270{
4271 switch (pCommand->u.roamCmd.roamReason) {
4272 case eCsrLostLink1:
4273 pCommand->u.roamCmd.roamReason = eCsrLostLink1Abort;
4274 break;
4275 case eCsrLostLink2:
4276 pCommand->u.roamCmd.roamReason = eCsrLostLink2Abort;
4277 break;
4278 case eCsrLostLink3:
4279 pCommand->u.roamCmd.roamReason = eCsrLostLink3Abort;
4280 break;
4281 default:
4282 sms_log(pMac, LOGE,
4283 FL(" aborting roaming reason %d not recognized"),
4284 pCommand->u.roamCmd.roamReason);
4285 break;
4286 }
4287}
4288
4289/**
4290 * csr_roam_select_bss() - Handle join scenario based on profile
4291 * @mac_ctx: Global MAC Context
4292 * @roam_bss_entry: The next BSS to join
4293 * @csr_result_info: Result of join
4294 * @csr_scan_result: Global scan result
4295 * @session_id: SME Session ID
4296 * @roam_id: Roaming ID
4297 * @roam_state: Current roaming state
4298 * @bss_list: BSS List
4299 *
4300 * Return: true if the entire BSS list is done, false otherwise.
4301 */
4302static bool csr_roam_select_bss(tpAniSirGlobal mac_ctx,
4303 tListElem *roam_bss_entry, tCsrScanResultInfo **csr_result_info,
4304 tCsrScanResult **csr_scan_result, uint32_t session_id,
4305 uint32_t roam_id, eCsrJoinState *roam_state,
4306 tScanResultList *bss_list)
4307{
4308 uint8_t conc_channel = 0;
4309 bool status = false;
4310 tCsrScanResult *scan_result = NULL;
4311 tCsrScanResultInfo *result = NULL;
4312
4313 while (roam_bss_entry) {
4314 scan_result = GET_BASE_ADDR(roam_bss_entry, tCsrScanResult,
4315 Link);
4316 /*
4317 * If concurrency enabled take the
4318 * concurrent connected channel first.
4319 * Valid multichannel concurrent
4320 * sessions exempted
4321 */
4322 result = &scan_result->Result;
4323 if (cds_concurrent_open_sessions_running() &&
4324 !csr_is_valid_mc_concurrent_session(mac_ctx,
4325 session_id, &result->BssDescriptor)) {
4326 conc_channel = csr_get_concurrent_operation_channel(
4327 mac_ctx);
4328 sms_log(mac_ctx, LOG1, FL("csr Conc Channel = %d"),
4329 conc_channel);
4330 if ((conc_channel) && (conc_channel ==
4331 result->BssDescriptor.channelId)) {
4332 /*
4333 * make this 0 because we do not want the below
4334 * check to pass as we don't want to connect on
4335 * other channel
4336 */
4337 sms_log(mac_ctx, LOG1, FL("Conc chnl match=%d"),
4338 conc_channel);
4339 conc_channel = 0;
4340 }
4341 }
4342
4343 /* Ok to roam this */
4344 if (!conc_channel &&
4345 CDF_IS_STATUS_SUCCESS(csr_roam_should_roam(mac_ctx,
4346 session_id, &result->BssDescriptor, roam_id))) {
4347 status = false;
4348 break;
4349 } else {
4350 *roam_state = eCsrStopRoamingDueToConcurrency;
4351 status = true;
4352 }
4353 roam_bss_entry = csr_ll_next(&bss_list->List, roam_bss_entry,
4354 LL_ACCESS_LOCK);
4355 }
4356 *csr_result_info = result;
4357 *csr_scan_result = scan_result;
4358 return status;
4359}
4360
4361/**
4362 * csr_roam_join_handle_profile() - Handle join scenario based on profile
4363 * @mac_ctx: Global MAC Context
4364 * @session_id: SME Session ID
4365 * @cmd: Command
4366 * @roam_info_ptr: Pointed to the roaming info for join
4367 * @roam_state: Current roaming state
4368 * @result: Result of join
4369 * @scan_result: Global scan result
4370 *
4371 * Return: None
4372 */
4373static void csr_roam_join_handle_profile(tpAniSirGlobal mac_ctx,
4374 uint32_t session_id, tSmeCmd *cmd, tCsrRoamInfo *roam_info_ptr,
4375 eCsrJoinState *roam_state, tCsrScanResultInfo *result,
4376 tCsrScanResult *scan_result)
4377{
4378#ifndef WLAN_MDM_CODE_REDUCTION_OPT
4379 uint8_t acm_mask = 0;
4380#endif
4381 CDF_STATUS status;
4382 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
4383 tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
4384 tDot11fBeaconIEs *ies_local = NULL;
4385 /*
4386 * We have something to roam, tell HDD when it is infra.
4387 * For IBSS, the indication goes back to HDD via eCSR_ROAM_IBSS_IND
4388 * For WDS, the indication is eCSR_ROAM_WDS_IND
4389 */
4390 if (CSR_IS_INFRASTRUCTURE(profile)) {
4391 if (roam_info_ptr && session->bRefAssocStartCnt) {
4392 session->bRefAssocStartCnt--;
4393 roam_info_ptr->pProfile = profile;
4394 /*
4395 * Complete the last assoc attempt as a
4396 * new one is about to be tried
4397 */
4398 csr_roam_call_callback(mac_ctx, session_id,
4399 roam_info_ptr, cmd->u.roamCmd.roamId,
4400 eCSR_ROAM_ASSOCIATION_COMPLETION,
4401 eCSR_ROAM_RESULT_NOT_ASSOCIATED);
4402 }
4403 /* If roaming has stopped, don't continue the roaming command */
4404 if (!CSR_IS_ROAMING(session) && CSR_IS_ROAMING_COMMAND(cmd)) {
4405 /* No need to complete roaming as it already complete */
4406 sms_log(mac_ctx, LOGW,
4407 FL(
4408 "Roam cmd(reason %d)aborted as roam complete"),
4409 cmd->u.roamCmd.roamReason);
4410 *roam_state = eCsrStopRoaming;
4411 csr_set_abort_roaming_command(mac_ctx, cmd);
4412 return;
4413 }
4414 cdf_mem_set(roam_info_ptr, sizeof(tCsrRoamInfo), 0);
4415 if (!scan_result)
4416 cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
4417 else
4418 ies_local = scan_result->Result.pvIes;
4419
4420 if (scan_result && !ies_local &&
4421 (!CDF_IS_STATUS_SUCCESS(
4422 csr_get_parsed_bss_description_ies(
4423 mac_ctx,
4424 &result->BssDescriptor,
4425 &ies_local)))) {
4426 sms_log(mac_ctx, LOGE, FL(" cannot parse IEs"));
4427 *roam_state = eCsrStopRoaming;
4428 return;
4429 }
4430 roam_info_ptr->pBssDesc = &result->BssDescriptor;
4431 cmd->u.roamCmd.pLastRoamBss = roam_info_ptr->pBssDesc;
4432 /* dont put uapsd_mask if BSS doesn't support uAPSD */
4433 if (scan_result && cmd->u.roamCmd.roamProfile.uapsd_mask
4434 && CSR_IS_QOS_BSS(ies_local)
4435 && CSR_IS_UAPSD_BSS(ies_local)) {
4436#ifndef WLAN_MDM_CODE_REDUCTION_OPT
4437 acm_mask = sme_qos_get_acm_mask(mac_ctx,
4438 &result->BssDescriptor, ies_local);
4439#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
4440 } else {
4441 cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
4442 }
4443 if (ies_local && !result->pvIes)
4444 cdf_mem_free(ies_local);
4445 roam_info_ptr->pProfile = profile;
4446 session->bRefAssocStartCnt++;
4447 csr_roam_call_callback(mac_ctx, session_id, roam_info_ptr,
4448 cmd->u.roamCmd.roamId, eCSR_ROAM_ASSOCIATION_START,
4449 eCSR_ROAM_RESULT_NONE);
4450 }
4451 if (NULL != cmd->u.roamCmd.pRoamBssEntry) {
4452 /*
4453 * We have BSS
4454 * Need to assign these value because
4455 * they are used in csr_is_same_profile
4456 */
4457 scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
4458 tCsrScanResult, Link);
4459 /*
4460 * The OSEN IE doesn't provide the cipher suite.Therefore set
4461 * to constant value of AES
4462 */
4463 if (cmd->u.roamCmd.roamProfile.bOSENAssociation) {
4464 cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
4465 eCSR_ENCRYPT_TYPE_AES;
4466 cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
4467 eCSR_ENCRYPT_TYPE_AES;
4468 } else {
4469 /* Negotiated while building scan result. */
4470 cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
4471 scan_result->ucEncryptionType;
4472 cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
4473 scan_result->mcEncryptionType;
4474 }
4475 cmd->u.roamCmd.roamProfile.negotiatedAuthType =
4476 scan_result->authType;
4477 if (CSR_IS_START_IBSS(&cmd->u.roamCmd.roamProfile)) {
4478 if (csr_is_same_profile(mac_ctx,
4479 &session->connectedProfile, profile)) {
4480 *roam_state = eCsrStartIbssSameIbss;
4481 return;
4482 }
4483 }
4484 if (cmd->u.roamCmd.fReassocToSelfNoCapChange) {
4485 /* trying to connect to the one already connected */
4486 cmd->u.roamCmd.fReassocToSelfNoCapChange = false;
4487 *roam_state = eCsrReassocToSelfNoCapChange;
4488 return;
4489 }
4490 /* Attempt to Join this Bss... */
4491 *roam_state = csr_roam_join(mac_ctx, session_id,
4492 &scan_result->Result, profile);
4493 return;
4494 }
4495
4496 /* For an IBSS profile, then we need to start the IBSS. */
4497 if (CSR_IS_START_IBSS(profile)) {
4498 bool same_ibss = false;
4499 /* Attempt to start this IBSS... */
4500 csr_roam_assign_default_param(mac_ctx, cmd);
4501 status = csr_roam_start_ibss(mac_ctx, session_id,
4502 profile, &same_ibss);
4503 if (CDF_IS_STATUS_SUCCESS(status)) {
4504 if (same_ibss)
4505 *roam_state = eCsrStartIbssSameIbss;
4506 else
4507 *roam_state = eCsrContinueRoaming;
4508 } else {
4509 /* it somehow fail need to stop */
4510 *roam_state = eCsrStopRoaming;
4511 }
4512 return;
4513 } else if ((CSR_IS_WDS_AP(profile)) ||
4514 (CSR_IS_INFRA_AP(profile))) {
4515 /* Attempt to start this WDS... */
4516 csr_roam_assign_default_param(mac_ctx, cmd);
4517 /* For AP WDS, we dont have any BSSDescription */
4518 status = csr_roam_start_wds(mac_ctx, session_id, profile, NULL);
4519 if (CDF_IS_STATUS_SUCCESS(status))
4520 *roam_state = eCsrContinueRoaming;
4521 else
4522 *roam_state = eCsrStopRoaming;
4523 } else {
4524 /* Nothing we can do */
4525 sms_log(mac_ctx, LOGW, FL("cannot continue without BSS list"));
4526 *roam_state = eCsrStopRoaming;
4527 return;
4528 }
4529
4530}
4531/**
4532 * csr_roam_join_next_bss() - Pick the next BSS for join
4533 * @mac_ctx: Global MAC Context
4534 * @cmd: Command
4535 * @use_same_bss: Use Same BSS to Join
4536 *
4537 * Return: The Join State
4538 */
4539static eCsrJoinState csr_roam_join_next_bss(tpAniSirGlobal mac_ctx,
4540 tSmeCmd *cmd, bool use_same_bss)
4541{
4542 tCsrScanResult *scan_result = NULL;
4543 eCsrJoinState roam_state = eCsrStopRoaming;
4544 tScanResultList *bss_list =
4545 (tScanResultList *) cmd->u.roamCmd.hBSSList;
4546 bool done = false;
4547 tCsrRoamInfo roam_info, *roam_info_ptr = NULL;
4548 uint32_t session_id = cmd->sessionId;
4549 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
4550 tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
4551 tCsrRoamJoinStatus *join_status;
4552 tCsrScanResultInfo *result = NULL;
4553
4554 if (!session) {
4555 sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
4556 return eCsrStopRoaming;
4557 }
4558
4559 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
4560 cdf_mem_copy(&roam_info.bssid, &session->joinFailStatusCode.bssId,
4561 sizeof(tSirMacAddr));
4562 /*
4563 * When handling AP's capability change, continue to associate
4564 * to same BSS and make sure pRoamBssEntry is not Null.
4565 */
4566 if ((NULL != bss_list) &&
4567 ((false == use_same_bss) ||
4568 (cmd->u.roamCmd.pRoamBssEntry == NULL))) {
4569 if (cmd->u.roamCmd.pRoamBssEntry == NULL) {
4570 /* Try the first BSS */
4571 cmd->u.roamCmd.pLastRoamBss = NULL;
4572 cmd->u.roamCmd.pRoamBssEntry =
4573 csr_ll_peek_head(&bss_list->List,
4574 LL_ACCESS_LOCK);
4575 } else {
4576 cmd->u.roamCmd.pRoamBssEntry =
4577 csr_ll_next(&bss_list->List,
4578 cmd->u.roamCmd.pRoamBssEntry,
4579 LL_ACCESS_LOCK);
4580 /*
4581 * Done with all the BSSs.
4582 * In this case, will tell HDD the
4583 * completion
4584 */
4585 if (NULL == cmd->u.roamCmd.pRoamBssEntry)
4586 goto end;
4587 /*
4588 * We need to indicate to HDD that we
4589 * are done with this one.
4590 */
4591 roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
4592 join_status = &session->joinFailStatusCode;
4593 roam_info.statusCode = join_status->statusCode;
4594 roam_info.reasonCode = join_status->reasonCode;
4595 roam_info_ptr = &roam_info;
4596 }
4597 done = csr_roam_select_bss(mac_ctx,
4598 cmd->u.roamCmd.pRoamBssEntry, &result,
4599 &scan_result, session_id, cmd->u.roamCmd.roamId,
4600 &roam_state, bss_list);
4601 if (done)
4602 goto end;
4603 }
4604 if (!roam_info_ptr)
4605 roam_info_ptr = &roam_info;
4606 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
4607 csr_roam_join_handle_profile(mac_ctx, session_id, cmd, roam_info_ptr,
4608 &roam_state, result, scan_result);
4609end:
4610 if ((eCsrStopRoaming == roam_state) && CSR_IS_INFRASTRUCTURE(profile) &&
4611 (session->bRefAssocStartCnt > 0)) {
4612 /*
4613 * Need to indicate association_completion if association_start
4614 * has been done
4615 */
4616 session->bRefAssocStartCnt--;
4617 /*
4618 * Complete the last assoc attempte as a
4619 * new one is about to be tried
4620 */
4621 roam_info_ptr = &roam_info;
4622 roam_info_ptr->pProfile = profile;
4623 csr_roam_call_callback(mac_ctx, session_id,
4624 roam_info_ptr, cmd->u.roamCmd.roamId,
4625 eCSR_ROAM_ASSOCIATION_COMPLETION,
4626 eCSR_ROAM_RESULT_NOT_ASSOCIATED);
4627 }
4628
4629 return roam_state;
4630}
4631
4632static CDF_STATUS csr_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4633{
4634 CDF_STATUS status = CDF_STATUS_SUCCESS;
4635 eCsrJoinState RoamState;
4636 eCsrRoamSubState substate;
4637 uint32_t sessionId = pCommand->sessionId;
4638
4639 /* Attept to join a Bss... */
4640 RoamState = csr_roam_join_next_bss(pMac, pCommand, false);
4641
4642 /* if nothing to join.. */
4643 if ((eCsrStopRoaming == RoamState) ||
4644 (eCsrStopRoamingDueToConcurrency == RoamState)) {
4645 bool fComplete = false;
4646 /* and if connected in Infrastructure mode... */
4647 if (csr_is_conn_state_infra(pMac, sessionId)) {
4648 /* ... then we need to issue a disassociation */
4649 substate = eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN;
4650 status = csr_roam_issue_disassociate(pMac, sessionId,
4651 substate, false);
4652 if (!CDF_IS_STATUS_SUCCESS(status)) {
4653 sms_log(pMac, LOGW,
4654 FL("fail issuing disassoc status = %d"),
4655 status);
4656 /*
4657 * roam command is completed by caller in the
4658 * failed case
4659 */
4660 fComplete = true;
4661 }
4662 } else if (csr_is_conn_state_ibss(pMac, sessionId)) {
4663 status = csr_roam_issue_stop_bss(pMac, sessionId,
4664 eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
4665 if (!CDF_IS_STATUS_SUCCESS(status)) {
4666 sms_log(pMac, LOGW,
4667 FL("fail issuing stop bss status = %d"),
4668 status);
4669 /*
4670 * roam command is completed by caller in the
4671 * failed case
4672 */
4673 fComplete = true;
4674 }
4675 } else if (csr_is_conn_state_connected_infra_ap(pMac,
4676 sessionId)) {
4677 substate = eCSR_ROAM_SUBSTATE_STOP_BSS_REQ;
4678 status = csr_roam_issue_stop_bss(pMac, sessionId,
4679 substate);
4680 if (!CDF_IS_STATUS_SUCCESS(status)) {
4681 sms_log(pMac, LOGW,
4682 FL("fail issuing stop bss status = %d"),
4683 status);
4684 /*
4685 * roam command is completed by caller in the
4686 * failed case
4687 */
4688 fComplete = true;
4689 }
4690 } else {
4691 fComplete = true;
4692 }
4693
4694 if (fComplete) {
4695 /* otherwise, we can complete the Roam command here. */
4696 if (eCsrStopRoamingDueToConcurrency == RoamState)
4697 csr_roam_complete(pMac,
4698 eCsrJoinFailureDueToConcurrency, NULL);
4699 else
4700 csr_roam_complete(pMac,
4701 eCsrNothingToJoin, NULL);
4702 }
4703 } else if (eCsrReassocToSelfNoCapChange == RoamState) {
4704 csr_roam_complete(pMac, eCsrSilentlyStopRoamingSaveState,
4705 NULL);
4706 } else if (eCsrStartIbssSameIbss == RoamState) {
4707 csr_roam_complete(pMac, eCsrSilentlyStopRoaming, NULL);
4708 }
4709
4710 return status;
4711}
4712
4713CDF_STATUS csr_process_ft_reassoc_roam_command(tpAniSirGlobal pMac,
4714 tSmeCmd *pCommand)
4715{
4716 uint32_t sessionId;
4717 tCsrRoamSession *pSession;
4718 tCsrScanResult *pScanResult = NULL;
4719 tSirBssDescription *pBssDesc = NULL;
4720 CDF_STATUS status = CDF_STATUS_SUCCESS;
4721 sessionId = pCommand->sessionId;
4722 pSession = CSR_GET_SESSION(pMac, sessionId);
4723
4724 if (!pSession) {
4725 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
4726 return CDF_STATUS_E_FAILURE;
4727 }
4728
4729 if (CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) {
4730 /* the roaming is cancelled. Simply complete the command */
4731 sms_log(pMac, LOG1, FL("Roam command canceled"));
4732 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
4733 return CDF_STATUS_E_FAILURE;
4734 }
4735 if (pCommand->u.roamCmd.pRoamBssEntry) {
4736 pScanResult =
4737 GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
4738 tCsrScanResult, Link);
4739 pBssDesc = &pScanResult->Result.BssDescriptor;
4740 } else {
4741 /* the roaming is cancelled. Simply complete the command */
4742 sms_log(pMac, LOG1, FL("Roam command canceled"));
4743 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
4744 return CDF_STATUS_E_FAILURE;
4745 }
4746 status = csr_roam_issue_reassociate(pMac, sessionId, pBssDesc,
4747 (tDot11fBeaconIEs *) (pScanResult->
4748 Result.pvIes),
4749 &pCommand->u.roamCmd.roamProfile);
4750 return status;
4751}
4752
4753/**
4754 * csr_roam_trigger_reassociate() - Helper function to trigger reassociate
4755 * @mac_ctx: pointer to mac context
4756 * @cmd: sme command
4757 * @roam_info: Roaming infor structure
4758 * @session_ptr: session pointer
4759 * @session_id: session id
4760 *
4761 * This function will trigger reassociate.
4762 *
4763 * Return: CDF_STATUS for success or failure.
4764 */
4765static CDF_STATUS csr_roam_trigger_reassociate(tpAniSirGlobal mac_ctx,
4766 tSmeCmd *cmd, tCsrRoamInfo *roam_info,
4767 tCsrRoamSession *session_ptr, uint32_t session_id)
4768{
4769 tDot11fBeaconIEs *pIes = NULL;
4770 CDF_STATUS status = CDF_STATUS_SUCCESS;
4771
4772 if (session_ptr->pConnectBssDesc) {
4773 status = csr_get_parsed_bss_description_ies(mac_ctx,
4774 session_ptr->pConnectBssDesc, &pIes);
4775 if (!CDF_IS_STATUS_SUCCESS(status)) {
4776 sms_log(mac_ctx, LOGE, FL("fail to parse IEs"));
4777 } else {
4778 roam_info->reasonCode =
4779 eCsrRoamReasonStaCapabilityChanged;
4780 csr_roam_call_callback(mac_ctx, session_ptr->sessionId,
4781 roam_info, 0, eCSR_ROAM_ROAMING_START,
4782 eCSR_ROAM_RESULT_NONE);
4783 session_ptr->roamingReason = eCsrReassocRoaming;
4784 roam_info->pBssDesc = session_ptr->pConnectBssDesc;
4785 roam_info->pProfile = &cmd->u.roamCmd.roamProfile;
4786 session_ptr->bRefAssocStartCnt++;
4787 csr_roam_call_callback(mac_ctx, session_id, roam_info,
4788 cmd->u.roamCmd.roamId,
4789 eCSR_ROAM_ASSOCIATION_START,
4790 eCSR_ROAM_RESULT_NONE);
4791
4792 sms_log(mac_ctx, LOG1,
4793 FL("calling csr_roam_issue_reassociate"));
4794 status = csr_roam_issue_reassociate(mac_ctx, session_id,
4795 session_ptr->pConnectBssDesc, pIes,
4796 &cmd->u.roamCmd.roamProfile);
4797 if (!CDF_IS_STATUS_SUCCESS(status)) {
4798 sms_log(mac_ctx, LOGE, FL("failed status %d"),
4799 status);
4800 csr_release_command_roam(mac_ctx, cmd);
4801 }
4802
4803 cdf_mem_free(pIes);
4804 pIes = NULL;
4805 }
4806 } else {
4807 sms_log(mac_ctx, LOGE, FL
4808 ("reassoc to same AP failed as connected BSS is NULL"));
4809 status = CDF_STATUS_E_FAILURE;
4810 }
4811 return status;
4812}
4813
4814CDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4815{
4816 CDF_STATUS status = CDF_STATUS_SUCCESS;
4817 tCsrRoamInfo roamInfo;
4818 uint32_t sessionId = pCommand->sessionId;
4819 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
4820
4821 if (!pSession) {
4822 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
4823 return CDF_STATUS_E_FAILURE;
4824 }
4825 sms_log(pMac, LOG1, FL("Roam Reason : %d, sessionId: %d"),
4826 pCommand->u.roamCmd.roamReason, sessionId);
4827
4828 switch (pCommand->u.roamCmd.roamReason) {
4829 case eCsrForcedDisassoc:
4830 if (eCSR_ROAMING_STATE_IDLE == pMac->roam.curState[sessionId]) {
4831 sms_log(pMac, LOGE,
4832 FL("Ignore eCsrForcedDisassoc cmd on roam state"
4833 " %d"), eCSR_ROAMING_STATE_IDLE);
4834 return CDF_STATUS_E_FAILURE;
4835 }
4836
4837 status = csr_roam_process_disassoc_deauth(pMac, pCommand,
4838 true, false);
4839 csr_free_roam_profile(pMac, sessionId);
4840 break;
4841 case eCsrSmeIssuedDisassocForHandoff:
4842 /* Not to free pMac->roam.pCurRoamProfile (via
4843 * csr_free_roam_profile) because its needed after disconnect */
4844 status = csr_roam_process_disassoc_deauth(pMac, pCommand,
4845 true, false);
4846
4847 break;
4848 case eCsrForcedDisassocMICFailure:
4849 status = csr_roam_process_disassoc_deauth(pMac, pCommand,
4850 true, true);
4851 csr_free_roam_profile(pMac, sessionId);
4852 break;
4853 case eCsrForcedDeauth:
4854 status = csr_roam_process_disassoc_deauth(pMac, pCommand,
4855 false, false);
4856 csr_free_roam_profile(pMac, sessionId);
4857 break;
4858 case eCsrHddIssuedReassocToSameAP:
4859 case eCsrSmeIssuedReassocToSameAP:
4860 status = csr_roam_trigger_reassociate(pMac, pCommand, &roamInfo,
4861 pSession, sessionId);
4862 break;
4863 case eCsrCapsChange:
4864 sms_log(pMac, LOGE, FL("received eCsrCapsChange "));
4865 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
4866 sessionId);
4867 status = csr_roam_issue_disassociate(pMac, sessionId,
4868 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
4869 false);
4870 break;
4871 case eCsrSmeIssuedFTReassoc:
4872 sms_log(pMac, LOG1, FL("received FT Reassoc Req "));
4873 status = csr_process_ft_reassoc_roam_command(pMac, pCommand);
4874 break;
4875
4876 case eCsrStopBss:
4877 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
4878 sessionId);
4879 status = csr_roam_issue_stop_bss(pMac, sessionId,
4880 eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
4881 break;
4882
4883 case eCsrForcedDisassocSta:
4884 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
4885 sessionId);
4886 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
4887 sessionId);
4888 status = csr_send_mb_disassoc_req_msg(pMac, sessionId,
4889 pCommand->u.roamCmd.peerMac,
4890 pCommand->u.roamCmd.reason);
4891 break;
4892
4893 case eCsrForcedDeauthSta:
4894 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
4895 sessionId);
4896 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
4897 sessionId);
4898 status = csr_send_mb_deauth_req_msg(pMac, sessionId,
4899 pCommand->u.roamCmd.peerMac,
4900 pCommand->u.roamCmd.reason);
4901 break;
4902
4903 case eCsrPerformPreauth:
4904 sms_log(pMac, LOG1, FL("Attempting FT PreAuth Req"));
4905 status = csr_roam_issue_ft_preauth_req(pMac, sessionId,
4906 pCommand->u.roamCmd.pLastRoamBss);
4907 break;
4908 default:
4909 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
4910 sessionId);
4911
4912 if (pCommand->u.roamCmd.fUpdateCurRoamProfile) {
4913 /* Remember the roaming profile */
4914 csr_free_roam_profile(pMac, sessionId);
4915 pSession->pCurRoamProfile =
4916 cdf_mem_malloc(sizeof(tCsrRoamProfile));
4917 if (NULL != pSession->pCurRoamProfile) {
4918 cdf_mem_set(pSession->pCurRoamProfile,
4919 sizeof(tCsrRoamProfile), 0);
4920 csr_roam_copy_profile(pMac,
4921 pSession->pCurRoamProfile,
4922 &pCommand->u.roamCmd.roamProfile);
4923 }
4924 }
4925 /*
4926 * At this point original uapsd_mask is saved in
4927 * pCurRoamProfile. uapsd_mask in the pCommand may change from
4928 * this point on. Attempt to roam with the new scan results
4929 * (if we need to..)
4930 */
4931 status = csr_roam(pMac, pCommand);
4932 if (!CDF_IS_STATUS_SUCCESS(status))
4933 sms_log(pMac, LOGW,
4934 FL("csr_roam() failed with status = 0x%08X"),
4935 status);
4936 break;
4937 }
4938 return status;
4939}
4940
4941void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4942{
4943 pCommand->u.roamCmd.pLastRoamBss = NULL;
4944 pCommand->u.roamCmd.pRoamBssEntry = NULL;
4945 /* Because u.roamCmd is union and share with scanCmd and StatusChange */
4946 cdf_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0);
4947}
4948
4949void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4950{
4951 if (pCommand->u.roamCmd.fReleaseBssList) {
4952 csr_scan_result_purge(pMac, pCommand->u.roamCmd.hBSSList);
4953 pCommand->u.roamCmd.fReleaseBssList = false;
4954 pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
4955 }
4956 if (pCommand->u.roamCmd.fReleaseProfile) {
4957 csr_release_profile(pMac, &pCommand->u.roamCmd.roamProfile);
4958 pCommand->u.roamCmd.fReleaseProfile = false;
4959 }
4960 pCommand->u.roamCmd.pRoamBssEntry = NULL;
4961 /* Because u.roamCmd is union and share with scanCmd and StatusChange */
4962 cdf_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0);
4963}
4964
4965void csr_reinit_wm_status_change_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
4966{
4967 cdf_mem_set(&pCommand->u.wmStatusChangeCmd, sizeof(tWmStatusChangeCmd),
4968 0);
4969}
4970
4971void csr_roam_complete(tpAniSirGlobal pMac, eCsrRoamCompleteResult Result,
4972 void *Context)
4973{
4974 tListElem *pEntry;
4975 tSmeCmd *pCommand;
4976 bool fReleaseCommand = true;
4977 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
4978 "%s: Roam Completion ...", __func__);
4979 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
4980 if (pEntry) {
4981 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
4982 /* If the head of the queue is Active and it is a ROAM command, remove */
4983 /* and put this on the Free queue. */
4984 if (eSmeCommandRoam == pCommand->command) {
4985 /* we need to process the result first before removing it from active list because state changes */
4986 /* still happening insides roamQProcessRoamResults so no other roam command should be issued */
4987 fReleaseCommand =
4988 csr_roam_process_results(pMac, pCommand, Result,
4989 Context);
4990 if (fReleaseCommand) {
4991 if (csr_ll_remove_entry
4992 (&pMac->sme.smeCmdActiveList, pEntry,
4993 LL_ACCESS_LOCK)) {
4994 csr_release_command_roam(pMac, pCommand);
4995 } else {
4996 sms_log(pMac, LOGE,
4997 " **********csr_roam_complete fail to release command reason %d",
4998 pCommand->u.roamCmd.roamReason);
4999 }
5000 } else {
5001 sms_log(pMac, LOGE,
5002 " **********csr_roam_complete fail to release command reason %d",
5003 pCommand->u.roamCmd.roamReason);
5004 }
5005 } else {
5006 sms_log(pMac, LOGW,
5007 "CSR: Roam Completion called but ROAM command is not ACTIVE ...");
5008 }
5009 } else {
5010 sms_log(pMac, LOGW,
5011 "CSR: Roam Completion called but NO commands are ACTIVE ...");
5012 }
5013 if (fReleaseCommand) {
5014 sme_process_pending_queue(pMac);
5015 }
5016}
5017
5018void csr_reset_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId)
5019{
5020 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5021 if (!pSession) {
5022 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
5023 return;
5024 }
5025 cdf_mem_set(&(pSession->PmkidCandidateInfo[0]),
5026 sizeof(tPmkidCandidateInfo) * CSR_MAX_PMKID_ALLOWED, 0);
5027 pSession->NumPmkidCandidate = 0;
5028}
5029
5030#ifdef FEATURE_WLAN_WAPI
5031void csr_reset_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId)
5032{
5033 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5034 if (!pSession) {
5035 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
5036 return;
5037 }
5038 cdf_mem_set(&(pSession->BkidCandidateInfo[0]),
5039 sizeof(tBkidCandidateInfo) * CSR_MAX_BKID_ALLOWED, 0);
5040 pSession->NumBkidCandidate = 0;
5041}
5042#endif /* FEATURE_WLAN_WAPI */
5043extern uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE];
5044
5045/**
5046 * csr_roam_save_params() - Helper function to save params
5047 * @mac_ctx: pointer to mac context
5048 * @session_ptr: Session pointer
5049 * @auth_type: auth type
5050 * @ie_ptr: pointer to ie
5051 * @ie_local: pointr to local ie
5052 *
5053 * This function will save params to session
5054 *
5055 * Return: none.
5056 */
5057static CDF_STATUS csr_roam_save_params(tpAniSirGlobal mac_ctx,
5058 tCsrRoamSession *session_ptr,
5059 eCsrAuthType auth_type,
5060 tDot11fBeaconIEs *ie_ptr,
5061 tDot11fBeaconIEs *ie_local)
5062{
5063 uint32_t nIeLen;
5064 uint8_t *pIeBuf;
5065
5066 if ((eCSR_AUTH_TYPE_RSN == auth_type) ||
5067#if defined WLAN_FEATURE_VOWIFI_11R
5068 (eCSR_AUTH_TYPE_FT_RSN == auth_type) ||
5069 (eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type) ||
5070#endif /* WLAN_FEATURE_VOWIFI_11R */
5071#if defined WLAN_FEATURE_11W
5072 (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == auth_type) ||
5073 (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == auth_type) ||
5074#endif
5075 (eCSR_AUTH_TYPE_RSN_PSK == auth_type)) {
5076 if (ie_local->RSN.present) {
5077 tDot11fIERSN *rsnie = &ie_local->RSN;
5078 /*
5079 * Calculate the actual length
5080 * version + gp_cipher_suite + pwise_cipher_suite_count
5081 * + akm_suite_count + reserved + pwise_cipher_suites
5082 */
5083 nIeLen = 8 + 2 + 2
5084 + (rsnie->pwise_cipher_suite_count * 4)
5085 + (rsnie->akm_suite_count * 4);
5086 if (rsnie->pmkid_count)
5087 /* pmkid */
5088 nIeLen += 2 + rsnie->pmkid_count * 4;
5089
5090 /* nIeLen doesn't count EID and length fields */
5091 session_ptr->pWpaRsnRspIE = cdf_mem_malloc(nIeLen + 2);
5092 if (NULL == session_ptr->pWpaRsnRspIE)
5093 return CDF_STATUS_E_NOMEM;
5094
5095 cdf_mem_set(session_ptr->pWpaRsnRspIE,
5096 nIeLen + 2, 0);
5097 session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_RSN;
5098 session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
5099 /* copy upto akm_suites */
5100 pIeBuf = session_ptr->pWpaRsnRspIE + 2;
5101 cdf_mem_copy(pIeBuf, &rsnie->version,
5102 sizeof(rsnie->version));
5103 pIeBuf += sizeof(rsnie->version);
5104 cdf_mem_copy(pIeBuf, &rsnie->gp_cipher_suite,
5105 sizeof(rsnie->gp_cipher_suite));
5106 pIeBuf += sizeof(rsnie->gp_cipher_suite);
5107 cdf_mem_copy(pIeBuf, &rsnie->pwise_cipher_suite_count,
5108 sizeof(rsnie->pwise_cipher_suite_count));
5109 pIeBuf += sizeof(rsnie->pwise_cipher_suite_count);
5110 if (rsnie->pwise_cipher_suite_count) {
5111 /* copy pwise_cipher_suites */
5112 cdf_mem_copy(pIeBuf, rsnie->pwise_cipher_suites,
5113 rsnie->pwise_cipher_suite_count * 4);
5114 pIeBuf += rsnie->pwise_cipher_suite_count * 4;
5115 }
5116 cdf_mem_copy(pIeBuf, &rsnie->akm_suite_count, 2);
5117 pIeBuf += 2;
5118 if (rsnie->akm_suite_count) {
5119 /* copy akm_suites */
5120 cdf_mem_copy(pIeBuf, rsnie->akm_suites,
5121 rsnie->akm_suite_count * 4);
5122 pIeBuf += rsnie->akm_suite_count * 4;
5123 }
5124 /* copy the rest */
5125 cdf_mem_copy(pIeBuf, rsnie->akm_suites +
5126 rsnie->akm_suite_count * 4,
5127 2 + rsnie->pmkid_count * 4);
5128 session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
5129 }
5130 } else if ((eCSR_AUTH_TYPE_WPA == auth_type) ||
5131 (eCSR_AUTH_TYPE_WPA_PSK == auth_type)) {
5132 if (ie_local->WPA.present) {
5133 tDot11fIEWPA *wpaie = &ie_local->WPA;
5134 /* Calculate the actual length wpaie */
5135 nIeLen = 12 + 2 /* auth_suite_count */
5136 + wpaie->unicast_cipher_count * 4
5137 + wpaie->auth_suite_count * 4;
5138
5139 /* The WPA capabilities follows the Auth Suite
5140 * (two octects)-- this field is optional, and
5141 * we always "send" zero, so just remove it. This is
5142 * consistent with our assumptions in the frames
5143 * compiler; nIeLen doesn't count EID & length fields */
5144 session_ptr->pWpaRsnRspIE = cdf_mem_malloc(nIeLen + 2);
5145 if (NULL == session_ptr->pWpaRsnRspIE)
5146 return CDF_STATUS_E_NOMEM;
5147 session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_WPA;
5148 session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
5149 pIeBuf = session_ptr->pWpaRsnRspIE + 2;
5150 /* Copy WPA OUI */
5151 cdf_mem_copy(pIeBuf, &csr_wpa_oui[1], 4);
5152 pIeBuf += 4;
5153 cdf_mem_copy(pIeBuf, &wpaie->version,
5154 8 + wpaie->unicast_cipher_count * 4);
5155 pIeBuf += 8 + wpaie->unicast_cipher_count * 4;
5156 cdf_mem_copy(pIeBuf, &wpaie->auth_suite_count,
5157 2 + wpaie->auth_suite_count * 4);
5158 pIeBuf += wpaie->auth_suite_count * 4;
5159 session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
5160 }
5161 }
5162#ifdef FEATURE_WLAN_WAPI
5163 else if ((eCSR_AUTH_TYPE_WAPI_WAI_PSK == auth_type) ||
5164 (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ==
5165 auth_type)) {
5166 if (ie_local->WAPI.present) {
5167 tDot11fIEWAPI *wapi_ie = &ie_local->WAPI;
5168 /* Calculate the actual length of wapi ie*/
5169 nIeLen = 4 + 2 /* pwise_cipher_suite_count */
5170 + wapi_ie->akm_suite_count * 4
5171 + wapi_ie->unicast_cipher_suite_count * 4
5172 + 6; /* gp_cipher_suite + preauth + reserved */
5173
5174 if (wapi_ie->bkid_count)
5175 nIeLen += 2 + wapi_ie->bkid_count * 4;
5176
5177 /* nIeLen doesn't count EID and length fields */
5178 session_ptr->pWapiRspIE =
5179 cdf_mem_malloc(nIeLen + 2);
5180 if (NULL == session_ptr->pWapiRspIE)
5181 return CDF_STATUS_E_NOMEM;
5182 session_ptr->pWapiRspIE[0] = DOT11F_EID_WAPI;
5183 session_ptr->pWapiRspIE[1] = (uint8_t) nIeLen;
5184 pIeBuf = session_ptr->pWapiRspIE + 2;
5185 /* copy upto akm_suite_count */
5186 cdf_mem_copy(pIeBuf, &wapi_ie->version, 2);
5187 pIeBuf += 4;
5188 if (wapi_ie->akm_suite_count) {
5189 /* copy akm_suites */
5190 cdf_mem_copy(pIeBuf,
5191 wapi_ie->akm_suites,
5192 wapi_ie->akm_suite_count * 4);
5193 pIeBuf += wapi_ie->akm_suite_count * 4;
5194 }
5195 cdf_mem_copy(pIeBuf,
5196 &wapi_ie->unicast_cipher_suite_count, 2);
5197 pIeBuf += 2;
5198 if (wapi_ie->unicast_cipher_suite_count) {
5199 uint16_t suite_size =
5200 wapi_ie->unicast_cipher_suite_count * 4;
5201 /* copy pwise_cipher_suites */
5202 cdf_mem_copy(pIeBuf,
5203 wapi_ie->unicast_cipher_suites,
5204 suite_size);
5205 pIeBuf += suite_size;
5206 }
5207 /* gp_cipher_suite */
5208 cdf_mem_copy(pIeBuf,
5209 wapi_ie->multicast_cipher_suite, 4);
5210 pIeBuf += 4;
5211 /* preauth + reserved */
5212 cdf_mem_copy(pIeBuf,
5213 wapi_ie->multicast_cipher_suite + 4, 2);
5214 pIeBuf += 2;
5215 if (wapi_ie->bkid_count) {
5216 /* bkid_count */
5217 cdf_mem_copy(pIeBuf, &wapi_ie->bkid_count, 2);
5218 pIeBuf += 2;
5219 /* copy akm_suites */
5220 cdf_mem_copy(pIeBuf, wapi_ie->bkid,
5221 wapi_ie->bkid_count * 4);
5222 pIeBuf += wapi_ie->bkid_count * 4;
5223 }
5224 session_ptr->nWapiRspIeLength = nIeLen + 2;
5225 }
5226 }
5227#endif /* FEATURE_WLAN_WAPI */
5228 return CDF_STATUS_SUCCESS;
5229}
5230
5231static CDF_STATUS csr_roam_save_security_rsp_ie(tpAniSirGlobal pMac,
5232 uint32_t sessionId,
5233 eCsrAuthType authType,
5234 tSirBssDescription *pSirBssDesc,
5235 tDot11fBeaconIEs *pIes)
5236{
5237 CDF_STATUS status = CDF_STATUS_SUCCESS;
5238 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5239 tDot11fBeaconIEs *pIesLocal = pIes;
5240
5241 if (!pSession) {
5242 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
5243 return CDF_STATUS_E_FAILURE;
5244 }
5245#ifdef WLAN_FEATURE_ROAM_OFFLOAD
5246 if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
5247 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
5248 FL("LFR3:csr_roam_save_security_rsp_ie"));
5249 }
5250#endif
5251
5252 if ((eCSR_AUTH_TYPE_WPA == authType) ||
5253 (eCSR_AUTH_TYPE_WPA_PSK == authType) ||
5254 (eCSR_AUTH_TYPE_RSN == authType) ||
5255 (eCSR_AUTH_TYPE_RSN_PSK == authType)
5256#if defined WLAN_FEATURE_VOWIFI_11R
5257 || (eCSR_AUTH_TYPE_FT_RSN == authType) ||
5258 (eCSR_AUTH_TYPE_FT_RSN_PSK == authType)
5259#endif /* FEATURE_WLAN_WAPI */
5260#ifdef FEATURE_WLAN_WAPI
5261 || (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) ||
5262 (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)
5263#endif /* FEATURE_WLAN_WAPI */
5264#ifdef WLAN_FEATURE_11W
5265 || (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
5266 (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType)
5267#endif /* FEATURE_WLAN_WAPI */
5268 ) {
5269 if (!pIesLocal && !CDF_IS_STATUS_SUCCESS
5270 (csr_get_parsed_bss_description_ies(pMac,
5271 pSirBssDesc, &pIesLocal)))
5272 sms_log(pMac, LOGE, FL(" cannot parse IEs"));
5273 if (pIesLocal) {
5274 status = csr_roam_save_params(pMac, pSession, authType,
5275 pIes, pIesLocal);
5276 if (!pIes)
5277 /* locally allocated */
5278 cdf_mem_free(pIesLocal);
5279 }
5280 }
5281 return status;
5282}
5283
5284#ifdef WLAN_FEATURE_VOWIFI_11R
5285/* Returns whether the current association is a 11r assoc or not */
5286bool csr_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
5287{
5288#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
5289 return csr_neighbor_roam_is11r_assoc(pMac, sessionId);
5290#else
5291 return false;
5292#endif
5293}
5294#endif
5295#ifdef FEATURE_WLAN_ESE
5296/* Returns whether the current association is a ESE assoc or not */
5297bool csr_roam_is_ese_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
5298{
5299#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
5300 return csr_neighbor_roam_is_ese_assoc(pMac, sessionId);
5301#else
5302 return false;
5303#endif
5304}
5305#endif
5306#ifdef FEATURE_WLAN_LFR
5307/* Returns whether "Legacy Fast Roaming" is currently enabled...or not */
5308bool csr_roam_is_fast_roam_enabled(tpAniSirGlobal pMac, uint32_t sessionId)
5309{
5310 tCsrRoamSession *pSession = NULL;
5311
5312 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
5313 pSession = CSR_GET_SESSION(pMac, sessionId);
5314 if (NULL != pSession->pCurRoamProfile) {
5315 if (pSession->pCurRoamProfile->csrPersona !=
5316 CDF_STA_MODE) {
5317 return false;
5318 }
5319 }
5320 }
5321 if (true == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) {
5322 return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
5323 } else {
5324 return pMac->roam.configParam.isFastRoamIniFeatureEnabled &&
5325 (!csr_is_concurrent_session_running(pMac));
5326 }
5327}
5328
5329#ifdef FEATURE_WLAN_ESE
5330/**
5331 * csr_neighbor_roam_is_ese_assoc() - Check the Association type
5332 * @mac_ctx: Global MAC Context
5333 * @session_id: Session ID on which the check should be done
5334 *
5335 * This function returns whether the current association
5336 * is a ESE assoc or not
5337 *
5338 * Return: True if ESE association, false otherwise.
5339 **/
5340bool csr_neighbor_roam_is_ese_assoc(tpAniSirGlobal mac_ctx, uint8_t session_id)
5341{
5342 return mac_ctx->roam.neighborRoamInfo[session_id].isESEAssoc;
5343}
5344#endif /* FEATURE_WLAN_ESE */
5345
5346/* Returns whether "FW based BG scan" is currently enabled...or not */
5347bool csr_roam_is_roam_offload_scan_enabled(tpAniSirGlobal pMac)
5348{
5349 return pMac->roam.configParam.isRoamOffloadScanEnabled;
5350}
5351#endif
5352
5353#if defined(FEATURE_WLAN_ESE)
5354bool csr_roam_is_ese_ini_feature_enabled(tpAniSirGlobal pMac)
5355{
5356 return pMac->roam.configParam.isEseIniFeatureEnabled;
5357}
5358#endif /*FEATURE_WLAN_ESE */
5359
5360#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
5361eCsrPhyMode csr_roamdot11mode_to_phymode(uint8_t dot11mode)
5362{
5363 eCsrPhyMode phymode = eCSR_DOT11_MODE_abg;
5364
5365 switch (dot11mode) {
5366 case WNI_CFG_DOT11_MODE_ALL:
5367 phymode = eCSR_DOT11_MODE_abg;
5368 break;
5369 case WNI_CFG_DOT11_MODE_11A:
5370 phymode = eCSR_DOT11_MODE_11a;
5371 break;
5372 case WNI_CFG_DOT11_MODE_11B:
5373 phymode = eCSR_DOT11_MODE_11b;
5374 break;
5375 case WNI_CFG_DOT11_MODE_11G:
5376 phymode = eCSR_DOT11_MODE_11g;
5377 break;
5378 case WNI_CFG_DOT11_MODE_11N:
5379 phymode = eCSR_DOT11_MODE_11n;
5380 break;
5381 case WNI_CFG_DOT11_MODE_11G_ONLY:
5382 phymode = eCSR_DOT11_MODE_11g_ONLY;
5383 break;
5384 case WNI_CFG_DOT11_MODE_11N_ONLY:
5385 phymode = eCSR_DOT11_MODE_11n_ONLY;
5386 break;
5387 case WNI_CFG_DOT11_MODE_11AC:
5388 phymode = eCSR_DOT11_MODE_11ac;
5389 break;
5390 case WNI_CFG_DOT11_MODE_11AC_ONLY:
5391 phymode = eCSR_DOT11_MODE_11ac_ONLY;
5392 break;
5393 default:
5394 break;
5395 }
5396
5397 return phymode;
5398}
5399#endif
5400
5401#ifdef WLAN_FEATURE_ROAM_OFFLOAD
5402CDF_STATUS csr_roam_offload_send_synch_cnf(tpAniSirGlobal pMac, uint8_t sessionId)
5403{
5404 tpSirSmeRoamOffloadSynchCnf pRoamOffloadSynchCnf;
5405 cds_msg_t msg;
5406 tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
5407 pRoamOffloadSynchCnf =
5408 cdf_mem_malloc(sizeof(tSirSmeRoamOffloadSynchCnf));
5409 if (NULL == pRoamOffloadSynchCnf) {
5410 CDF_TRACE(CDF_MODULE_ID_SME,
5411 CDF_TRACE_LEVEL_ERROR,
5412 "%s: not able to allocate memory for roam"
5413 "offload synch confirmation data", __func__);
5414 pSession->roamOffloadSynchParams.bRoamSynchInProgress =
5415 false;
5416 return CDF_STATUS_E_NOMEM;
5417 }
5418 pRoamOffloadSynchCnf->sessionId = sessionId;
5419 msg.type = WMA_ROAM_OFFLOAD_SYNCH_CNF;
5420 msg.reserved = 0;
5421 msg.bodyptr = pRoamOffloadSynchCnf;
5422 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5423 "LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
5424 if (!CDF_IS_STATUS_SUCCESS
5425 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
5426 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
5427 "%s: Not able to post WMA_ROAM_OFFLOAD_SYNCH_CNF message to WMA",
5428 __func__);
5429 cdf_mem_free(pRoamOffloadSynchCnf);
5430 pSession->roamOffloadSynchParams.bRoamSynchInProgress =
5431 false;
5432 return CDF_STATUS_E_FAILURE;
5433 }
5434 pSession->roamOffloadSynchParams.bRoamSynchInProgress = false;
5435 return CDF_STATUS_SUCCESS;
5436}
5437
5438void csr_roam_synch_clean_up (tpAniSirGlobal mac, uint8_t session_id)
5439{
5440 cds_msg_t msg;
5441 struct roam_offload_synch_fail *roam_offload_failed = NULL;
5442 tCsrRoamSession *session = &mac->roam.roamSession[session_id];
5443
5444 /* Clean up the roam synch in progress for LFR3 */
5445 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5446 "%s: Roam Synch Failed, Clean Up", __func__);
5447 session->roamOffloadSynchParams.bRoamSynchInProgress = false;
5448
5449 roam_offload_failed = cdf_mem_malloc(
5450 sizeof(struct roam_offload_synch_fail));
5451 if (NULL == roam_offload_failed) {
5452 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5453 "%s: unable to allocate memory for roam synch fail" ,
5454 __func__);
5455 return;
5456 }
5457
5458 roam_offload_failed->session_id = session_id;
5459 msg.type = WMA_ROAM_OFFLOAD_SYNCH_FAIL;
5460 msg.reserved = 0;
5461 msg.bodyptr = roam_offload_failed;
5462 if (!CDF_IS_STATUS_SUCCESS(cds_mq_post_message(CDF_MODULE_ID_WMA,
5463 &msg))) {
5464 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
5465 "%s: Unable to post WMA_ROAM_OFFLOAD_SYNCH_FAIL to WMA",
5466 __func__);
5467 cdf_mem_free(roam_offload_failed);
5468 }
5469}
5470#endif
5471
5472#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
5473/**
5474 * csr_roam_copy_ht_profile() - Copy from src to dst
5475 * @dst_profile: Destination HT profile
5476 * @src_profile: Source HT profile
5477 *
5478 * Copy the HT profile from the given source to destination
5479 *
5480 * Return: None
5481 */
5482static void csr_roam_copy_ht_profile(tCsrRoamHTProfile *dst_profile,
5483 tSirSmeHTProfile *src_profile)
5484{
5485 dst_profile->phymode =
5486 csr_roamdot11mode_to_phymode(src_profile->dot11mode);
5487 dst_profile->htCapability = src_profile->htCapability;
5488 dst_profile->htSupportedChannelWidthSet =
5489 src_profile->htSupportedChannelWidthSet;
5490 dst_profile->htRecommendedTxWidthSet =
5491 src_profile->htRecommendedTxWidthSet;
5492 dst_profile->htSecondaryChannelOffset =
5493 src_profile->htSecondaryChannelOffset;
5494#ifdef WLAN_FEATURE_11AC
5495 dst_profile->vhtCapability = src_profile->vhtCapability;
5496 dst_profile->vhtTxChannelWidthSet = src_profile->vhtTxChannelWidthSet;
5497 dst_profile->apCenterChan = src_profile->apCenterChan;
5498 dst_profile->apChanWidth = src_profile->apChanWidth;
5499#endif
5500}
5501#endif
5502
5503/**
5504 * csr_roam_process_results_default() - Process the result for start bss
5505 * @mac_ctx: Global MAC Context
5506 * @cmd: Command to be processed
5507 * @context: Additional data in context of the cmd
5508 *
5509 * Return: None
5510 */
5511static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx,
5512 tSmeCmd *cmd, void *context, eCsrRoamCompleteResult res)
5513{
5514 uint32_t session_id = cmd->sessionId;
5515 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
5516 tCsrRoamInfo roam_info;
5517 CDF_STATUS status;
5518
5519 sms_log(mac_ctx, LOGW, FL("receives no association indication"));
5520 sms_log(mac_ctx, LOG1, FL("Assoc ref count %d"),
5521 session->bRefAssocStartCnt);
5522 if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile)
5523 || CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) {
5524 /*
5525 * do not free for the other profiles as we need
5526 * to send down stop BSS later
5527 */
5528 csr_free_connect_bss_desc(mac_ctx, session_id);
5529 csr_roam_free_connect_profile(mac_ctx,
5530 &session->connectedProfile);
5531 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
5532 csr_set_default_dot11_mode(mac_ctx);
5533 }
5534
5535 switch (cmd->u.roamCmd.roamReason) {
5536 /*
5537 * If this transition is because of an 802.11 OID, then we
5538 * transition back to INIT state so we sit waiting for more
5539 * OIDs to be issued and we don't start the IDLE timer.
5540 */
5541 case eCsrSmeIssuedFTReassoc:
5542 case eCsrSmeIssuedAssocToSimilarAP:
5543 case eCsrHddIssued:
5544 case eCsrSmeIssuedDisassocForHandoff:
5545 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
5546 session_id);
5547 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
5548 roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
5549 roam_info.pProfile = &cmd->u.roamCmd.roamProfile;
5550 roam_info.statusCode = session->joinFailStatusCode.statusCode;
5551 roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
5552 cdf_mem_copy(&roam_info.bssid,
5553 &session->joinFailStatusCode.bssId,
5554 sizeof(struct cdf_mac_addr));
5555
5556#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
5557 /*
5558 * If Join fails while Handoff is in progress, indicate
5559 * disassociated event to supplicant to reconnect
5560 */
5561 if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)) {
5562 csr_neighbor_roam_indicate_connect(mac_ctx,
5563 (uint8_t)session_id, CDF_STATUS_E_FAILURE);
5564 }
5565#endif
5566 if (session->bRefAssocStartCnt > 0) {
5567 session->bRefAssocStartCnt--;
5568 if (eCsrJoinFailureDueToConcurrency == res)
5569 csr_roam_call_callback(mac_ctx, session_id,
5570 &roam_info, cmd->u.roamCmd.roamId,
5571 eCSR_ROAM_ASSOCIATION_COMPLETION,
5572 eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL);
5573 else
5574 csr_roam_call_callback(mac_ctx, session_id,
5575 &roam_info, cmd->u.roamCmd.roamId,
5576 eCSR_ROAM_ASSOCIATION_COMPLETION,
5577 eCSR_ROAM_RESULT_FAILURE);
5578 } else {
5579 /*
5580 * bRefAssocStartCnt is not incremented when
5581 * eRoamState == eCsrStopRoamingDueToConcurrency
5582 * in csr_roam_join_next_bss API. so handle this in
5583 * else case by sending assoc failure
5584 */
5585 csr_roam_call_callback(mac_ctx, session_id,
5586 &roam_info, cmd->u.scanCmd.roamId,
5587 eCSR_ROAM_ASSOCIATION_FAILURE,
5588 eCSR_ROAM_RESULT_FAILURE);
5589 }
5590 sms_log(mac_ctx, LOG1, FL("roam(reason %d) failed"),
5591 cmd->u.roamCmd.roamReason);
5592#ifndef WLAN_MDM_CODE_REDUCTION_OPT
5593 sme_qos_update_hand_off((uint8_t) session_id, false);
5594 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
5595 SME_QOS_CSR_DISCONNECT_IND, NULL);
5596#endif
5597 csr_roam_completion(mac_ctx, session_id, NULL, cmd,
5598 eCSR_ROAM_RESULT_FAILURE, false);
5599#ifdef FEATURE_WLAN_BTAMP_UT_RF
5600 /*
5601 * For WDS STA. To fix the issue where the WDS AP side may
5602 * be too busy by BT activity and not able to receive
5603 * WLAN traffic. Retry the join
5604 */
5605 if (CSR_IS_WDS_STA(profile))
5606 csr_roam_start_join_retry_timer(mac_ctx, session_id,
5607 CSR_JOIN_RETRY_TIMEOUT_PERIOD);
5608#endif
5609 break;
5610 case eCsrHddIssuedReassocToSameAP:
5611 case eCsrSmeIssuedReassocToSameAP:
5612 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
5613 session_id);
5614
5615 csr_roam_call_callback(mac_ctx, session_id, NULL,
5616 cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
5617 eCSR_ROAM_RESULT_FORCED);
5618#ifndef WLAN_MDM_CODE_REDUCTION_OPT
5619 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
5620 SME_QOS_CSR_DISCONNECT_IND, NULL);
5621#endif
5622 csr_roam_completion(mac_ctx, session_id, NULL, cmd,
5623 eCSR_ROAM_RESULT_FAILURE, false);
5624 break;
5625 case eCsrForcedDisassoc:
5626 case eCsrForcedDeauth:
5627 case eCsrSmeIssuedIbssJoinFailure:
5628 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
5629 session_id);
5630
5631 if (eCsrSmeIssuedIbssJoinFailure == cmd->u.roamCmd.roamReason)
5632 /* notify HDD that IBSS join failed */
5633 csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
5634 eCSR_ROAM_IBSS_IND,
5635 eCSR_ROAM_RESULT_IBSS_JOIN_FAILED);
5636 else
5637 csr_roam_call_callback(mac_ctx, session_id, NULL,
5638 cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
5639 eCSR_ROAM_RESULT_FORCED);
5640#ifndef WLAN_MDM_CODE_REDUCTION_OPT
5641 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
5642 SME_QOS_CSR_DISCONNECT_IND,
5643 NULL);
5644#endif
5645 csr_roam_link_down(mac_ctx, session_id);
5646
5647 if (mac_ctx->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) {
5648 sms_log(mac_ctx, LOGW,
5649 FL("FW still in connected state"));
5650 break;
5651 }
5652 break;
5653 case eCsrForcedIbssLeave:
5654 csr_roam_call_callback(mac_ctx, session_id, NULL,
5655 cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_LEAVE,
5656 eCSR_ROAM_RESULT_IBSS_STOP);
5657 break;
5658 case eCsrForcedDisassocMICFailure:
5659 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
5660 session_id);
5661
5662 csr_roam_call_callback(mac_ctx, session_id, NULL,
5663 cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
5664 eCSR_ROAM_RESULT_MIC_FAILURE);
5665#ifndef WLAN_MDM_CODE_REDUCTION_OPT
5666 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
5667 SME_QOS_CSR_DISCONNECT_REQ, NULL);
5668#endif
5669 break;
5670 case eCsrStopBss:
5671 csr_roam_call_callback(mac_ctx, session_id, NULL,
5672 cmd->u.roamCmd.roamId, eCSR_ROAM_INFRA_IND,
5673 eCSR_ROAM_RESULT_INFRA_STOPPED);
5674 break;
5675 case eCsrForcedDisassocSta:
5676 case eCsrForcedDeauthSta:
5677 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
5678 session_id);
5679 session = CSR_GET_SESSION(mac_ctx, session_id);
5680 if (CSR_IS_SESSION_VALID(mac_ctx, session_id) &&
5681 CSR_IS_INFRA_AP(&session->connectedProfile)) {
5682 roam_info.u.pConnectedProfile =
5683 &session->connectedProfile;
5684 cdf_mem_copy(roam_info.peerMac.bytes,
5685 cmd->u.roamCmd.peerMac,
5686 sizeof(tSirMacAddr));
5687 roam_info.reasonCode = eCSR_ROAM_RESULT_FORCED;
5688 roam_info.statusCode = eSIR_SME_SUCCESS;
5689 status = csr_roam_call_callback(mac_ctx, session_id,
5690 &roam_info, cmd->u.roamCmd.roamId,
5691 eCSR_ROAM_LOSTLINK,
5692 eCSR_ROAM_RESULT_FORCED);
5693 }
5694 break;
5695 case eCsrLostLink1:
5696 /* if lost link roam1 failed, then issue lost link Scan2 ... */
5697 csr_scan_request_lost_link2(mac_ctx, session_id);
5698 break;
5699 case eCsrLostLink2:
5700 /* if lost link roam2 failed, then issue lost link scan3 ... */
5701 csr_scan_request_lost_link3(mac_ctx, session_id);
5702 break;
5703 case eCsrLostLink3:
5704 default:
5705 csr_roam_state_change(mac_ctx,
5706 eCSR_ROAMING_STATE_IDLE, session_id);
5707
5708 /* We are done with one round of lostlink roaming here */
5709 csr_scan_handle_failed_lostlink3(mac_ctx, session_id);
5710 break;
5711 }
5712}
5713
5714/**
5715 * csr_roam_process_start_bss_success() - Process the result for start bss
5716 * @mac_ctx: Global MAC Context
5717 * @cmd: Command to be processed
5718 * @context: Additional data in context of the cmd
5719 *
5720 * Return: None
5721 */
5722static void csr_roam_process_start_bss_success(tpAniSirGlobal mac_ctx,
5723 tSmeCmd *cmd, void *context)
5724{
5725 uint32_t session_id = cmd->sessionId;
5726 tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
5727 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
5728 tSirBssDescription *bss_desc = NULL;
5729 tCsrRoamInfo roam_info;
5730 tSirSmeStartBssRsp *start_bss_rsp = NULL;
5731 tCsrScanResult *scan_res = NULL;
5732 eRoamCmdStatus roam_status;
5733 eCsrRoamResult roam_result;
5734 tDot11fBeaconIEs *ies_ptr = NULL;
5735 tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
5736 CDF_STATUS status;
5737 host_log_ibss_pkt_type *ibss_log;
5738 uint32_t bi;
5739#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
5740 tSirSmeHTProfile *src_profile = NULL;
5741 tCsrRoamHTProfile *dst_profile = NULL;
5742#endif
5743
5744 /*
5745 * on the StartBss Response, LIM is returning the Bss Description that
5746 * we are beaconing. Add this Bss Description to our scan results and
5747 * chain the Profile to this Bss Description. On a Start BSS, there was
5748 * no detected Bss description (no partner) so we issued the Start Bss
5749 * to start the Ibss without any Bss description. Lim was kind enough
5750 * to return the Bss Description that we start beaconing for the newly
5751 * started Ibss.
5752 */
5753 sms_log(mac_ctx, LOG2, FL("receives start BSS ok indication"));
5754 status = CDF_STATUS_E_FAILURE;
5755 start_bss_rsp = (tSirSmeStartBssRsp *) context;
5756 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
5757 if (CSR_IS_IBSS(profile))
5758 session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
5759 else if (CSR_IS_INFRA_AP(profile))
5760 session->connectState =
5761 eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
5762 else
5763 session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
5764 if (!CSR_IS_WDS_STA(profile)) {
5765 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
5766 session_id);
5767 bss_desc = &start_bss_rsp->bssDescription;
5768 if (!CDF_IS_STATUS_SUCCESS
5769 (csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
5770 &ies_ptr))) {
5771 sms_log(mac_ctx, LOGW, FL("cannot parse IBSS IEs"));
5772 roam_info.pBssDesc = bss_desc;
5773 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
5774 cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_IND,
5775 eCSR_ROAM_RESULT_IBSS_START_FAILED);
5776 return;
5777 }
5778 if (!CSR_IS_INFRA_AP(profile)) {
5779 scan_res =
5780 csr_scan_append_bss_description(mac_ctx,
5781 bss_desc, ies_ptr, false,
5782 session_id);
5783 }
5784 csr_roam_save_connected_bss_desc(mac_ctx, session_id, bss_desc);
5785 csr_roam_free_connect_profile(mac_ctx,
5786 &session->connectedProfile);
5787 csr_roam_free_connected_info(mac_ctx,
5788 &session->connectedInfo);
5789 if (bss_desc) {
5790 csr_roam_save_connected_infomation(mac_ctx, session_id,
5791 profile, bss_desc, ies_ptr);
5792 cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
5793 sizeof(struct cdf_mac_addr));
5794 }
5795 /* We are done with the IEs so free it */
5796 cdf_mem_free(ies_ptr);
5797#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
5798 WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
5799 host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
5800 if (ibss_log) {
5801 if (CSR_INVALID_SCANRESULT_HANDLE ==
5802 cmd->u.roamCmd.hBSSList) {
5803 /*
5804 * We start the IBSS (didn't find any
5805 * matched IBSS out there)
5806 */
5807 ibss_log->eventId =
5808 WLAN_IBSS_EVENT_START_IBSS_RSP;
5809 } else {
5810 ibss_log->eventId =
5811 WLAN_IBSS_EVENT_JOIN_IBSS_RSP;
5812 }
5813 if (bss_desc) {
5814 cdf_mem_copy(ibss_log->bssid,
5815 bss_desc->bssId, 6);
5816 ibss_log->operatingChannel =
5817 bss_desc->channelId;
5818 }
5819 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(
5820 mac_ctx,
5821 WNI_CFG_BEACON_INTERVAL,
5822 &bi)))
5823 /* U8 is not enough for BI */
5824 ibss_log->beaconInterval = (uint8_t) bi;
5825 WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
5826 }
5827#endif
5828 /*
5829 * Only set context for non-WDS_STA. We don't even need it for
5830 * WDS_AP. But since the encryption.
5831 * is WPA2-PSK so it won't matter.
5832 */
5833 if (CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType)
5834 && session->pCurRoamProfile
5835 && !CSR_IS_INFRA_AP(session->pCurRoamProfile)) {
5836 /*
5837 * Issue the set Context request to LIM to establish
5838 * the Broadcast STA context for the Ibss. In Rome IBSS
5839 * case, dummy key installation will break proper BSS
5840 * key installation, so skip it.
5841 */
5842 if (!CSR_IS_IBSS(session->pCurRoamProfile)) {
5843 /* NO keys. these key parameters don't matter */
5844 csr_roam_issue_set_context_req(mac_ctx,
5845 session_id,
5846 profile->negotiatedMCEncryptionType,
5847 bss_desc, &bcast_mac, false,
5848 false, eSIR_TX_RX, 0, 0, NULL, 0);
5849 }
5850
5851 }
5852 } else {
5853 /*
5854 * Keep the state to eCSR_ROAMING_STATE_JOINING.
5855 * Need to send join_req.
5856 */
5857 if (cmd->u.roamCmd.pRoamBssEntry) {
5858 scan_res = GET_BASE_ADDR(cmd->u.roamCmd.
5859 pRoamBssEntry, tCsrScanResult, Link);
5860 if (scan_res) {
5861 bss_desc = &scan_res->Result.BssDescriptor;
5862 ies_ptr = (tDot11fBeaconIEs *)
5863 (scan_res->Result.pvIes);
5864 /* Set the roaming substate to join attempt */
5865 csr_roam_substate_change(mac_ctx,
5866 eCSR_ROAM_SUBSTATE_JOIN_REQ,
5867 session_id);
5868 status = csr_send_join_req_msg(mac_ctx,
5869 session_id, bss_desc,
5870 profile, ies_ptr,
5871 eWNI_SME_JOIN_REQ);
5872 }
5873 } else {
5874 sms_log(mac_ctx, LOGE,
5875 "StartBSS for WDS station with no BssDesc");
5876 CDF_ASSERT(0);
5877 }
5878 }
5879 /*
5880 * Only tell upper layer is we start the BSS because Vista doesn't like
5881 * multiple connection indications. If we don't start the BSS ourself,
5882 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start
5883 * indication in Vista
5884 */
5885 if (!CSR_IS_JOIN_TO_IBSS(profile)) {
5886 roam_status = eCSR_ROAM_IBSS_IND;
5887 roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
5888 if (CSR_IS_WDS(profile)) {
5889 roam_status = eCSR_ROAM_WDS_IND;
5890 roam_result = eCSR_ROAM_RESULT_WDS_STARTED;
5891 }
5892 if (CSR_IS_INFRA_AP(profile)) {
5893 roam_status = eCSR_ROAM_INFRA_IND;
5894 roam_result = eCSR_ROAM_RESULT_INFRA_STARTED;
5895 }
5896 /*
5897 * Only tell upper layer is we start the BSS because Vista
5898 * doesn't like multiple connection indications. If we don't
5899 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS
5900 * will trigger the connection start indication in Vista
5901 */
5902 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
5903 roam_info.statusCode = session->joinFailStatusCode.statusCode;
5904 roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
5905 /* We start the IBSS (didn't find any matched IBSS out there) */
5906 roam_info.pBssDesc = bss_desc;
5907 roam_info.staId = (uint8_t) start_bss_rsp->staId;
5908 cdf_mem_copy(roam_info.bssid.bytes, bss_desc->bssId,
5909 sizeof(struct cdf_mac_addr));
5910 if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
5911 (csr_is_concurrent_session_running(mac_ctx))) {
5912 mac_ctx->roam.configParam.doBMPSWorkaround = 1;
5913 }
5914#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
5915 dst_profile = &session->connectedProfile.HTProfile;
5916 src_profile = &start_bss_rsp->HTProfile;
5917 if (mac_ctx->roam.configParam.cc_switch_mode
5918 != CDF_MCC_TO_SCC_SWITCH_DISABLE)
5919 csr_roam_copy_ht_profile(dst_profile, src_profile);
5920#endif
5921 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
5922 cmd->u.roamCmd.roamId,
5923 roam_status, roam_result);
5924 }
5925
5926
5927 if (CSR_IS_WDS_STA(profile)) {
5928 /* need to send stop BSS because we fail to send join_req */
5929 csr_roam_issue_disassociate_cmd(mac_ctx, session_id,
5930 eCSR_DISCONNECT_REASON_UNSPECIFIED);
5931 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
5932 cmd->u.roamCmd.roamId,
5933 eCSR_ROAM_WDS_IND,
5934 eCSR_ROAM_RESULT_WDS_STOPPED);
5935 }
5936}
5937
5938/**
5939 * csr_roam_process_join_res() - Process the Join results
5940 * @mac_ctx: Global MAC Context
5941 * @result: Result after the command was processed
5942 * @cmd: Command to be processed
5943 * @context: Additional data in context of the cmd
5944 *
5945 * Process the join results which are obtained in a succesful join
5946 *
5947 * Return: None
5948 */
5949static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
5950 eCsrRoamCompleteResult res, tSmeCmd *cmd, void *context)
5951{
5952 tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
5953 sme_QosAssocInfo assoc_info;
5954 uint32_t key_timeout_interval = 0;
5955 uint8_t acm_mask = 0; /* HDD needs ACM mask in assoc rsp callback */
5956 uint32_t session_id = cmd->sessionId;
5957 tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
5958 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
5959 tSirBssDescription *bss_desc = NULL;
5960 tCsrScanResult *scan_res = NULL;
5961 sme_qos_csr_event_indType ind_qos;
5962 csr_roam_offload_synch_params *roam_offload_params = NULL;
5963#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
5964 tSirSmeHTProfile *src_profile = NULL;
5965 tCsrRoamHTProfile *dst_profile = NULL;
5966#endif
5967 tCsrRoamConnectedProfile *conn_profile = NULL;
5968 tDot11fBeaconIEs *ies_ptr = NULL;
5969 tCsrRoamInfo roam_info;
5970 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
5971 tSirSmeJoinRsp *join_rsp = (tSirSmeJoinRsp *) context;
5972 uint32_t len;
5973
5974 roam_offload_params = &session->roamOffloadSynchParams;
5975 conn_profile = &session->connectedProfile;
5976 if (eCsrReassocSuccess == res)
5977 ind_qos = SME_QOS_CSR_REASSOC_COMPLETE;
5978 else
5979 ind_qos = SME_QOS_CSR_ASSOC_COMPLETE;
5980 sms_log(mac_ctx, LOGW, FL("receives association indication"));
5981 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
5982 /* always free the memory here */
5983 if (session->pWpaRsnRspIE) {
5984 session->nWpaRsnRspIeLength = 0;
5985 cdf_mem_free(session->pWpaRsnRspIE);
5986 session->pWpaRsnRspIE = NULL;
5987 }
5988#ifdef FEATURE_WLAN_WAPI
5989 if (session->pWapiRspIE) {
5990 session->nWapiRspIeLength = 0;
5991 cdf_mem_free(session->pWapiRspIE);
5992 session->pWapiRspIE = NULL;
5993 }
5994#endif /* FEATURE_WLAN_WAPI */
5995#ifdef FEATURE_WLAN_BTAMP_UT_RF
5996 session->maxRetryCount = 0;
5997 csr_roam_stop_join_retry_timer(mac_ctx, session_id);
5998#endif
5999 /*
6000 * Reset remain_in_power_active_till_dhcp as
6001 * it might have been set by last failed secured connection.
6002 * It should be set only for secured connection.
6003 */
6004 ps_global_info->remain_in_power_active_till_dhcp = false;
6005 if (CSR_IS_INFRASTRUCTURE(profile))
6006 session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
6007 else
6008 session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;
6009 /*
6010 * Use the last connected bssdesc for reassoc-ing to the same AP.
6011 * NOTE: What to do when reassoc to a different AP???
6012 */
6013 if ((eCsrHddIssuedReassocToSameAP == cmd->u.roamCmd.roamReason)
6014 || (eCsrSmeIssuedReassocToSameAP ==
6015 cmd->u.roamCmd.roamReason)) {
6016 bss_desc = session->pConnectBssDesc;
6017 if (bss_desc)
6018 cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
6019 sizeof(struct cdf_mac_addr));
6020 } else {
6021 if (cmd->u.roamCmd.pRoamBssEntry) {
6022 scan_res = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
6023 tCsrScanResult, Link);
6024 if (scan_res != NULL) {
6025 bss_desc = &scan_res->Result.BssDescriptor;
6026 ies_ptr = (tDot11fBeaconIEs *)
6027 (scan_res->Result.pvIes);
6028 cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
6029 sizeof(struct cdf_mac_addr));
6030 }
6031 }
6032 }
6033 if (bss_desc) {
6034 roam_info.staId = STA_INVALID_IDX;
6035 csr_roam_save_connected_infomation(mac_ctx, session_id,
6036 profile, bss_desc, ies_ptr);
6037 /* Save WPA/RSN IE */
6038 csr_roam_save_security_rsp_ie(mac_ctx, session_id,
6039 profile->negotiatedAuthType, bss_desc, ies_ptr);
6040#ifdef FEATURE_WLAN_ESE
6041 roam_info.isESEAssoc = conn_profile->isESEAssoc;
6042#endif
6043
6044 /*
6045 * csr_roam_state_change also affects sub-state.
6046 * Hence, csr_roam_state_change happens first and then
6047 * substate change.
6048 * Moving even save profile above so that below
6049 * mentioned conditon is also met.
6050 * JEZ100225: Moved to after saving the profile.
6051 * Fix needed in main/latest
6052 */
6053 csr_roam_state_change(mac_ctx,
6054 eCSR_ROAMING_STATE_JOINED, session_id);
6055
6056 /*
6057 * Make sure the Set Context is issued before link
6058 * indication to NDIS. After link indication is
6059 * made to NDIS, frames could start flowing.
6060 * If we have not set context with LIM, the frames
6061 * will be dropped for the security context may not
6062 * be set properly.
6063 *
6064 * this was causing issues in the 2c_wlan_wep WHQL test
6065 * when the SetContext was issued after the link
6066 * indication. (Link Indication happens in the
6067 * profFSMSetConnectedInfra call).
6068 *
6069 * this reordering was done on titan_prod_usb branch
6070 * and is being replicated here.
6071 */
6072
6073 if (CSR_IS_ENC_TYPE_STATIC
6074 (profile->negotiatedUCEncryptionType) &&
6075 !profile->bWPSAssociation) {
6076 /*
6077 * Issue the set Context request to LIM to establish
6078 * the Unicast STA context
6079 */
6080 if (!CDF_IS_STATUS_SUCCESS(
6081 csr_roam_issue_set_context_req(mac_ctx,
6082 session_id,
6083 profile->negotiatedUCEncryptionType,
6084 bss_desc, &(bss_desc->bssId),
6085 false, true,
6086 eSIR_TX_RX, 0, 0, NULL, 0))) {
6087 /* NO keys. these key parameters don't matter */
6088 sms_log(mac_ctx, LOGE,
6089 FL("Set context for unicast fail"));
6090 csr_roam_substate_change(mac_ctx,
6091 eCSR_ROAM_SUBSTATE_NONE, session_id);
6092 }
6093 /*
6094 * Issue the set Context request to LIM
6095 * to establish the Broadcast STA context
6096 * NO keys. these key parameters don't matter
6097 */
6098 csr_roam_issue_set_context_req(mac_ctx, session_id,
6099 profile->negotiatedMCEncryptionType,
6100 bss_desc, &bcast_mac, false, false,
6101 eSIR_TX_RX, 0, 0, NULL, 0);
6102 } else {
6103#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6104 if (roam_offload_params->bRoamSynchInProgress
6105 && (roam_offload_params->authStatus
6106 == CSR_ROAM_AUTH_STATUS_AUTHENTICATED)) {
6107 CDF_TRACE(CDF_MODULE_ID_SME,
6108 CDF_TRACE_LEVEL_DEBUG,
6109 FL("LFR3:Don't start waitforkey timer"));
6110 csr_roam_substate_change(mac_ctx,
6111 eCSR_ROAM_SUBSTATE_NONE, session_id);
6112 } else {
6113#endif
6114 /* Need to wait for supplicant authtication */
6115 roam_info.fAuthRequired = true;
6116 /*
6117 * Set the substate to WaitForKey in case
6118 * authentiation is needed
6119 */
6120 csr_roam_substate_change(mac_ctx,
6121 eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
6122 session_id);
6123
6124 /*
6125 * Set remain_in_power_active_till_dhcp to make
6126 * sure we wait for until keys are set before
6127 * going into BMPS.
6128 */
6129 ps_global_info->remain_in_power_active_till_dhcp
6130 = true;
6131
6132 if (profile->bWPSAssociation)
6133 key_timeout_interval =
6134 CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
6135 else
6136 key_timeout_interval =
6137 CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
6138
6139 /* Save session_id in case of timeout */
6140 mac_ctx->roam.WaitForKeyTimerInfo.sessionId =
6141 (uint8_t) session_id;
6142 /*
6143 * This time should be long enough for the rest
6144 * of the process plus setting key
6145 */
6146 if (!CDF_IS_STATUS_SUCCESS
6147 (csr_roam_start_wait_for_key_timer(
6148 mac_ctx, key_timeout_interval))
6149 ) {
6150 /* Reset state so nothing is blocked. */
6151 sms_log(mac_ctx, LOGE, FL
6152 ("Failed preauth timer start"));
6153 csr_roam_substate_change(mac_ctx,
6154 eCSR_ROAM_SUBSTATE_NONE,
6155 session_id);
6156 }
6157#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6158 }
6159#endif
6160 }
6161
6162 assoc_info.pBssDesc = bss_desc; /* could be NULL */
6163 assoc_info.pProfile = profile;
6164 if (context) {
6165#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6166 if (roam_offload_params->bRoamSynchInProgress)
6167 CDF_TRACE(CDF_MODULE_ID_SME,
6168 CDF_TRACE_LEVEL_DEBUG,
6169 FL("LFR3:Clear Connected info"));
6170#endif
6171 csr_roam_free_connected_info(mac_ctx,
6172 &session->connectedInfo);
6173 len = join_rsp->assocReqLength +
6174 join_rsp->assocRspLength +
6175 join_rsp->beaconLength;
6176#ifdef WLAN_FEATURE_VOWIFI_11R
6177 len += join_rsp->parsedRicRspLen;
6178#endif /* WLAN_FEATURE_VOWIFI_11R */
6179#ifdef FEATURE_WLAN_ESE
6180 len += join_rsp->tspecIeLen;
6181#endif
6182 if (len) {
6183 session->connectedInfo.pbFrames =
6184 cdf_mem_malloc(len);
6185 if (session->connectedInfo.pbFrames !=
6186 NULL) {
6187 cdf_mem_copy(
6188 session->connectedInfo.pbFrames,
6189 join_rsp->frames, len);
6190 session->connectedInfo.nAssocReqLength =
6191 join_rsp->assocReqLength;
6192 session->connectedInfo.nAssocRspLength =
6193 join_rsp->assocRspLength;
6194 session->connectedInfo.nBeaconLength =
6195 join_rsp->beaconLength;
6196#ifdef WLAN_FEATURE_VOWIFI_11R
6197 session->connectedInfo.nRICRspLength =
6198 join_rsp->parsedRicRspLen;
6199#endif /* WLAN_FEATURE_VOWIFI_11R */
6200#ifdef FEATURE_WLAN_ESE
6201 session->connectedInfo.nTspecIeLength =
6202 join_rsp->tspecIeLen;
6203#endif
6204 roam_info.nAssocReqLength =
6205 join_rsp->assocReqLength;
6206 roam_info.nAssocRspLength =
6207 join_rsp->assocRspLength;
6208 roam_info.nBeaconLength =
6209 join_rsp->beaconLength;
6210 roam_info.pbFrames =
6211 session->connectedInfo.pbFrames;
6212 }
6213 }
6214 if (cmd->u.roamCmd.fReassoc)
6215 roam_info.fReassocReq =
6216 roam_info.fReassocRsp = true;
6217 conn_profile->vht_channel_width =
6218 join_rsp->vht_channel_width;
6219 session->connectedInfo.staId =
6220 (uint8_t) join_rsp->staId;
6221 roam_info.staId = (uint8_t) join_rsp->staId;
6222 roam_info.ucastSig = (uint8_t) join_rsp->ucastSig;
6223 roam_info.bcastSig = (uint8_t) join_rsp->bcastSig;
6224 roam_info.timingMeasCap = join_rsp->timingMeasCap;
6225#ifdef FEATURE_WLAN_TDLS
6226 roam_info.tdls_prohibited = join_rsp->tdls_prohibited;
6227 roam_info.tdls_chan_swit_prohibited =
6228 join_rsp->tdls_chan_swit_prohibited;
6229 sms_log(mac_ctx, LOG1,
6230 FL("tdls:prohibit: %d, chan_swit_prohibit: %d"),
6231 roam_info.tdls_prohibited,
6232 roam_info.tdls_chan_swit_prohibited);
6233#endif
6234#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
6235 src_profile = &join_rsp->HTProfile;
6236 dst_profile = &conn_profile->HTProfile;
6237 if (mac_ctx->roam.configParam.cc_switch_mode
6238 != CDF_MCC_TO_SCC_SWITCH_DISABLE)
6239 csr_roam_copy_ht_profile(dst_profile,
6240 src_profile);
6241#endif
6242 } else {
6243 if (cmd->u.roamCmd.fReassoc) {
6244 roam_info.fReassocReq =
6245 roam_info.fReassocRsp = true;
6246 roam_info.nAssocReqLength =
6247 session->connectedInfo.nAssocReqLength;
6248 roam_info.nAssocRspLength =
6249 session->connectedInfo.nAssocRspLength;
6250 roam_info.nBeaconLength =
6251 session->connectedInfo.nBeaconLength;
6252 roam_info.pbFrames =
6253 session->connectedInfo.pbFrames;
6254 }
6255 }
6256
6257 /*
6258 * Update the staId from the previous connected profile info
6259 * as the reassociation is triggred at SME/HDD
6260 */
6261
6262 if ((eCsrHddIssuedReassocToSameAP ==
6263 cmd->u.roamCmd.roamReason) ||
6264 (eCsrSmeIssuedReassocToSameAP ==
6265 cmd->u.roamCmd.roamReason))
6266 roam_info.staId = session->connectedInfo.staId;
6267
6268#ifndef WLAN_MDM_CODE_REDUCTION_OPT
6269 /*
6270 * Indicate SME-QOS with reassoc success event,
6271 * only after copying the frames
6272 */
6273 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id, ind_qos,
6274 &assoc_info);
6275#endif
6276 roam_info.pBssDesc = bss_desc;
6277 roam_info.statusCode =
6278 session->joinFailStatusCode.statusCode;
6279 roam_info.reasonCode =
6280 session->joinFailStatusCode.reasonCode;
6281#ifndef WLAN_MDM_CODE_REDUCTION_OPT
6282 acm_mask = sme_qos_get_acm_mask(mac_ctx, bss_desc, NULL);
6283#endif
6284 conn_profile->acm_mask = acm_mask;
6285 /*
6286 * start UAPSD if uapsd_mask is not 0 because HDD will
6287 * configure for trigger frame It may be better to let QoS do
6288 * this????
6289 */
6290 if (conn_profile->modifyProfileFields.uapsd_mask) {
6291 sms_log(mac_ctx, LOGE,
6292 " uapsd_mask (0x%X) set, request UAPSD now",
6293 conn_profile->modifyProfileFields.uapsd_mask);
6294 sme_ps_start_uapsd(mac_ctx, session_id,
6295 NULL, NULL);
6296 }
6297 conn_profile->dot11Mode = session->bssParams.uCfgDot11Mode;
6298 roam_info.u.pConnectedProfile = conn_profile;
6299
6300 if (session->bRefAssocStartCnt > 0) {
6301 session->bRefAssocStartCnt--;
6302 if (!IS_FEATURE_SUPPORTED_BY_FW
6303 (SLM_SESSIONIZATION) &&
6304 (csr_is_concurrent_session_running(mac_ctx))) {
6305 mac_ctx->roam.configParam.doBMPSWorkaround = 1;
6306 }
6307#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6308 if (roam_offload_params->bRoamSynchInProgress) {
6309 roam_info.roamSynchInProgress = 1;
6310 roam_info.synchAuthStatus =
6311 roam_offload_params->authStatus;
6312 cdf_mem_copy(roam_info.kck,
6313 roam_offload_params->kck,
6314 SIR_KCK_KEY_LEN);
6315 cdf_mem_copy(roam_info.kek,
6316 roam_offload_params->kek,
6317 SIR_KEK_KEY_LEN);
6318 cdf_mem_copy(roam_info.replay_ctr,
6319 roam_offload_params->replay_ctr,
6320 SIR_REPLAY_CTR_LEN);
6321 CDF_TRACE(CDF_MODULE_ID_SME,
6322 CDF_TRACE_LEVEL_DEBUG,
6323 FL
6324 ("LFR3: Copy KCK, KEK and Replay Ctr"));
6325 }
6326#endif
6327 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
6328 cmd->u.roamCmd.roamId,
6329 eCSR_ROAM_ASSOCIATION_COMPLETION,
6330 eCSR_ROAM_RESULT_ASSOCIATED);
6331#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6332 if (roam_offload_params->bRoamSynchInProgress
6333 && (roam_offload_params->authStatus
6334 == CSR_ROAM_AUTH_STATUS_CONNECTED)) {
6335 CDF_TRACE(CDF_MODULE_ID_SME,
6336 CDF_TRACE_LEVEL_DEBUG,
6337 FL("LFR3:Send Synch Cnf for Auth status connected"));
6338 csr_roam_offload_send_synch_cnf(mac_ctx,
6339 session_id);
6340 }
6341#endif
6342 }
6343
6344 csr_roam_completion(mac_ctx, session_id, NULL, cmd,
6345 eCSR_ROAM_RESULT_NONE, true);
6346 csr_reset_pmkid_candidate_list(mac_ctx, session_id);
6347#ifdef FEATURE_WLAN_WAPI
6348 csr_reset_bkid_candidate_list(mac_ctx, session_id);
6349#endif
6350 } else {
6351 sms_log(mac_ctx, LOGW,
6352 "Roam command doesn't have a BSS desc");
6353 }
6354 /* Not to signal link up because keys are yet to be set.
6355 * The linkup function will overwrite the sub-state that
6356 * we need to keep at this point.
6357 */
6358 if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
6359#ifdef WLAN_FEATURE_ROAM_OFFLOAD
6360 if (roam_offload_params->bRoamSynchInProgress) {
6361 CDF_TRACE(CDF_MODULE_ID_SME,
6362 CDF_TRACE_LEVEL_DEBUG,
6363 FL
6364 ("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
6365 }
6366#endif
6367 csr_roam_link_up(mac_ctx, conn_profile->bssid);
6368 }
6369}
6370
6371/**
6372 * csr_roam_process_results() - Process the Roam Results
6373 * @mac_ctx: Global MAC Context
6374 * @cmd: Command that has been processed
6375 * @res: Results available after processing the command
6376 * @context: Context
6377 *
6378 * Process the available results and make an appropriate decision
6379 *
6380 * Return: true if the command can be released, else not.
6381 */
6382static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
6383 eCsrRoamCompleteResult res, void *context)
6384{
6385 bool release_cmd = true;
6386 tSirBssDescription *bss_desc = NULL;
6387 tCsrRoamInfo roam_info;
6388 uint32_t session_id = cmd->sessionId;
6389 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
6390 tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
6391 eRoamCmdStatus roam_status;
6392 eCsrRoamResult roam_result;
6393 host_log_ibss_pkt_type *ibss_log;
6394
6395 if (!session) {
6396 sms_log(mac_ctx, LOGE, FL("session %d not found "), session_id);
6397 return false;
6398 }
6399 sms_log(mac_ctx, LOG1, FL("Processing ROAM results..."));
6400 switch (res) {
6401 case eCsrJoinSuccess:
6402 case eCsrReassocSuccess:
6403 csr_roam_process_join_res(mac_ctx, res, cmd, context);
6404 break;
6405 case eCsrStartBssSuccess:
6406 csr_roam_process_start_bss_success(mac_ctx, cmd, context);
6407 break;
6408 case eCsrStartBssFailure:
6409#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
6410 WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
6411 host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
6412 if (ibss_log) {
6413 ibss_log->status = WLAN_IBSS_STATUS_FAILURE;
6414 WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
6415 }
6416#endif
6417 roam_status = eCSR_ROAM_IBSS_IND;
6418 roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
6419 if (CSR_IS_WDS(profile)) {
6420 roam_status = eCSR_ROAM_WDS_IND;
6421 roam_result = eCSR_ROAM_RESULT_WDS_STARTED;
6422 }
6423 if (CSR_IS_INFRA_AP(profile)) {
6424 roam_status = eCSR_ROAM_INFRA_IND;
6425 roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED;
6426 }
6427 if (context) {
6428 bss_desc = (tSirBssDescription *) context;
6429 } else {
6430 bss_desc = NULL;
6431 }
6432 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
6433 roam_info.pBssDesc = bss_desc;
6434 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
6435 cmd->u.roamCmd.roamId, roam_status,
6436 roam_result);
6437 csr_set_default_dot11_mode(mac_ctx);
6438 break;
6439 case eCsrSilentlyStopRoaming:
6440 /*
6441 * We are here because we try to start the same IBSS.
6442 * No message to PE. return the roaming state to Joined.
6443 */
6444 sms_log(mac_ctx, LOGW, FL("receives silently stop roam ind"));
6445 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
6446 session_id);
6447 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
6448 session_id);
6449 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
6450 roam_info.pBssDesc = session->pConnectBssDesc;
6451 if (roam_info.pBssDesc)
6452 cdf_mem_copy(&roam_info.bssid,
6453 &roam_info.pBssDesc->bssId,
6454 sizeof(struct cdf_mac_addr));
6455 /*
6456 * Since there is no change in the current state, simply pass
6457 * back no result otherwise HDD may be mistakenly mark to
6458 * disconnected state.
6459 */
6460 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
6461 cmd->u.roamCmd.roamId,
6462 eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_NONE);
6463 break;
6464 case eCsrSilentlyStopRoamingSaveState:
6465 /* We are here because we try to connect to the same AP */
6466 /* No message to PE */
6467 sms_log(mac_ctx, LOGW,
6468 FL("receives silently stop roaming indication"));
6469 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
6470
6471 /* to aviod resetting the substate to NONE */
6472 mac_ctx->roam.curState[session_id] = eCSR_ROAMING_STATE_JOINED;
6473 /*
6474 * No need to change substate to wai_for_key because there
6475 * is no state change
6476 */
6477 roam_info.pBssDesc = session->pConnectBssDesc;
6478 if (roam_info.pBssDesc)
6479 cdf_mem_copy(&roam_info.bssid,
6480 &roam_info.pBssDesc->bssId,
6481 sizeof(struct cdf_mac_addr));
6482 roam_info.statusCode = session->joinFailStatusCode.statusCode;
6483 roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
6484 roam_info.nBeaconLength = session->connectedInfo.nBeaconLength;
6485 roam_info.nAssocReqLength =
6486 session->connectedInfo.nAssocReqLength;
6487 roam_info.nAssocRspLength =
6488 session->connectedInfo.nAssocRspLength;
6489 roam_info.pbFrames = session->connectedInfo.pbFrames;
6490 roam_info.staId = session->connectedInfo.staId;
6491 roam_info.u.pConnectedProfile = &session->connectedProfile;
6492 if (0 == roam_info.staId) {
6493 CDF_ASSERT(0);
6494 return false;
6495 }
6496 session->bRefAssocStartCnt--;
6497 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
6498 cmd->u.roamCmd.roamId,
6499 eCSR_ROAM_ASSOCIATION_COMPLETION,
6500 eCSR_ROAM_RESULT_ASSOCIATED);
6501 csr_roam_completion(mac_ctx, session_id, NULL, cmd,
6502 eCSR_ROAM_RESULT_ASSOCIATED, true);
6503 break;
6504 case eCsrReassocFailure:
6505#ifndef WLAN_MDM_CODE_REDUCTION_OPT
6506 sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
6507 SME_QOS_CSR_REASSOC_FAILURE, NULL);
6508#endif
6509 case eCsrJoinWdsFailure:
6510 sms_log(mac_ctx, LOGW, FL("failed to join WDS"));
6511 csr_free_connect_bss_desc(mac_ctx, session_id);
6512 csr_roam_free_connect_profile(mac_ctx,
6513 &session->connectedProfile);
6514 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
6515 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
6516 roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
6517 roam_info.statusCode = session->joinFailStatusCode.statusCode;
6518 roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
6519 csr_roam_call_callback(mac_ctx, session_id, &roam_info,
6520 cmd->u.roamCmd.roamId, eCSR_ROAM_WDS_IND,
6521 eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED);
6522 /* Need to issue stop_bss */
6523 break;
6524 case eCsrJoinFailure:
6525 case eCsrNothingToJoin:
6526 case eCsrJoinFailureDueToConcurrency:
6527 default:
6528 csr_roam_process_results_default(mac_ctx, cmd, context, res);
6529 break;
6530 }
6531 return release_cmd;
6532}
6533
6534CDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
6535 tCsrRoamProfile *pDstProfile,
6536 tCsrRoamProfile *pSrcProfile)
6537{
6538 CDF_STATUS status = CDF_STATUS_SUCCESS;
6539 uint32_t size = 0;
6540
6541 cdf_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0);
6542 if (pSrcProfile->BSSIDs.numOfBSSIDs) {
6543 size = sizeof(struct cdf_mac_addr) * pSrcProfile->BSSIDs.numOfBSSIDs;
6544 pDstProfile->BSSIDs.bssid = cdf_mem_malloc(size);
6545 if (NULL == pDstProfile->BSSIDs.bssid) {
6546 status = CDF_STATUS_E_NOMEM;
6547 goto end;
6548 }
6549 pDstProfile->BSSIDs.numOfBSSIDs =
6550 pSrcProfile->BSSIDs.numOfBSSIDs;
6551 cdf_mem_copy(pDstProfile->BSSIDs.bssid,
6552 pSrcProfile->BSSIDs.bssid, size);
6553 }
6554 if (pSrcProfile->SSIDs.numOfSSIDs) {
6555 size = sizeof(tCsrSSIDInfo) * pSrcProfile->SSIDs.numOfSSIDs;
6556 pDstProfile->SSIDs.SSIDList = cdf_mem_malloc(size);
6557 if (NULL == pDstProfile->SSIDs.SSIDList) {
6558 status = CDF_STATUS_E_NOMEM;
6559 goto end;
6560 }
6561 pDstProfile->SSIDs.numOfSSIDs =
6562 pSrcProfile->SSIDs.numOfSSIDs;
6563 cdf_mem_copy(pDstProfile->SSIDs.SSIDList,
6564 pSrcProfile->SSIDs.SSIDList, size);
6565 }
6566 if (pSrcProfile->nWPAReqIELength) {
6567 pDstProfile->pWPAReqIE =
6568 cdf_mem_malloc(pSrcProfile->nWPAReqIELength);
6569 if (NULL == pDstProfile->pWPAReqIE) {
6570 status = CDF_STATUS_E_NOMEM;
6571 goto end;
6572 }
6573 pDstProfile->nWPAReqIELength =
6574 pSrcProfile->nWPAReqIELength;
6575 cdf_mem_copy(pDstProfile->pWPAReqIE, pSrcProfile->pWPAReqIE,
6576 pSrcProfile->nWPAReqIELength);
6577 }
6578 if (pSrcProfile->nRSNReqIELength) {
6579 pDstProfile->pRSNReqIE =
6580 cdf_mem_malloc(pSrcProfile->nRSNReqIELength);
6581 if (NULL == pDstProfile->pRSNReqIE) {
6582 status = CDF_STATUS_E_NOMEM;
6583 goto end;
6584 }
6585 pDstProfile->nRSNReqIELength =
6586 pSrcProfile->nRSNReqIELength;
6587 cdf_mem_copy(pDstProfile->pRSNReqIE, pSrcProfile->pRSNReqIE,
6588 pSrcProfile->nRSNReqIELength);
6589 }
6590#ifdef FEATURE_WLAN_WAPI
6591 if (pSrcProfile->nWAPIReqIELength) {
6592 pDstProfile->pWAPIReqIE =
6593 cdf_mem_malloc(pSrcProfile->nWAPIReqIELength);
6594 if (NULL == pDstProfile->pWAPIReqIE) {
6595 status = CDF_STATUS_E_NOMEM;
6596 goto end;
6597 }
6598 pDstProfile->nWAPIReqIELength =
6599 pSrcProfile->nWAPIReqIELength;
6600 cdf_mem_copy(pDstProfile->pWAPIReqIE, pSrcProfile->pWAPIReqIE,
6601 pSrcProfile->nWAPIReqIELength);
6602 }
6603#endif /* FEATURE_WLAN_WAPI */
6604 if (pSrcProfile->nAddIEScanLength) {
6605 pDstProfile->pAddIEScan =
6606 cdf_mem_malloc(pSrcProfile->nAddIEScanLength);
6607 if (NULL == pDstProfile->pAddIEScan) {
6608 status = CDF_STATUS_E_NOMEM;
6609 goto end;
6610 }
6611 pDstProfile->nAddIEScanLength =
6612 pSrcProfile->nAddIEScanLength;
6613 cdf_mem_copy(pDstProfile->pAddIEScan, pSrcProfile->pAddIEScan,
6614 pSrcProfile->nAddIEScanLength);
6615 }
6616 if (pSrcProfile->nAddIEAssocLength) {
6617 pDstProfile->pAddIEAssoc =
6618 cdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
6619 if (NULL == pDstProfile->pAddIEAssoc) {
6620 status = CDF_STATUS_E_NOMEM;
6621 goto end;
6622 }
6623 pDstProfile->nAddIEAssocLength =
6624 pSrcProfile->nAddIEAssocLength;
6625 cdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
6626 pSrcProfile->nAddIEAssocLength);
6627 }
6628 if (pSrcProfile->ChannelInfo.ChannelList) {
6629 pDstProfile->ChannelInfo.ChannelList =
6630 cdf_mem_malloc(pSrcProfile->ChannelInfo.
6631 numOfChannels);
6632 if (NULL == pDstProfile->ChannelInfo.ChannelList) {
6633 status = CDF_STATUS_E_NOMEM;
6634 goto end;
6635 }
6636 pDstProfile->ChannelInfo.numOfChannels =
6637 pSrcProfile->ChannelInfo.numOfChannels;
6638 cdf_mem_copy(pDstProfile->ChannelInfo.ChannelList,
6639 pSrcProfile->ChannelInfo.ChannelList,
6640 pSrcProfile->ChannelInfo.numOfChannels);
6641 }
6642 pDstProfile->AuthType = pSrcProfile->AuthType;
6643 pDstProfile->EncryptionType = pSrcProfile->EncryptionType;
6644 pDstProfile->mcEncryptionType = pSrcProfile->mcEncryptionType;
6645 pDstProfile->negotiatedUCEncryptionType =
6646 pSrcProfile->negotiatedUCEncryptionType;
6647 pDstProfile->negotiatedMCEncryptionType =
6648 pSrcProfile->negotiatedMCEncryptionType;
6649 pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType;
6650#ifdef WLAN_FEATURE_11W
6651 pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
6652 pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
6653 pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
6654#endif
6655 pDstProfile->BSSType = pSrcProfile->BSSType;
6656 pDstProfile->phyMode = pSrcProfile->phyMode;
6657 pDstProfile->csrPersona = pSrcProfile->csrPersona;
6658
6659#ifdef FEATURE_WLAN_WAPI
6660 if (csr_is_profile_wapi(pSrcProfile))
6661 if (pDstProfile->phyMode & eCSR_DOT11_MODE_11n)
6662 pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n;
6663#endif /* FEATURE_WLAN_WAPI */
6664 pDstProfile->CBMode = pSrcProfile->CBMode;
6665 pDstProfile->ch_params.ch_width = pSrcProfile->ch_params.ch_width;
6666 pDstProfile->ch_params.center_freq_seg0 =
6667 pSrcProfile->ch_params.center_freq_seg0;
6668 pDstProfile->ch_params.center_freq_seg1 =
6669 pSrcProfile->ch_params.center_freq_seg1;
6670 pDstProfile->ch_params.sec_ch_offset =
6671 pSrcProfile->ch_params.sec_ch_offset;
6672 /*Save the WPS info */
6673 pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation;
6674 pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation;
6675 pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask;
6676 pDstProfile->beaconInterval = pSrcProfile->beaconInterval;
6677 pDstProfile->privacy = pSrcProfile->privacy;
6678 pDstProfile->fwdWPSPBCProbeReq = pSrcProfile->fwdWPSPBCProbeReq;
6679 pDstProfile->csr80211AuthType = pSrcProfile->csr80211AuthType;
6680 pDstProfile->dtimPeriod = pSrcProfile->dtimPeriod;
6681 pDstProfile->ApUapsdEnable = pSrcProfile->ApUapsdEnable;
6682 pDstProfile->SSIDs.SSIDList[0].ssidHidden =
6683 pSrcProfile->SSIDs.SSIDList[0].ssidHidden;
6684 pDstProfile->protEnabled = pSrcProfile->protEnabled;
6685 pDstProfile->obssProtEnabled = pSrcProfile->obssProtEnabled;
6686 pDstProfile->cfg_protection = pSrcProfile->cfg_protection;
6687 pDstProfile->wps_state = pSrcProfile->wps_state;
6688 pDstProfile->ieee80211d = pSrcProfile->ieee80211d;
6689 pDstProfile->sap_dot11mc = pSrcProfile->sap_dot11mc;
6690 cdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
6691 sizeof(pDstProfile->Keys));
6692#ifdef WLAN_FEATURE_11W
6693 pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
6694 pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
6695 pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
6696#endif
6697#ifdef WLAN_FEATURE_VOWIFI_11R
6698 if (pSrcProfile->MDID.mdiePresent) {
6699 pDstProfile->MDID.mdiePresent = 1;
6700 pDstProfile->MDID.mobilityDomain =
6701 pSrcProfile->MDID.mobilityDomain;
6702 }
6703#endif
6704 cdf_mem_copy(&pDstProfile->addIeParams, &pSrcProfile->addIeParams,
6705 sizeof(tSirAddIeParams));
6706end:
6707 if (!CDF_IS_STATUS_SUCCESS(status)) {
6708 csr_release_profile(pMac, pDstProfile);
6709 pDstProfile = NULL;
6710 }
6711
6712 return status;
6713}
6714
6715CDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac,
6716 uint32_t sessionId, tCsrRoamProfile *pDstProfile)
6717{
6718 CDF_STATUS status = CDF_STATUS_SUCCESS;
6719 tCsrRoamConnectedProfile *pSrcProfile =
6720 &pMac->roam.roamSession[sessionId].connectedProfile;
6721
6722 cdf_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0);
6723
6724 pDstProfile->BSSIDs.bssid = cdf_mem_malloc(sizeof(struct cdf_mac_addr));
6725 if (NULL == pDstProfile->BSSIDs.bssid) {
6726 status = CDF_STATUS_E_NOMEM;
6727 sms_log(pMac, LOGE,
6728 FL("failed to allocate memory for BSSID "
6729 MAC_ADDRESS_STR),
6730 MAC_ADDR_ARRAY(pSrcProfile->bssid.bytes));
6731 goto end;
6732 }
6733 pDstProfile->BSSIDs.numOfBSSIDs = 1;
6734 cdf_copy_macaddr(pDstProfile->BSSIDs.bssid, &pSrcProfile->bssid);
6735
6736 if (pSrcProfile->SSID.ssId) {
6737 pDstProfile->SSIDs.SSIDList =
6738 cdf_mem_malloc(sizeof(tCsrSSIDInfo));
6739 if (NULL == pDstProfile->SSIDs.SSIDList) {
6740 status = CDF_STATUS_E_NOMEM;
6741 sms_log(pMac, LOGE,
6742 FL("failed to allocate memory for SSID "
6743 MAC_ADDRESS_STR),
6744 MAC_ADDR_ARRAY(pSrcProfile->bssid.bytes));
6745 goto end;
6746 }
6747 pDstProfile->SSIDs.numOfSSIDs = 1;
6748 pDstProfile->SSIDs.SSIDList[0].handoffPermitted =
6749 pSrcProfile->handoffPermitted;
6750 pDstProfile->SSIDs.SSIDList[0].ssidHidden =
6751 pSrcProfile->ssidHidden;
6752 cdf_mem_copy(&pDstProfile->SSIDs.SSIDList[0].SSID,
6753 &pSrcProfile->SSID, sizeof(tSirMacSSid));
6754 }
6755 if (pSrcProfile->nAddIEAssocLength) {
6756 pDstProfile->pAddIEAssoc =
6757 cdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
6758 if (NULL == pDstProfile->pAddIEAssoc) {
6759 status = CDF_STATUS_E_NOMEM;
6760 sms_log(pMac, LOGE,
6761 FL("failed to allocate mem for additional ie"));
6762 goto end;
6763 }
6764 pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength;
6765 cdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
6766 pSrcProfile->nAddIEAssocLength);
6767 }
6768 pDstProfile->ChannelInfo.ChannelList = cdf_mem_malloc(1);
6769 if (NULL == pDstProfile->ChannelInfo.ChannelList) {
6770 status = CDF_STATUS_E_NOMEM;
6771 goto end;
6772 }
6773 pDstProfile->ChannelInfo.numOfChannels = 1;
6774 pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel;
6775 pDstProfile->AuthType.numEntries = 1;
6776 pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType;
6777 pDstProfile->negotiatedAuthType = pSrcProfile->AuthType;
6778 pDstProfile->EncryptionType.numEntries = 1;
6779 pDstProfile->EncryptionType.encryptionType[0] =
6780 pSrcProfile->EncryptionType;
6781 pDstProfile->negotiatedUCEncryptionType =
6782 pSrcProfile->EncryptionType;
6783 pDstProfile->mcEncryptionType.numEntries = 1;
6784 pDstProfile->mcEncryptionType.encryptionType[0] =
6785 pSrcProfile->mcEncryptionType;
6786 pDstProfile->negotiatedMCEncryptionType =
6787 pSrcProfile->mcEncryptionType;
6788 pDstProfile->BSSType = pSrcProfile->BSSType;
6789 pDstProfile->CBMode = pSrcProfile->CBMode;
6790 cdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
6791 sizeof(pDstProfile->Keys));
6792#ifdef WLAN_FEATURE_VOWIFI_11R
6793 if (pSrcProfile->MDID.mdiePresent) {
6794 pDstProfile->MDID.mdiePresent = 1;
6795 pDstProfile->MDID.mobilityDomain =
6796 pSrcProfile->MDID.mobilityDomain;
6797 }
6798#endif
6799
6800end:
6801 if (!CDF_IS_STATUS_SUCCESS(status)) {
6802 csr_release_profile(pMac, pDstProfile);
6803 pDstProfile = NULL;
6804 }
6805
6806 return status;
6807}
6808
6809CDF_STATUS csr_roam_issue_connect(tpAniSirGlobal pMac, uint32_t sessionId,
6810 tCsrRoamProfile *pProfile,
6811 tScanResultHandle hBSSList,
6812 eCsrRoamReason reason, uint32_t roamId,
6813 bool fImediate, bool fClearScan)
6814{
6815 CDF_STATUS status = CDF_STATUS_SUCCESS;
6816 tSmeCmd *pCommand;
6817
6818 pCommand = csr_get_command_buffer(pMac);
6819 if (NULL == pCommand) {
6820 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
6821 status = CDF_STATUS_E_RESOURCES;
6822 } else {
6823 if (fClearScan) {
6824 csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
6825 }
6826 pCommand->u.roamCmd.fReleaseProfile = false;
6827 if (NULL == pProfile) {
6828 /* We can roam now */
6829 /* Since pProfile is NULL, we need to build our own profile, set everything to default */
6830 /* We can only support open and no encryption */
6831 pCommand->u.roamCmd.roamProfile.AuthType.numEntries = 1;
6832 pCommand->u.roamCmd.roamProfile.AuthType.authType[0] =
6833 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6834 pCommand->u.roamCmd.roamProfile.EncryptionType.
6835 numEntries = 1;
6836 pCommand->u.roamCmd.roamProfile.EncryptionType.
6837 encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
6838 pCommand->u.roamCmd.roamProfile.csrPersona =
6839 CDF_STA_MODE;
6840 } else {
6841 /* make a copy of the profile */
6842 status =
6843 csr_roam_copy_profile(pMac,
6844 &pCommand->u.roamCmd.roamProfile,
6845 pProfile);
6846 if (CDF_IS_STATUS_SUCCESS(status)) {
6847 pCommand->u.roamCmd.fReleaseProfile = true;
6848 }
6849 }
6850
6851 pCommand->command = eSmeCommandRoam;
6852 pCommand->sessionId = (uint8_t) sessionId;
6853 pCommand->u.roamCmd.hBSSList = hBSSList;
6854 pCommand->u.roamCmd.roamId = roamId;
6855 pCommand->u.roamCmd.roamReason = reason;
6856 /* We need to free the BssList when the command is done */
6857 pCommand->u.roamCmd.fReleaseBssList = true;
6858 pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
6859 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
6860 FL("CSR PERSONA=%d"),
6861 pCommand->u.roamCmd.roamProfile.csrPersona);
6862 status = csr_queue_sme_command(pMac, pCommand, fImediate);
6863 if (!CDF_IS_STATUS_SUCCESS(status)) {
6864 sms_log(pMac, LOGE,
6865 FL(" fail to send message status = %d"), status);
6866 csr_release_command_roam(pMac, pCommand);
6867 }
6868 }
6869
6870 return status;
6871}
6872
6873CDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
6874 tCsrRoamProfile *pProfile,
6875 tCsrRoamModifyProfileFields *pMmodProfileFields,
6876 eCsrRoamReason reason, uint32_t roamId,
6877 bool fImediate)
6878{
6879 CDF_STATUS status = CDF_STATUS_SUCCESS;
6880 tSmeCmd *pCommand;
6881
6882 pCommand = csr_get_command_buffer(pMac);
6883 if (NULL == pCommand) {
6884 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
6885 status = CDF_STATUS_E_RESOURCES;
6886 } else {
6887 csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
6888 if (pProfile) {
6889 /* This is likely trying to reassoc to different profile */
6890 pCommand->u.roamCmd.fReleaseProfile = false;
6891 /* make a copy of the profile */
6892 status =
6893 csr_roam_copy_profile(pMac,
6894 &pCommand->u.roamCmd.roamProfile,
6895 pProfile);
6896 pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
6897 } else {
6898 status =
6899 csr_roam_copy_connected_profile(pMac, sessionId,
6900 &pCommand->u.roamCmd.
6901 roamProfile);
6902 /* how to update WPA/WPA2 info in roamProfile?? */
6903 pCommand->u.roamCmd.roamProfile.uapsd_mask =
6904 pMmodProfileFields->uapsd_mask;
6905 }
6906 if (CDF_IS_STATUS_SUCCESS(status)) {
6907 pCommand->u.roamCmd.fReleaseProfile = true;
6908 }
6909 pCommand->command = eSmeCommandRoam;
6910 pCommand->sessionId = (uint8_t) sessionId;
6911 pCommand->u.roamCmd.roamId = roamId;
6912 pCommand->u.roamCmd.roamReason = reason;
6913 /* We need to free the BssList when the command is done */
6914 /* For reassoc there is no BSS list, so the bool set to false */
6915 pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
6916 pCommand->u.roamCmd.fReleaseBssList = false;
6917 pCommand->u.roamCmd.fReassoc = true;
6918 csr_roam_remove_duplicate_command(pMac, sessionId, pCommand,
6919 reason);
6920 status = csr_queue_sme_command(pMac, pCommand, fImediate);
6921 if (!CDF_IS_STATUS_SUCCESS(status)) {
6922 sms_log(pMac, LOGE,
6923 FL(" fail to send message status = %d"), status);
6924 csr_roam_completion(pMac, sessionId, NULL, pCommand,
6925 eCSR_ROAM_RESULT_FAILURE, false);
6926 csr_release_command_roam(pMac, pCommand);
6927 }
6928 }
6929 return status;
6930}
6931
6932CDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal pMac, uint32_t sessionId,
6933 tpSirBssDescription pBssDescription,
6934 eCsrRoamReason reason, bool fImmediate)
6935{
6936 CDF_STATUS status = CDF_STATUS_SUCCESS;
6937 tSmeCmd *pCommand;
6938
6939 pCommand = csr_get_command_buffer(pMac);
6940 if (NULL == pCommand) {
6941 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
6942 status = CDF_STATUS_E_RESOURCES;
6943 } else {
6944 if (pBssDescription) {
6945 /* copy over the parameters we need later */
6946 pCommand->command = eSmeCommandRoam;
6947 pCommand->sessionId = (uint8_t) sessionId;
6948 pCommand->u.roamCmd.roamReason = reason;
6949 /* this is the important parameter */
6950 /* in this case we are using this field for the "next" BSS */
6951 pCommand->u.roamCmd.pLastRoamBss = pBssDescription;
6952 status = csr_queue_sme_command(pMac, pCommand, fImmediate);
6953 if (!CDF_IS_STATUS_SUCCESS(status)) {
6954 sms_log(pMac, LOGE,
6955 FL
6956 (" fail to enqueue preauth command, status = %d"),
6957 status);
6958 csr_release_command_preauth(pMac, pCommand);
6959 }
6960 } else {
6961 /* Return failure */
6962 status = CDF_STATUS_E_RESOURCES;
6963 }
6964 }
6965 return status;
6966}
6967
6968CDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac, eCsrRoamReason reason)
6969{
6970 tListElem *pEntry;
6971 tSmeCmd *pCommand;
6972 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
6973 if (pEntry) {
6974 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6975 if ((eSmeCommandRoam == pCommand->command) &&
6976 (eCsrPerformPreauth == reason)) {
6977 sms_log(pMac, LOG1, FL("DQ-Command = %d, Reason = %d"),
6978 pCommand->command,
6979 pCommand->u.roamCmd.roamReason);
6980 if (csr_ll_remove_entry
6981 (&pMac->sme.smeCmdActiveList, pEntry,
6982 LL_ACCESS_LOCK)) {
6983 csr_release_command_preauth(pMac, pCommand);
6984 }
6985 } else if ((eSmeCommandRoam == pCommand->command) &&
6986 (eCsrSmeIssuedFTReassoc == reason)) {
6987 sms_log(pMac, LOG1, FL("DQ-Command = %d, Reason = %d"),
6988 pCommand->command,
6989 pCommand->u.roamCmd.roamReason);
6990 if (csr_ll_remove_entry
6991 (&pMac->sme.smeCmdActiveList, pEntry,
6992 LL_ACCESS_LOCK)) {
6993 csr_release_command_roam(pMac, pCommand);
6994 }
6995 } else {
6996 sms_log(pMac, LOGE, FL("Command = %d, Reason = %d "),
6997 pCommand->command,
6998 pCommand->u.roamCmd.roamReason);
6999 }
7000 } else {
7001 sms_log(pMac, LOGE,
7002 FL("pEntry NULL for eWNI_SME_FT_PRE_AUTH_RSP"));
7003 }
7004 sme_process_pending_queue(pMac);
7005 return CDF_STATUS_SUCCESS;
7006}
7007
7008CDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
7009 tCsrRoamProfile *pProfile,
7010 uint32_t *pRoamId)
7011{
7012 CDF_STATUS status = CDF_STATUS_SUCCESS;
7013 tScanResultHandle hBSSList;
7014 tCsrScanResultFilter *pScanFilter;
7015 uint32_t roamId = 0;
7016 bool fCallCallback = false;
7017 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7018 tSirBssDescription first_ap_profile;
7019
7020 if (NULL == pSession) {
7021 sms_log(pMac, LOGE,
7022 FL("session does not exist for given sessionId:%d"),
7023 sessionId);
7024 return CDF_STATUS_E_FAILURE;
7025 }
7026
7027 if (NULL == pProfile) {
7028 sms_log(pMac, LOGP, FL("No profile specified"));
7029 return CDF_STATUS_E_FAILURE;
7030 }
7031 /* Initialize the count before proceeding with the Join requests */
7032 pSession->join_bssid_count = 0;
7033 sms_log(pMac, LOG1,
7034 FL("called BSSType = %d authtype = %d encryType = %d"),
7035 pProfile->BSSType, pProfile->AuthType.authType[0],
7036 pProfile->EncryptionType.encryptionType[0]);
7037 csr_roam_cancel_roaming(pMac, sessionId);
7038 csr_scan_remove_fresh_scan_command(pMac, sessionId);
7039 /* Only abort the scan if its not used for other roam/connect purpose */
7040 csr_scan_abort_mac_scan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT);
7041 csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
7042 /* Check whether ssid changes */
7043 if (csr_is_conn_state_connected(pMac, sessionId) &&
7044 pProfile->SSIDs.numOfSSIDs && !csr_is_ssid_in_list(pMac,
7045 &pSession->connectedProfile.SSID, &pProfile->SSIDs))
7046 csr_roam_issue_disassociate_cmd(pMac, sessionId,
7047 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7048#ifdef FEATURE_WLAN_BTAMP_UT_RF
7049 pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT;
7050#endif
7051 pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
7052 if (NULL == pScanFilter) {
7053 status = CDF_STATUS_E_NOMEM;
7054 goto end;
7055 }
7056
7057 cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter),
7058 0);
7059 /* Try to connect to any BSS */
7060 if (NULL == pProfile) {
7061 /* No encryption */
7062 pScanFilter->EncryptionType.numEntries = 1;
7063 pScanFilter->EncryptionType.encryptionType[0] =
7064 eCSR_ENCRYPT_TYPE_NONE;
7065 } else {
7066 /* Here is the profile we need to connect to */
7067 status = csr_roam_prepare_filter_from_profile(pMac,
7068 pProfile, pScanFilter);
7069 }
7070 roamId = GET_NEXT_ROAM_ID(&pMac->roam);
7071 if (pRoamId)
7072 *pRoamId = roamId;
7073 if (!CDF_IS_STATUS_SUCCESS(status)) {
7074 cdf_mem_free(pScanFilter);
7075 goto end;
7076 }
7077
7078 /*Save the WPS info */
7079 if (NULL != pProfile) {
7080 pScanFilter->bWPSAssociation =
7081 pProfile->bWPSAssociation;
7082 pScanFilter->bOSENAssociation =
7083 pProfile->bOSENAssociation;
7084 } else {
7085 pScanFilter->bWPSAssociation = 0;
7086 pScanFilter->bOSENAssociation = 0;
7087 }
7088 if ((pProfile && CSR_IS_WDS_AP(pProfile)) || (pProfile
7089 && CSR_IS_INFRA_AP(pProfile))) {
7090 /* This can be started right away */
7091 status = csr_roam_issue_connect(pMac, sessionId, pProfile, NULL,
7092 eCsrHddIssued, roamId, false, false);
7093 if (!CDF_IS_STATUS_SUCCESS(status)) {
7094 sms_log(pMac, LOGE,
7095 FL("CSR failed to issue start BSS cmd with status = 0x%08X"),
7096 status);
7097 fCallCallback = true;
7098 } else {
7099 sms_log(pMac, LOG1,
7100 FL("Connect request to proceed for sap mode"));
7101 }
7102
7103 csr_free_scan_filter(pMac, pScanFilter);
7104 cdf_mem_free(pScanFilter);
7105 goto end;
7106 }
7107 status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
7108 sms_log(pMac, LOG1,
7109 FL("******* csr_scan_get_result Status ****** %d"), status);
7110 if (CDF_IS_STATUS_SUCCESS(status)) {
7111 /* check if set hw mode needs to be done */
7112 if ((pMac->policy_manager_enabled) &&
7113 (pScanFilter->csrPersona == CDF_STA_MODE)) {
7114 csr_get_bssdescr_from_scan_handle(hBSSList,
7115 &first_ap_profile);
7116 if (!cds_handle_conc_multiport(sessionId,
7117 first_ap_profile.channelId)) {
7118 sms_log(pMac, LOG1, FL("conc multiport error"));
7119 csr_scan_result_purge(pMac, hBSSList);
7120 fCallCallback = true;
7121 goto error;
7122 }
7123 }
7124
7125 status = csr_roam_issue_connect(pMac, sessionId, pProfile,
7126 hBSSList, eCsrHddIssued, roamId, false, false);
7127 if (!CDF_IS_STATUS_SUCCESS(status)) {
7128 sms_log(pMac, LOGE,
7129 FL("CSR failed to issue connect cmd with status = 0x%08X"),
7130 status);
7131 csr_scan_result_purge(pMac, hBSSList);
7132 fCallCallback = true;
7133 }
7134 } else if (NULL != pProfile) {
7135 /* Check whether it is for start ibss */
7136 if (CSR_IS_START_IBSS(pProfile)) {
7137 status = csr_roam_issue_connect(pMac, sessionId,
7138 pProfile, NULL, eCsrHddIssued,
7139 roamId, false, false);
7140 if (!CDF_IS_STATUS_SUCCESS(status)) {
7141 sms_log(pMac, LOGE,
7142 FL("CSR failed to issue startIBSS cmd with status = 0x%08X"),
7143 status);
7144 fCallCallback = true;
7145 }
7146 } else {
7147 /* scan for this SSID */
7148 status = csr_scan_for_ssid(pMac, sessionId, pProfile,
7149 roamId, true);
7150 if (!CDF_IS_STATUS_SUCCESS(status)) {
7151 sms_log(pMac, LOGE,
7152 FL("CSR failed to issue SSID scan cmd with status = 0x%08X"),
7153 status);
7154 fCallCallback = true;
7155 } else {
7156 sms_log(pMac, LOG1,
7157 FL("SSID scan requested"));
7158 }
7159 }
7160 } else {
7161 fCallCallback = true;
7162 }
7163
7164error:
7165 if (NULL != pProfile)
7166 /*
7167 * we need to free memory for filter
7168 * if profile exists
7169 */
7170 csr_free_scan_filter(pMac, pScanFilter);
7171
7172 cdf_mem_free(pScanFilter);
7173end:
7174 /* tell the caller if we fail to trigger a join request */
7175 if (fCallCallback) {
7176 csr_roam_call_callback(pMac, sessionId, NULL, roamId,
7177 eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
7178 }
7179 return status;
7180}
7181
7182/**
7183 * csr_roam_reassoc() - process reassoc command
7184 * @mac_ctx: mac global context
7185 * @session_id: session id
7186 * @profile: roam profile
7187 * @mod_fields: AC info being modified in reassoc
7188 * @roam_id: roam id to be populated
7189 *
7190 * Return: status of operation
7191 */
7192CDF_STATUS
7193csr_roam_reassoc(tpAniSirGlobal mac_ctx, uint32_t session_id,
7194 tCsrRoamProfile *profile,
7195 tCsrRoamModifyProfileFields mod_fields,
7196 uint32_t *roam_id)
7197{
7198 CDF_STATUS status = CDF_STATUS_SUCCESS;
7199 bool fCallCallback = true;
7200 uint32_t roamId = 0;
7201
7202 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
7203 if (NULL == profile) {
7204 sms_log(mac_ctx, LOGP, FL("No profile specified"));
7205 return CDF_STATUS_E_FAILURE;
7206 }
7207 sms_log(mac_ctx, LOG1,
7208 FL("called BSSType = %d authtype = %d encryType = %d"),
7209 profile->BSSType, profile->AuthType.authType[0],
7210 profile->EncryptionType.encryptionType[0]);
7211 csr_roam_cancel_roaming(mac_ctx, session_id);
7212 csr_scan_remove_fresh_scan_command(mac_ctx, session_id);
7213 csr_scan_abort_mac_scan_not_for_connect(mac_ctx, session_id);
7214 csr_roam_remove_duplicate_command(mac_ctx, session_id, NULL,
7215 eCsrHddIssuedReassocToSameAP);
7216 if (csr_is_conn_state_connected(mac_ctx, session_id)) {
7217 if (profile) {
7218 if (profile->SSIDs.numOfSSIDs &&
7219 csr_is_ssid_in_list(mac_ctx,
7220 &session->connectedProfile.SSID,
7221 &profile->SSIDs)) {
7222 fCallCallback = false;
7223 } else {
7224 /*
7225 * Connected SSID did not match with what is
7226 * asked in profile
7227 */
7228 sms_log(mac_ctx, LOG1, FL("SSID mismatch"));
7229 }
7230 } else if (!cdf_mem_compare(&mod_fields,
7231 &session->connectedProfile.modifyProfileFields,
7232 sizeof(tCsrRoamModifyProfileFields))) {
7233 fCallCallback = false;
7234 } else {
7235 sms_log(mac_ctx, LOG1,
7236 /*
7237 * Either the profile is NULL or none of the
7238 * fields in tCsrRoamModifyProfileFields got
7239 * modified
7240 */
7241 FL("Profile NULL or nothing to modify."));
7242 }
7243 } else {
7244 sms_log(mac_ctx, LOG1, FL("Not connected! No need to reassoc"));
7245 }
7246 if (!fCallCallback) {
7247 roamId = GET_NEXT_ROAM_ID(&mac_ctx->roam);
7248 if (roam_id)
7249 *roam_id = roamId;
7250 status = csr_roam_issue_reassoc(mac_ctx, session_id, profile,
7251 &mod_fields, eCsrHddIssuedReassocToSameAP,
7252 roamId, false);
7253 } else {
7254 status = csr_roam_call_callback(mac_ctx, session_id, NULL,
7255 roamId, eCSR_ROAM_FAILED,
7256 eCSR_ROAM_RESULT_FAILURE);
7257 }
7258 return status;
7259}
7260
7261CDF_STATUS csr_roam_join_last_profile(tpAniSirGlobal pMac, uint32_t sessionId)
7262{
7263 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7264 tScanResultHandle hBSSList = NULL;
7265 tCsrScanResultFilter *pScanFilter = NULL;
7266 uint32_t roamId;
7267 tCsrRoamProfile *pProfile = NULL;
7268 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7269
7270 if (!pSession) {
7271 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
7272 return CDF_STATUS_E_FAILURE;
7273 }
7274
7275 if (pSession->pCurRoamProfile) {
7276 csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
7277 /* We have to make a copy of pCurRoamProfile because it
7278 * will be free inside csr_roam_issue_connect */
7279 pProfile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
7280 if (NULL == pProfile) {
7281 status = CDF_STATUS_E_NOMEM;
7282 goto end;
7283 }
7284 cdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
7285 status = csr_roam_copy_profile(pMac, pProfile,
7286 pSession->pCurRoamProfile);
7287 if (!CDF_IS_STATUS_SUCCESS(status))
7288 goto end;
7289 pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
7290 if (NULL == pScanFilter) {
7291 status = CDF_STATUS_E_NOMEM;
7292 goto end;
7293 }
7294 cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
7295 status = csr_roam_prepare_filter_from_profile(pMac, pProfile,
7296 pScanFilter);
7297 if (!CDF_IS_STATUS_SUCCESS(status))
7298 goto end;
7299 roamId = GET_NEXT_ROAM_ID(&pMac->roam);
7300 status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
7301 if (CDF_IS_STATUS_SUCCESS(status)) {
7302 /* we want to put the last connected BSS to the
7303 * very beginning, if possible */
7304 csr_move_bss_to_head_from_bssid(pMac,
7305 &pSession->connectedProfile.bssid, hBSSList);
7306 status = csr_roam_issue_connect(pMac, sessionId,
7307 pProfile, hBSSList, eCsrHddIssued,
7308 roamId, false, false);
7309 if (!CDF_IS_STATUS_SUCCESS(status)) {
7310 csr_scan_result_purge(pMac, hBSSList);
7311 goto end;
7312 }
7313 } else {
7314 /* scan for this SSID only incase AP suppresses SSID */
7315 status = csr_scan_for_ssid(pMac, sessionId, pProfile,
7316 roamId, true);
7317 if (!CDF_IS_STATUS_SUCCESS(status))
7318 goto end;
7319 }
7320 } /* We have a profile */
7321 else {
7322 sms_log(pMac, LOGW, FL("cannot find a roaming profile"));
7323 goto end;
7324 }
7325end:
7326 if (pScanFilter) {
7327 csr_free_scan_filter(pMac, pScanFilter);
7328 cdf_mem_free(pScanFilter);
7329 }
7330 if (NULL != pProfile) {
7331 csr_release_profile(pMac, pProfile);
7332 cdf_mem_free(pProfile);
7333 }
7334 return status;
7335}
7336
7337CDF_STATUS csr_roam_reconnect(tpAniSirGlobal pMac, uint32_t sessionId)
7338{
7339 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7340 if (csr_is_conn_state_connected(pMac, sessionId)) {
7341 status =
7342 csr_roam_issue_disassociate_cmd(pMac, sessionId,
7343 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7344 if (CDF_IS_STATUS_SUCCESS(status)) {
7345 status = csr_roam_join_last_profile(pMac, sessionId);
7346 }
7347 }
7348 return status;
7349}
7350
7351CDF_STATUS csr_roam_connect_to_last_profile(tpAniSirGlobal pMac, uint32_t sessionId)
7352{
7353 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7354 sms_log(pMac, LOGW, FL("is called"));
7355 csr_roam_cancel_roaming(pMac, sessionId);
7356 csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
7357 if (csr_is_conn_state_disconnected(pMac, sessionId)) {
7358 status = csr_roam_join_last_profile(pMac, sessionId);
7359 }
7360 return status;
7361}
7362
7363CDF_STATUS csr_roam_process_disassoc_deauth(tpAniSirGlobal pMac, tSmeCmd *pCommand,
7364 bool fDisassoc, bool fMICFailure)
7365{
7366 CDF_STATUS status = CDF_STATUS_SUCCESS;
7367 bool fComplete = false;
7368 eCsrRoamSubState NewSubstate;
7369 uint32_t sessionId = pCommand->sessionId;
7370
7371 if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
7372 sms_log(pMac, LOG1,
7373 FL(" Stop Wait for key timer and change substate to"
7374 " eCSR_ROAM_SUBSTATE_NONE"));
7375 csr_roam_stop_wait_for_key_timer(pMac);
7376 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId);
7377 }
7378 /* change state to 'Roaming'... */
7379 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
7380
7381 if (csr_is_conn_state_ibss(pMac, sessionId)) {
7382 /* If we are in an IBSS, then stop the IBSS... */
7383 status =
7384 csr_roam_issue_stop_bss(pMac, sessionId,
7385 eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
7386 fComplete = (!CDF_IS_STATUS_SUCCESS(status));
7387 } else if (csr_is_conn_state_infra(pMac, sessionId)) {
7388 /*
7389 * in Infrastructure, we need to disassociate from the
7390 * Infrastructure network...
7391 */
7392 NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
7393 if (eCsrSmeIssuedDisassocForHandoff ==
7394 pCommand->u.roamCmd.roamReason) {
7395 NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF;
7396 } else
7397 if ((eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason)
7398 && (eSIR_MAC_DISASSOC_LEAVING_BSS_REASON ==
7399 pCommand->u.roamCmd.reason)) {
7400 NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT;
7401 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7402 FL
7403 ("set to substate eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT"));
7404 }
7405 if (fDisassoc) {
7406 status =
7407 csr_roam_issue_disassociate(pMac, sessionId,
7408 NewSubstate, fMICFailure);
7409 } else {
7410 status =
7411 csr_roam_issue_deauth(pMac, sessionId,
7412 eCSR_ROAM_SUBSTATE_DEAUTH_REQ);
7413 }
7414 fComplete = (!CDF_IS_STATUS_SUCCESS(status));
7415 } else if (csr_is_conn_state_wds(pMac, sessionId)) {
7416 if (CSR_IS_WDS_AP
7417 (&pMac->roam.roamSession[sessionId].connectedProfile)) {
7418 status =
7419 csr_roam_issue_stop_bss(pMac, sessionId,
7420 eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
7421 fComplete = (!CDF_IS_STATUS_SUCCESS(status));
7422 }
7423 /* This has to be WDS station */
7424 else if (csr_is_conn_state_connected_wds(pMac, sessionId)) {
7425 /* This has to be WDS station */
7426 pCommand->u.roamCmd.fStopWds = true;
7427 if (fDisassoc) {
7428 status =
7429 csr_roam_issue_disassociate(pMac, sessionId,
7430 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
7431 fMICFailure);
7432 fComplete = (!CDF_IS_STATUS_SUCCESS(status));
7433 }
7434 }
7435 } else {
7436 /* we got a dis-assoc request while not connected to any peer */
7437 /* just complete the command */
7438 fComplete = true;
7439 status = CDF_STATUS_E_FAILURE;
7440 }
7441 if (fComplete) {
7442 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
7443 }
7444
7445 if (CDF_IS_STATUS_SUCCESS(status)) {
7446 if (csr_is_conn_state_infra(pMac, sessionId)) {
7447 /* Set the state to disconnect here */
7448 pMac->roam.roamSession[sessionId].connectState =
7449 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
7450 }
7451 } else {
7452 sms_log(pMac, LOGW, FL(" failed with status %d"), status);
7453 }
7454 return status;
7455}
7456
7457/**
7458 * csr_prepare_disconnect_command() - function to prepare disconnect command
7459 * @mac: pointer to global mac structure
7460 * @session_id: sme session index
7461 * @sme_cmd: pointer to sme command being prepared
7462 *
7463 * Function to prepare internal sme disconnect command
7464 * Return: CDF_STATUS_SUCCESS on success else CDF_STATUS_E_RESOURCES on failure
7465 */
7466
7467CDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
7468 uint32_t session_id, tSmeCmd **sme_cmd)
7469{
7470 tSmeCmd *command;
7471
7472 command = csr_get_command_buffer(mac);
7473 if (!command) {
7474 sms_log(mac, LOGE, FL("fail to get command buffer"));
7475 return CDF_STATUS_E_RESOURCES;
7476 }
7477
7478 command->command = eSmeCommandRoam;
7479 command->sessionId = (uint8_t)session_id;
7480 command->u.roamCmd.roamReason = eCsrForcedDisassoc;
7481
7482 *sme_cmd = command;
7483 return CDF_STATUS_SUCCESS;
7484}
7485
7486CDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
7487 eCsrRoamDisconnectReason reason)
7488{
7489 CDF_STATUS status = CDF_STATUS_SUCCESS;
7490 tSmeCmd *pCommand;
7491 bool fHighPriority = false;
7492 do {
7493 pCommand = csr_get_command_buffer(pMac);
7494 if (!pCommand) {
7495 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
7496 status = CDF_STATUS_E_RESOURCES;
7497 break;
7498 }
7499 /* Change the substate in case it is wait-for-key */
7500 if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
7501 csr_roam_stop_wait_for_key_timer(pMac);
7502 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
7503 sessionId);
7504 }
7505 pCommand->command = eSmeCommandRoam;
7506 pCommand->sessionId = (uint8_t) sessionId;
7507 sms_log(pMac, LOG1,
7508 FL("Disassociate reason: %d, sessionId: %d"),
7509 reason, sessionId);
7510 switch (reason) {
7511 case eCSR_DISCONNECT_REASON_MIC_ERROR:
7512 pCommand->u.roamCmd.roamReason =
7513 eCsrForcedDisassocMICFailure;
7514 break;
7515 case eCSR_DISCONNECT_REASON_DEAUTH:
7516 pCommand->u.roamCmd.roamReason = eCsrForcedDeauth;
7517 break;
7518 case eCSR_DISCONNECT_REASON_HANDOFF:
7519 fHighPriority = true;
7520 pCommand->u.roamCmd.roamReason =
7521 eCsrSmeIssuedDisassocForHandoff;
7522 break;
7523 case eCSR_DISCONNECT_REASON_UNSPECIFIED:
7524 case eCSR_DISCONNECT_REASON_DISASSOC:
7525 pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
7526 break;
7527 case eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE:
7528 pCommand->u.roamCmd.roamReason =
7529 eCsrSmeIssuedIbssJoinFailure;
7530 break;
7531 case eCSR_DISCONNECT_REASON_IBSS_LEAVE:
7532 pCommand->u.roamCmd.roamReason = eCsrForcedIbssLeave;
7533 break;
7534 case eCSR_DISCONNECT_REASON_STA_HAS_LEFT:
7535 pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
7536 pCommand->u.roamCmd.reason =
7537 eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
7538 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7539 FL
7540 ("SME convert to internal reason code eCsrStaHasLeft"));
7541 break;
7542 default:
7543 break;
7544 }
7545 status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
7546 if (!CDF_IS_STATUS_SUCCESS(status)) {
7547 sms_log(pMac, LOGE,
7548 FL(" fail to send message status = %d"), status);
7549 csr_release_command_roam(pMac, pCommand);
7550 }
7551 } while (0);
7552 return status;
7553}
7554
7555CDF_STATUS csr_roam_issue_stop_bss_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
7556 bool fHighPriority)
7557{
7558 CDF_STATUS status = CDF_STATUS_SUCCESS;
7559 tSmeCmd *pCommand;
7560 pCommand = csr_get_command_buffer(pMac);
7561 if (NULL != pCommand) {
7562 /* Change the substate in case it is wait-for-key */
7563 if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
7564 csr_roam_stop_wait_for_key_timer(pMac);
7565 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
7566 sessionId);
7567 }
7568 pCommand->command = eSmeCommandRoam;
7569 pCommand->sessionId = (uint8_t) sessionId;
7570 pCommand->u.roamCmd.roamReason = eCsrStopBss;
7571 status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
7572 if (!CDF_IS_STATUS_SUCCESS(status)) {
7573 sms_log(pMac, LOGE,
7574 FL(" fail to send message status = %d"), status);
7575 csr_release_command_roam(pMac, pCommand);
7576 }
7577 } else {
7578 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
7579 status = CDF_STATUS_E_RESOURCES;
7580 }
7581 return status;
7582}
7583
7584CDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
7585 eCsrRoamDisconnectReason reason)
7586{
7587 CDF_STATUS status = CDF_STATUS_SUCCESS;
7588 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7589
7590 if (!pSession) {
7591 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
7592 return CDF_STATUS_E_FAILURE;
7593 }
7594#ifdef FEATURE_WLAN_BTAMP_UT_RF
7595 /* Stop the retry */
7596 pSession->maxRetryCount = 0;
7597 csr_roam_stop_join_retry_timer(pMac, sessionId);
7598#endif
7599 /* Not to call cancel roaming here */
7600 /* Only issue disconnect when necessary */
7601 if (csr_is_conn_state_connected(pMac, sessionId)
7602 || csr_is_bss_type_ibss(pSession->connectedProfile.BSSType)
7603 || csr_is_bss_type_wds(pSession->connectedProfile.BSSType)
7604 || csr_is_roam_command_waiting_for_session(pMac, sessionId)) {
7605 sms_log(pMac, LOG2, FL("called"));
7606 status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
7607 reason);
7608 } else {
7609 csr_scan_abort_scan_for_ssid(pMac, sessionId);
7610 status = CDF_STATUS_CMD_NOT_QUEUED;
7611 sms_log(pMac, LOG1,
7612 FL
7613 (" Disconnect cmd not queued, Roam command is not present"
7614 " return with status %d"), status);
7615 }
7616 return status;
7617}
7618
7619CDF_STATUS csr_roam_disconnect(tpAniSirGlobal pMac, uint32_t sessionId,
7620 eCsrRoamDisconnectReason reason)
7621{
7622 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7623
7624 if (!pSession) {
7625 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
7626 return CDF_STATUS_E_FAILURE;
7627 }
7628
7629 csr_roam_cancel_roaming(pMac, sessionId);
7630 csr_roam_remove_duplicate_command(pMac, sessionId, NULL,
7631 eCsrForcedDisassoc);
7632
7633 return csr_roam_disconnect_internal(pMac, sessionId, reason);
7634}
7635
7636CDF_STATUS csr_roam_save_connected_infomation(tpAniSirGlobal pMac,
7637 uint32_t sessionId,
7638 tCsrRoamProfile *pProfile,
7639 tSirBssDescription *pSirBssDesc,
7640 tDot11fBeaconIEs *pIes)
7641{
7642 CDF_STATUS status = CDF_STATUS_SUCCESS;
7643 tDot11fBeaconIEs *pIesTemp = pIes;
7644 uint8_t index;
7645 tCsrRoamSession *pSession = NULL;
7646 tCsrRoamConnectedProfile *pConnectProfile = NULL;
7647
7648 pSession = CSR_GET_SESSION(pMac, sessionId);
7649 if (NULL == pSession) {
7650 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7651 FL("session %d not found"), sessionId);
7652 return CDF_STATUS_E_FAILURE;
7653 }
7654 pConnectProfile = &pSession->connectedProfile;
7655#ifdef WLAN_FEATURE_ROAM_OFFLOAD
7656 if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
7657 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
7658 FL("csr_roam_save_connected_infomation"));
7659 }
7660#endif
7661 if (pConnectProfile->pAddIEAssoc) {
7662 cdf_mem_free(pConnectProfile->pAddIEAssoc);
7663 pConnectProfile->pAddIEAssoc = NULL;
7664 }
7665 cdf_mem_set(&pSession->connectedProfile,
7666 sizeof(tCsrRoamConnectedProfile), 0);
7667 pConnectProfile->AuthType = pProfile->negotiatedAuthType;
7668 pConnectProfile->AuthInfo = pProfile->AuthType;
7669 pConnectProfile->CBMode = pProfile->CBMode; /* *** this may not be valid */
7670 pConnectProfile->EncryptionType = pProfile->negotiatedUCEncryptionType;
7671 pConnectProfile->EncryptionInfo = pProfile->EncryptionType;
7672 pConnectProfile->mcEncryptionType =
7673 pProfile->negotiatedMCEncryptionType;
7674 pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType;
7675 pConnectProfile->BSSType = pProfile->BSSType;
7676 pConnectProfile->modifyProfileFields.uapsd_mask = pProfile->uapsd_mask;
7677 pConnectProfile->operationChannel = pSirBssDesc->channelId;
7678 pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
7679 if (!pConnectProfile->beaconInterval) {
7680 sms_log(pMac, LOGW, FL("ERROR: Beacon interval is ZERO"));
7681 }
7682 cdf_mem_copy(&pConnectProfile->Keys, &pProfile->Keys, sizeof(tCsrKeys));
7683 /* saving the addional IE`s like Hot spot indication element and extended capabilities */
7684 if (pProfile->nAddIEAssocLength) {
7685 pConnectProfile->pAddIEAssoc =
7686 cdf_mem_malloc(pProfile->nAddIEAssocLength);
7687 if (NULL == pConnectProfile->pAddIEAssoc)
7688 status = CDF_STATUS_E_NOMEM;
7689 else
7690 status = CDF_STATUS_SUCCESS;
7691 if (!CDF_IS_STATUS_SUCCESS(status)) {
7692 sms_log(pMac, LOGE,
7693 FL
7694 ("Failed to allocate memory for additional IEs"));
7695 return CDF_STATUS_E_FAILURE;
7696 }
7697 pConnectProfile->nAddIEAssocLength =
7698 pProfile->nAddIEAssocLength;
7699 cdf_mem_copy(pConnectProfile->pAddIEAssoc,
7700 pProfile->pAddIEAssoc,
7701 pProfile->nAddIEAssocLength);
7702 }
7703#ifdef WLAN_FEATURE_11W
7704 pConnectProfile->MFPEnabled = pProfile->MFPEnabled;
7705 pConnectProfile->MFPRequired = pProfile->MFPRequired;
7706 pConnectProfile->MFPCapable = pProfile->MFPCapable;
7707#endif
7708 /* Save bssid */
7709 csr_get_bss_id_bss_desc(pMac, pSirBssDesc, &pConnectProfile->bssid);
7710#ifdef WLAN_FEATURE_VOWIFI_11R
7711 if (pSirBssDesc->mdiePresent) {
7712 pConnectProfile->MDID.mdiePresent = 1;
7713 pConnectProfile->MDID.mobilityDomain =
7714 (pSirBssDesc->mdie[1] << 8) | (pSirBssDesc->mdie[0]);
7715 }
7716#endif
7717 if (NULL == pIesTemp) {
7718 status =
7719 csr_get_parsed_bss_description_ies(pMac, pSirBssDesc,
7720 &pIesTemp);
7721 }
7722#ifdef FEATURE_WLAN_ESE
7723 if ((csr_is_profile_ese(pProfile) ||
7724 (CDF_IS_STATUS_SUCCESS(status) && (pIesTemp->ESEVersion.present)
7725 && (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)))
7726 && (pMac->roam.configParam.isEseIniFeatureEnabled)) {
7727 pConnectProfile->isESEAssoc = 1;
7728 }
7729#endif
7730 /* save ssid */
7731 if (CDF_IS_STATUS_SUCCESS(status)) {
7732 if (pIesTemp->SSID.present) {
7733 pConnectProfile->SSID.length = pIesTemp->SSID.num_ssid;
7734 cdf_mem_copy(pConnectProfile->SSID.ssId,
7735 pIesTemp->SSID.ssid,
7736 pIesTemp->SSID.num_ssid);
7737 }
7738 /* Save the bss desc */
7739 status =
7740 csr_roam_save_connected_bss_desc(pMac, sessionId, pSirBssDesc);
7741
7742 if (CSR_IS_QOS_BSS(pIesTemp) || pIesTemp->HTCaps.present) {
7743 /* Some HT AP's dont send WMM IE so in that case we assume all HT Ap's are Qos Enabled AP's */
7744 pConnectProfile->qap = true;
7745 } else {
7746 pConnectProfile->qap = false;
7747 }
7748
7749 if (pIesTemp->ExtCap.present) {
7750 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
7751 pIesTemp->ExtCap.bytes;
7752 pConnectProfile->proxyARPService = p_ext_cap->
7753 proxy_arp_service;
7754 }
7755
7756 if (NULL == pIes) {
7757 /* Free memory if it allocated locally */
7758 cdf_mem_free(pIesTemp);
7759 }
7760 }
7761 /* Save Qos connection */
7762 pConnectProfile->qosConnection =
7763 pMac->roam.roamSession[sessionId].fWMMConnection;
7764
7765 if (!CDF_IS_STATUS_SUCCESS(status)) {
7766 csr_free_connect_bss_desc(pMac, sessionId);
7767 }
7768 for (index = 0; index < pProfile->SSIDs.numOfSSIDs; index++) {
7769 if ((pProfile->SSIDs.SSIDList[index].SSID.length ==
7770 pConnectProfile->SSID.length)
7771 && cdf_mem_compare(pProfile->SSIDs.SSIDList[index].SSID.
7772 ssId, pConnectProfile->SSID.ssId,
7773 pConnectProfile->SSID.length)) {
7774 pConnectProfile->handoffPermitted =
7775 pProfile->SSIDs.SSIDList[index].handoffPermitted;
7776 break;
7777 }
7778 pConnectProfile->handoffPermitted = false;
7779 }
7780
7781 return status;
7782}
7783
7784
7785static bool is_disconnect_pending(tpAniSirGlobal pmac,
7786 uint8_t sessionid)
7787{
7788 tListElem *entry = NULL;
7789 tListElem *next_entry = NULL;
7790 tSmeCmd *command = NULL;
7791 bool disconnect_cmd_exist = false;
7792
7793 csr_ll_lock(&pmac->sme.smeCmdPendingList);
7794 entry = csr_ll_peek_head(&pmac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
7795 while (entry) {
7796 next_entry = csr_ll_next(&pmac->sme.smeCmdPendingList,
7797 entry, LL_ACCESS_NOLOCK);
7798
7799 command = GET_BASE_ADDR(entry, tSmeCmd, Link);
7800 if (command && CSR_IS_DISCONNECT_COMMAND(command) &&
7801 command->sessionId == sessionid){
7802 disconnect_cmd_exist = true;
7803 break;
7804 }
7805 entry = next_entry;
7806 }
7807 csr_ll_unlock(&pmac->sme.smeCmdPendingList);
7808 return disconnect_cmd_exist;
7809}
7810
7811static void csr_roam_join_rsp_processor(tpAniSirGlobal pMac,
7812 tSirSmeJoinRsp *pSmeJoinRsp)
7813{
7814 tListElem *pEntry = NULL;
7815 tSmeCmd *pCommand = NULL;
7816 tCsrRoamSession *session_ptr;
7817
7818 if (pSmeJoinRsp) {
7819 session_ptr = CSR_GET_SESSION(pMac, pSmeJoinRsp->sessionId);
7820 } else {
7821 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7822 FL("Sme Join Response is NULL"));
7823 return;
7824 }
7825 if (!session_ptr) {
7826 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7827 FL("session %d not found"), pSmeJoinRsp->sessionId);
7828 return;
7829 }
7830 /* The head of the active list is the request we sent */
7831 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
7832 if (pEntry) {
7833 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
7834 }
7835 if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
7836 if (pCommand
7837 && eCsrSmeIssuedAssocToSimilarAP ==
7838 pCommand->u.roamCmd.roamReason) {
7839#ifndef WLAN_MDM_CODE_REDUCTION_OPT
7840 sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
7841 SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
7842#endif
7843 }
7844 /* *
7845 * The join bssid count can be reset as soon as
7846 * we are done with the join requests and returning
7847 * the response to upper layers
7848 * */
7849 session_ptr->join_bssid_count = 0;
7850 csr_roam_complete(pMac, eCsrJoinSuccess, (void *)pSmeJoinRsp);
7851 } else {
7852 uint32_t roamId = 0;
7853 bool is_dis_pending;
7854
7855 /* The head of the active list is the request we sent */
7856 /* Try to get back the same profile and roam again */
7857 if (pCommand) {
7858 roamId = pCommand->u.roamCmd.roamId;
7859 }
7860 session_ptr->joinFailStatusCode.statusCode =
7861 pSmeJoinRsp->statusCode;
7862 session_ptr->joinFailStatusCode.reasonCode =
7863 pSmeJoinRsp->protStatusCode;
7864 sms_log(pMac, LOGW,
7865 "SmeJoinReq failed with statusCode= 0x%08X [%d]",
7866 pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
7867#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
7868 /* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */
7869 if (csr_roam_is_handoff_in_progress(pMac, pSmeJoinRsp->sessionId)) {
7870 csr_roam_call_callback(pMac, pSmeJoinRsp->sessionId, NULL,
7871 roamId, eCSR_ROAM_DISASSOCIATED,
7872 eCSR_ROAM_RESULT_FORCED);
7873 /* Should indicate neighbor roam algorithm about the connect failure here */
7874 csr_neighbor_roam_indicate_connect(pMac,
7875 pSmeJoinRsp->sessionId,
7876 CDF_STATUS_E_FAILURE);
7877 }
7878#endif
7879 /*
7880 * if userspace has issued disconnection,
7881 * driver should not continue connecting
7882 */
7883 is_dis_pending = is_disconnect_pending(pMac, session_ptr->sessionId);
7884 if (pCommand && (session_ptr->join_bssid_count <
7885 CSR_MAX_BSSID_COUNT) && !is_dis_pending) {
7886 if (CSR_IS_WDS_STA(&pCommand->u.roamCmd.roamProfile)) {
7887 pCommand->u.roamCmd.fStopWds = true;
7888 session_ptr->connectedProfile.BSSType =
7889 eCSR_BSS_TYPE_WDS_STA;
7890 csr_roam_reissue_roam_command(pMac);
7891 } else if (CSR_IS_WDS(&pCommand->u.roamCmd.roamProfile)) {
7892 session_ptr->join_bssid_count = 0;
7893 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
7894 } else {
7895 csr_roam(pMac, pCommand);
7896 }
7897 } else {
7898 /* ****************************************************
7899 * When the upper layers issue a connect command, there
7900 * is a roam command with reason eCsrHddIssued that
7901 * gets enqueued and an associated timer for the SME
7902 * command timeout is started which is currently 120
7903 * seconds. This command would be dequeued only upon
7904 * succesfull connections. In case of join failures, if
7905 * there are too many BSS in the cache, and if we fail
7906 * Join requests with all of them, there is a chance of
7907 * timing out the above timer.
7908 * ***************************************************/
7909 if (session_ptr->join_bssid_count >=
7910 CSR_MAX_BSSID_COUNT)
7911 CDF_TRACE(CDF_MODULE_ID_SME,
7912 CDF_TRACE_LEVEL_ERROR,
7913 FL("Excessive Join Req Failures"));
7914
7915 if (is_dis_pending)
7916 CDF_TRACE(CDF_MODULE_ID_SME,
7917 CDF_TRACE_LEVEL_ERROR,
7918 FL("disconnect is pending, complete roam"));
7919
7920 session_ptr->join_bssid_count = 0;
7921 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
7922 }
7923 } /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */
7924}
7925
7926CDF_STATUS csr_roam_issue_join(tpAniSirGlobal pMac, uint32_t sessionId,
7927 tSirBssDescription *pSirBssDesc,
7928 tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile,
7929 uint32_t roamId)
7930{
7931 CDF_STATUS status;
7932 sms_log(pMac, LOG1, "Attempting to Join Bssid= " MAC_ADDRESS_STR,
7933 MAC_ADDR_ARRAY(pSirBssDesc->bssId));
7934
7935 /* Set the roaming substate to 'join attempt'... */
7936 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId);
7937 /* attempt to Join this BSS... */
7938 status =
7939 csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile, pIes,
7940 eWNI_SME_JOIN_REQ);
7941 return status;
7942}
7943
7944static CDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
7945 uint32_t sessionId,
7946 tSirBssDescription *pSirBssDesc,
7947 tDot11fBeaconIEs *pIes,
7948 tCsrRoamProfile *pProfile)
7949{
7950 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
7951 /* Set the roaming substate to 'join attempt'... */
7952 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId);
7953 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7954 FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"));
7955 /* attempt to Join this BSS... */
7956 return csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile, pIes,
7957 eWNI_SME_REASSOC_REQ);
7958}
7959
7960void csr_roam_reissue_roam_command(tpAniSirGlobal pMac)
7961{
7962 tListElem *pEntry;
7963 tSmeCmd *pCommand;
7964 tCsrRoamInfo roamInfo;
7965 uint32_t sessionId;
7966 tCsrRoamSession *pSession;
7967
7968 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
7969 if (NULL == pEntry) {
7970 sms_log(pMac, LOGE,
7971 FL("Disassoc rsp can't continue, no active CMD"));
7972 return;
7973 }
7974 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
7975 if (eSmeCommandRoam != pCommand->command) {
7976 sms_log(pMac, LOGW, FL("Active cmd, is not a roaming CMD"));
7977 return;
7978 }
7979 sessionId = pCommand->sessionId;
7980 pSession = CSR_GET_SESSION(pMac, sessionId);
7981
7982 if (!pSession) {
7983 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
7984 return;
7985 }
7986
7987 if (!pCommand->u.roamCmd.fStopWds) {
7988 if (pSession->bRefAssocStartCnt > 0) {
7989 /*
7990 * bRefAssocStartCnt was incremented in
7991 * csr_roam_join_next_bss when the roam command issued
7992 * previously. As part of reissuing the roam command
7993 * again csr_roam_join_next_bss is going increment
7994 * RefAssocStartCnt. So make sure to decrement the
7995 * bRefAssocStartCnt
7996 */
7997 pSession->bRefAssocStartCnt--;
7998 }
7999 if (eCsrStopRoaming == csr_roam_join_next_bss(pMac, pCommand,
8000 true)) {
8001 sms_log(pMac, LOGW,
8002 FL("Failed to reissue join command"));
8003 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8004 }
8005 return;
8006 }
8007 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
8008 roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss;
8009 roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
8010 roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
8011 if (CSR_IS_WDS(&pSession->connectedProfile)) {
8012 pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
8013 csr_roam_call_callback(pMac, sessionId, &roamInfo,
8014 pCommand->u.roamCmd.roamId,
8015 eCSR_ROAM_WDS_IND,
8016 eCSR_ROAM_RESULT_WDS_DISASSOCIATED);
8017 } else if (CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
8018 pSession->connectState =
8019 eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
8020 csr_roam_call_callback(pMac, sessionId, &roamInfo,
8021 pCommand->u.roamCmd.roamId,
8022 eCSR_ROAM_INFRA_IND,
8023 eCSR_ROAM_RESULT_INFRA_DISASSOCIATED);
8024 }
8025
8026 if (!CDF_IS_STATUS_SUCCESS(csr_roam_issue_stop_bss(pMac, sessionId,
8027 eCSR_ROAM_SUBSTATE_STOP_BSS_REQ))) {
8028 sms_log(pMac, LOGE,
8029 FL("Failed to reissue stop_bss command for WDS"));
8030 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8031 }
8032}
8033
8034bool csr_is_roam_command_waiting_for_session(tpAniSirGlobal pMac, uint32_t sessionId)
8035{
8036 bool fRet = false;
8037 tListElem *pEntry;
8038 tSmeCmd *pCommand = NULL;
8039 /* alwasy lock active list before locking pending list */
8040 csr_ll_lock(&pMac->sme.smeCmdActiveList);
8041 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
8042 if (pEntry) {
8043 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
8044 if ((eSmeCommandRoam == pCommand->command)
8045 && (sessionId == pCommand->sessionId)) {
8046 fRet = true;
8047 }
8048 }
8049 if (false == fRet) {
8050 csr_ll_lock(&pMac->sme.smeCmdPendingList);
8051 pEntry =
8052 csr_ll_peek_head(&pMac->sme.smeCmdPendingList,
8053 LL_ACCESS_NOLOCK);
8054 while (pEntry) {
8055 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
8056 if ((eSmeCommandRoam == pCommand->command)
8057 && (sessionId == pCommand->sessionId)) {
8058 fRet = true;
8059 break;
8060 }
8061 pEntry =
8062 csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
8063 LL_ACCESS_NOLOCK);
8064 }
8065 csr_ll_unlock(&pMac->sme.smeCmdPendingList);
8066 }
8067 if (false == fRet) {
8068 csr_ll_lock(&pMac->roam.roamCmdPendingList);
8069 pEntry =
8070 csr_ll_peek_head(&pMac->roam.roamCmdPendingList,
8071 LL_ACCESS_NOLOCK);
8072 while (pEntry) {
8073 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
8074 if ((eSmeCommandRoam == pCommand->command)
8075 && (sessionId == pCommand->sessionId)) {
8076 fRet = true;
8077 break;
8078 }
8079 pEntry =
8080 csr_ll_next(&pMac->roam.roamCmdPendingList, pEntry,
8081 LL_ACCESS_NOLOCK);
8082 }
8083 csr_ll_unlock(&pMac->roam.roamCmdPendingList);
8084 }
8085 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
8086 return fRet;
8087}
8088
8089bool csr_is_roam_command_waiting(tpAniSirGlobal pMac)
8090{
8091 bool fRet = false;
8092 uint32_t i;
8093 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
8094 fRet = csr_is_roam_command_waiting_for_session(pMac, i);
8095 if (CSR_IS_SESSION_VALID(pMac, i)
8096 && (fRet)) {
8097 break;
8098 }
8099 }
8100 return fRet;
8101}
8102
8103bool csr_is_command_waiting(tpAniSirGlobal pMac)
8104{
8105 bool fRet = false;
8106 /* alwasy lock active list before locking pending list */
8107 csr_ll_lock(&pMac->sme.smeCmdActiveList);
8108 fRet = csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
8109 if (false == fRet) {
8110 fRet =
8111 csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
8112 LL_ACCESS_LOCK);
8113 }
8114 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
8115 return fRet;
8116}
8117
8118bool csr_is_scan_for_roam_command_active(tpAniSirGlobal pMac)
8119{
8120 bool fRet = false;
8121 tListElem *pEntry;
8122 tCsrCmd *pCommand;
8123 /* alwasy lock active list before locking pending list */
8124 csr_ll_lock(&pMac->sme.smeCmdActiveList);
8125 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
8126 if (pEntry) {
8127 pCommand = GET_BASE_ADDR(pEntry, tCsrCmd, Link);
8128 if ((eCsrRoamCommandScan == pCommand->command) &&
8129 ((eCsrScanForSsid == pCommand->u.scanCmd.reason) ||
8130 (eCsrScanP2PFindPeer == pCommand->u.scanCmd.reason))) {
8131 fRet = true;
8132 }
8133 }
8134 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
8135 return fRet;
8136}
8137
8138CDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId)
8139{
8140 CDF_STATUS status = CDF_STATUS_SUCCESS;
8141 tSmeCmd *pCommand = NULL;
8142 bool fHighPriority = true;
8143 bool fRemoveCmd = false;
8144 tListElem *pEntry;
8145 /* Delete the old assoc command. All is setup for reassoc to be serialized */
8146 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
8147 if (pEntry) {
8148 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
8149 if (!pCommand) {
8150 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
8151 return CDF_STATUS_E_RESOURCES;
8152 }
8153 if (eSmeCommandRoam == pCommand->command) {
8154 if (pCommand->u.roamCmd.roamReason ==
8155 eCsrSmeIssuedAssocToSimilarAP) {
8156 fRemoveCmd =
8157 csr_ll_remove_entry(&pMac->sme.
8158 smeCmdActiveList, pEntry,
8159 LL_ACCESS_LOCK);
8160 } else {
8161 sms_log(pMac, LOGE,
8162 FL
8163 (" Unexpected active roam command present "));
8164 }
8165 if (fRemoveCmd == false) {
8166 /* Implies we did not get the serialized assoc command we */
8167 /* were expecting */
8168 pCommand = NULL;
8169 }
8170 }
8171 }
8172 if (NULL == pCommand) {
8173 sms_log(pMac, LOGE,
8174 FL
8175 (" fail to get command buffer as expected based on previous connect roam command"));
8176 return CDF_STATUS_E_RESOURCES;
8177 }
8178 do {
8179 /* Change the substate in case it is wait-for-key */
8180 if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
8181 csr_roam_stop_wait_for_key_timer(pMac);
8182 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
8183 sessionId);
8184 }
8185 pCommand->command = eSmeCommandRoam;
8186 pCommand->sessionId = (uint8_t) sessionId;
8187 pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc;
8188 status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
8189 if (!CDF_IS_STATUS_SUCCESS(status)) {
8190 sms_log(pMac, LOGE,
8191 FL(" fail to send message status = %d"), status);
8192 csr_release_command_roam(pMac, pCommand);
8193 }
8194 } while (0);
8195
8196 return status;
8197}
8198
8199static void
8200csr_roaming_state_config_cnf_processor(tpAniSirGlobal mac_ctx,
8201 uint32_t result)
8202{
8203 tListElem *entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
8204 LL_ACCESS_LOCK);
8205 tCsrScanResult *scan_result = NULL;
8206 tSirBssDescription *bss_desc = NULL;
8207 tSmeCmd *cmd = NULL;
8208 uint32_t session_id;
8209 tCsrRoamSession *session;
8210 tDot11fBeaconIEs *local_ies = NULL;
8211 CDF_STATUS status = CDF_STATUS_E_FAILURE;
8212
8213 if (NULL == entry) {
8214 sms_log(mac_ctx, LOGE, FL("CFG_CNF with active list empty"));
8215 return;
8216 }
8217 cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
8218 session_id = cmd->sessionId;
8219 session = CSR_GET_SESSION(mac_ctx, session_id);
8220
8221 if (!session) {
8222 sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
8223 return;
8224 }
8225
8226 if (CSR_IS_ROAMING(session) && session->fCancelRoaming) {
8227 /* the roaming is cancelled. Simply complete the command */
8228 sms_log(mac_ctx, LOGW, FL("Roam command canceled"));
8229 csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL);
8230 return;
8231 }
8232
8233 /* If the roaming has stopped, not to continue the roaming command */
8234 if (!CSR_IS_ROAMING(session) && CSR_IS_ROAMING_COMMAND(cmd)) {
8235 /* No need to complete roaming here as it already completes */
8236 sms_log(mac_ctx, LOGW,
8237 FL("Roam cmd (reason %d) aborted(roaming completed)"),
8238 cmd->u.roamCmd.roamReason);
8239 csr_set_abort_roaming_command(mac_ctx, cmd);
8240 csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL);
8241 return;
8242 }
8243
8244 if (!IS_SIR_STATUS_SUCCESS(result)) {
8245 /*
8246 * In the event the configuration failed, for infra let the roam
8247 * processor attempt to join something else...
8248 */
8249 if (cmd->u.roamCmd.pRoamBssEntry
8250 && CSR_IS_INFRASTRUCTURE(&cmd->u.roamCmd.roamProfile)) {
8251 csr_roam(mac_ctx, cmd);
8252 } else {
8253 /* We need to complete the command */
8254 if (csr_is_bss_type_ibss
8255 (cmd->u.roamCmd.roamProfile.BSSType)) {
8256 csr_roam_complete(mac_ctx, eCsrStartBssFailure,
8257 NULL);
8258 } else {
8259 csr_roam_complete(mac_ctx, eCsrNothingToJoin,
8260 NULL);
8261 }
8262 }
8263 return;
8264 }
8265
8266 /* we have active entry */
8267 sms_log(mac_ctx, LOG2, "Cfg sequence complete");
8268 /*
8269 * Successfully set the configuration parameters for the new Bss.
8270 * Attempt to join the roaming Bss
8271 */
8272 if (cmd->u.roamCmd.pRoamBssEntry) {
8273 scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
8274 tCsrScanResult,
8275 Link);
8276 bss_desc = &scan_result->Result.BssDescriptor;
8277 }
8278 if (csr_is_bss_type_ibss(cmd->u.roamCmd.roamProfile.BSSType)
8279 || CSR_IS_WDS(&cmd->u.roamCmd.roamProfile)
8280 || CSR_IS_INFRA_AP(&cmd->u.roamCmd.roamProfile)) {
8281 if (!CDF_IS_STATUS_SUCCESS(csr_roam_issue_start_bss(mac_ctx,
8282 session_id, &session->bssParams,
8283 &cmd->u.roamCmd.roamProfile,
8284 bss_desc,
8285 cmd->u.roamCmd.roamId))) {
8286 sms_log(mac_ctx, LOGE, FL("CSR start BSS failed"));
8287 /* We need to complete the command */
8288 csr_roam_complete(mac_ctx, eCsrStartBssFailure, NULL);
8289 }
8290 return;
8291 }
8292
8293 if (!cmd->u.roamCmd.pRoamBssEntry) {
8294 sms_log(mac_ctx, LOGE, FL("pRoamBssEntry is NULL"));
8295 /* We need to complete the command */
8296 csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL);
8297 return;
8298 }
8299
8300 if (NULL == scan_result) {
8301 /* If we are roaming TO an Infrastructure BSS... */
8302 CDF_ASSERT(scan_result != NULL);
8303 return;
8304 }
8305
8306 if (!csr_is_infra_bss_desc(bss_desc)) {
8307 sms_log(mac_ctx, LOGW,
8308 FL("found BSSType mismatching the one in BSS descp"));
8309 return;
8310 }
8311
8312 local_ies = (tDot11fBeaconIEs *) scan_result->Result.pvIes;
8313 if (!local_ies) {
8314 status = csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
8315 &local_ies);
8316 if (!CDF_IS_STATUS_SUCCESS(status))
8317 return;
8318 }
8319
8320 if (csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
8321 if (csr_is_ssid_equal(mac_ctx, session->pConnectBssDesc,
8322 bss_desc, local_ies)) {
8323 cmd->u.roamCmd.fReassoc = true;
8324 csr_roam_issue_reassociate(mac_ctx, session_id,
8325 bss_desc, local_ies,
8326 &cmd->u.roamCmd.roamProfile);
8327 } else {
8328 /*
8329 * otherwise, we have to issue a new Join request to LIM
8330 * because we disassociated from the previously
8331 * associated AP.
8332 */
8333 status = csr_roam_issue_join(mac_ctx, session_id,
8334 bss_desc, local_ies,
8335 &cmd->u.roamCmd.roamProfile,
8336 cmd->u.roamCmd.roamId);
8337 if (!CDF_IS_STATUS_SUCCESS(status)) {
8338 /* try something else */
8339 csr_roam(mac_ctx, cmd);
8340 }
8341 }
8342 } else {
8343 status = CDF_STATUS_SUCCESS;
8344 /*
8345 * We need to come with other way to figure out that this is
8346 * because of HO in BMP The below API will be only available for
8347 * Android as it uses a different HO algorithm. Reassoc request
8348 * will be used only for ESE and 11r handoff whereas other
8349 * legacy roaming should use join request
8350 */
8351#ifdef WLAN_FEATURE_VOWIFI_11R
8352 if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
8353 && csr_roam_is11r_assoc(mac_ctx, session_id)) {
8354 status = csr_roam_issue_reassociate(mac_ctx,
8355 session_id, bss_desc,
8356 (tDot11fBeaconIEs *)
8357 (scan_result->Result.pvIes),
8358 &cmd->u.roamCmd.roamProfile);
8359 } else
8360#endif
8361#ifdef FEATURE_WLAN_ESE
8362 if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
8363 && csr_roam_is_ese_assoc(mac_ctx, session_id)) {
8364 /* Now serialize the reassoc command. */
8365 status = csr_roam_issue_reassociate_cmd(mac_ctx,
8366 session_id);
8367 } else
8368#endif
8369#ifdef FEATURE_WLAN_LFR
8370 if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
8371 && csr_roam_is_fast_roam_enabled(mac_ctx, session_id)) {
8372 /* Now serialize the reassoc command. */
8373 status = csr_roam_issue_reassociate_cmd(mac_ctx,
8374 session_id);
8375 } else
8376#endif
8377 {
8378 /*
8379 * else we are not connected and attempting to Join. Issue the
8380 * Join request.
8381 */
8382 status = csr_roam_issue_join(mac_ctx, session_id,
8383 bss_desc,
8384 (tDot11fBeaconIEs *)
8385 (scan_result->Result.pvIes),
8386 &cmd->u.roamCmd.roamProfile,
8387 cmd->u.roamCmd.roamId);
8388 }
8389 if (!CDF_IS_STATUS_SUCCESS(status)) {
8390 /* try something else */
8391 csr_roam(mac_ctx, cmd);
8392 }
8393 }
8394 if (!scan_result->Result.pvIes) {
8395 /* Locally allocated */
8396 cdf_mem_free(local_ies);
8397 }
8398}
8399
8400static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
8401 tpSirSmeJoinRsp pSmeJoinRsp)
8402{
8403 eCsrRoamCompleteResult result;
8404 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
8405 &pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId];
8406 tCsrRoamInfo roamInfo;
8407 uint32_t roamId = 0;
8408
8409 if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
8410 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8411 FL("CSR SmeReassocReq Successful"));
8412 result = eCsrReassocSuccess;
8413 /* Defeaturize this part later if needed */
8414#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
8415 /* Since the neighbor roam algorithm uses reassoc req for handoff instead of join,
8416 * we need the response contents while processing the result in csr_roam_process_results() */
8417 if (csr_roam_is_handoff_in_progress(pMac, pSmeJoinRsp->sessionId)) {
8418 /* Need to dig more on indicating events to SME QoS module */
8419 sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
8420 SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
8421 csr_roam_complete(pMac, result, pSmeJoinRsp);
8422 } else
8423#endif
8424 {
8425 csr_roam_complete(pMac, result, NULL);
8426 }
8427 }
8428 /* Should we handle this similar to handling the join failure? Is it ok
8429 * to call csr_roam_complete() with state as CsrJoinFailure */
8430 else {
8431 sms_log(pMac, LOGW,
8432 "CSR SmeReassocReq failed with statusCode= 0x%08X [%d]",
8433 pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
8434 result = eCsrReassocFailure;
8435#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
8436 defined(FEATURE_WLAN_LFR)
8437 if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE ==
8438 pSmeJoinRsp->statusCode)
8439 || (eSIR_SME_FT_REASSOC_FAILURE ==
8440 pSmeJoinRsp->statusCode)
8441 || (eSIR_SME_INVALID_PARAMETERS ==
8442 pSmeJoinRsp->statusCode)) {
8443 /* Inform HDD to turn off FT flag in HDD */
8444 if (pNeighborRoamInfo) {
8445 cdf_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
8446 csr_roam_call_callback(pMac,
8447 pSmeJoinRsp->sessionId,
8448 &roamInfo, roamId,
8449 eCSR_ROAM_FT_REASSOC_FAILED,
8450 eSIR_SME_SUCCESS);
8451 /*
8452 * Since the above callback sends a disconnect
8453 * to HDD, we should clean-up our state
8454 * machine as well to be in sync with the upper
8455 * layers. There is no need to send a disassoc
8456 * since: 1) we will never reassoc to the current
8457 * AP in LFR, and 2) there is no need to issue a
8458 * disassoc to the AP with which we were trying
8459 * to reassoc.
8460 */
8461 csr_roam_complete(pMac, eCsrJoinFailure, NULL);
8462 return;
8463 }
8464 }
8465#endif
8466 /* In the event that the Reassociation fails, then we need to Disassociate the current association and keep */
8467 /* roaming. Note that we will attempt to Join the AP instead of a Reassoc since we may have attempted a */
8468 /* 'Reassoc to self', which AP's that don't support Reassoc will force a Disassoc. */
8469 /* The disassoc rsp message will remove the command from active list */
8470 if (!CDF_IS_STATUS_SUCCESS
8471 (csr_roam_issue_disassociate
8472 (pMac, pSmeJoinRsp->sessionId,
8473 eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false))) {
8474 csr_roam_complete(pMac, eCsrJoinFailure, NULL);
8475 }
8476 }
8477}
8478
8479static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
8480 tSirSmeRsp *pSmeRsp)
8481{
8482#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
8483 {
8484 host_log_ibss_pkt_type *pIbssLog;
8485 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
8486 LOG_WLAN_IBSS_C);
8487 if (pIbssLog) {
8488 pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_RSP;
8489 if (eSIR_SME_SUCCESS != pSmeRsp->statusCode) {
8490 pIbssLog->status = WLAN_IBSS_STATUS_FAILURE;
8491 }
8492 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
8493 }
8494 }
8495#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
8496 pMac->roam.roamSession[pSmeRsp->sessionId].connectState =
8497 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
8498 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, pSmeRsp->sessionId)) {
8499 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8500 } else
8501 if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE
8502 (pMac, pSmeRsp->sessionId)) {
8503 csr_roam_reissue_roam_command(pMac);
8504 }
8505}
8506
8507/**
8508 * csr_dequeue_command() - removes a command from active cmd list
8509 * @pMac: mac global context
8510 *
8511 * Return: void
8512 */
8513static void
8514csr_dequeue_command(tpAniSirGlobal mac_ctx)
8515{
8516 bool fRemoveCmd;
8517 tSmeCmd *cmd = NULL;
8518 tListElem *entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
8519 LL_ACCESS_LOCK);
8520 if (!entry) {
8521 sms_log(mac_ctx, LOGE, FL("NO commands are active"));
8522 return;
8523 }
8524
8525 cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
8526 /*
8527 * If the head of the queue is Active and it is a given cmd type, remove
8528 * and put this on the Free queue.
8529 */
8530 if (eSmeCommandRoam != cmd->command) {
8531 sms_log(mac_ctx, LOGE, FL("Roam command not active"));
8532 return;
8533 }
8534 /*
8535 * we need to process the result first before removing it from active
8536 * list because state changes still happening insides
8537 * roamQProcessRoamResults so no other roam command should be issued.
8538 */
8539 fRemoveCmd = csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList, entry,
8540 LL_ACCESS_LOCK);
8541 if (cmd->u.roamCmd.fReleaseProfile) {
8542 csr_release_profile(mac_ctx, &cmd->u.roamCmd.roamProfile);
8543 cmd->u.roamCmd.fReleaseProfile = false;
8544 }
8545 if (fRemoveCmd)
8546 csr_release_command_roam(mac_ctx, cmd);
8547 else
8548 sms_log(mac_ctx, LOGE, FL("fail to remove cmd reason %d"),
8549 cmd->u.roamCmd.roamReason);
8550}
8551
8552/**
8553 * csr_post_roam_failure() - post roam failure back to csr and issues a disassoc
8554 * @pMac: mac global context
8555 * @session_id: session id
8556 * @roam_info: roam info struct
8557 * @scan_filter: scan filter to free
8558 * @cur_roam_profile: current csr roam profile
8559 *
8560 * Return: void
8561 */
8562static void
8563csr_post_roam_failure(tpAniSirGlobal mac_ctx,
8564 uint32_t session_id,
8565 tCsrRoamInfo *roam_info,
8566 tCsrScanResultFilter *scan_filter,
8567 tCsrRoamProfile *cur_roam_profile)
8568{
8569 CDF_STATUS status;
8570
8571 if (scan_filter) {
8572 csr_free_scan_filter(mac_ctx, scan_filter);
8573 cdf_mem_free(scan_filter);
8574 }
8575 if (cur_roam_profile)
8576 cdf_mem_free(cur_roam_profile);
8577
8578#ifdef WLAN_FEATURE_ROAM_OFFLOAD
8579 csr_roam_synch_clean_up(mac_ctx, session_id);
8580#endif
8581 /* Inform the upper layers that the reassoc failed */
8582 cdf_mem_zero(roam_info, sizeof(tCsrRoamInfo));
8583 csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
8584 eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
8585 /*
8586 * Issue a disassoc request so that PE/LIM uses this to clean-up the FT
8587 * session. Upon success, we would re-enter this routine after receiving
8588 * the disassoc response and will fall into the reassoc fail sub-state.
8589 * And, eventually call csr_roam_complete which would remove the roam
8590 * command from SME active queue.
8591 */
8592 status = csr_roam_issue_disassociate(mac_ctx, session_id,
8593 eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false);
8594 if (!CDF_IS_STATUS_SUCCESS(status)) {
8595 sms_log(mac_ctx, LOGE,
8596 FL("csr_roam_issue_disassociate failed, status %d"),
8597 status);
8598 csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL);
8599 }
8600}
8601
8602/**
8603 * csr_check_profile_in_scan_cache() - finds if roam profile is present in scan
8604 * cache or not
8605 * @pMac: mac global context
8606 * @scan_filter: out param, scan filter
8607 * @neighbor_roam_info: roam info struct
8608 * @hBSSList: scan result
8609 *
8610 * Return: true if found else false.
8611 */
8612static bool
8613csr_check_profile_in_scan_cache(tpAniSirGlobal mac_ctx,
8614 tCsrScanResultFilter **scan_filter,
8615 tpCsrNeighborRoamControlInfo neighbor_roam_info,
8616 tScanResultHandle *hBSSList)
8617{
8618 CDF_STATUS status;
8619 *scan_filter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
8620 if (NULL == *scan_filter) {
8621 sms_log(mac_ctx, LOGE, FL("alloc for ScanFilter failed."));
8622 return false;
8623 }
8624 cdf_mem_set(*scan_filter, sizeof(tCsrScanResultFilter), 0);
8625 (*scan_filter)->scan_filter_for_roam = 1;
8626 status = csr_roam_prepare_filter_from_profile(mac_ctx,
8627 &neighbor_roam_info->csrNeighborRoamProfile,
8628 *scan_filter);
8629 if (!CDF_IS_STATUS_SUCCESS(status)) {
8630 sms_log(mac_ctx, LOGE,
8631 FL("failed to prepare scan filter, status %d"),
8632 status);
8633 return false;
8634 }
8635 status = csr_scan_get_result(mac_ctx, *scan_filter, hBSSList);
8636 if (!CDF_IS_STATUS_SUCCESS(status)) {
8637 sms_log(mac_ctx, LOGE,
8638 FL("csr_scan_get_result failed, status %d"),
8639 status);
8640 return false;
8641 }
8642 return true;
8643}
8644
8645void csr_roam_roaming_state_disassoc_rsp_processor(tpAniSirGlobal pMac,
8646 tSirSmeDisassocRsp *pSmeRsp)
8647{
8648#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
8649 tScanResultHandle hBSSList;
8650 tCsrRoamInfo roamInfo;
8651 tCsrScanResultFilter *pScanFilter = NULL;
8652 uint32_t roamId = 0;
8653 tCsrRoamProfile *pCurRoamProfile = NULL;
8654#endif
8655 CDF_STATUS status;
8656 uint32_t sessionId;
8657 tCsrRoamSession *pSession;
8658 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
8659 tSirSmeDisassocRsp SmeDisassocRsp;
8660
8661 csr_ser_des_unpack_diassoc_rsp((uint8_t *) pSmeRsp, &SmeDisassocRsp);
8662 sessionId = SmeDisassocRsp.sessionId;
8663 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG, FL("sessionId %d"),
8664 sessionId);
8665
8666 if (csr_is_conn_state_infra(pMac, sessionId)) {
8667 pMac->roam.roamSession[sessionId].connectState =
8668 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
8669 }
8670
8671 pSession = CSR_GET_SESSION(pMac, sessionId);
8672 if (!pSession) {
8673 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
8674 return;
8675 }
8676
8677 if (CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId)) {
8678 sms_log(pMac, LOG2, "***eCsrNothingToJoin***");
8679 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8680 } else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) ||
8681 CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId)) {
8682 if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
8683 sms_log(pMac, LOG2,
8684 FL("CSR force disassociated successful"));
8685 /*
8686 * A callback to HDD will be issued from
8687 * csr_roam_complete so no need to do anything here
8688 */
8689 }
8690 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8691 } else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)) {
8692 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8693 FL("CSR SmeDisassocReq due to HO on session %d"),
8694 sessionId);
8695 pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
8696#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
8697 /*
8698 * First ensure if the roam profile is in the scan cache.
8699 * If not, post a reassoc failure and disconnect.
8700 */
8701 if (!csr_check_profile_in_scan_cache(pMac, &pScanFilter,
8702 pNeighborRoamInfo, &hBSSList))
8703 goto POST_ROAM_FAILURE;
8704
8705 /*
8706 * After ensuring that the roam profile is in the scan result
8707 * list, dequeue the command from the active list.
8708 */
8709 csr_dequeue_command(pMac);
8710
8711 /* notify HDD about handoff and provide the BSSID too */
8712 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
8713
8714 cdf_copy_macaddr(&roamInfo.bssid,
8715 pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid);
8716
8717 csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
8718 eCSR_ROAM_ROAMING_START,
8719 eCSR_ROAM_RESULT_NONE);
8720
8721 /*
8722 * Copy the connected profile to apply the same for this
8723 * connection as well
8724 */
8725 pCurRoamProfile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
8726 if (pCurRoamProfile != NULL) {
8727 /*
8728 * notify sub-modules like QoS etc. that handoff
8729 * happening
8730 */
8731 sme_qos_csr_event_ind(pMac, sessionId,
8732 SME_QOS_CSR_HANDOFF_ASSOC_REQ,
8733 NULL);
8734 cdf_mem_set(pCurRoamProfile, sizeof(tCsrRoamProfile),
8735 0);
8736 csr_roam_copy_profile(pMac, pCurRoamProfile,
8737 pSession->pCurRoamProfile);
8738 /* make sure to put it at the head of the cmd queue */
8739 status = csr_roam_issue_connect(pMac, sessionId,
8740 pCurRoamProfile, hBSSList,
8741 eCsrSmeIssuedAssocToSimilarAP,
8742 roamId, true, false);
8743 if (!CDF_IS_STATUS_SUCCESS(status))
8744 sms_log(pMac, LOGE,
8745 FL("issue_connect failed. status %d"),
8746 status);
8747
8748 csr_release_profile(pMac, pCurRoamProfile);
8749 cdf_mem_free(pCurRoamProfile);
8750 csr_free_scan_filter(pMac, pScanFilter);
8751 cdf_mem_free(pScanFilter);
8752 return;
8753 }
8754
8755POST_ROAM_FAILURE:
8756 csr_post_roam_failure(pMac, sessionId, &roamInfo,
8757 pScanFilter, pCurRoamProfile);
8758#endif
8759 } /* else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac ) ) */
8760 else if (CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId)) {
8761 /* Disassoc due to Reassoc failure falls into this codepath */
8762 csr_roam_complete(pMac, eCsrJoinFailure, NULL);
8763 } else {
8764 if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
8765 /*
8766 * Successfully disassociated from the 'old' Bss.
8767 * We get Disassociate response in three conditions.
8768 * 1) The case where we are disasociating from an Infra
8769 * Bss to start an IBSS.
8770 * 2) When we are disassociating from an Infra Bss to
8771 * join an IBSS or a new infra network.
8772 * 3) Where we are doing an Infra to Infra roam between
8773 * networks with different SSIDs.
8774 * In all cases, we set the new Bss configuration here
8775 * and attempt to join
8776 */
8777 sms_log(pMac, LOG2,
8778 FL("Disassociated successfully"));
8779 } else {
8780 sms_log(pMac, LOGE,
8781 FL("DisassocReq failed, statusCode= 0x%08X"),
8782 SmeDisassocRsp.statusCode);
8783 }
8784 /* We are not done yet. Get the data and continue roaming */
8785 csr_roam_reissue_roam_command(pMac);
8786 }
8787}
8788
8789static void csr_roam_roaming_state_deauth_rsp_processor(tpAniSirGlobal pMac,
8790 tSirSmeDeauthRsp *pSmeRsp)
8791{
8792 tSirResultCodes statusCode;
8793 /* No one is sending eWNI_SME_DEAUTH_REQ to PE. */
8794 sms_log(pMac, LOGW, FL("is no-op"));
8795 statusCode = csr_get_de_auth_rsp_status_code(pSmeRsp);
8796 pMac->roam.deauthRspStatus = statusCode;
8797 if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId)) {
8798 csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
8799 } else {
8800 if (eSIR_SME_SUCCESS == statusCode) {
8801 /* Successfully deauth from the 'old' Bss... */
8802 /* */
8803 sms_log(pMac, LOG2,
8804 "CSR SmeDeauthReq disassociated Successfully");
8805 } else {
8806 sms_log(pMac, LOGW,
8807 "SmeDeauthReq failed with statusCode= 0x%08X",
8808 statusCode);
8809 }
8810 /* We are not done yet. Get the data and continue roaming */
8811 csr_roam_reissue_roam_command(pMac);
8812 }
8813}
8814
8815static void csr_roam_roaming_state_start_bss_rsp_processor(tpAniSirGlobal pMac,
8816 tSirSmeStartBssRsp *
8817 pSmeStartBssRsp)
8818{
8819 eCsrRoamCompleteResult result;
8820
8821 if (eSIR_SME_SUCCESS == pSmeStartBssRsp->statusCode) {
8822 sms_log(pMac, LOGW, "SmeStartBssReq Successful");
8823 result = eCsrStartBssSuccess;
8824 } else {
8825 sms_log(pMac, LOGW,
8826 "SmeStartBssReq failed with statusCode= 0x%08X",
8827 pSmeStartBssRsp->statusCode);
8828 /* Let csr_roam_complete decide what to do */
8829 result = eCsrStartBssFailure;
8830 }
8831 csr_roam_complete(pMac, result, pSmeStartBssRsp);
8832}
8833
8834/**
8835 * csr_roaming_state_msg_processor() - process roaming messages
8836 * @pMac: mac global context
8837 * @pMsgBuf: message buffer
8838 *
8839 * We need to be careful on whether to cast pMsgBuf (pSmeRsp) to other type of
8840 * strucutres. It depends on how the message is constructed. If the message is
8841 * sent by lim_send_sme_rsp, the pMsgBuf is only a generic response and can only
8842 * be used as pointer to tSirSmeRsp. For the messages where sender allocates
8843 * memory for specific structures, then it can be cast accordingly.
8844 *
8845 * Return: status of operation
8846 */
8847void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
8848{
8849 tSirSmeRsp *pSmeRsp;
8850 tSmeIbssPeerInd *pIbssPeerInd;
8851 tCsrRoamInfo roamInfo;
8852 pSmeRsp = (tSirSmeRsp *) pMsgBuf;
8853 sms_log(pMac, LOG2, FL("Message %d[0x%04X] received in substate %s"),
8854 pSmeRsp->messageType, pSmeRsp->messageType,
8855 mac_trace_getcsr_roam_sub_state(
8856 pMac->roam.curSubState[pSmeRsp->sessionId]));
8857 pSmeRsp->messageType = pSmeRsp->messageType;
8858 pSmeRsp->length = pSmeRsp->length;
8859 pSmeRsp->statusCode = pSmeRsp->statusCode;
8860
8861 switch (pSmeRsp->messageType) {
8862
8863 case eWNI_SME_JOIN_RSP:
8864 /* in Roaming state, process the Join response message... */
8865 if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, pSmeRsp->sessionId))
8866 /* We sent a JOIN_REQ */
8867 csr_roam_join_rsp_processor(pMac,
8868 (tSirSmeJoinRsp *) pSmeRsp);
8869 break;
8870 case eWNI_SME_REASSOC_RSP:
8871 /* or the Reassociation response message... */
8872 if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, pSmeRsp->sessionId))
8873 csr_roam_roaming_state_reassoc_rsp_processor(pMac,
8874 (tpSirSmeJoinRsp) pSmeRsp);
8875 break;
8876 case eWNI_SME_STOP_BSS_RSP:
8877 /* or the Stop Bss response message... */
8878 csr_roam_roaming_state_stop_bss_rsp_processor(pMac, pSmeRsp);
8879 break;
8880 case eWNI_SME_DISASSOC_RSP:
8881 /* or the Disassociate response message... */
8882 if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, pSmeRsp->sessionId)
8883 || CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac,
8884 pSmeRsp->sessionId)
8885 || CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac,
8886 pSmeRsp->sessionId)
8887 || CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac,
8888 pSmeRsp->sessionId)
8889 || CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac,
8890 pSmeRsp->sessionId)
8891 || CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac,
8892 pSmeRsp->sessionId)) {
8893 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8894 FL("eWNI_SME_DISASSOC_RSP subState = %s"),
8895 mac_trace_getcsr_roam_sub_state(
8896 pMac->roam.curSubState[pSmeRsp->sessionId]));
8897 csr_roam_roaming_state_disassoc_rsp_processor(pMac,
8898 (tSirSmeDisassocRsp *) pSmeRsp);
8899 }
8900 break;
8901 case eWNI_SME_DEAUTH_RSP:
8902 /* or the Deauthentication response message... */
8903 if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId))
8904 csr_roam_roaming_state_deauth_rsp_processor(pMac,
8905 (tSirSmeDeauthRsp *) pSmeRsp);
8906 break;
8907 case eWNI_SME_START_BSS_RSP:
8908 /* or the Start BSS response message... */
8909 if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac,
8910 pSmeRsp->sessionId))
8911 csr_roam_roaming_state_start_bss_rsp_processor(pMac,
8912 (tSirSmeStartBssRsp *) pSmeRsp);
8913 break;
8914 /* In case CSR issues STOP_BSS, we need to tell HDD about peer departed
8915 * becasue PE is removing them
8916 */
8917 case eWNI_SME_IBSS_PEER_DEPARTED_IND:
8918 pIbssPeerInd = (tSmeIbssPeerInd *) pSmeRsp;
8919 sms_log(pMac, LOGE,
8920 FL("Peer departed ntf from LIM in joining state"));
8921 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
8922 roamInfo.staId = (uint8_t) pIbssPeerInd->staId;
8923 roamInfo.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
8924 roamInfo.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
8925 cdf_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr,
8926 sizeof(struct cdf_mac_addr));
8927 csr_roam_call_callback(pMac, pSmeRsp->sessionId, &roamInfo, 0,
8928 eCSR_ROAM_CONNECT_STATUS_UPDATE,
8929 eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
8930 break;
8931 case eWNI_SME_GET_RSSI_REQ:
8932 {
8933 tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsgBuf;
8934 if (NULL != pGetRssiReq->rssiCallback)
8935 ((tCsrRssiCallback) pGetRssiReq->rssiCallback)
8936 (pGetRssiReq->lastRSSI, pGetRssiReq->staId,
8937 pGetRssiReq->pDevContext);
8938 else
8939 sms_log(pMac, LOGE,
8940 FL("pGetRssiReq->rssiCallback is NULL"));
8941 }
8942 break;
8943 default:
8944 sms_log(pMac, LOG1,
8945 FL("Unexpected message type = %d[0x%X] received in substate %s"),
8946 pSmeRsp->messageType, pSmeRsp->messageType,
8947 mac_trace_getcsr_roam_sub_state(
8948 pMac->roam.curSubState[pSmeRsp->sessionId]));
8949 /* If we are connected, check the link status change */
8950 if (!csr_is_conn_state_disconnected(pMac, pSmeRsp->sessionId))
8951 csr_roam_check_for_link_status_change(pMac, pSmeRsp);
8952 break;
8953 }
8954}
8955
8956void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
8957{
8958 tSirSmeRsp *pSirMsg = (tSirSmeRsp *) pMsgBuf;
8959 switch (pSirMsg->messageType) {
8960 case eWNI_SME_GET_STATISTICS_RSP:
8961 sms_log(pMac, LOG2, FL("Stats rsp from PE"));
8962 csr_roam_stats_rsp_processor(pMac, pSirMsg);
8963 break;
8964 case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
8965 {
8966 tCsrRoamSession *pSession;
8967 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
8968 tCsrRoamInfo roamInfo;
8969 tCsrRoamInfo *pRoamInfo = NULL;
8970 uint32_t sessionId;
8971 CDF_STATUS status;
8972 sms_log(pMac, LOG1,
8973 FL
8974 ("ASSOCIATION confirmation can be given to upper layer "));
8975 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
8976 pRoamInfo = &roamInfo;
8977 pUpperLayerAssocCnf =
8978 (tSirSmeAssocIndToUpperLayerCnf *) pMsgBuf;
8979 status =
8980 csr_roam_get_session_id_from_bssid(pMac,
8981 (struct cdf_mac_addr *)
8982 pUpperLayerAssocCnf->
8983 bssId, &sessionId);
8984 pSession = CSR_GET_SESSION(pMac, sessionId);
8985
8986 if (!pSession) {
8987 sms_log(pMac, LOGE,
8988 FL(" session %d not found "),
8989 sessionId);
8990 return;
8991 }
8992
8993 pRoamInfo->statusCode = eSIR_SME_SUCCESS; /* send the status code as Success */
8994 pRoamInfo->u.pConnectedProfile =
8995 &pSession->connectedProfile;
8996 pRoamInfo->staId = (uint8_t) pUpperLayerAssocCnf->aid;
8997 pRoamInfo->rsnIELen =
8998 (uint8_t) pUpperLayerAssocCnf->rsnIE.length;
8999 pRoamInfo->prsnIE =
9000 pUpperLayerAssocCnf->rsnIE.rsnIEdata;
9001#ifdef FEATURE_WLAN_WAPI
9002 pRoamInfo->wapiIELen =
9003 (uint8_t) pUpperLayerAssocCnf->wapiIE.length;
9004 pRoamInfo->pwapiIE =
9005 pUpperLayerAssocCnf->wapiIE.wapiIEdata;
9006#endif
9007 pRoamInfo->addIELen =
9008 (uint8_t) pUpperLayerAssocCnf->addIE.length;
9009 pRoamInfo->paddIE =
9010 pUpperLayerAssocCnf->addIE.addIEdata;
9011 cdf_mem_copy(pRoamInfo->peerMac.bytes,
9012 pUpperLayerAssocCnf->peerMacAddr,
9013 sizeof(tSirMacAddr));
9014 cdf_mem_copy(&pRoamInfo->bssid,
9015 pUpperLayerAssocCnf->bssId,
9016 sizeof(struct cdf_mac_addr));
9017 pRoamInfo->wmmEnabledSta =
9018 pUpperLayerAssocCnf->wmmEnabledSta;
9019 pRoamInfo->timingMeasCap =
9020 pUpperLayerAssocCnf->timingMeasCap;
9021 cdf_mem_copy(&pRoamInfo->chan_info,
9022 &pUpperLayerAssocCnf->chan_info,
9023 sizeof(tSirSmeChanInfo));
9024 if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
9025 pMac->roam.roamSession[sessionId].connectState =
9026 eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
9027 pRoamInfo->fReassocReq =
9028 pUpperLayerAssocCnf->reassocReq;
9029 status =
9030 csr_roam_call_callback(pMac, sessionId,
9031 pRoamInfo, 0,
9032 eCSR_ROAM_INFRA_IND,
9033 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
9034 }
9035 if (CSR_IS_WDS_AP(pRoamInfo->u.pConnectedProfile)) {
9036 cdf_sleep(100);
9037 pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED; /* Sta */
9038 status = csr_roam_call_callback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND); /* Sta */
9039 }
9040
9041 }
9042 break;
9043 default:
9044 csr_roam_check_for_link_status_change(pMac, pSirMsg);
9045 break;
9046 }
9047}
9048
9049CDF_STATUS csr_roam_issue_set_context_req(tpAniSirGlobal pMac,
9050 uint32_t sessionId,
9051 eCsrEncryptionType EncryptType,
9052 tSirBssDescription *pBssDescription,
9053 tSirMacAddr *bssId, bool addKey,
9054 bool fUnicast,
9055 tAniKeyDirection aniKeyDirection,
9056 uint8_t keyId, uint16_t keyLength,
9057 uint8_t *pKey, uint8_t paeRole)
9058{
9059 CDF_STATUS status = CDF_STATUS_SUCCESS;
9060 tAniEdType edType;
9061
9062 if (eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType) {
9063 EncryptType = eCSR_ENCRYPT_TYPE_NONE;
9064 }
9065
9066 edType = csr_translate_encrypt_type_to_ed_type(EncryptType);
9067
9068 /*
9069 * Allow 0 keys to be set for the non-WPA encrypt types. For WPA encrypt
9070 * types, the num keys must be non-zero or LIM will reject the set
9071 * context (assumes the SET_CONTEXT does not occur until the keys are
9072 * distrubuted).
9073 */
9074 if (CSR_IS_ENC_TYPE_STATIC(EncryptType) || addKey) {
9075 tCsrRoamSetKey setKey;
9076 setKey.encType = EncryptType;
9077 setKey.keyDirection = aniKeyDirection;
9078 cdf_mem_copy(&setKey.peerMac, bssId, sizeof(struct cdf_mac_addr));
9079 /* 0 for supplicant */
9080 setKey.paeRole = paeRole;
9081 /* Key index */
9082 setKey.keyId = keyId;
9083 setKey.keyLength = keyLength;
9084 if (keyLength) {
9085 cdf_mem_copy(setKey.Key, pKey, keyLength);
9086 }
9087 status = csr_roam_issue_set_key_command(pMac, sessionId,
9088 &setKey, 0);
9089 }
9090 return status;
9091}
9092
9093/**
9094 * csr_update_key_cmd() - update key info in set key command
9095 * @mac_ctx: mac global context
9096 * @session: roam session
9097 * @set_key: input set key command
9098 * @set_key_cmd: set key command to update
9099 * @enqueue_cmd: indicates if command need to be enqueued to sme
9100 *
9101 * This function will validate the key length, adjust if too long. Tt will
9102 * update bool enqueue_cmd, to false if some error has occured key are local.
9103 *
9104 * Return: status of operation
9105 */
9106static CDF_STATUS
9107csr_update_key_cmd(tpAniSirGlobal mac_ctx, tCsrRoamSession *session,
9108 tCsrRoamSetKey *set_key, tSmeCmd *set_key_cmd,
9109 bool *enqueue_cmd)
9110{
9111 switch (set_key->encType) {
9112 case eCSR_ENCRYPT_TYPE_WEP40:
9113 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9114 /* KeyLength maybe 0 for static WEP */
9115 if (set_key->keyLength) {
9116 if (set_key->keyLength < CSR_WEP40_KEY_LEN) {
9117 sms_log(mac_ctx, LOGW,
9118 FL("Invalid WEP40 keylength [= %d]"),
9119 set_key->keyLength);
9120 *enqueue_cmd = false;
9121 return CDF_STATUS_E_INVAL;
9122 }
9123
9124 set_key_cmd->u.setKeyCmd.keyLength = CSR_WEP40_KEY_LEN;
9125 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9126 CSR_WEP40_KEY_LEN);
9127 }
9128 *enqueue_cmd = true;
9129 break;
9130 case eCSR_ENCRYPT_TYPE_WEP104:
9131 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9132 /* KeyLength maybe 0 for static WEP */
9133 if (set_key->keyLength) {
9134 if (set_key->keyLength < CSR_WEP104_KEY_LEN) {
9135 sms_log(mac_ctx, LOGW,
9136 FL("Invalid WEP104 keylength [= %d]"),
9137 set_key->keyLength);
9138 *enqueue_cmd = false;
9139 return CDF_STATUS_E_INVAL;
9140 }
9141
9142 set_key_cmd->u.setKeyCmd.keyLength = CSR_WEP104_KEY_LEN;
9143 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9144 CSR_WEP104_KEY_LEN);
9145 }
9146 *enqueue_cmd = true;
9147 break;
9148 case eCSR_ENCRYPT_TYPE_TKIP:
9149 if (set_key->keyLength < CSR_TKIP_KEY_LEN) {
9150 sms_log(mac_ctx, LOGW,
9151 FL("Invalid TKIP keylength [= %d]"),
9152 set_key->keyLength);
9153 *enqueue_cmd = false;
9154 return CDF_STATUS_E_INVAL;
9155 }
9156 set_key_cmd->u.setKeyCmd.keyLength = CSR_TKIP_KEY_LEN;
9157 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9158 CSR_TKIP_KEY_LEN);
9159 *enqueue_cmd = true;
9160 break;
9161 case eCSR_ENCRYPT_TYPE_AES:
9162 if (set_key->keyLength < CSR_AES_KEY_LEN) {
9163 sms_log(mac_ctx, LOGW,
9164 FL("Invalid AES/CCMP keylength [= %d]"),
9165 set_key->keyLength);
9166 *enqueue_cmd = false;
9167 return CDF_STATUS_E_INVAL;
9168 }
9169 set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
9170 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9171 CSR_AES_KEY_LEN);
9172 *enqueue_cmd = true;
9173 break;
9174#ifdef FEATURE_WLAN_WAPI
9175 case eCSR_ENCRYPT_TYPE_WPI:
9176 if (set_key->keyLength < CSR_WAPI_KEY_LEN) {
9177 sms_log(mac_ctx, LOGW,
9178 FL("Invalid WAPI keylength [= %d]"),
9179 set_key->keyLength);
9180 *enqueue_cmd = false;
9181 return CDF_STATUS_E_INVAL;
9182 }
9183 set_key_cmd->u.setKeyCmd.keyLength = CSR_WAPI_KEY_LEN;
9184 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9185 CSR_WAPI_KEY_LEN);
9186 if (session->pCurRoamProfile) {
9187 session->pCurRoamProfile->negotiatedUCEncryptionType =
9188 eCSR_ENCRYPT_TYPE_WPI;
9189 } else {
9190 sms_log(mac_ctx, LOGW,
9191 FL("pCurRoamProfile is NULL."));
9192 *enqueue_cmd = false;
9193 return CDF_STATUS_E_INVAL;
9194 }
9195 *enqueue_cmd = true;
9196 break;
9197#endif /* FEATURE_WLAN_WAPI */
9198#ifdef FEATURE_WLAN_ESE
9199 case eCSR_ENCRYPT_TYPE_KRK:
9200 /* no need to enqueue KRK key request, since they are local */
9201 *enqueue_cmd = false;
9202 if (set_key->keyLength < CSR_KRK_KEY_LEN) {
9203 sms_log(mac_ctx, LOGW,
9204 FL("Invalid KRK keylength [= %d]"),
9205 set_key->keyLength);
9206 return CDF_STATUS_E_INVAL;
9207 }
9208 cdf_mem_copy(session->eseCckmInfo.krk, set_key->Key,
9209 CSR_KRK_KEY_LEN);
9210 session->eseCckmInfo.reassoc_req_num = 1;
9211 session->eseCckmInfo.krk_plumbed = true;
9212 break;
9213#ifdef WLAN_FEATURE_ROAM_OFFLOAD
9214 case eCSR_ENCRYPT_TYPE_BTK:
9215 /* no need to enqueue KRK key request, since they are local */
9216 *enqueue_cmd = false;
9217 if (set_key->keyLength < SIR_BTK_KEY_LEN) {
9218 sms_log(mac_ctx, LOGW,
9219 FL("LFR3:Invalid BTK keylength [= %d]"),
9220 set_key->keyLength);
9221 return CDF_STATUS_E_INVAL;
9222 }
9223 cdf_mem_copy(session->eseCckmInfo.btk, set_key->Key,
9224 SIR_BTK_KEY_LEN);
9225 break;
9226#endif
9227#endif /* FEATURE_WLAN_ESE */
9228#ifdef WLAN_FEATURE_11W
9229 /* Check for 11w BIP */
9230 case eCSR_ENCRYPT_TYPE_AES_CMAC:
9231 if (set_key->keyLength < CSR_AES_KEY_LEN) {
9232 sms_log(mac_ctx, LOGW,
9233 FL("Invalid AES/CCMP keylength [= %d]"),
9234 set_key->keyLength);
9235 *enqueue_cmd = false;
9236 return CDF_STATUS_E_INVAL;
9237 }
9238 set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
9239 cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
9240 CSR_AES_KEY_LEN);
9241 *enqueue_cmd = true;
9242 break;
9243#endif /* WLAN_FEATURE_11W */
9244 default:
9245 /* for open security also we want to enqueue command */
9246 *enqueue_cmd = true;
9247 return CDF_STATUS_SUCCESS;
9248 } /* end of switch */
9249 return CDF_STATUS_SUCCESS;
9250}
9251
9252
9253static CDF_STATUS csr_roam_issue_set_key_command(tpAniSirGlobal pMac,
9254 uint32_t sessionId,
9255 tCsrRoamSetKey *pSetKey,
9256 uint32_t roamId)
9257{
9258 CDF_STATUS status = CDF_STATUS_E_INVAL;
9259 bool enqueue_cmd = true;
9260 tSmeCmd *pCommand = NULL;
9261#if defined(FEATURE_WLAN_ESE) || defined (FEATURE_WLAN_WAPI)
9262 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
9263 if (NULL == pSession) {
9264 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9265 FL("session %d not found"), sessionId);
9266 return CDF_STATUS_E_FAILURE;
9267 }
9268#endif /* FEATURE_WLAN_ESE */
9269
9270 pCommand = csr_get_command_buffer(pMac);
9271 if (NULL == pCommand) {
9272 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
9273 return CDF_STATUS_E_RESOURCES;
9274 }
9275 cdf_mem_zero(pCommand, sizeof(tSmeCmd));
9276 pCommand->command = eSmeCommandSetKey;
9277 pCommand->sessionId = (uint8_t) sessionId;
9278 /*
9279 * following function will validate the key length, Adjust if too long.
9280 * for static WEP the keys are not set thru' SetContextReq
9281 *
9282 * it will update bool enqueue_cmd, to false if some error has occured
9283 * key are local. enqueue sme command only if enqueue_cmd is true
9284 * status is indication of success or failure and will be returned to
9285 * called of current function if command is not enqueued due to key req
9286 * being local
9287 */
9288 status = csr_update_key_cmd(pMac, pSession, pSetKey,
9289 pCommand, &enqueue_cmd);
9290 if (enqueue_cmd) {
9291 pCommand->u.setKeyCmd.roamId = roamId;
9292 pCommand->u.setKeyCmd.encType = pSetKey->encType;
9293 pCommand->u.setKeyCmd.keyDirection = pSetKey->keyDirection;
9294 cdf_mem_copy(&pCommand->u.setKeyCmd.peerMac, &pSetKey->peerMac,
9295 sizeof(struct cdf_mac_addr));
9296 /* 0 for supplicant */
9297 pCommand->u.setKeyCmd.paeRole = pSetKey->paeRole;
9298 pCommand->u.setKeyCmd.keyId = pSetKey->keyId;
9299 cdf_mem_copy(pCommand->u.setKeyCmd.keyRsc, pSetKey->keyRsc,
9300 CSR_MAX_RSC_LEN);
9301 /*
9302 * Always put set key to the head of the Q because it is the
9303 * only thing to get executed in case of WT_KEY state
9304 */
9305
9306 status = csr_queue_sme_command(pMac, pCommand, true);
9307 if (!CDF_IS_STATUS_SUCCESS(status)) {
9308 sms_log(pMac, LOGE,
9309 FL("fail to send message status = %d"), status);
9310 /* update to false so that command can be freed */
9311 enqueue_cmd = false;
9312 }
9313 }
9314
9315 /*
9316 * Free the command if enqueue_cmd == false:
9317 * this means that command was not enqueued because either there has
9318 * been a failure, or it is a "local" operation like the set ESE CCKM
9319 * KRK key.
9320 */
9321 if (false == enqueue_cmd)
9322 csr_release_command_set_key(pMac, pCommand);
9323
9324 return status;
9325}
9326
9327CDF_STATUS csr_roam_process_set_key_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
9328{
9329 CDF_STATUS status;
9330 uint8_t numKeys = (pCommand->u.setKeyCmd.keyLength) ? 1 : 0;
9331 tAniEdType edType =
9332 csr_translate_encrypt_type_to_ed_type(pCommand->u.setKeyCmd.encType);
9333 bool fUnicast =
9334 (pCommand->u.setKeyCmd.peerMac[0] == 0xFF) ? false : true;
9335 uint32_t sessionId = pCommand->sessionId;
9336#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
9337 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
9338 WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
9339 host_event_wlan_security_payload_type);
9340
9341 if (NULL == pSession) {
9342 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
9343 return CDF_STATUS_E_FAILURE;
9344 }
9345
9346 if (eSIR_ED_NONE != edType) {
9347 cdf_mem_set(&setKeyEvent,
9348 sizeof(host_event_wlan_security_payload_type), 0);
9349 if (*((uint8_t *) &pCommand->u.setKeyCmd.peerMac) & 0x01) {
9350 setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_REQ;
9351 setKeyEvent.encryptionModeMulticast =
9352 (uint8_t) diag_enc_type_from_csr_type(pCommand->u.
9353 setKeyCmd.encType);
9354 setKeyEvent.encryptionModeUnicast =
9355 (uint8_t) diag_enc_type_from_csr_type(pSession->
9356 connectedProfile.
9357 EncryptionType);
9358 } else {
9359 setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_REQ;
9360 setKeyEvent.encryptionModeUnicast =
9361 (uint8_t) diag_enc_type_from_csr_type(pCommand->u.
9362 setKeyCmd.encType);
9363 setKeyEvent.encryptionModeMulticast =
9364 (uint8_t) diag_enc_type_from_csr_type(pSession->
9365 connectedProfile.
9366 mcEncryptionType);
9367 }
9368 cdf_mem_copy(setKeyEvent.bssid,
9369 pSession->connectedProfile.bssid.bytes,
9370 CDF_MAC_ADDR_SIZE);
9371 if (CSR_IS_ENC_TYPE_STATIC(pCommand->u.setKeyCmd.encType)) {
9372 uint32_t defKeyId;
9373 /* It has to be static WEP here */
9374 if (IS_SIR_STATUS_SUCCESS
9375 (wlan_cfg_get_int
9376 (pMac, WNI_CFG_WEP_DEFAULT_KEYID, &defKeyId))) {
9377 setKeyEvent.keyId = (uint8_t) defKeyId;
9378 }
9379 } else {
9380 setKeyEvent.keyId = pCommand->u.setKeyCmd.keyId;
9381 }
9382 setKeyEvent.authMode =
9383 (uint8_t) diag_auth_type_from_csr_type(pSession->
9384 connectedProfile.
9385 AuthType);
9386 WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
9387 }
9388#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
9389 if (csr_is_set_key_allowed(pMac, sessionId)) {
9390 status = csr_send_mb_set_context_req_msg(pMac, sessionId,
9391 (uint8_t *) &pCommand->u.
9392 setKeyCmd.peerMac, numKeys,
9393 edType, fUnicast,
9394 pCommand->u.setKeyCmd.
9395 keyDirection,
9396 pCommand->u.setKeyCmd.keyId,
9397 pCommand->u.setKeyCmd.
9398 keyLength,
9399 pCommand->u.setKeyCmd.Key,
9400 pCommand->u.setKeyCmd.
9401 paeRole,
9402 pCommand->u.setKeyCmd.
9403 keyRsc);
9404 } else {
9405 sms_log(pMac, LOGW, FL(" cannot process not connected"));
9406 /* Set this status so the error handling take care of the case. */
9407 status = CDF_STATUS_CSR_WRONG_STATE;
9408 }
9409 if (!CDF_IS_STATUS_SUCCESS(status)) {
9410 sms_log(pMac, LOGE, FL(" error status %d"), status);
9411 csr_roam_call_callback(pMac, sessionId, NULL,
9412 pCommand->u.setKeyCmd.roamId,
9413 eCSR_ROAM_SET_KEY_COMPLETE,
9414 eCSR_ROAM_RESULT_FAILURE);
9415#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
9416 if (eSIR_ED_NONE != edType) {
9417 if (*((uint8_t *) &pCommand->u.setKeyCmd.peerMac) &
9418 0x01) {
9419 setKeyEvent.eventId =
9420 WLAN_SECURITY_EVENT_SET_GTK_RSP;
9421 } else {
9422 setKeyEvent.eventId =
9423 WLAN_SECURITY_EVENT_SET_PTK_RSP;
9424 }
9425 setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
9426 WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent,
9427 EVENT_WLAN_SECURITY);
9428 }
9429#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
9430 }
9431 return status;
9432}
9433
9434CDF_STATUS csr_roam_set_key(tpAniSirGlobal pMac, uint32_t sessionId,
9435 tCsrRoamSetKey *pSetKey, uint32_t roamId)
9436{
9437 CDF_STATUS status;
9438
9439 if (!csr_is_set_key_allowed(pMac, sessionId)) {
9440 status = CDF_STATUS_CSR_WRONG_STATE;
9441 } else {
9442 status =
9443 csr_roam_issue_set_key_command(pMac, sessionId, pSetKey, roamId);
9444 }
9445 return status;
9446}
9447
9448/*
9449 Prepare a filter base on a profile for parsing the scan results.
9450 Upon successful return, caller MUST call csr_free_scan_filter on
9451 pScanFilter when it is done with the filter.
9452 */
9453CDF_STATUS
9454csr_roam_prepare_filter_from_profile(tpAniSirGlobal mac_ctx,
9455 tCsrRoamProfile *profile,
9456 tCsrScanResultFilter *scan_fltr)
9457{
9458 CDF_STATUS status = CDF_STATUS_SUCCESS;
9459 uint32_t size = 0;
9460 uint8_t idx = 0;
9461 tCsrChannelInfo *fltr_ch_info = &scan_fltr->ChannelInfo;
9462 tCsrChannelInfo *profile_ch_info = &profile->ChannelInfo;
9463 struct roam_ext_params *roam_params;
9464 uint8_t i;
9465
9466 roam_params = &mac_ctx->roam.configParam.roam_params;
9467
9468 if (profile->BSSIDs.numOfBSSIDs) {
9469 size = sizeof(struct cdf_mac_addr) * profile->BSSIDs.numOfBSSIDs;
9470 scan_fltr->BSSIDs.bssid = cdf_mem_malloc(size);
9471 if (NULL == scan_fltr->BSSIDs.bssid) {
9472 status = CDF_STATUS_E_NOMEM;
9473 goto free_filter;
9474 }
9475 scan_fltr->BSSIDs.numOfBSSIDs = profile->BSSIDs.numOfBSSIDs;
9476 cdf_mem_copy(scan_fltr->BSSIDs.bssid,
9477 profile->BSSIDs.bssid, size);
9478 }
9479
9480 if (profile->SSIDs.numOfSSIDs) {
9481 if (!CSR_IS_WDS_STA(profile)) {
9482 scan_fltr->SSIDs.numOfSSIDs = profile->SSIDs.numOfSSIDs;
9483 } else {
9484 /*
9485 * For WDS station we always use idx 1 for self SSID.
9486 * Index 0 for peer's SSID that we want to join
9487 */
9488 scan_fltr->SSIDs.numOfSSIDs = 1;
9489 }
9490 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
9491 FL("No of Allowed List:%d"),
9492 roam_params->num_ssid_allowed_list);
9493 if (scan_fltr->scan_filter_for_roam
9494 && roam_params->num_ssid_allowed_list) {
9495 scan_fltr->SSIDs.numOfSSIDs =
9496 roam_params->num_ssid_allowed_list;
9497 size = sizeof(tCsrSSIDInfo) *
9498 scan_fltr->SSIDs.numOfSSIDs;
9499 scan_fltr->SSIDs.SSIDList = cdf_mem_malloc(size);
9500 if (NULL == scan_fltr->SSIDs.SSIDList)
9501 status = CDF_STATUS_E_FAILURE;
9502 else
9503 status = CDF_STATUS_SUCCESS;
9504 if (!CDF_IS_STATUS_SUCCESS(status))
9505 goto free_filter;
9506 for (i = 0;
9507 i < roam_params->num_ssid_allowed_list;
9508 i++) {
9509 cdf_mem_copy((void *)
9510 scan_fltr->SSIDs.SSIDList[i].SSID.ssId,
9511 roam_params->ssid_allowed_list[i].ssId,
9512 roam_params->ssid_allowed_list[i].length);
9513 scan_fltr->SSIDs.SSIDList[i].SSID.length =
9514 roam_params->ssid_allowed_list[i].length;
9515 scan_fltr->SSIDs.SSIDList[i].handoffPermitted =
9516 1;
9517 scan_fltr->SSIDs.SSIDList[i].ssidHidden = 0;
9518 }
9519 } else {
9520 size = sizeof(tCsrSSIDInfo) *
9521 profile->SSIDs.numOfSSIDs;
9522 scan_fltr->SSIDs.SSIDList = cdf_mem_malloc(size);
9523 if (NULL == scan_fltr->SSIDs.SSIDList) {
9524 status = CDF_STATUS_E_NOMEM;
9525 goto free_filter;
9526 }
9527 cdf_mem_copy(scan_fltr->SSIDs.SSIDList,
9528 profile->SSIDs.SSIDList, size);
9529 }
9530 }
9531
9532 if (!profile_ch_info->ChannelList
9533 || (profile_ch_info->ChannelList[0] == 0)) {
9534 fltr_ch_info->numOfChannels = 0;
9535 fltr_ch_info->ChannelList = NULL;
9536 } else if (profile_ch_info->numOfChannels) {
9537 fltr_ch_info->numOfChannels = 0;
9538 fltr_ch_info->ChannelList =
9539 cdf_mem_malloc(sizeof(*(fltr_ch_info->ChannelList)) *
9540 profile_ch_info->numOfChannels);
9541 if (NULL == fltr_ch_info->ChannelList) {
9542 status = CDF_STATUS_E_NOMEM;
9543 goto free_filter;
9544 }
9545
9546 for (idx = 0; idx < profile_ch_info->numOfChannels; idx++) {
9547 if (csr_roam_is_channel_valid(mac_ctx,
9548 profile_ch_info->ChannelList[idx])) {
9549 fltr_ch_info->
9550 ChannelList[fltr_ch_info->numOfChannels]
9551 = profile_ch_info->ChannelList[idx];
9552 fltr_ch_info->numOfChannels++;
9553 } else {
9554 sms_log(mac_ctx, LOG1,
9555 FL("Channel (%d) is invalid"),
9556 profile_ch_info->ChannelList[idx]);
9557 }
9558 }
9559 } else {
9560 sms_log(mac_ctx, LOGE, FL("Channel list empty"));
9561 status = CDF_STATUS_E_FAILURE;
9562 goto free_filter;
9563 }
9564 scan_fltr->uapsd_mask = profile->uapsd_mask;
9565 scan_fltr->authType = profile->AuthType;
9566 scan_fltr->EncryptionType = profile->EncryptionType;
9567 scan_fltr->mcEncryptionType = profile->mcEncryptionType;
9568 scan_fltr->BSSType = profile->BSSType;
9569 scan_fltr->phyMode = profile->phyMode;
9570#ifdef FEATURE_WLAN_WAPI
9571 /*
9572 * check if user asked for WAPI with 11n or auto mode, in that
9573 * case modify the phymode to 11g
9574 */
9575 if (csr_is_profile_wapi(profile)) {
9576 if (scan_fltr->phyMode & eCSR_DOT11_MODE_11n)
9577 scan_fltr->phyMode &= ~eCSR_DOT11_MODE_11n;
9578 if (scan_fltr->phyMode & eCSR_DOT11_MODE_AUTO)
9579 scan_fltr->phyMode &= ~eCSR_DOT11_MODE_AUTO;
9580 if (!scan_fltr->phyMode)
9581 scan_fltr->phyMode = eCSR_DOT11_MODE_11g;
9582 }
9583#endif /* FEATURE_WLAN_WAPI */
9584 /*Save the WPS info */
9585 scan_fltr->bWPSAssociation = profile->bWPSAssociation;
9586 scan_fltr->bOSENAssociation = profile->bOSENAssociation;
9587 if (profile->countryCode[0]) {
9588 /*
9589 * This causes the matching function to use countryCode as one
9590 * of the criteria.
9591 */
9592 cdf_mem_copy(scan_fltr->countryCode, profile->countryCode,
9593 WNI_CFG_COUNTRY_CODE_LEN);
9594 }
9595#ifdef WLAN_FEATURE_VOWIFI_11R
9596 if (profile->MDID.mdiePresent) {
9597 scan_fltr->MDID.mdiePresent = 1;
9598 scan_fltr->MDID.mobilityDomain = profile->MDID.mobilityDomain;
9599 }
9600#endif
9601
9602#ifdef WLAN_FEATURE_11W
9603 /* Management Frame Protection */
9604 scan_fltr->MFPEnabled = profile->MFPEnabled;
9605 scan_fltr->MFPRequired = profile->MFPRequired;
9606 scan_fltr->MFPCapable = profile->MFPCapable;
9607#endif
9608 scan_fltr->csrPersona = profile->csrPersona;
9609
9610free_filter:
9611 if (!CDF_IS_STATUS_SUCCESS(status))
9612 csr_free_scan_filter(mac_ctx, scan_fltr);
9613
9614 return status;
9615}
9616
9617bool csr_roam_issue_wm_status_change(tpAniSirGlobal pMac, uint32_t sessionId,
9618 eCsrRoamWmStatusChangeTypes Type,
9619 tSirSmeRsp *pSmeRsp)
9620{
9621 bool fCommandQueued = false;
9622 tSmeCmd *pCommand;
9623 do {
9624 /* Validate the type is ok... */
9625 if ((eCsrDisassociated != Type)
9626 && (eCsrDeauthenticated != Type))
9627 break;
9628 pCommand = csr_get_command_buffer(pMac);
9629 if (!pCommand) {
9630 sms_log(pMac, LOGE, FL(" fail to get command buffer"));
9631 break;
9632 }
9633 /* Change the substate in case it is waiting for key */
9634 if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
9635 csr_roam_stop_wait_for_key_timer(pMac);
9636 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
9637 sessionId);
9638 }
9639 pCommand->command = eSmeCommandWmStatusChange;
9640 pCommand->sessionId = (uint8_t) sessionId;
9641 pCommand->u.wmStatusChangeCmd.Type = Type;
9642 if (eCsrDisassociated == Type) {
9643 cdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
9644 DisassocIndMsg, pSmeRsp,
9645 sizeof(pCommand->u.wmStatusChangeCmd.u.
9646 DisassocIndMsg));
9647 } else {
9648 cdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
9649 DeauthIndMsg, pSmeRsp,
9650 sizeof(pCommand->u.wmStatusChangeCmd.u.
9651 DeauthIndMsg));
9652 }
9653 if (CDF_IS_STATUS_SUCCESS
9654 (csr_queue_sme_command(pMac, pCommand, true))) {
9655 fCommandQueued = true;
9656 } else {
9657 sms_log(pMac, LOGE, FL(" fail to send message "));
9658 csr_release_command_wm_status_change(pMac, pCommand);
9659 }
9660
9661 /* AP has issued Dissac/Deauth, Set the operating mode value to configured value */
9662 csr_set_default_dot11_mode(pMac);
9663 } while (0);
9664 return fCommandQueued;
9665}
9666
9667static CDF_STATUS csr_send_snr_request(void *pGetRssiReq)
9668{
9669 void *wma_handle;
9670
9671 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
9672 if (!wma_handle) {
9673 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9674 "wma_handle is NULL");
9675 return CDF_STATUS_E_FAILURE;
9676 }
9677
9678 if (CDF_STATUS_SUCCESS !=
9679 wma_send_snr_request(wma_handle, pGetRssiReq)) {
9680 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9681 "Failed to Trigger wma stats request");
9682 return CDF_STATUS_E_FAILURE;
9683 }
9684
9685 /* dont send success, otherwise call back
9686 * will released with out values */
9687 return CDF_STATUS_E_BUSY;
9688}
9689
9690static void csr_update_rssi(tpAniSirGlobal pMac, void *pMsg)
9691{
9692 int8_t rssi = 0;
9693 tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsg;
9694 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
9695 if (pGetRssiReq) {
9696 if (NULL != pGetRssiReq->p_cds_context) {
9697 cdf_status = csr_send_snr_request(pGetRssiReq);
9698 } else {
9699 sms_log(pMac, LOGE,
9700 FL("pGetRssiReq->p_cds_context is NULL"));
9701 return;
9702 }
9703
9704 if (NULL != pGetRssiReq->rssiCallback) {
9705 if (cdf_status != CDF_STATUS_E_BUSY)
9706 ((tCsrRssiCallback) (pGetRssiReq->rssiCallback))
9707 (rssi, pGetRssiReq->staId,
9708 pGetRssiReq->pDevContext);
9709 else
9710 sms_log(pMac, LOG1,
9711 FL
9712 ("rssi request is posted. waiting for reply"));
9713 } else {
9714 sms_log(pMac, LOGE,
9715 FL("pGetRssiReq->rssiCallback is NULL"));
9716 return;
9717 }
9718 } else {
9719 sms_log(pMac, LOGE, FL("pGetRssiReq is NULL"));
9720 }
9721 return;
9722
9723}
9724
9725static void csr_update_snr(tpAniSirGlobal pMac, void *pMsg)
9726{
9727 tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg;
9728
9729 if (pGetSnrReq) {
9730 if (CDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) {
9731 sms_log(pMac, LOGE, FL("Error in wma_get_snr"));
9732 return;
9733 }
9734
9735 } else {
9736 sms_log(pMac, LOGE, FL("pGetSnrReq is NULL"));
9737 }
9738 return;
9739}
9740
9741#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
9742void csr_tsm_stats_rsp_processor(tpAniSirGlobal pMac, void *pMsg)
9743{
9744 tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg;
9745
9746 if (NULL != pTsmStatsRsp) {
9747 /* Get roam Rssi request is backed up and passed back to the response,
9748 Extract the request message to fetch callback */
9749 tpAniGetTsmStatsReq reqBkp
9750 = (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq;
9751
9752 if (NULL != reqBkp) {
9753 if (NULL != reqBkp->tsmStatsCallback) {
9754 ((tCsrTsmStatsCallback)
9755 (reqBkp->tsmStatsCallback))(pTsmStatsRsp->
9756 tsmMetrics,
9757 pTsmStatsRsp->
9758 staId,
9759 reqBkp->
9760 pDevContext);
9761 reqBkp->tsmStatsCallback = NULL;
9762 }
9763 cdf_mem_free(reqBkp);
9764 pTsmStatsRsp->tsmStatsReq = NULL;
9765 } else {
9766 sms_log(pMac, LOGE, FL("reqBkp is NULL"));
9767 if (NULL != reqBkp) {
9768 cdf_mem_free(reqBkp);
9769 pTsmStatsRsp->tsmStatsReq = NULL;
9770 }
9771 }
9772 } else {
9773 sms_log(pMac, LOGE, FL("pTsmStatsRsp is NULL"));
9774 }
9775 return;
9776}
9777
9778void csr_send_ese_adjacent_ap_rep_ind(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
9779{
9780 uint32_t roamTS2 = 0;
9781 tCsrRoamInfo roamInfo;
9782 tpPESession pSessionEntry = NULL;
9783 uint8_t sessionId = CSR_SESSION_ID_INVALID;
9784
9785 if (NULL == pSession) {
9786 sms_log(pMac, LOGE, FL("pSession is NULL"));
9787 return;
9788 }
9789
9790 roamTS2 = cdf_mc_timer_get_system_time();
9791 roamInfo.tsmRoamDelay = roamTS2 - pSession->roamTS1;
9792 sms_log(pMac, LOG1, "Bssid(" MAC_ADDRESS_STR ") Roaming Delay(%u ms)",
9793 MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes),
9794 roamInfo.tsmRoamDelay);
9795
9796 pSessionEntry = pe_find_session_by_bssid(pMac,
9797 pSession->connectedProfile.bssid.bytes,
9798 &sessionId);
9799 if (NULL == pSessionEntry) {
9800 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
9801 return;
9802 }
9803
9804 pSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly
9805 = roamInfo.tsmRoamDelay;
9806
9807 csr_roam_call_callback(pMac, pSession->sessionId, &roamInfo,
9808 0, eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0);
9809}
9810#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
9811
9812CDF_STATUS csr_send_reset_ap_caps_changed(tpAniSirGlobal pMac, tSirMacAddr *bssId)
9813{
9814 tpSirResetAPCapsChange pMsg;
9815 uint16_t len;
9816 CDF_STATUS status = CDF_STATUS_SUCCESS;
9817
9818 /* Create the message and send to lim */
9819 len = sizeof(tSirResetAPCapsChange);
9820 pMsg = cdf_mem_malloc(len);
9821 if (NULL == pMsg)
9822 status = CDF_STATUS_E_NOMEM;
9823 else
9824 status = CDF_STATUS_SUCCESS;
9825 if (CDF_IS_STATUS_SUCCESS(status)) {
9826 cdf_mem_set(pMsg, sizeof(tSirResetAPCapsChange), 0);
9827 pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED;
9828 pMsg->length = len;
9829 cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
9830 sms_log(pMac, LOG1,
9831 FL("CSR reset caps change for Bssid= " MAC_ADDRESS_STR),
9832 MAC_ADDR_ARRAY(pMsg->bssId));
9833 status = cds_send_mb_message_to_mac(pMsg);
9834 } else {
9835 sms_log(pMac, LOGE, FL("Memory allocation failed\n"));
9836 }
9837 return status;
9838}
9839
9840static void
9841csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
9842{
9843 tCsrRoamSession *session;
9844 uint32_t sessionId = CSR_SESSION_ID_INVALID;
9845 CDF_STATUS status;
9846 tCsrRoamInfo *roam_info_ptr = NULL;
9847 tSirSmeAssocInd *pAssocInd;
9848 tCsrRoamInfo roam_info;
9849 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
9850
9851 sms_log(mac_ctx, LOG1, FL("Receive WNI_SME_ASSOC_IND from SME"));
9852 pAssocInd = (tSirSmeAssocInd *) msg_ptr;
9853 status = csr_roam_get_session_id_from_bssid(mac_ctx,
9854 (struct cdf_mac_addr *) pAssocInd->bssId, &sessionId);
9855 if (!CDF_IS_STATUS_SUCCESS(status)) {
9856 sms_log(mac_ctx, LOG1,
9857 FL("Couldn't find session_id for given BSSID"));
9858 return;
9859 }
9860 session = CSR_GET_SESSION(mac_ctx, sessionId);
9861 if (!session) {
9862 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
9863 return;
9864 }
9865 roam_info_ptr = &roam_info;
9866 /* Required for indicating the frames to upper layer */
9867 roam_info_ptr->assocReqLength = pAssocInd->assocReqLength;
9868 roam_info_ptr->assocReqPtr = pAssocInd->assocReqPtr;
9869 roam_info_ptr->beaconPtr = pAssocInd->beaconPtr;
9870 roam_info_ptr->beaconLength = pAssocInd->beaconLength;
9871 roam_info_ptr->statusCode = eSIR_SME_SUCCESS;
9872 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
9873 roam_info_ptr->staId = (uint8_t) pAssocInd->staId;
9874 roam_info_ptr->rsnIELen = (uint8_t) pAssocInd->rsnIE.length;
9875 roam_info_ptr->prsnIE = pAssocInd->rsnIE.rsnIEdata;
9876#ifdef FEATURE_WLAN_WAPI
9877 roam_info_ptr->wapiIELen = (uint8_t) pAssocInd->wapiIE.length;
9878 roam_info_ptr->pwapiIE = pAssocInd->wapiIE.wapiIEdata;
9879#endif
9880 roam_info_ptr->addIELen = (uint8_t) pAssocInd->addIE.length;
9881 roam_info_ptr->paddIE = pAssocInd->addIE.addIEdata;
9882 cdf_mem_copy(roam_info_ptr->peerMac.bytes,
9883 pAssocInd->peerMacAddr,
9884 sizeof(tSirMacAddr));
9885 cdf_mem_copy(roam_info_ptr->bssid.bytes,
9886 pAssocInd->bssId,
9887 sizeof(struct cdf_mac_addr));
9888 roam_info_ptr->wmmEnabledSta = pAssocInd->wmmEnabledSta;
9889 roam_info_ptr->timingMeasCap = pAssocInd->timingMeasCap;
9890 cdf_mem_copy(&roam_info_ptr->chan_info,
9891 &pAssocInd->chan_info,
9892 sizeof(tSirSmeChanInfo));
9893 if (CSR_IS_WDS_AP(roam_info_ptr->u.pConnectedProfile))
9894 status = csr_roam_call_callback(mac_ctx, sessionId,
9895 roam_info_ptr, 0, eCSR_ROAM_WDS_IND,
9896 eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);
9897 if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)) {
9898 if (session->pCurRoamProfile &&
9899 CSR_IS_ENC_TYPE_STATIC(
9900 session->pCurRoamProfile->negotiatedUCEncryptionType)) {
9901 /* NO keys... these key parameters don't matter. */
9902 csr_roam_issue_set_context_req(mac_ctx, sessionId,
9903 session->pCurRoamProfile->negotiatedUCEncryptionType,
9904 session->pConnectBssDesc,
9905 &(roam_info_ptr->peerMac.bytes),
9906 false, true, eSIR_TX_RX, 0, 0, NULL, 0);
9907 roam_info_ptr->fAuthRequired = false;
9908 } else {
9909 roam_info_ptr->fAuthRequired = true;
9910 }
9911 status = csr_roam_call_callback(mac_ctx, sessionId,
9912 roam_info_ptr, 0, eCSR_ROAM_INFRA_IND,
9913 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
9914 if (!CDF_IS_STATUS_SUCCESS(status))
9915 /* Refused due to Mac filtering */
9916 roam_info_ptr->statusCode = eSIR_SME_ASSOC_REFUSED;
9917 }
9918
9919 /* Send Association completion message to PE */
9920 status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status);
9921 /*
9922 * send a message to CSR itself just to avoid the EAPOL frames going
9923 * OTA before association response
9924 */
9925 if (CSR_IS_WDS_AP(roam_info_ptr->u.pConnectedProfile)) {
9926 status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
9927 pAssocInd, status, sessionId);
9928 } else if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)
9929 && (roam_info_ptr->statusCode != eSIR_SME_ASSOC_REFUSED)) {
9930 roam_info_ptr->fReassocReq = pAssocInd->reassocReq;
9931 status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
9932 pAssocInd, status, sessionId);
9933 }
9934}
9935
9936static void
9937csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
9938{
9939 tCsrRoamSession *session;
9940 uint32_t sessionId = CSR_SESSION_ID_INVALID;
9941 CDF_STATUS status;
9942 tCsrRoamInfo *roam_info_ptr = NULL;
9943 tSirSmeDisassocInd *pDisassocInd;
9944 tSmeCmd cmd;
9945 tCsrRoamInfo roam_info;
9946
9947 /*
9948 * Check if AP dis-associated us because of MIC failure. If so,
9949 * then we need to take action immediately and not wait till the
9950 * the WmStatusChange requests is pushed and processed
9951 */
9952 pDisassocInd = (tSirSmeDisassocInd *) msg_ptr;
9953 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
9954 status = csr_roam_get_session_id_from_bssid(mac_ctx,
9955 (struct cdf_mac_addr *) pDisassocInd->bssId, &sessionId);
9956 if (!CDF_IS_STATUS_SUCCESS(status)) {
9957 sms_log(mac_ctx, LOGE, FL("Session Id not found for BSSID "
9958 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pDisassocInd->bssId));
9959 return;
9960 }
9961
9962 sms_log(mac_ctx, LOGE,
9963 FL("DISASSOCIATION Indication from MAC for session %d "),
9964 sessionId);
9965 sms_log(mac_ctx, LOGE,
9966 FL("DISASSOCIATION from peer =" MAC_ADDRESS_STR
9967 " " " reason = %d status = %d "),
9968 MAC_ADDR_ARRAY(pDisassocInd->peerMacAddr),
9969 pDisassocInd->reasonCode,
9970 pDisassocInd->statusCode);
9971 /*
9972 * If we are in neighbor preauth done state then on receiving
9973 * disassoc or deauth we dont roam instead we just disassoc
9974 * from current ap and then go to disconnected state
9975 * This happens for ESE and 11r FT connections ONLY.
9976 */
9977#ifdef WLAN_FEATURE_VOWIFI_11R
9978 if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
9979 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
9980 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
9981 mac_ctx, sessionId);
9982#endif
9983#ifdef FEATURE_WLAN_ESE
9984 if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
9985 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
9986 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
9987 mac_ctx, sessionId);
9988#endif
9989#ifdef FEATURE_WLAN_LFR
9990 if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
9991 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
9992 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
9993 mac_ctx, sessionId);
9994#endif
9995 session = CSR_GET_SESSION(mac_ctx, sessionId);
9996 if (!session) {
9997 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
9998 return;
9999 }
10000 if (csr_is_conn_state_infra(mac_ctx, sessionId))
10001 session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
10002#ifndef WLAN_MDM_CODE_REDUCTION_OPT
10003 sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
10004 SME_QOS_CSR_DISCONNECT_IND, NULL);
10005#endif
10006 csr_roam_link_down(mac_ctx, sessionId);
10007 csr_roam_issue_wm_status_change(mac_ctx, sessionId,
10008 eCsrDisassociated, msg_ptr);
10009 if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
10010 roam_info_ptr = &roam_info;
10011 roam_info_ptr->statusCode = pDisassocInd->statusCode;
10012 roam_info_ptr->reasonCode = pDisassocInd->reasonCode;
10013 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
10014 roam_info_ptr->staId = (uint8_t) pDisassocInd->staId;
10015 cdf_mem_copy(roam_info_ptr->peerMac.bytes,
10016 pDisassocInd->peerMacAddr,
10017 sizeof(tSirMacAddr));
10018 cdf_mem_copy(&roam_info_ptr->bssid.bytes,
10019 pDisassocInd->bssId,
10020 sizeof(struct cdf_mac_addr));
10021 status = csr_roam_call_callback(mac_ctx, sessionId,
10022 roam_info_ptr, 0,
10023 eCSR_ROAM_INFRA_IND,
10024 eCSR_ROAM_RESULT_DISASSOC_IND);
10025 /*
10026 * STA/P2P client got disassociated so remove any pending
10027 * deauth commands in sme pending list
10028 */
10029 cmd.command = eSmeCommandRoam;
10030 cmd.sessionId = (uint8_t) sessionId;
10031 cmd.u.roamCmd.roamReason = eCsrForcedDeauthSta;
10032 cdf_mem_copy(cmd.u.roamCmd.peerMac,
10033 pDisassocInd->peerMacAddr,
10034 sizeof(tSirMacAddr));
10035 csr_roam_remove_duplicate_command(mac_ctx, sessionId, &cmd,
10036 eCsrForcedDeauthSta);
10037 }
10038}
10039
10040static void
10041csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10042{
10043 tCsrRoamSession *session;
10044 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10045 CDF_STATUS status;
10046 tCsrRoamInfo *roam_info_ptr = NULL;
10047 tSirSmeDeauthInd *pDeauthInd;
10048 tCsrRoamInfo roam_info;
10049
10050 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10051 sms_log(mac_ctx, LOG1, FL("DEAUTHENTICATION Indication from MAC"));
10052 pDeauthInd = (tpSirSmeDeauthInd) msg_ptr;
10053 status = csr_roam_get_session_id_from_bssid(mac_ctx,
10054 (struct cdf_mac_addr *) pDeauthInd->
10055 bssId, &sessionId);
10056 if (!CDF_IS_STATUS_SUCCESS(status))
10057 return;
10058 /* If we are in neighbor preauth done state then on receiving
10059 * disassoc or deauth we dont roam instead we just disassoc
10060 * from current ap and then go to disconnected state
10061 * This happens for ESE and 11r FT connections ONLY.
10062 */
10063#ifdef WLAN_FEATURE_VOWIFI_11R
10064 if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
10065 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
10066 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
10067 mac_ctx, sessionId);
10068#endif
10069#ifdef FEATURE_WLAN_ESE
10070 if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
10071 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
10072 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
10073 mac_ctx, sessionId);
10074#endif
10075#ifdef FEATURE_WLAN_LFR
10076 if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
10077 (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
10078 csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
10079 mac_ctx, sessionId);
10080#endif
10081 session = CSR_GET_SESSION(mac_ctx, sessionId);
10082 if (!session) {
10083 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
10084 return;
10085 }
10086
10087 if (csr_is_conn_state_infra(mac_ctx, sessionId))
10088 session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
10089#ifndef WLAN_MDM_CODE_REDUCTION_OPT
10090 sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
10091 SME_QOS_CSR_DISCONNECT_IND, NULL);
10092#endif
10093 csr_roam_link_down(mac_ctx, sessionId);
10094 csr_roam_issue_wm_status_change(mac_ctx, sessionId,
10095 eCsrDeauthenticated,
10096 msg_ptr);
10097 if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
10098 roam_info_ptr = &roam_info;
10099 roam_info_ptr->statusCode = pDeauthInd->statusCode;
10100 roam_info_ptr->reasonCode = pDeauthInd->reasonCode;
10101 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
10102 roam_info_ptr->staId = (uint8_t) pDeauthInd->staId;
10103 cdf_mem_copy(roam_info_ptr->peerMac.bytes,
10104 pDeauthInd->peerMacAddr,
10105 sizeof(tSirMacAddr));
10106 cdf_mem_copy(&roam_info_ptr->bssid.bytes,
10107 pDeauthInd->bssId,
10108 sizeof(struct cdf_mac_addr));
10109 status = csr_roam_call_callback(mac_ctx, sessionId,
10110 roam_info_ptr, 0,
10111 eCSR_ROAM_INFRA_IND,
10112 eCSR_ROAM_RESULT_DEAUTH_IND);
10113 }
10114}
10115
10116static void
10117csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10118{
10119 tCsrRoamSession *session;
10120 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10121 CDF_STATUS status;
10122 tpSirSmeSwitchChannelInd pSwitchChnInd;
10123
10124 /* in case of STA, the SWITCH_CHANNEL originates from its AP */
10125 sms_log(mac_ctx, LOGW, FL("eWNI_SME_SWITCH_CHL_IND from SME"));
10126 pSwitchChnInd = (tpSirSmeSwitchChannelInd) msg_ptr;
10127 /* Update with the new channel id. The channel id is hidden in the
10128 * statusCode.
10129 */
10130 status = csr_roam_get_session_id_from_bssid(mac_ctx,
10131 (struct cdf_mac_addr *) pSwitchChnInd->bssId, &sessionId);
10132 if (CDF_IS_STATUS_SUCCESS(status)) {
10133 session = CSR_GET_SESSION(mac_ctx, sessionId);
10134 if (!session) {
10135 sms_log(mac_ctx, LOGE,
10136 FL("session %d not found"), sessionId);
10137 return;
10138 }
10139 session->connectedProfile.operationChannel =
10140 (uint8_t) pSwitchChnInd->newChannelId;
10141 if (session->pConnectBssDesc) {
10142 session->pConnectBssDesc->channelId =
10143 (uint8_t) pSwitchChnInd->newChannelId;
10144 }
10145 }
10146}
10147
10148static void
10149csr_roam_chk_lnk_deauth_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10150{
10151 tCsrRoamSession *session;
10152 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10153 CDF_STATUS status;
10154 tCsrRoamInfo *roam_info_ptr = NULL;
10155 tSirSmeDeauthRsp *pDeauthRsp = (tSirSmeDeauthRsp *) msg_ptr;
10156 tCsrRoamInfo roam_info;
10157
10158 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10159 sms_log(mac_ctx, LOGW, FL("eWNI_SME_DEAUTH_RSP from SME"));
10160 sessionId = pDeauthRsp->sessionId;
10161 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
10162 return;
10163 session = CSR_GET_SESSION(mac_ctx, sessionId);
10164 if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
10165 roam_info_ptr = &roam_info;
10166 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
10167 cdf_mem_copy(roam_info_ptr->peerMac.bytes,
10168 pDeauthRsp->peerMacAddr,
10169 sizeof(tSirMacAddr));
10170 roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
10171 roam_info_ptr->statusCode = pDeauthRsp->statusCode;
10172 status = csr_roam_call_callback(mac_ctx, sessionId,
10173 roam_info_ptr, 0,
10174 eCSR_ROAM_LOSTLINK,
10175 eCSR_ROAM_RESULT_FORCED);
10176 }
10177}
10178
10179static void
10180csr_roam_chk_lnk_disassoc_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10181{
10182 tCsrRoamSession *session;
10183 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10184 CDF_STATUS status;
10185 tCsrRoamInfo *roam_info_ptr = NULL;
10186 tCsrRoamInfo roam_info;
10187 /*
10188 * session id is invalid here so cant use it to access the array
10189 * curSubstate as index
10190 */
10191 tSirSmeDisassocRsp *pDisassocRsp = (tSirSmeDisassocRsp *) msg_ptr;
10192
10193 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10194 sms_log(mac_ctx, LOGW, FL("eWNI_SME_DISASSOC_RSP from SME "));
10195 sessionId = pDisassocRsp->sessionId;
10196 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
10197 return;
10198 session = CSR_GET_SESSION(mac_ctx, sessionId);
10199 if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
10200 roam_info_ptr = &roam_info;
10201 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
10202 cdf_mem_copy(roam_info_ptr->peerMac.bytes,
10203 pDisassocRsp->peerMacAddr,
10204 sizeof(tSirMacAddr));
10205 roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
10206 roam_info_ptr->statusCode = pDisassocRsp->statusCode;
10207 status = csr_roam_call_callback(mac_ctx, sessionId,
10208 roam_info_ptr, 0,
10209 eCSR_ROAM_LOSTLINK,
10210 eCSR_ROAM_RESULT_FORCED);
10211 }
10212}
10213
10214#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10215static void
10216csr_roam_diag_mic_fail(tpAniSirGlobal mac_ctx, uint32_t sessionId)
10217{
10218 WLAN_HOST_DIAG_EVENT_DEF(secEvent,
10219 host_event_wlan_security_payload_type);
10220 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, sessionId);
10221 if (!session) {
10222 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
10223 return;
10224 }
10225 cdf_mem_set(&secEvent, sizeof(host_event_wlan_security_payload_type),
10226 0);
10227 secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR;
10228 secEvent.encryptionModeMulticast =
10229 (uint8_t) diag_enc_type_from_csr_type(
10230 session->connectedProfile.mcEncryptionType);
10231 secEvent.encryptionModeUnicast =
10232 (uint8_t) diag_enc_type_from_csr_type(
10233 session->connectedProfile.EncryptionType);
10234 secEvent.authMode =
10235 (uint8_t) diag_auth_type_from_csr_type(
10236 session->connectedProfile.AuthType);
10237 cdf_mem_copy(secEvent.bssid, session->connectedProfile.bssid.bytes,
10238 CDF_MAC_ADDR_SIZE);
10239 WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
10240}
10241#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10242
10243static void
10244csr_roam_chk_lnk_mic_fail_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10245{
10246 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10247 CDF_STATUS status;
10248 tCsrRoamInfo *roam_info_ptr = NULL;
10249 tCsrRoamInfo roam_info;
10250 tpSirSmeMicFailureInd pMicInd = (tpSirSmeMicFailureInd) msg_ptr;
10251 eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
10252
10253 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10254 status = csr_roam_get_session_id_from_bssid(mac_ctx,
10255 (struct cdf_mac_addr *) pMicInd->bssId, &sessionId);
10256 if (CDF_IS_STATUS_SUCCESS(status)) {
10257 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
10258 roam_info.u.pMICFailureInfo = &pMicInd->info;
10259 roam_info_ptr = &roam_info;
10260 if (pMicInd->info.multicast)
10261 result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP;
10262 else
10263 result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
10264 csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
10265 eCSR_ROAM_MIC_ERROR_IND, result);
10266 }
10267#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10268 csr_roam_diag_mic_fail(mac_ctx, sessionId);
10269#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10270}
10271
10272static void
10273csr_roam_chk_lnk_pbs_probe_req_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10274{
10275 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10276 CDF_STATUS status;
10277 tCsrRoamInfo roam_info;
10278 tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr;
10279
10280 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10281 sms_log(mac_ctx, LOG1, FL("WPS PBC Probe request Indication from SME"));
10282
10283 status = csr_roam_get_session_id_from_bssid(mac_ctx,
10284 (struct cdf_mac_addr *)pProbeReqInd->bssId, &sessionId);
10285 if (CDF_IS_STATUS_SUCCESS(status)) {
10286 cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
10287 roam_info.u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq;
10288 csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
10289 0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
10290 eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
10291 }
10292}
10293
10294#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10295static void
10296csr_roam_diag_joined_new_bss(tpAniSirGlobal mac_ctx,
10297 tSirSmeNewBssInfo *pNewBss)
10298{
10299 host_log_ibss_pkt_type *pIbssLog;
10300 uint32_t bi;
10301 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
10302 LOG_WLAN_IBSS_C);
10303 if (!pIbssLog)
10304 return;
10305 pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING;
10306 if (pNewBss) {
10307 cdf_mem_copy(pIbssLog->bssid, pNewBss->bssId, 6);
10308 if (pNewBss->ssId.length)
10309 cdf_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId,
10310 pNewBss->ssId.length);
10311 pIbssLog->operatingChannel = pNewBss->channelNumber;
10312 }
10313 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(mac_ctx,
10314 WNI_CFG_BEACON_INTERVAL,
10315 &bi)))
10316 /* U8 is not enough for beacon interval */
10317 pIbssLog->beaconInterval = (uint8_t) bi;
10318 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
10319}
10320#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10321
10322static void
10323csr_roam_chk_lnk_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
10324 tSirSmeRsp *msg_ptr)
10325{
10326 tCsrRoamSession *session;
10327 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10328 CDF_STATUS status;
10329 tCsrRoamInfo *roam_info_ptr = NULL;
10330 tSirSmeWmStatusChangeNtf *pStatusChangeMsg;
10331 tCsrRoamInfo roam_info;
10332 tSirSmeApNewCaps *pApNewCaps;
10333 eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
10334 tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
10335 tSirSmeNewBssInfo *pNewBss;
10336 eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED;
10337
10338 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10339 pStatusChangeMsg = (tSirSmeWmStatusChangeNtf *) msg_ptr;
10340 switch (pStatusChangeMsg->statusChangeCode) {
10341 case eSIR_SME_IBSS_ACTIVE:
10342 sessionId = csr_find_ibss_session(mac_ctx);
10343 if (CSR_SESSION_ID_INVALID == sessionId)
10344 break;
10345 session = CSR_GET_SESSION(mac_ctx, sessionId);
10346 if (!session) {
10347 sms_log(mac_ctx, LOGE, FL("session %d not found"),
10348 sessionId);
10349 return;
10350 }
10351 session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED;
10352 if (session->pConnectBssDesc) {
10353 cdf_mem_copy(&roam_info.bssid,
10354 session->pConnectBssDesc->bssId,
10355 sizeof(struct cdf_mac_addr));
10356 roam_info.u.pConnectedProfile =
10357 &session->connectedProfile;
10358 roam_info_ptr = &roam_info;
10359 } else {
10360 sms_log(mac_ctx, LOGE,
10361 FL("CSR: connected BSS is empty"));
10362 }
10363 result = eCSR_ROAM_RESULT_IBSS_CONNECT;
10364 roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
10365 break;
10366
10367 case eSIR_SME_IBSS_INACTIVE:
10368 sessionId = csr_find_ibss_session(mac_ctx);
10369 if (CSR_SESSION_ID_INVALID != sessionId) {
10370 session = CSR_GET_SESSION(mac_ctx, sessionId);
10371 if (!session) {
10372 sms_log(mac_ctx, LOGE,
10373 FL("session %d not found"), sessionId);
10374 return;
10375 }
10376 session->connectState =
10377 eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
10378 result = eCSR_ROAM_RESULT_IBSS_INACTIVE;
10379 roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
10380 }
10381 break;
10382
10383 case eSIR_SME_JOINED_NEW_BSS:
10384 /* IBSS coalescing. */
10385 sms_log(mac_ctx, LOGW,
10386 FL("CSR: eSIR_SME_JOINED_NEW_BSS received from PE"));
10387 sessionId = csr_find_ibss_session(mac_ctx);
10388 if (CSR_SESSION_ID_INVALID == sessionId)
10389 break;
10390 session = CSR_GET_SESSION(mac_ctx, sessionId);
10391 if (!session) {
10392 sms_log(mac_ctx, LOGE, FL("session %d not found"),
10393 sessionId);
10394 return;
10395 }
10396 /* update the connection state information */
10397 pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo;
10398#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10399 csr_roam_diag_joined_new_bss(mac_ctx, pNewBss);
10400#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10401 csr_roam_update_connected_profile_from_new_bss(mac_ctx,
10402 sessionId,
10403 pNewBss);
10404
10405 if ((eCSR_ENCRYPT_TYPE_NONE ==
10406 session->connectedProfile.EncryptionType)) {
10407 csr_roam_issue_set_context_req(mac_ctx,
10408 sessionId,
10409 session->connectedProfile.EncryptionType,
10410 session->pConnectBssDesc,
10411 &Broadcastaddr, false, false,
10412 eSIR_TX_RX, 0, 0, NULL, 0);
10413 }
10414 result = eCSR_ROAM_RESULT_IBSS_COALESCED;
10415 roamStatus = eCSR_ROAM_IBSS_IND;
10416 cdf_mem_copy(&roam_info.bssid, &pNewBss->bssId,
10417 sizeof(struct cdf_mac_addr));
10418 roam_info_ptr = &roam_info;
10419 /* This BSSID is the real BSSID, save it */
10420 if (session->pConnectBssDesc)
10421 cdf_mem_copy(session->pConnectBssDesc->bssId,
10422 &pNewBss->bssId, sizeof(struct cdf_mac_addr));
10423 break;
10424
10425 /*
10426 * detection by LIM that the capabilities of the associated
10427 * AP have changed.
10428 */
10429 case eSIR_SME_AP_CAPS_CHANGED:
10430 pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps;
10431 sms_log(mac_ctx, LOGW,
10432 FL("CSR handling eSIR_SME_AP_CAPS_CHANGED"));
10433 status = csr_roam_get_session_id_from_bssid(mac_ctx,
10434 (struct cdf_mac_addr *)pApNewCaps->bssId, &sessionId);
10435 if (!CDF_IS_STATUS_SUCCESS(status))
10436 break;
10437 if (eCSR_ROAMING_STATE_JOINED ==
10438 mac_ctx->roam.curState[sessionId]
10439 && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC
10440 == mac_ctx->roam.curSubState[sessionId])
10441 || (eCSR_ROAM_SUBSTATE_NONE ==
10442 mac_ctx->roam.curSubState[sessionId])
10443 || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC
10444 == mac_ctx->roam.curSubState[sessionId])
10445 || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC ==
10446 mac_ctx->roam.curSubState[sessionId]))) {
10447 sms_log(mac_ctx, LOGW,
10448 FL("Calling csr_roam_disconnect_internal"));
10449 csr_roam_disconnect_internal(mac_ctx, sessionId,
10450 eCSR_DISCONNECT_REASON_UNSPECIFIED);
10451 } else {
10452 sms_log(mac_ctx, LOGW,
10453 FL("Skipping the new scan as CSR is in state %s and sub-state %s"),
10454 mac_trace_getcsr_roam_state(
10455 mac_ctx->roam.curState[sessionId]),
10456 mac_trace_getcsr_roam_sub_state(
10457 mac_ctx->roam.curSubState[sessionId]));
10458 /* We ignore the caps change event if CSR is not in full
10459 * connected state. Send one event to PE to reset
10460 * limSentCapsChangeNtf Once limSentCapsChangeNtf set
10461 * 0, lim can send sub sequent CAPS change event
10462 * otherwise lim cannot send any CAPS change events to
10463 * SME
10464 */
10465 csr_send_reset_ap_caps_changed(mac_ctx,
10466 &pApNewCaps->bssId);
10467 }
10468 break;
10469
10470 default:
10471 roamStatus = eCSR_ROAM_FAILED;
10472 result = eCSR_ROAM_RESULT_NONE;
10473 break;
10474 } /* end switch on statusChangeCode */
10475 if (eCSR_ROAM_RESULT_NONE != result) {
10476 csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
10477 roamStatus, result);
10478 }
10479}
10480
10481static void
10482csr_roam_chk_lnk_ibss_new_peer_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10483{
10484 tCsrRoamSession *session;
10485 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10486 CDF_STATUS status;
10487 tCsrRoamInfo *roam_info_ptr = NULL;
10488 tSmeIbssPeerInd *pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
10489 tCsrRoamInfo roam_info;
10490#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10491 host_log_ibss_pkt_type *pIbssLog;
10492 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
10493 LOG_WLAN_IBSS_C);
10494 if (pIbssLog) {
10495 pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN;
10496 cdf_mem_copy(pIbssLog->peerMacAddr, &pIbssPeerInd->peerAddr, 6);
10497 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
10498 }
10499#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10500
10501 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10502 sessionId = csr_find_ibss_session(mac_ctx);
10503 if (CSR_SESSION_ID_INVALID == sessionId)
10504 return;
10505 session = CSR_GET_SESSION(mac_ctx, sessionId);
10506 if (!session) {
10507 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
10508 return;
10509 }
10510 /*
10511 * Issue the set Context request to LIM to establish the Unicast STA
10512 * context for the new peer...
10513 */
10514 if (!session->pConnectBssDesc) {
10515 sms_log(mac_ctx, LOGW, FL("CSR: connected BSS is empty"));
10516 goto callback_and_free;
10517 }
10518 cdf_mem_copy(&roam_info.peerMac, pIbssPeerInd->peerAddr,
10519 sizeof(struct cdf_mac_addr));
10520 cdf_mem_copy(&roam_info.bssid, session->pConnectBssDesc->bssId,
10521 sizeof(struct cdf_mac_addr));
10522 if (pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) {
10523 roam_info.pbFrames = cdf_mem_malloc((pIbssPeerInd->mesgLen -
10524 sizeof(tSmeIbssPeerInd)));
10525 if (NULL == roam_info.pbFrames) {
10526 status = CDF_STATUS_E_NOMEM;
10527 } else {
10528 status = CDF_STATUS_SUCCESS;
10529 roam_info.nBeaconLength = pIbssPeerInd->mesgLen -
10530 sizeof(tSmeIbssPeerInd);
10531 cdf_mem_copy(roam_info.pbFrames,
10532 ((uint8_t *) pIbssPeerInd) +
10533 sizeof(tSmeIbssPeerInd),
10534 roam_info.nBeaconLength);
10535 }
10536 roam_info.staId = (uint8_t) pIbssPeerInd->staId;
10537 roam_info.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
10538 roam_info.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
10539 roam_info.pBssDesc = cdf_mem_malloc(
10540 session->pConnectBssDesc->length);
10541 if (NULL == roam_info.pBssDesc) {
10542 status = CDF_STATUS_E_NOMEM;
10543 if (roam_info.pbFrames)
10544 cdf_mem_free(roam_info.pbFrames);
10545 if (roam_info.pBssDesc)
10546 cdf_mem_free(roam_info.pBssDesc);
10547 } else {
10548 status = CDF_STATUS_SUCCESS;
10549 cdf_mem_copy(roam_info.pBssDesc,
10550 session->pConnectBssDesc,
10551 session->pConnectBssDesc->length);
10552 roam_info_ptr = &roam_info;
10553 }
10554 } else {
10555 roam_info_ptr = &roam_info;
10556 }
10557 if ((eCSR_ENCRYPT_TYPE_NONE ==
10558 session->connectedProfile.EncryptionType)) {
10559 /* NO keys. these key parameters don't matter */
10560 csr_roam_issue_set_context_req(mac_ctx, sessionId,
10561 session->connectedProfile.EncryptionType,
10562 session->pConnectBssDesc, &(pIbssPeerInd->peerAddr),
10563 false, true, eSIR_TX_RX, 0, 0, NULL, 0);
10564 }
10565
10566callback_and_free:
10567 /* send up the sec type for the new peer */
10568 if (roam_info_ptr)
10569 roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
10570 csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
10571 eCSR_ROAM_CONNECT_STATUS_UPDATE,
10572 eCSR_ROAM_RESULT_IBSS_NEW_PEER);
10573 if (roam_info_ptr) {
10574 if (roam_info.pbFrames)
10575 cdf_mem_free(roam_info.pbFrames);
10576 if (roam_info.pBssDesc)
10577 cdf_mem_free(roam_info.pBssDesc);
10578 }
10579}
10580
10581static void
10582csr_roam_chk_lnk_ibss_peer_departed_ind(tpAniSirGlobal mac_ctx,
10583 tSirSmeRsp *msg_ptr)
10584{
10585 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10586 tCsrRoamInfo roam_info;
10587 tSmeIbssPeerInd *pIbssPeerInd;
10588
10589 if (NULL == msg_ptr) {
10590 sms_log(mac_ctx, LOGE, FL("IBSS peer ind. message is NULL"));
10591 return;
10592 }
10593 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10594 pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
10595 sessionId = csr_find_ibss_session(mac_ctx);
10596 if (CSR_SESSION_ID_INVALID != sessionId) {
10597#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10598 host_log_ibss_pkt_type *pIbssLog;
10599 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
10600 LOG_WLAN_IBSS_C);
10601 if (pIbssLog) {
10602 pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE;
10603 if (pIbssPeerInd) {
10604 cdf_mem_copy(pIbssLog->peerMacAddr,
10605 &pIbssPeerInd->peerAddr, 6);
10606 }
10607 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
10608 }
10609#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10610 sms_log(mac_ctx, LOGW,
10611 FL("CSR: Peer departed notification from LIM"));
10612 roam_info.staId = (uint8_t) pIbssPeerInd->staId;
10613 roam_info.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
10614 roam_info.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
10615 cdf_mem_copy(&roam_info.peerMac, pIbssPeerInd->peerAddr,
10616 sizeof(struct cdf_mac_addr));
10617 csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
10618 eCSR_ROAM_CONNECT_STATUS_UPDATE,
10619 eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
10620 }
10621}
10622
10623#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10624static void
10625csr_roam_diag_set_ctx_rsp(tpAniSirGlobal mac_ctx,
10626 tCsrRoamSession *session,
10627 tSirSmeSetContextRsp *pRsp)
10628{
10629 WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
10630 host_event_wlan_security_payload_type);
10631 if (eCSR_ENCRYPT_TYPE_NONE ==
10632 session->connectedProfile.EncryptionType)
10633 return;
10634 cdf_mem_set(&setKeyEvent,
10635 sizeof(host_event_wlan_security_payload_type), 0);
10636 if (pRsp->peerMacAddr[0] & 0x01)
10637 setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_RSP;
10638 else
10639 setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_RSP;
10640 setKeyEvent.encryptionModeMulticast =
10641 (uint8_t) diag_enc_type_from_csr_type(
10642 session->connectedProfile.mcEncryptionType);
10643 setKeyEvent.encryptionModeUnicast =
10644 (uint8_t) diag_enc_type_from_csr_type(
10645 session->connectedProfile.EncryptionType);
10646 cdf_mem_copy(setKeyEvent.bssid, session->connectedProfile.bssid.bytes,
10647 CDF_MAC_ADDR_SIZE);
10648 setKeyEvent.authMode =
10649 (uint8_t) diag_auth_type_from_csr_type(
10650 session->connectedProfile.AuthType);
10651 if (eSIR_SME_SUCCESS != pRsp->statusCode)
10652 setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
10653 WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
10654}
10655#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10656
10657static void
10658csr_roam_chk_lnk_set_ctx_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10659{
10660 tCsrRoamSession *session;
10661 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10662 CDF_STATUS status;
10663 tCsrRoamInfo *roam_info_ptr = NULL;
10664 tSmeCmd *cmd;
10665 tCsrRoamInfo roam_info;
10666 eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
10667 tSirSmeSetContextRsp *pRsp = (tSirSmeSetContextRsp *) msg_ptr;
10668 tListElem *entry;
10669 tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
10670
10671 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10672 entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
10673 LL_ACCESS_LOCK);
10674 if (!entry) {
10675 sms_log(mac_ctx, LOGE, FL("CSR: NO commands are ACTIVE ..."));
10676 goto process_pending_n_exit;
10677 }
10678
10679 cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
10680 if (eSmeCommandSetKey != cmd->command) {
10681 sms_log(mac_ctx, LOGE, FL("CSR: setkey cmd is not ACTIVE ..."));
10682 goto process_pending_n_exit;
10683 }
10684 sessionId = cmd->sessionId;
10685 session = CSR_GET_SESSION(mac_ctx, sessionId);
10686 if (!session) {
10687 sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
10688 return;
10689 }
10690#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
10691 csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp);
10692#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
10693 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) {
10694 csr_roam_stop_wait_for_key_timer(mac_ctx);
10695 /* We are done with authentication, whethere succeed or not */
10696 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
10697 sessionId);
10698 /* We do it here because this linkup function is not called
10699 * after association when a key needs to be set.
10700 */
10701 if (csr_is_conn_state_connected_infra(mac_ctx, sessionId))
10702 csr_roam_link_up(mac_ctx,
10703 session->connectedProfile.bssid);
10704 }
10705 if (eSIR_SME_SUCCESS == pRsp->statusCode) {
10706 cdf_mem_copy(&roam_info.peerMac, &pRsp->peerMacAddr,
10707 sizeof(struct cdf_mac_addr));
10708 /* Make sure we install the GTK before indicating to HDD as
10709 * authenticated. This is to prevent broadcast packets go out
10710 * after PTK and before GTK.
10711 */
10712 if (cdf_mem_compare(&Broadcastaddr, pRsp->peerMacAddr,
10713 sizeof(tSirMacAddr))) {
10714 tpSirSetActiveModeSetBncFilterReq pMsg;
10715 pMsg = cdf_mem_malloc(
10716 sizeof(tSirSetActiveModeSetBncFilterReq));
10717 pMsg->messageType = eWNI_SME_SET_BCN_FILTER_REQ;
10718 pMsg->length = sizeof(uint8_t);
10719 pMsg->seesionId = sessionId;
10720 status = cds_send_mb_message_to_mac(pMsg);
10721 result = eCSR_ROAM_RESULT_AUTHENTICATED;
10722 } else {
10723 result = eCSR_ROAM_RESULT_NONE;
10724 }
10725 roam_info_ptr = &roam_info;
10726 } else {
10727 result = eCSR_ROAM_RESULT_FAILURE;
10728 sms_log(mac_ctx, LOGE,
10729 FL("CSR: setkey command failed(%d) PeerMac "
10730 MAC_ADDRESS_STR),
10731 pRsp->statusCode, MAC_ADDR_ARRAY(pRsp->peerMacAddr));
10732 }
10733 csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
10734 cmd->u.setKeyCmd.roamId,
10735 eCSR_ROAM_SET_KEY_COMPLETE, result);
10736 /* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS
10737 * can go ahead and initiate the TSPEC if any are pending
10738 */
10739 sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
10740 SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL);
10741#ifdef FEATURE_WLAN_ESE
10742 /* Send Adjacent AP repot to new AP. */
10743 if (result == eCSR_ROAM_RESULT_AUTHENTICATED
10744 && session->isPrevApInfoValid
10745 && session->connectedProfile.isESEAssoc) {
10746#ifdef FEATURE_WLAN_ESE_UPLOAD
10747 csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session);
10748#else
10749 csr_ese_send_adjacent_ap_rep_msg(mac_ctx, session);
10750#endif
10751 session->isPrevApInfoValid = false;
10752 }
10753#endif
10754 if (csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList, entry,
10755 LL_ACCESS_LOCK))
10756 csr_release_command_set_key(mac_ctx, cmd);
10757
10758process_pending_n_exit:
10759 sme_process_pending_queue(mac_ctx);
10760}
10761
10762
10763static void
10764csr_roam_chk_lnk_max_assoc_exceeded(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
10765{
10766 uint32_t sessionId = CSR_SESSION_ID_INVALID;
10767 tSmeMaxAssocInd *pSmeMaxAssocInd;
10768 tCsrRoamInfo roam_info;
10769
10770 cdf_mem_set(&roam_info, sizeof(roam_info), 0);
10771 pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr;
10772 sms_log(mac_ctx, LOG1,
10773 FL("max assoc have been reached, new peer cannot be accepted"));
10774 sessionId = pSmeMaxAssocInd->sessionId;
10775 roam_info.sessionId = sessionId;
10776 cdf_mem_copy(&roam_info.peerMac, pSmeMaxAssocInd->peerMac,
10777 sizeof(struct cdf_mac_addr));
10778 csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
10779 eCSR_ROAM_INFRA_IND,
10780 eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
10781}
10782
10783void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg)
10784{
10785 if (NULL == pSirMsg) {
10786 sms_log(pMac, LOGE, FL("pSirMsg is NULL"));
10787 return;
10788 }
10789 switch (pSirMsg->messageType) {
10790 case eWNI_SME_ASSOC_IND:
10791 csr_roam_chk_lnk_assoc_ind(pMac, pSirMsg);
10792 break;
10793 case eWNI_SME_DISASSOC_IND:
10794 csr_roam_chk_lnk_disassoc_ind(pMac, pSirMsg);
10795 break;
10796 case eWNI_SME_DEAUTH_IND:
10797 csr_roam_chk_lnk_deauth_ind(pMac, pSirMsg);
10798 break;
10799 case eWNI_SME_SWITCH_CHL_IND:
10800 csr_roam_chk_lnk_swt_ch_ind(pMac, pSirMsg);
10801 break;
10802 case eWNI_SME_DEAUTH_RSP:
10803 csr_roam_chk_lnk_deauth_rsp(pMac, pSirMsg);
10804 break;
10805 case eWNI_SME_DISASSOC_RSP:
10806 csr_roam_chk_lnk_disassoc_rsp(pMac, pSirMsg);
10807 break;
10808 case eWNI_SME_MIC_FAILURE_IND:
10809 csr_roam_chk_lnk_mic_fail_ind(pMac, pSirMsg);
10810 break;
10811 case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
10812 csr_roam_chk_lnk_pbs_probe_req_ind(pMac, pSirMsg);
10813 break;
10814 case eWNI_SME_WM_STATUS_CHANGE_NTF:
10815 csr_roam_chk_lnk_wm_status_change_ntf(pMac, pSirMsg);
10816 break;
10817 case eWNI_SME_IBSS_NEW_PEER_IND:
10818 csr_roam_chk_lnk_ibss_new_peer_ind(pMac, pSirMsg);
10819 break;
10820 case eWNI_SME_IBSS_PEER_DEPARTED_IND:
10821 csr_roam_chk_lnk_ibss_peer_departed_ind(pMac, pSirMsg);
10822 break;
10823 case eWNI_SME_SETCONTEXT_RSP:
10824 csr_roam_chk_lnk_set_ctx_rsp(pMac, pSirMsg);
10825 break;
10826 case eWNI_SME_GET_STATISTICS_RSP:
10827 sms_log(pMac, LOG2, FL("Stats rsp from PE"));
10828 csr_roam_stats_rsp_processor(pMac, pSirMsg);
10829 break;
10830#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
10831 case eWNI_SME_GET_TSM_STATS_RSP:
10832 sms_log(pMac, LOG2, FL("TSM Stats rsp from PE"));
10833 csr_tsm_stats_rsp_processor(pMac, pSirMsg);
10834 break;
10835#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
10836 case eWNI_SME_GET_RSSI_REQ:
10837 sms_log(pMac, LOG2, FL("GetRssiReq from self"));
10838 csr_update_rssi(pMac, pSirMsg);
10839 break;
10840 case eWNI_SME_GET_SNR_REQ:
10841 sms_log(pMac, LOG2, FL("GetSnrReq from self"));
10842 csr_update_snr(pMac, pSirMsg);
10843 break;
10844#ifdef WLAN_FEATURE_VOWIFI_11R
10845 case eWNI_SME_FT_PRE_AUTH_RSP:
10846 csr_roam_ft_pre_auth_rsp_processor(pMac, (tpSirFTPreAuthRsp) pSirMsg);
10847 break;
10848#endif
10849 case eWNI_SME_MAX_ASSOC_EXCEEDED:
10850 csr_roam_chk_lnk_max_assoc_exceeded(pMac, pSirMsg);
10851 break;
10852 case eWNI_SME_CANDIDATE_FOUND_IND:
10853 sms_log(pMac, LOG2, FL("Candidate found indication from PE"));
10854 csr_neighbor_roam_candidate_found_ind_hdlr(pMac, pSirMsg);
10855 break;
10856 case eWNI_SME_HANDOFF_REQ:
10857 sms_log(pMac, LOG2, FL("Handoff Req from self"));
10858 csr_neighbor_roam_handoff_req_hdlr(pMac, pSirMsg);
10859 break;
10860 default:
10861 break;
10862 } /* end switch on message type */
10863}
10864
10865void csr_call_roaming_completion_callback(tpAniSirGlobal pMac,
10866 tCsrRoamSession *pSession,
10867 tCsrRoamInfo *pRoamInfo, uint32_t roamId,
10868 eCsrRoamResult roamResult)
10869{
10870 if (pSession) {
10871 if (pSession->bRefAssocStartCnt) {
10872 pSession->bRefAssocStartCnt--;
10873
10874 if (0 != pSession->bRefAssocStartCnt) {
10875 CDF_ASSERT(pSession->bRefAssocStartCnt == 0);
10876 return;
10877 }
10878 /* Need to call association_completion because there is an assoc_start pending. */
10879 csr_roam_call_callback(pMac, pSession->sessionId, NULL,
10880 roamId,
10881 eCSR_ROAM_ASSOCIATION_COMPLETION,
10882 eCSR_ROAM_RESULT_FAILURE);
10883 }
10884 csr_roam_call_callback(pMac, pSession->sessionId, pRoamInfo,
10885 roamId, eCSR_ROAM_ROAMING_COMPLETION,
10886 roamResult);
10887 } else {
10888 sms_log(pMac, LOGW, FL(" pSession is NULL"));
10889 }
10890}
10891
10892CDF_STATUS csr_roam_start_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
10893 eCsrRoamingReason roamingReason)
10894{
10895 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10896 if (CSR_IS_LOSTLINK_ROAMING(roamingReason) &&
10897 (false == pMac->roam.roamSession[sessionId].fCancelRoaming)) {
10898 status = csr_scan_request_lost_link1(pMac, sessionId);
10899 }
10900 return status;
10901}
10902
10903/* return a bool to indicate whether roaming completed or continue. */
10904bool csr_roam_complete_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
10905 bool fForce, eCsrRoamResult roamResult)
10906{
10907 bool fCompleted = true;
10908 uint32_t roamTime =
10909 (uint32_t) (pMac->roam.configParam.nRoamingTime *
10910 CDF_TICKS_PER_SECOND);
10911 uint32_t curTime = (uint32_t) cdf_mc_timer_get_system_ticks();
10912 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
10913 if (!pSession) {
10914 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
10915 return false;
10916 }
10917 /* Check whether time is up */
10918 if (pSession->fCancelRoaming || fForce ||
10919 ((curTime - pSession->roamingStartTime) > roamTime) ||
10920 eCsrReassocRoaming == pSession->roamingReason ||
10921 eCsrDynamicRoaming == pSession->roamingReason) {
10922 sms_log(pMac, LOGW, FL(" indicates roaming completion"));
10923 if (pSession->fCancelRoaming
10924 && CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason)) {
10925 /* roaming is cancelled, tell HDD to indicate disconnect */
10926 /* Because LIM overload deauth_ind for both deauth frame and missed beacon */
10927 /* we need to use this logic to detinguish it. For missed beacon, LIM set reason */
10928 /* to be eSIR_BEACON_MISSED */
10929 if (eSIR_BEACON_MISSED == pSession->roamingStatusCode) {
10930 roamResult = eCSR_ROAM_RESULT_LOSTLINK;
10931 } else if (eCsrLostlinkRoamingDisassoc ==
10932 pSession->roamingReason) {
10933 roamResult = eCSR_ROAM_RESULT_DISASSOC_IND;
10934 } else if (eCsrLostlinkRoamingDeauth ==
10935 pSession->roamingReason) {
10936 roamResult = eCSR_ROAM_RESULT_DEAUTH_IND;
10937 } else {
10938 roamResult = eCSR_ROAM_RESULT_LOSTLINK;
10939 }
10940 }
10941 csr_call_roaming_completion_callback(pMac, pSession, NULL, 0,
10942 roamResult);
10943 pSession->roamingReason = eCsrNotRoaming;
10944 } else {
10945 pSession->roamResult = roamResult;
10946 if (!CDF_IS_STATUS_SUCCESS
10947 (csr_roam_start_roaming_timer
10948 (pMac, sessionId, CDF_MC_TIMER_TO_SEC_UNIT))) {
10949 csr_call_roaming_completion_callback(pMac, pSession, NULL,
10950 0, roamResult);
10951 pSession->roamingReason = eCsrNotRoaming;
10952 } else {
10953 fCompleted = false;
10954 }
10955 }
10956 return fCompleted;
10957}
10958
10959void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId)
10960{
10961 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
10962
10963 if (!pSession) {
10964 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
10965 return;
10966 }
10967
10968 if (CSR_IS_ROAMING(pSession)) {
10969 sms_log(pMac, LOGW, "Cancel roaming");
10970 pSession->fCancelRoaming = true;
10971 if (CSR_IS_ROAM_JOINING(pMac, sessionId)
10972 && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
10973 /* No need to do anything in here because the handler takes care of it */
10974 } else {
10975 eCsrRoamResult roamResult =
10976 CSR_IS_LOSTLINK_ROAMING(pSession->
10977 roamingReason) ?
10978 eCSR_ROAM_RESULT_LOSTLINK : eCSR_ROAM_RESULT_NONE;
10979 /* Roaming is stopped after here */
10980 csr_roam_complete_roaming(pMac, sessionId, true,
10981 roamResult);
10982 /* Since CSR may be in lostlink roaming situation, abort all roaming related activities */
10983 csr_scan_abort_mac_scan(pMac, sessionId,
10984 eCSR_SCAN_ABORT_DEFAULT);
10985 csr_roam_stop_roaming_timer(pMac, sessionId);
10986 }
10987 }
10988}
10989
10990void csr_roam_roaming_timer_handler(void *pv)
10991{
10992 tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
10993 tpAniSirGlobal pMac = pInfo->pMac;
10994 uint32_t sessionId = pInfo->sessionId;
10995 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
10996
10997 if (!pSession) {
10998 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
10999 return;
11000 }
11001
11002 if (false == pSession->fCancelRoaming) {
11003 if (!CDF_IS_STATUS_SUCCESS
11004 (csr_roam_start_roaming
11005 (pMac, sessionId, pSession->roamingReason))) {
11006 csr_call_roaming_completion_callback(pMac, pSession, NULL,
11007 0,
11008 pSession->roamResult);
11009 pSession->roamingReason = eCsrNotRoaming;
11010 }
11011 }
11012}
11013
11014CDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId,
11015 uint32_t interval)
11016{
11017 CDF_STATUS status;
11018 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11019
11020 if (!pSession) {
11021 sms_log(pMac, LOGE, FL(" session %d not found"), sessionId);
11022 return CDF_STATUS_E_FAILURE;
11023 }
11024
11025 sms_log(pMac, LOG1, " csrScanStartRoamingTimer");
11026 pSession->roamingTimerInfo.sessionId = (uint8_t) sessionId;
11027 status = cdf_mc_timer_start(&pSession->hTimerRoaming,
11028 interval / CDF_MC_TIMER_TO_MS_UNIT);
11029
11030 return status;
11031}
11032
11033CDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId)
11034{
11035 return cdf_mc_timer_stop
11036 (&pMac->roam.roamSession[sessionId].hTimerRoaming);
11037}
11038
11039void csr_roam_wait_for_key_time_out_handler(void *pv)
11040{
11041 tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
11042 tpAniSirGlobal pMac = pInfo->pMac;
11043 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pInfo->sessionId);
11044 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11045
11046 if (pSession == NULL) {
11047 sms_log(pMac, LOGE, "%s: session not found", __func__);
11048 return;
11049 }
11050
11051 sms_log(pMac, LOGW,
11052 FL("WaitForKey timer expired in state=%s sub-state=%s"),
11053 mac_trace_get_neighbour_roam_state(pMac->roam.
11054 neighborRoamInfo[pInfo->sessionId].
11055 neighborRoamState),
11056 mac_trace_getcsr_roam_sub_state(pMac->roam.
11057 curSubState[pInfo->sessionId]));
11058
11059 if (CSR_IS_WAIT_FOR_KEY(pMac, pInfo->sessionId)) {
11060#ifdef FEATURE_WLAN_LFR
11061 if (csr_neighbor_roam_is_handoff_in_progress(pMac, pInfo->sessionId)) {
11062 /*
11063 * Enable heartbeat timer when hand-off is in progress
11064 * and Key Wait timer expired.
11065 */
11066 sms_log(pMac, LOG2,
11067 "Enabling HB timer after WaitKey expiry"
11068 " (nHBCount=%d)",
11069 pMac->roam.configParam.HeartbeatThresh24);
11070 cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
11071 pMac->roam.configParam.HeartbeatThresh24);
11072 }
11073#endif
11074 sms_log(pMac, LOGE, " SME pre-auth state timeout. ");
11075
11076 /* Change the substate so command queue is unblocked. */
11077 if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) {
11078 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
11079 pInfo->sessionId);
11080 }
11081
11082 if (csr_is_conn_state_connected_infra(pMac, pInfo->sessionId)) {
11083 csr_roam_link_up(pMac,
11084 pSession->connectedProfile.bssid);
11085 sme_process_pending_queue(pMac);
11086 status = sme_acquire_global_lock(&pMac->sme);
11087 if (CDF_IS_STATUS_SUCCESS(status)) {
11088 csr_roam_disconnect(pMac, pInfo->sessionId,
11089 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11090 sme_release_global_lock(&pMac->sme);
11091 }
11092 } else {
11093 sms_log(pMac, LOGE, "%s: session not found", __func__);
11094 }
11095 }
11096
11097}
11098
11099CDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval)
11100{
11101 CDF_STATUS status;
11102 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
11103 &pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
11104 sessionId];
11105#ifdef FEATURE_WLAN_LFR
11106 if (csr_neighbor_roam_is_handoff_in_progress(pMac,
11107 pMac->roam.WaitForKeyTimerInfo.
11108 sessionId)) {
11109 /* Disable heartbeat timer when hand-off is in progress */
11110 sms_log(pMac, LOG2,
11111 FL("disabling HB timer in state=%s sub-state=%s"),
11112 mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
11113 neighborRoamState),
11114 mac_trace_getcsr_roam_sub_state(pMac->roam.
11115 curSubState[pMac->roam.
11116 WaitForKeyTimerInfo.
11117 sessionId]
11118 ));
11119 cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0);
11120 }
11121#endif
11122 sms_log(pMac, LOG1, " csrScanStartWaitForKeyTimer");
11123 status = cdf_mc_timer_start(&pMac->roam.hTimerWaitForKey,
11124 interval / CDF_MC_TIMER_TO_MS_UNIT);
11125
11126 return status;
11127}
11128
11129CDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac)
11130{
11131 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
11132 &pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
11133 sessionId];
11134
11135 sms_log(pMac, LOG2,
11136 FL("WaitForKey timer stopped in state=%s sub-state=%s"),
11137 mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
11138 neighborRoamState),
11139 mac_trace_getcsr_roam_sub_state(pMac->roam.
11140 curSubState[pMac->roam.
11141 WaitForKeyTimerInfo.
11142 sessionId]));
11143#ifdef FEATURE_WLAN_LFR
11144 if (csr_neighbor_roam_is_handoff_in_progress(pMac,
11145 pMac->roam.WaitForKeyTimerInfo.
11146 sessionId)) {
11147 /*
11148 * Enable heartbeat timer when hand-off is in progress
11149 * and Key Wait timer got stopped for some reason
11150 */
11151 sms_log(pMac, LOG2, "Enabling HB timer after WaitKey stop"
11152 " (nHBCount=%d)",
11153 pMac->roam.configParam.HeartbeatThresh24);
11154 cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
11155 pMac->roam.configParam.HeartbeatThresh24);
11156 }
11157#endif
11158 return cdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
11159}
11160
11161void csr_roam_completion(tpAniSirGlobal pMac, uint32_t sessionId,
11162 tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand,
11163 eCsrRoamResult roamResult, bool fSuccess)
11164{
11165 eRoamCmdStatus roamStatus = csr_get_roam_complete_status(pMac, sessionId);
11166 uint32_t roamId = 0;
11167 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11168
11169 if (!pSession) {
11170 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
11171 return;
11172 }
11173
11174 if (pCommand) {
11175 roamId = pCommand->u.roamCmd.roamId;
11176 if (sessionId != pCommand->sessionId) {
11177 CDF_ASSERT(sessionId == pCommand->sessionId);
11178 return;
11179 }
11180 }
11181 if (eCSR_ROAM_ROAMING_COMPLETION == roamStatus) {
11182 /* if success, force roaming completion */
11183 csr_roam_complete_roaming(pMac, sessionId, fSuccess, roamResult);
11184 } else {
11185 if (pSession->bRefAssocStartCnt != 0) {
11186 CDF_ASSERT(pSession->bRefAssocStartCnt == 0);
11187 return;
11188 }
11189 sms_log(pMac, LOGW,
11190 FL
11191 (" indicates association completion. roamResult = %d"),
11192 roamResult);
11193 csr_roam_call_callback(pMac, sessionId, pRoamInfo, roamId,
11194 roamStatus, roamResult);
11195 }
11196}
11197
11198CDF_STATUS csr_roam_lost_link(tpAniSirGlobal pMac, uint32_t sessionId,
11199 uint32_t type, tSirSmeRsp *pSirMsg)
11200{
11201 CDF_STATUS status = CDF_STATUS_SUCCESS;
11202 tSirSmeDeauthInd *pDeauthIndMsg = NULL;
11203 tSirSmeDisassocInd *pDisassocIndMsg = NULL;
11204 eCsrRoamResult result = eCSR_ROAM_RESULT_LOSTLINK;
11205 tCsrRoamInfo *pRoamInfo = NULL;
11206 tCsrRoamInfo roamInfo;
11207 bool fToRoam;
11208 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11209
11210 if (!pSession) {
11211 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
11212 return CDF_STATUS_E_FAILURE;
11213 }
11214 /* Only need to roam for infra station. In this case P2P client will roam as well */
11215 fToRoam = CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile);
11216 pSession->fCancelRoaming = false;
11217 if (eWNI_SME_DISASSOC_IND == type) {
11218 result = eCSR_ROAM_RESULT_DISASSOC_IND;
11219 pDisassocIndMsg = (tSirSmeDisassocInd *) pSirMsg;
11220 pSession->roamingStatusCode = pDisassocIndMsg->statusCode;
11221 pSession->joinFailStatusCode.reasonCode =
11222 pDisassocIndMsg->reasonCode;
11223 } else if (eWNI_SME_DEAUTH_IND == type) {
11224 result = eCSR_ROAM_RESULT_DEAUTH_IND;
11225 pDeauthIndMsg = (tSirSmeDeauthInd *) pSirMsg;
11226 pSession->roamingStatusCode = pDeauthIndMsg->statusCode;
11227 /* Convert into proper reason code */
11228 if ((pDeauthIndMsg->reasonCode == eSIR_BEACON_MISSED) ||
11229 (pDeauthIndMsg->reasonCode ==
11230 eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON))
11231 pSession->joinFailStatusCode.reasonCode = 0;
11232 else
11233 pSession->joinFailStatusCode.reasonCode =
11234 pDeauthIndMsg->reasonCode;
11235 /*
11236 * cfg layer expects 0 as reason code if
11237 * the driver dosent know the reason code
11238 * eSIR_BEACON_MISSED is defined as locally
11239 */
11240 } else {
11241 sms_log(pMac, LOGW, FL("gets an unknown type (%d)"), type);
11242 result = eCSR_ROAM_RESULT_NONE;
11243 pSession->joinFailStatusCode.reasonCode = 1;
11244 }
11245
11246 /* call profile lost link routine here */
11247 if (!CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
11248 csr_roam_call_callback(pMac, sessionId, NULL, 0,
11249 eCSR_ROAM_LOSTLINK_DETECTED, result);
11250 /*Move the state to Idle after disconnection */
11251 csr_roam_state_change(pMac, eCSR_ROAMING_STATE_IDLE, sessionId);
11252
11253 }
11254
11255 if (eWNI_SME_DISASSOC_IND == type) {
11256 status = csr_send_mb_disassoc_cnf_msg(pMac, pDisassocIndMsg);
11257 } else if (eWNI_SME_DEAUTH_IND == type) {
11258 status = csr_send_mb_deauth_cnf_msg(pMac, pDeauthIndMsg);
11259 }
11260 if (!CDF_IS_STATUS_SUCCESS(status)) {
11261 /* If fail to send confirmation to PE, not to trigger roaming */
11262 fToRoam = false;
11263 }
11264 /* prepare to tell HDD to disconnect */
11265 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
11266 roamInfo.statusCode = (tSirResultCodes) pSession->roamingStatusCode;
11267 roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
11268 if (eWNI_SME_DISASSOC_IND == type) {
11269 /* staMacAddr */
11270 cdf_mem_copy(roamInfo.peerMac.bytes,
11271 pDisassocIndMsg->peerMacAddr,
11272 sizeof(tSirMacAddr));
11273 roamInfo.staId = (uint8_t) pDisassocIndMsg->staId;
11274 roamInfo.reasonCode = pDisassocIndMsg->reasonCode;
11275 } else if (eWNI_SME_DEAUTH_IND == type) {
11276 /* staMacAddr */
11277 cdf_mem_copy(roamInfo.peerMac.bytes,
11278 pDeauthIndMsg->peerMacAddr,
11279 sizeof(tSirMacAddr));
11280 roamInfo.staId = (uint8_t) pDeauthIndMsg->staId;
11281 roamInfo.reasonCode = pDeauthIndMsg->reasonCode;
11282 }
11283 sms_log(pMac, LOGW, FL("roamInfo.staId (%d)"), roamInfo.staId);
11284
11285 /* See if we can possibly roam. If so, start the roaming process and notify HDD
11286 that we are roaming. But if we cannot possibly roam, or if we are unable to
11287 currently roam, then notify HDD of the lost link */
11288 if (fToRoam) {
11289 /* Only remove the connected BSS in infrastructure mode */
11290 csr_roam_remove_connected_bss_from_scan_cache(pMac,
11291 &pSession->
11292 connectedProfile);
11293 /* Not to do anying for lostlink with WDS */
11294 status = csr_roam_start_roaming(pMac, sessionId,
11295 (eWNI_SME_DEAUTH_IND == type) ?
11296 eCsrLostlinkRoamingDeauth :
11297 eCsrLostlinkRoamingDisassoc);
11298 if (pMac->roam.configParam.nRoamingTime) {
11299 status = csr_roam_start_roaming(pMac, sessionId,
11300 (eWNI_SME_DEAUTH_IND == type) ?
11301 eCsrLostlinkRoamingDeauth :
11302 eCsrLostlinkRoamingDisassoc);
11303 if (CDF_IS_STATUS_SUCCESS(status)) {
11304 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
11305 /* For IBSS, we need to give some more info to HDD */
11306 if (csr_is_bss_type_ibss
11307 (pSession->connectedProfile.BSSType)) {
11308 roamInfo.u.pConnectedProfile =
11309 &pSession->connectedProfile;
11310 roamInfo.statusCode =
11311 (tSirResultCodes) pSession->
11312 roamingStatusCode;
11313 roamInfo.reasonCode =
11314 pSession->joinFailStatusCode.
11315 reasonCode;
11316 } else {
11317 roamInfo.reasonCode =
11318 eCsrRoamReasonSmeIssuedForLostLink;
11319 }
11320 pRoamInfo = &roamInfo;
11321 pSession->roamingReason =
11322 (eWNI_SME_DEAUTH_IND ==
11323 type) ? eCsrLostlinkRoamingDeauth :
11324 eCsrLostlinkRoamingDisassoc;
11325 pSession->roamingStartTime =
11326 (uint32_t) cdf_mc_timer_get_system_ticks();
11327 csr_roam_call_callback(pMac, sessionId, pRoamInfo,
11328 0, eCSR_ROAM_ROAMING_START,
11329 eCSR_ROAM_RESULT_LOSTLINK);
11330 } else {
11331 sms_log(pMac, LOGW,
11332 " %s Fail to start roaming, status = %d",
11333 __func__, status);
11334 fToRoam = false;
11335 }
11336 } else {
11337 /* We are told not to roam, indicate lostlink */
11338 fToRoam = false;
11339 }
11340 }
11341 if (!fToRoam) {
11342 /* Tell HDD about the lost link */
11343 if (!CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
11344 /* Don't call csr_roam_call_callback for GO/SoftAp case as this indication
11345 * was already given as part of eWNI_SME_DISASSOC_IND msg handling in
11346 * csr_roam_check_for_link_status_change API.
11347 */
11348 csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
11349 eCSR_ROAM_LOSTLINK, result);
11350 }
11351
11352 }
11353
11354 return status;
11355}
11356
11357CDF_STATUS csr_roam_lost_link_afterhandoff_failure(tpAniSirGlobal pMac,
11358 uint32_t sessionId)
11359{
11360 CDF_STATUS status = CDF_STATUS_SUCCESS;
11361 tListElem *pEntry = NULL;
11362 tSmeCmd *pCommand = NULL;
11363 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11364
11365 if (!pSession) {
11366 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
11367 return CDF_STATUS_E_FAILURE;
11368 }
11369
11370 pSession->fCancelRoaming = false;
11371 /* Only remove the connected BSS in infrastructure mode */
11372 csr_roam_remove_connected_bss_from_scan_cache(pMac,
11373 &pSession->connectedProfile);
11374 if (pMac->roam.configParam.nRoamingTime) {
11375 status = csr_roam_start_roaming(pMac, sessionId,
11376 pSession->roamingReason);
11377 if (CDF_IS_STATUS_SUCCESS(status)) {
11378 /*
11379 * before starting the lost link logic release
11380 * the roam command for handoff
11381 */
11382 pEntry =
11383 csr_ll_peek_head(&pMac->sme.smeCmdActiveList,
11384 LL_ACCESS_LOCK);
11385 if (pEntry) {
11386 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
11387 }
11388 if (pCommand) {
11389 if ((eSmeCommandRoam == pCommand->command) &&
11390 (eCsrSmeIssuedAssocToSimilarAP ==
11391 pCommand->u.roamCmd.roamReason)) {
11392 if (csr_ll_remove_entry
11393 (&pMac->sme.smeCmdActiveList,
11394 pEntry, LL_ACCESS_LOCK)) {
11395 csr_release_command_roam(pMac,
11396 pCommand);
11397 }
11398 }
11399 }
11400 sms_log(pMac, LOGW, "Lost link roaming started ...");
11401 }
11402 } else {
11403 /* We are told not to roam, indicate lostlink */
11404 status = CDF_STATUS_E_FAILURE;
11405 }
11406
11407 return status;
11408}
11409
11410void csr_roam_wm_status_change_complete(tpAniSirGlobal pMac)
11411{
11412 tListElem *pEntry;
11413 tSmeCmd *pCommand;
11414 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
11415 if (pEntry) {
11416 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
11417 if (eSmeCommandWmStatusChange == pCommand->command) {
11418 /* Nothing to process in a Lost Link completion.... It just kicks off a */
11419 /* roaming sequence. */
11420 if (csr_ll_remove_entry
11421 (&pMac->sme.smeCmdActiveList, pEntry,
11422 LL_ACCESS_LOCK)) {
11423 csr_release_command_wm_status_change(pMac, pCommand);
11424 } else {
11425 sms_log(pMac, LOGE,
11426 " ******csr_roam_wm_status_change_complete fail to release command");
11427 }
11428
11429 } else {
11430 sms_log(pMac, LOGW,
11431 "CSR: WmStatusChange Completion called but LOST LINK command is not ACTIVE ...");
11432 }
11433 } else {
11434 sms_log(pMac, LOGW,
11435 "CSR: WmStatusChange Completion called but NO commands are ACTIVE ...");
11436 }
11437 sme_process_pending_queue(pMac);
11438}
11439
11440void csr_roam_process_wm_status_change_command(tpAniSirGlobal pMac,
11441 tSmeCmd *pCommand)
11442{
11443 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11444 tSirSmeRsp *pSirSmeMsg;
11445 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pCommand->sessionId);
11446
11447 if (!pSession) {
11448 sms_log(pMac, LOGE, FL(" session %d not found "),
11449 pCommand->sessionId);
11450 return;
11451 }
11452 sms_log(pMac, LOG1, FL("session:%d, CmdType : %d"),
11453 pCommand->sessionId, pCommand->u.wmStatusChangeCmd.Type);
11454
11455 switch (pCommand->u.wmStatusChangeCmd.Type) {
11456 case eCsrDisassociated:
11457 pSirSmeMsg =
11458 (tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
11459 DisassocIndMsg;
11460 status =
11461 csr_roam_lost_link(pMac, pCommand->sessionId,
11462 eWNI_SME_DISASSOC_IND, pSirSmeMsg);
11463 break;
11464 case eCsrDeauthenticated:
11465 pSirSmeMsg =
11466 (tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
11467 DeauthIndMsg;
11468 status =
11469 csr_roam_lost_link(pMac, pCommand->sessionId,
11470 eWNI_SME_DEAUTH_IND, pSirSmeMsg);
11471 break;
11472 default:
11473 sms_log(pMac, LOGW, FL("gets an unknown command %d"),
11474 pCommand->u.wmStatusChangeCmd.Type);
11475 break;
11476 }
11477 /* For WDS, we want to stop BSS as well when it is indicated that it is disconnected. */
11478 if (CSR_IS_CONN_WDS(&pSession->connectedProfile)) {
11479 if (!CDF_IS_STATUS_SUCCESS
11480 (csr_roam_issue_stop_bss_cmd(pMac, pCommand->sessionId, true))) {
11481 /* This is not good */
11482 sms_log(pMac, LOGE,
11483 FL(" failed to issue stopBSS command"));
11484 }
11485 }
11486 /* Lost Link just triggers a roaming sequence. We can complte the Lost Link */
11487 /* command here since there is nothing else to do. */
11488 csr_roam_wm_status_change_complete(pMac);
11489}
11490
11491
11492/**
11493 * csr_compute_mode_and_band() - computes dot11mode
11494 * @pMac: mac global context
11495 * @dot11_mode: out param, do11 mode calculated
11496 * @band: out param, band caclculated
11497 * @opr_ch: operating channels
11498 *
11499 * This function finds dot11 mode based on current mode, operating channel and
11500 * fw supported modes.
11501 *
11502 * Return: void
11503 */
11504static void
11505csr_compute_mode_and_band(tpAniSirGlobal mac_ctx,
11506 eCsrCfgDot11Mode *dot11_mode,
11507 eCsrBand *band,
11508 uint8_t opr_ch)
11509{
11510 bool vht_24_ghz = mac_ctx->roam.configParam.enableVhtFor24GHz;
11511 switch (mac_ctx->roam.configParam.uCfgDot11Mode) {
11512 case eCSR_CFG_DOT11_MODE_11A:
11513 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
11514 *band = eCSR_BAND_5G;
11515 break;
11516 case eCSR_CFG_DOT11_MODE_11B:
11517 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
11518 *band = eCSR_BAND_24;
11519 break;
11520 case eCSR_CFG_DOT11_MODE_11G:
11521 *dot11_mode = eCSR_CFG_DOT11_MODE_11G;
11522 *band = eCSR_BAND_24;
11523 break;
11524 case eCSR_CFG_DOT11_MODE_11N:
11525 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11526 *band = CSR_GET_BAND(opr_ch);
11527 break;
11528#ifdef WLAN_FEATURE_11AC
11529 case eCSR_CFG_DOT11_MODE_11AC:
11530 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
11531 /*
11532 * If the operating channel is in 2.4 GHz band, check
11533 * for INI item to disable VHT operation in 2.4 GHz band
11534 */
11535 if (CDS_IS_CHANNEL_24GHZ(opr_ch) && !vht_24_ghz)
11536 /* Disable 11AC operation */
11537 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11538 else
11539 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
11540 } else {
11541 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11542 }
11543 *band = CSR_GET_BAND(opr_ch);
11544 break;
11545 case eCSR_CFG_DOT11_MODE_11AC_ONLY:
11546 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
11547 /*
11548 * If the operating channel is in 2.4 GHz band, check
11549 * for INI item to disable VHT operation in 2.4 GHz band
11550 */
11551 if (CDS_IS_CHANNEL_24GHZ(opr_ch) && !vht_24_ghz)
11552 /* Disable 11AC operation */
11553 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11554 else
11555 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
11556 } else {
11557 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11558 }
11559 *band = CSR_GET_BAND(opr_ch);
11560 break;
11561#endif
11562 case eCSR_CFG_DOT11_MODE_AUTO:
11563#ifdef WLAN_FEATURE_11AC
11564 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
11565 /*
11566 * If the operating channel is in 2.4 GHz band,
11567 * check for INI item to disable VHT operation
11568 * in 2.4 GHz band
11569 */
11570 if (CDS_IS_CHANNEL_24GHZ(opr_ch)
11571 && !vht_24_ghz)
11572 /* Disable 11AC operation */
11573 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11574 else
11575 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
11576 } else {
11577 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11578 }
11579#else
11580 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
11581#endif
11582 *band = CSR_GET_BAND(opr_ch);
11583 break;
11584 default:
11585 /*
11586 * Global dot11 Mode setting is 11a/b/g. use the channel number
11587 * to determine the Mode setting.
11588 */
11589 if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch) {
11590 *band = mac_ctx->roam.configParam.eBand;
11591 if (eCSR_BAND_24 == *band) {
11592 /*
11593 * See reason in else if ( CDS_IS_CHANNEL_24GHZ
11594 * (opr_ch) ) to pick 11B
11595 */
11596 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
11597 } else {
11598 /* prefer 5GHz */
11599 *band = eCSR_BAND_5G;
11600 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
11601 }
11602 } else if (CDS_IS_CHANNEL_24GHZ(opr_ch)) {
11603 /*
11604 * WiFi tests require IBSS networks to start in 11b mode
11605 * without any change to the default parameter settings
11606 * on the adapter. We use ACU to start an IBSS through
11607 * creation of a startIBSS profile. This startIBSS
11608 * profile has Auto MACProtocol and the adapter property
11609 * setting for dot11Mode is also AUTO. So in this case,
11610 * let's start the IBSS network in 11b mode instead of
11611 * 11g mode. So this is for Auto=profile->MacProtocol &&
11612 * Auto=Global. dot11Mode && profile->channel is < 14,
11613 * then start the IBSS in b mode.
11614 *
11615 * Note: we used to have this start as an 11g IBSS for
11616 * best performance. now to specify that the user will
11617 * have to set the do11Mode in the property page to 11g
11618 * to force it.
11619 */
11620 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
11621 *band = eCSR_BAND_24;
11622 } else {
11623 /* else, it's a 5.0GHz channel. Set mode to 11a. */
11624 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
11625 *band = eCSR_BAND_5G;
11626 }
11627 break;
11628 } /* switch */
11629}
11630
11631/**
11632 * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode
11633 * information.
11634 * @mac_ctx: mac global context
11635 * @profile: bss profile
11636 * @band: out param, band caclculated
11637 * @opr_ch: operating channels
11638 *
11639 * This function finds dot11 mode based on current mode, operating channel and
11640 * fw supported modes. The only tricky part is that if phyMode is set to 11abg,
11641 * this function may return eCSR_CFG_DOT11_MODE_11B instead of
11642 * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick.
11643 *
11644 * Return: dot11mode
11645 */
11646static eCsrCfgDot11Mode
11647csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal mac_ctx,
11648 tCsrRoamProfile *profile,
11649 uint8_t opr_chn,
11650 eCsrBand *p_band)
11651{
11652 eCsrBand band;
11653 eCsrCfgDot11Mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
11654 eCsrCfgDot11Mode cfg_dot11_mode =
11655 csr_get_cfg_dot11_mode_from_csr_phy_mode(profile,
11656 (eCsrPhyMode) profile->phyMode,
11657 mac_ctx->roam.configParam.ProprietaryRatesEnabled);
11658
11659 /*
11660 * If the global setting for dot11Mode is set to auto/abg, we overwrite
11661 * the setting in the profile.
11662 */
11663 if (((!CSR_IS_INFRA_AP(profile) && !CSR_IS_WDS(profile))
11664 && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode)
11665 || (eCSR_CFG_DOT11_MODE_ABG == curr_mode)))
11666 || (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode)
11667 || (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) {
11668 csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode,
11669 &band, opr_chn);
11670 } /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */
11671 else {
11672 /* dot11 mode is set, lets pick the band */
11673 if (eCSR_OPERATING_CHANNEL_AUTO == opr_chn) {
11674 /* channel is Auto also. */
11675 band = mac_ctx->roam.configParam.eBand;
11676 if (eCSR_BAND_ALL == band) {
11677 /* prefer 5GHz */
11678 band = eCSR_BAND_5G;
11679 }
11680 } else{
11681 band = CSR_GET_BAND(opr_chn);
11682 }
11683 }
11684 if (p_band)
11685 *p_band = band;
11686
11687 if (opr_chn == 14) {
11688 sms_log(mac_ctx, LOGE, FL("Switching to Dot11B mode"));
11689 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B;
11690 }
11691
11692 /*
11693 * Incase of WEP Security encryption type is coming as part of add key.
11694 * So while STart BSS dont have information
11695 */
11696 if ((!CSR_IS_11n_ALLOWED(profile->EncryptionType.encryptionType[0])
11697 || ((profile->privacy == 1)
11698 && (profile->EncryptionType.encryptionType[0] ==
11699 eCSR_ENCRYPT_TYPE_NONE)))
11700 && ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) ||
11701#ifdef WLAN_FEATURE_11AC
11702 (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode)
11703#endif
11704 )) {
11705 /* We cannot do 11n here */
11706 if (CDS_IS_CHANNEL_24GHZ(opr_chn))
11707 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
11708 else
11709 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
11710 }
11711 return cfg_dot11_mode;
11712}
11713
11714CDF_STATUS csr_roam_issue_stop_bss(tpAniSirGlobal pMac, uint32_t sessionId,
11715 eCsrRoamSubState NewSubstate)
11716{
11717 CDF_STATUS status;
11718 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11719
11720 if (!pSession) {
11721 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
11722 return CDF_STATUS_E_FAILURE;
11723 }
11724#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
11725 {
11726 host_log_ibss_pkt_type *pIbssLog;
11727 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
11728 LOG_WLAN_IBSS_C);
11729 if (pIbssLog) {
11730 pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_REQ;
11731 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
11732 }
11733 }
11734#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
11735 /* Set the roaming substate to 'stop Bss request'... */
11736 csr_roam_substate_change(pMac, NewSubstate, sessionId);
11737
11738 /* attempt to stop the Bss (reason code is ignored...) */
11739 status = csr_send_mb_stop_bss_req_msg(pMac, sessionId);
11740 if (!CDF_IS_STATUS_SUCCESS(status)) {
11741 sms_log(pMac, LOGW,
11742 FL("csr_send_mb_stop_bss_req_msg failed with status %d"),
11743 status);
11744 }
11745 return status;
11746}
11747
11748/* pNumChan is a caller allocated space with the sizeof pChannels */
11749CDF_STATUS csr_get_cfg_valid_channels(tpAniSirGlobal pMac, uint8_t *pChannels,
11750 uint32_t *pNumChan)
11751{
11752 if (!IS_SIR_STATUS_SUCCESS(wlan_cfg_get_str(pMac,
11753 WNI_CFG_VALID_CHANNEL_LIST,
11754 (uint8_t *) pChannels, pNumChan)))
11755 return CDF_STATUS_E_FAILURE;
11756 return CDF_STATUS_SUCCESS;
11757}
11758
11759tPowerdBm csr_get_cfg_max_tx_power(tpAniSirGlobal pMac, uint8_t channel)
11760{
11761 uint32_t cfgLength = 0;
11762 uint16_t cfgId = 0;
11763 tPowerdBm maxTxPwr = 0;
11764 uint8_t *pCountryInfo = NULL;
11765 CDF_STATUS status;
11766 uint8_t count = 0;
11767 uint8_t firstChannel;
11768 uint8_t maxChannels;
11769
11770 if (CDS_IS_CHANNEL_5GHZ(channel)) {
11771 cfgId = WNI_CFG_MAX_TX_POWER_5;
11772 cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
11773 } else if (CDS_IS_CHANNEL_24GHZ(channel)) {
11774 cfgId = WNI_CFG_MAX_TX_POWER_2_4;
11775 cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
11776 } else
11777 return maxTxPwr;
11778
11779 pCountryInfo = cdf_mem_malloc(cfgLength);
11780 if (NULL == pCountryInfo)
11781 status = CDF_STATUS_E_NOMEM;
11782 else
11783 status = CDF_STATUS_SUCCESS;
11784 if (status != CDF_STATUS_SUCCESS) {
11785 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11786 FL("%s: failed to allocate memory, status = %d"),
11787 __FUNCTION__, status);
11788 goto error;
11789 }
11790 if (wlan_cfg_get_str(pMac, cfgId, (uint8_t *)pCountryInfo,
11791 &cfgLength) != eSIR_SUCCESS) {
11792 goto error;
11793 }
11794 /* Identify the channel and maxtxpower */
11795 while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) {
11796 firstChannel = pCountryInfo[count++];
11797 maxChannels = pCountryInfo[count++];
11798 maxTxPwr = pCountryInfo[count++];
11799
11800 if ((channel >= firstChannel) &&
11801 (channel < (firstChannel + maxChannels))) {
11802 break;
11803 }
11804 }
11805
11806error:
11807 if (NULL != pCountryInfo)
11808 cdf_mem_free(pCountryInfo);
11809
11810 return maxTxPwr;
11811}
11812
11813bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel)
11814{
11815 bool fValid = false;
11816 uint32_t idxValidChannels;
11817 uint32_t len = sizeof(pMac->roam.validChannelList);
11818
11819 if (CDF_IS_STATUS_SUCCESS
11820 (csr_get_cfg_valid_channels(pMac, pMac->roam.validChannelList, &len))) {
11821 for (idxValidChannels = 0; (idxValidChannels < len);
11822 idxValidChannels++) {
11823 if (channel ==
11824 pMac->roam.validChannelList[idxValidChannels]) {
11825 fValid = true;
11826 break;
11827 }
11828 }
11829 }
11830 pMac->roam.numValidChannels = len;
11831 return fValid;
11832}
11833
11834bool csr_roam_is_valid40_mhz_channel(tpAniSirGlobal pMac, uint8_t channel)
11835{
11836 bool fValid = false;
11837 uint8_t i;
11838 for (i = 0; i < pMac->scan.base40MHzChannels.numChannels; i++) {
11839 if (channel == pMac->scan.base40MHzChannels.channelList[i]) {
11840 fValid = true;
11841 break;
11842 }
11843 }
11844 return fValid;
11845}
11846
11847/* This function check and validate whether the NIC can do CB (40MHz) */
11848static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
11849 uint8_t primaryChn,
11850 tDot11fBeaconIEs *pIes)
11851{
11852 ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED;
11853 uint8_t centerChn;
11854 uint32_t ChannelBondingMode;
11855 if (CDS_IS_CHANNEL_24GHZ(primaryChn)) {
11856 /*
11857 * gChannelBondingMode24GHz configuration item is common for
11858 * SAP and STA mode and currently MDM does not support
11859 * HT40 in 2.4Ghz STA mode.
11860 * So disabling the HT40 in 2.4GHz station mode
11861 */
11862#ifdef QCA_HT_20_24G_STA_ONLY
11863 ChannelBondingMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
11864#else
11865 ChannelBondingMode =
11866 pMac->roam.configParam.channelBondingMode24GHz;
11867#endif
11868 } else {
11869 ChannelBondingMode =
11870 pMac->roam.configParam.channelBondingMode5GHz;
11871 }
11872
11873 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == ChannelBondingMode)
11874 return PHY_SINGLE_CHANNEL_CENTERED;
11875
11876 /* Figure what the other side's CB mode */
11877 if (!(pIes->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ ==
11878 pIes->HTCaps.supportedChannelWidthSet))) {
11879 return PHY_SINGLE_CHANNEL_CENTERED;
11880 }
11881
11882 /* Check set as TKIP or not. */
11883 if (((NULL != &(pIes->RSN.pwise_cipher_suites[0][0]) &&
11884 (pIes->RSN.pwise_cipher_suite_count == 1)) &&
11885 !memcmp(&(pIes->RSN.pwise_cipher_suites[0][0]),
11886 "\x00\x0f\xac\x02", 4))
11887 || (((NULL != &(pIes->WPA)) &&
11888 (pIes->WPA.unicast_cipher_count == 1))
11889 && ((NULL != &(pIes->WPA.unicast_ciphers[0]))
11890 && !memcmp(&(pIes->WPA.unicast_ciphers[0]),
11891 "\x00\x0f\xac\x02", 4)))) {
11892 sms_log(pMac, LOGW,
11893 " No channel bonding in TKIP mode ");
11894 return PHY_SINGLE_CHANNEL_CENTERED;
11895 }
11896
11897 if (!pIes->HTInfo.present)
11898 return PHY_SINGLE_CHANNEL_CENTERED;
11899
11900 /*
11901 * This is called during INFRA STA/CLIENT and should use the merged
11902 * value of supported channel width and recommended tx width as per
11903 * standard
11904 */
11905 sms_log(pMac, LOG1, "scws %u rtws %u sco %u",
11906 pIes->HTCaps.supportedChannelWidthSet,
11907 pIes->HTInfo.recommendedTxWidthSet,
11908 pIes->HTInfo.secondaryChannelOffset);
11909
11910 if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ)
11911 eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset;
11912 else
11913 eRet = PHY_SINGLE_CHANNEL_CENTERED;
11914
11915 switch (eRet) {
11916 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
11917 centerChn = primaryChn + CSR_CB_CENTER_CHANNEL_OFFSET;
11918 break;
11919 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
11920 centerChn = primaryChn - CSR_CB_CENTER_CHANNEL_OFFSET;
11921 break;
11922 case PHY_SINGLE_CHANNEL_CENTERED:
11923 default:
11924 centerChn = primaryChn;
11925 break;
11926 }
11927
11928 if ((PHY_SINGLE_CHANNEL_CENTERED != eRet)
11929 && !csr_roam_is_valid40_mhz_channel(pMac, centerChn)) {
11930 sms_log(pMac, LOGE,
11931 "Invalid center channel (%d), disable 40MHz mode",
11932 centerChn);
11933 eRet = PHY_SINGLE_CHANNEL_CENTERED;
11934 }
11935 return eRet;
11936}
11937
11938bool csr_is_encryption_in_list(tpAniSirGlobal pMac,
11939 tCsrEncryptionList *pCipherList,
11940 eCsrEncryptionType encryptionType)
11941{
11942 bool fFound = false;
11943 uint32_t idx;
11944 for (idx = 0; idx < pCipherList->numEntries; idx++) {
11945 if (pCipherList->encryptionType[idx] == encryptionType) {
11946 fFound = true;
11947 break;
11948 }
11949 }
11950 return fFound;
11951}
11952
11953bool csr_is_auth_in_list(tpAniSirGlobal pMac, tCsrAuthList *pAuthList,
11954 eCsrAuthType authType)
11955{
11956 bool fFound = false;
11957 uint32_t idx;
11958 for (idx = 0; idx < pAuthList->numEntries; idx++) {
11959 if (pAuthList->authType[idx] == authType) {
11960 fFound = true;
11961 break;
11962 }
11963 }
11964 return fFound;
11965}
11966
11967bool csr_is_same_profile(tpAniSirGlobal pMac,
11968 tCsrRoamConnectedProfile *pProfile1,
11969 tCsrRoamProfile *pProfile2)
11970{
11971 uint32_t i;
11972 bool fCheck = false;
11973 tCsrScanResultFilter *pScanFilter = NULL;
11974 CDF_STATUS status = CDF_STATUS_SUCCESS;
11975
11976 if (!(pProfile1 && pProfile2))
11977 return fCheck;
11978 pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
11979 if (NULL == pScanFilter)
11980 return fCheck;
11981
11982 cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
11983 status = csr_roam_prepare_filter_from_profile(pMac, pProfile2,
11984 pScanFilter);
11985 if (!(CDF_IS_STATUS_SUCCESS(status)))
11986 goto free_scan_filter;
11987
11988 for (i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) {
11989 fCheck = csr_is_ssid_match(pMac,
11990 pScanFilter->SSIDs.SSIDList[i].SSID.ssId,
11991 pScanFilter->SSIDs.SSIDList[i].SSID.length,
11992 pProfile1->SSID.ssId,
11993 pProfile1->SSID.length,
11994 false);
11995 if (fCheck)
11996 break;
11997 }
11998 if (!fCheck)
11999 goto free_scan_filter;
12000
12001 if (!csr_is_auth_in_list(pMac, &pProfile2->AuthType,
12002 pProfile1->AuthType)
12003 || (pProfile2->BSSType != pProfile1->BSSType)
12004 || !csr_is_encryption_in_list(pMac, &pProfile2->EncryptionType,
12005 pProfile1->EncryptionType)) {
12006 fCheck = false;
12007 goto free_scan_filter;
12008 }
12009#ifdef WLAN_FEATURE_VOWIFI_11R
12010 if (pProfile1->MDID.mdiePresent || pProfile2->MDID.mdiePresent) {
12011 if (pProfile1->MDID.mobilityDomain
12012 != pProfile2->MDID.mobilityDomain) {
12013 fCheck = false;
12014 goto free_scan_filter;
12015 }
12016 }
12017#endif
12018 /* Match found */
12019 fCheck = true;
12020free_scan_filter:
12021 csr_free_scan_filter(pMac, pScanFilter);
12022 cdf_mem_free(pScanFilter);
12023 return fCheck;
12024}
12025
12026bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
12027 tCsrRoamConnectedProfile *pConnProfile,
12028 tCsrRoamProfile *pProfile2)
12029{
12030 bool fCheck = false;
12031 int i;
12032 do {
12033 /* Only check for static WEP */
12034 if (!csr_is_encryption_in_list
12035 (pMac, &pProfile2->EncryptionType,
12036 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
12037 && !csr_is_encryption_in_list(pMac,
12038 &pProfile2->EncryptionType,
12039 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
12040 fCheck = true;
12041 break;
12042 }
12043 if (!csr_is_encryption_in_list
12044 (pMac, &pProfile2->EncryptionType,
12045 pConnProfile->EncryptionType))
12046 break;
12047 if (pConnProfile->Keys.defaultIndex !=
12048 pProfile2->Keys.defaultIndex)
12049 break;
12050 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
12051 if (pConnProfile->Keys.KeyLength[i] !=
12052 pProfile2->Keys.KeyLength[i])
12053 break;
12054 if (!cdf_mem_compare(&pConnProfile->Keys.KeyMaterial[i],
12055 &pProfile2->Keys.KeyMaterial[i],
12056 pProfile2->Keys.KeyLength[i])) {
12057 break;
12058 }
12059 }
12060 if (i == CSR_MAX_NUM_KEY) {
12061 fCheck = true;
12062 }
12063 } while (0);
12064 return fCheck;
12065}
12066
12067/* IBSS */
12068
12069uint8_t csr_roam_get_ibss_start_channel_number50(tpAniSirGlobal pMac)
12070{
12071 uint8_t channel = 0;
12072 uint32_t idx;
12073 uint32_t idxValidChannels;
12074 bool fFound = false;
12075 uint32_t len = sizeof(pMac->roam.validChannelList);
12076
12077 if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel5G) {
12078 channel = pMac->roam.configParam.AdHocChannel5G;
12079 if (!csr_roam_is_channel_valid(pMac, channel)) {
12080 channel = 0;
12081 }
12082 }
12083 if (0 == channel
12084 &&
12085 CDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels
12086 (pMac,
12087 (uint8_t *) pMac->roam.validChannelList,
12088 &len))) {
12089 for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_50) && !fFound;
12090 idx++) {
12091 for (idxValidChannels = 0;
12092 (idxValidChannels < len) && !fFound;
12093 idxValidChannels++) {
12094 if (csr_start_ibss_channels50[idx] ==
12095 pMac->roam.
12096 validChannelList[idxValidChannels]) {
12097 fFound = true;
12098 channel = csr_start_ibss_channels50[idx];
12099 }
12100 }
12101 }
12102 /*
12103 * this is rare, but if it does happen,
12104 * we find anyone in 11a bandwidth and
12105 * return the first 11a channel found!
12106 */
12107 if (!fFound) {
12108 for (idxValidChannels = 0; idxValidChannels < len;
12109 idxValidChannels++) {
12110 if (CDS_IS_CHANNEL_5GHZ(pMac->roam.
12111 validChannelList[idxValidChannels])) {
12112 /* the max channel# in 11g is 14 */
12113 if (idxValidChannels <
12114 CSR_NUM_IBSS_START_CHANNELS_50) {
12115 channel =
12116 pMac->roam.validChannelList
12117 [idxValidChannels];
12118 }
12119 break;
12120 }
12121 }
12122 }
12123 } /* if */
12124
12125 return channel;
12126}
12127
12128uint8_t csr_roam_get_ibss_start_channel_number24(tpAniSirGlobal pMac)
12129{
12130 uint8_t channel = 1;
12131 uint32_t idx;
12132 uint32_t idxValidChannels;
12133 bool fFound = false;
12134 uint32_t len = sizeof(pMac->roam.validChannelList);
12135
12136 if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel24) {
12137 channel = pMac->roam.configParam.AdHocChannel24;
12138 if (!csr_roam_is_channel_valid(pMac, channel)) {
12139 channel = 0;
12140 }
12141 }
12142
12143 if (0 == channel
12144 &&
12145 CDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels
12146 (pMac,
12147 (uint8_t *) pMac->roam.validChannelList,
12148 &len))) {
12149 for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_24) && !fFound;
12150 idx++) {
12151 for (idxValidChannels = 0;
12152 (idxValidChannels < len) && !fFound;
12153 idxValidChannels++) {
12154 if (csr_start_ibss_channels24[idx] ==
12155 pMac->roam.
12156 validChannelList[idxValidChannels]) {
12157 fFound = true;
12158 channel = csr_start_ibss_channels24[idx];
12159 }
12160 }
12161 }
12162 }
12163
12164 return channel;
12165}
12166
12167/**
12168 * csr_populate_basic_rates() - populates OFDM or CCK rates
12169 * @rates: rate struct to populate
12170 * @type: true: ofdm rates, false: cck rates
12171 * @masked: indicates if rates are to be masked with
12172 * CSR_DOT11_BASIC_RATE_MASK
12173 *
12174 * This function will populate OFDM or CCK rates
12175 *
12176 * Return: void
12177 */
12178static void
12179csr_populate_basic_rates(tSirMacRateSet *rate_set, bool type, bool masked)
12180{
12181 uint8_t ofdm_rates[8] = {
12182 SIR_MAC_RATE_6,
12183 SIR_MAC_RATE_9,
12184 SIR_MAC_RATE_12,
12185 SIR_MAC_RATE_18,
12186 SIR_MAC_RATE_24,
12187 SIR_MAC_RATE_36,
12188 SIR_MAC_RATE_48,
12189 SIR_MAC_RATE_54
12190 };
12191 uint8_t cck_rates[4] = {
12192 SIR_MAC_RATE_1,
12193 SIR_MAC_RATE_2,
12194 SIR_MAC_RATE_5_5,
12195 SIR_MAC_RATE_11
12196 };
12197
12198 if (type == true) {
12199 rate_set->numRates = 8;
12200 cdf_mem_copy(rate_set->rate, ofdm_rates, sizeof(ofdm_rates));
12201 if (masked) {
12202 rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
12203 rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
12204 rate_set->rate[4] |= CSR_DOT11_BASIC_RATE_MASK;
12205 }
12206 } else {
12207 rate_set->numRates = 4;
12208 cdf_mem_copy(rate_set->rate, cck_rates, sizeof(cck_rates));
12209 if (masked) {
12210 rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
12211 rate_set->rate[1] |= CSR_DOT11_BASIC_RATE_MASK;
12212 rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
12213 rate_set->rate[3] |= CSR_DOT11_BASIC_RATE_MASK;
12214 }
12215 }
12216}
12217
12218/**
12219 * csr_convert_mode_to_nw_type() - convert mode into network type
12220 * @dot11_mode: dot11_mode
12221 * @band: 2.4 or 5 GHz
12222 *
12223 * Return: tSirNwType
12224 */
12225static tSirNwType
12226csr_convert_mode_to_nw_type(eCsrCfgDot11Mode dot11_mode, eCsrBand band)
12227{
12228 switch (dot11_mode) {
12229 case eCSR_CFG_DOT11_MODE_11G:
12230 return eSIR_11G_NW_TYPE;
12231 case eCSR_CFG_DOT11_MODE_11B:
12232 return eSIR_11B_NW_TYPE;
12233 case eCSR_CFG_DOT11_MODE_11A:
12234 return eSIR_11A_NW_TYPE;
12235 case eCSR_CFG_DOT11_MODE_11N:
12236 default:
12237 /*
12238 * Because LIM only verifies it against 11a, 11b or 11g, set
12239 * only 11g or 11a here
12240 */
12241 if (eCSR_BAND_24 == band)
12242 return eSIR_11G_NW_TYPE;
12243 else
12244 return eSIR_11A_NW_TYPE;
12245 }
12246 return eSIR_DONOT_USE_NW_TYPE;
12247}
12248
12249/**
12250 * csr_roam_get_bss_start_parms() - get bss start param from profile
12251 * @pMac: mac global context
12252 * @pProfile: roam profile
12253 * @pParam: out param, start bss params
12254 *
12255 * This function populates start bss param from roam profile
12256 *
12257 * Return: void
12258 */
12259static void
12260csr_roam_get_bss_start_parms(tpAniSirGlobal pMac,
12261 tCsrRoamProfile *pProfile,
12262 tCsrRoamStartBssParams *pParam)
12263{
12264 eCsrBand band;
12265 uint8_t opr_ch = 0;
12266 tSirNwType nw_type;
12267 uint8_t tmp_opr_ch = 0;
12268 tSirMacRateSet *opr_rates = &pParam->operationalRateSet;
12269 tSirMacRateSet *ext_rates = &pParam->extendedRateSet;
12270
12271 if (pProfile->ChannelInfo.numOfChannels
12272 && pProfile->ChannelInfo.ChannelList) {
12273 tmp_opr_ch = pProfile->ChannelInfo.ChannelList[0];
12274 }
12275
12276 pParam->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(pMac,
12277 pProfile, tmp_opr_ch, &band);
12278
12279 if (((pProfile->csrPersona == CDF_P2P_CLIENT_MODE)
12280 || (pProfile->csrPersona == CDF_P2P_GO_MODE))
12281 && (pParam->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11B)) {
12282 /* This should never happen */
12283 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
12284 FL("For P2P (persona %d) dot11_mode is 11B"),
12285 pProfile->csrPersona);
12286 CDF_ASSERT(0);
12287 }
12288
12289 nw_type = csr_convert_mode_to_nw_type(pParam->uCfgDot11Mode, band);
12290 ext_rates->numRates = 0;
12291
12292 switch (nw_type) {
12293 default:
12294 sms_log(pMac, LOGE, FL("sees an unknown pSirNwType (%d)"),
12295 nw_type);
12296 case eSIR_11A_NW_TYPE:
12297 csr_populate_basic_rates(opr_rates, true, true);
12298 if (eCSR_OPERATING_CHANNEL_ANY != tmp_opr_ch) {
12299 opr_ch = tmp_opr_ch;
12300 break;
12301 }
12302 opr_ch = csr_roam_get_ibss_start_channel_number50(pMac);
12303 if (0 == opr_ch &&
12304 CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) &&
12305 CSR_IS_PHY_MODE_DUAL_BAND(pMac->roam.configParam.phyMode)) {
12306 /*
12307 * We could not find a 5G channel by auto pick, let's
12308 * try 2.4G channels. We only do this here because
12309 * csr_roam_get_phy_mode_band_for_bss always picks 11a
12310 * for AUTO
12311 */
12312 nw_type = eSIR_11B_NW_TYPE;
12313 opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
12314 csr_populate_basic_rates(opr_rates, false, true);
12315 }
12316 break;
12317 case eSIR_11B_NW_TYPE:
12318 csr_populate_basic_rates(opr_rates, false, true);
12319 if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
12320 opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
12321 else
12322 opr_ch = tmp_opr_ch;
12323 break;
12324 case eSIR_11G_NW_TYPE:
12325 /* For P2P Client and P2P GO, disable 11b rates */
12326 if ((pProfile->csrPersona == CDF_P2P_CLIENT_MODE)
12327 || (pProfile->csrPersona == CDF_P2P_GO_MODE)
12328 || (eCSR_CFG_DOT11_MODE_11G_ONLY ==
12329 pParam->uCfgDot11Mode)) {
12330 csr_populate_basic_rates(opr_rates, true, true);
12331 } else {
12332 csr_populate_basic_rates(opr_rates, false, true);
12333 csr_populate_basic_rates(ext_rates, true, false);
12334 }
12335
12336 if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
12337 opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
12338 else
12339 opr_ch = tmp_opr_ch;
12340 break;
12341 }
12342 pParam->operationChn = opr_ch;
12343 pParam->sirNwType = nw_type;
12344 pParam->ch_params.ch_width = pProfile->ch_params.ch_width;
12345 pParam->ch_params.center_freq_seg0 =
12346 pProfile->ch_params.center_freq_seg0;
12347 pParam->ch_params.center_freq_seg1 =
12348 pProfile->ch_params.center_freq_seg1;
12349 pParam->ch_params.sec_ch_offset =
12350 pProfile->ch_params.sec_ch_offset;
12351}
12352
12353static void
12354csr_roam_get_bss_start_parms_from_bss_desc(tpAniSirGlobal pMac,
12355 tSirBssDescription *pBssDesc,
12356 tDot11fBeaconIEs *pIes,
12357 tCsrRoamStartBssParams *pParam)
12358{
12359 if (!pParam) {
12360 sms_log(pMac, LOGE, FL("BSS param's pointer is NULL"));
12361 return;
12362 }
12363
12364 pParam->sirNwType = pBssDesc->nwType;
12365 pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
12366 pParam->operationChn = pBssDesc->channelId;
12367 cdf_mem_copy(&pParam->bssid, pBssDesc->bssId, sizeof(struct cdf_mac_addr));
12368
12369 if (!pIes) {
12370 pParam->ssId.length = 0;
12371 pParam->operationalRateSet.numRates = 0;
12372 sms_log(pMac, LOGE, FL("IEs struct pointer is NULL"));
12373 return;
12374 }
12375
12376 if (pIes->SuppRates.present) {
12377 pParam->operationalRateSet.numRates = pIes->SuppRates.num_rates;
12378 if (pIes->SuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
12379 sms_log(pMac, LOGE,
12380 FL("num_rates: %d > max val, resetting"),
12381 pIes->SuppRates.num_rates);
12382 pIes->SuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
12383 }
12384 cdf_mem_copy(pParam->operationalRateSet.rate,
12385 pIes->SuppRates.rates,
12386 sizeof(*pIes->SuppRates.rates) *
12387 pIes->SuppRates.num_rates);
12388 }
12389 if (pIes->ExtSuppRates.present) {
12390 pParam->extendedRateSet.numRates = pIes->ExtSuppRates.num_rates;
12391 if (pIes->ExtSuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
12392 sms_log(pMac, LOGE,
12393 FL("num_rates: %d > max val, resetting"),
12394 pIes->ExtSuppRates.num_rates);
12395 pIes->ExtSuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
12396 }
12397 cdf_mem_copy(pParam->extendedRateSet.rate,
12398 pIes->ExtSuppRates.rates,
12399 sizeof(*pIes->ExtSuppRates.rates) *
12400 pIes->ExtSuppRates.num_rates);
12401 }
12402 if (pIes->SSID.present) {
12403 pParam->ssId.length = pIes->SSID.num_ssid;
12404 cdf_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid,
12405 pParam->ssId.length);
12406 }
12407 pParam->cbMode = csr_get_cb_mode_from_ies(pMac, pParam->operationChn,
12408 pIes);
12409}
12410
12411static void csr_roam_determine_max_rate_for_ad_hoc(tpAniSirGlobal pMac,
12412 tSirMacRateSet *pSirRateSet)
12413{
12414 uint8_t MaxRate = 0;
12415 uint32_t i;
12416 uint8_t *pRate;
12417
12418 pRate = pSirRateSet->rate;
12419 for (i = 0; i < pSirRateSet->numRates; i++) {
12420 MaxRate =
12421 CSR_MAX(MaxRate, (pRate[i] & (~CSR_DOT11_BASIC_RATE_MASK)));
12422 }
12423
12424 /* Save the max rate in the connected state information... */
12425
12426 /* modify LastRates variable as well */
12427
12428 return;
12429}
12430
12431CDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
12432 tCsrRoamStartBssParams *pParam,
12433 tCsrRoamProfile *pProfile,
12434 tSirBssDescription *pBssDesc, uint32_t roamId)
12435{
12436 CDF_STATUS status = CDF_STATUS_SUCCESS;
12437 eCsrBand eBand;
12438 /* Set the roaming substate to 'Start BSS attempt'... */
12439 csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_START_BSS_REQ,
12440 sessionId);
12441#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
12442 /* Need to figure out whether we need to log WDS??? */
12443 if (CSR_IS_IBSS(pProfile)) {
12444 host_log_ibss_pkt_type *pIbssLog;
12445 WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
12446 LOG_WLAN_IBSS_C);
12447 if (pIbssLog) {
12448 if (pBssDesc) {
12449 pIbssLog->eventId =
12450 WLAN_IBSS_EVENT_JOIN_IBSS_REQ;
12451 cdf_mem_copy(pIbssLog->bssid, pBssDesc->bssId,
12452 6);
12453 } else {
12454 pIbssLog->eventId =
12455 WLAN_IBSS_EVENT_START_IBSS_REQ;
12456 }
12457 cdf_mem_copy(pIbssLog->ssid, pParam->ssId.ssId,
12458 pParam->ssId.length);
12459 if (pProfile->ChannelInfo.numOfChannels == 0) {
12460 pIbssLog->channelSetting = AUTO_PICK;
12461 } else {
12462 pIbssLog->channelSetting = SPECIFIED;
12463 }
12464 pIbssLog->operatingChannel = pParam->operationChn;
12465 WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
12466 }
12467 }
12468#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
12469 /* Put RSN information in for Starting BSS */
12470 pParam->nRSNIELength = (uint16_t) pProfile->nRSNReqIELength;
12471 pParam->pRSNIE = pProfile->pRSNReqIE;
12472
12473 pParam->privacy = pProfile->privacy;
12474 pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq;
12475 pParam->authType = pProfile->csr80211AuthType;
12476 pParam->beaconInterval = pProfile->beaconInterval;
12477 pParam->dtimPeriod = pProfile->dtimPeriod;
12478 pParam->ApUapsdEnable = pProfile->ApUapsdEnable;
12479 pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden;
12480 if (CSR_IS_INFRA_AP(pProfile) && (pParam->operationChn != 0)) {
12481 if (csr_is_valid_channel(pMac, pParam->operationChn) !=
12482 CDF_STATUS_SUCCESS) {
12483 pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL;
12484 }
12485 }
12486 pParam->protEnabled = pProfile->protEnabled;
12487 pParam->obssProtEnabled = pProfile->obssProtEnabled;
12488 pParam->ht_protection = pProfile->cfg_protection;
12489 pParam->wps_state = pProfile->wps_state;
12490
12491 pParam->uCfgDot11Mode =
12492 csr_roam_get_phy_mode_band_for_bss(pMac, pProfile,
12493 pParam->
12494 operationChn,
12495 &eBand);
12496 pParam->bssPersona = pProfile->csrPersona;
12497
12498#ifdef WLAN_FEATURE_11W
12499 pParam->mfpCapable = (0 != pProfile->MFPCapable);
12500 pParam->mfpRequired = (0 != pProfile->MFPRequired);
12501#endif
12502
12503 pParam->addIeParams.probeRespDataLen =
12504 pProfile->addIeParams.probeRespDataLen;
12505 pParam->addIeParams.probeRespData_buff =
12506 pProfile->addIeParams.probeRespData_buff;
12507
12508 pParam->addIeParams.assocRespDataLen =
12509 pProfile->addIeParams.assocRespDataLen;
12510 pParam->addIeParams.assocRespData_buff =
12511 pProfile->addIeParams.assocRespData_buff;
12512
12513 if (CSR_IS_IBSS(pProfile)) {
12514 pParam->addIeParams.probeRespBCNDataLen =
12515 pProfile->nWPAReqIELength;
12516 pParam->addIeParams.probeRespBCNData_buff = pProfile->pWPAReqIE;
12517 } else {
12518 pParam->addIeParams.probeRespBCNDataLen =
12519 pProfile->addIeParams.probeRespBCNDataLen;
12520 pParam->addIeParams.probeRespBCNData_buff =
12521 pProfile->addIeParams.probeRespBCNData_buff;
12522 }
12523 pParam->sap_dot11mc = pProfile->sap_dot11mc;
12524
12525 /* When starting an IBSS, start on the channel from the Profile. */
12526 status =
12527 csr_send_mb_start_bss_req_msg(pMac, sessionId, pProfile->BSSType, pParam,
12528 pBssDesc);
12529 return status;
12530}
12531
12532static void csr_roam_prepare_bss_params(tpAniSirGlobal pMac, uint32_t sessionId,
12533 tCsrRoamProfile *pProfile,
12534 tSirBssDescription *pBssDesc,
12535 tBssConfigParam *pBssConfig,
12536 tDot11fBeaconIEs *pIes)
12537{
12538 uint8_t Channel;
12539 ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED;
12540 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12541
12542 if (!pSession) {
12543 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12544 return;
12545 }
12546
12547 if (pBssDesc) {
12548 csr_roam_get_bss_start_parms_from_bss_desc(pMac, pBssDesc, pIes,
12549 &pSession->bssParams);
12550 /* Since csr_roam_get_bss_start_parms_from_bss_desc fills in the bssid for pSession->bssParams */
12551 /* The following code has to be do after that. */
12552 /* For WDS station, use selfMac as the self BSSID */
12553 if (CSR_IS_WDS_STA(pProfile)) {
12554 cdf_mem_copy(&pSession->bssParams.bssid,
12555 &pSession->selfMacAddr,
12556 sizeof(struct cdf_mac_addr));
12557 }
12558 } else {
12559 csr_roam_get_bss_start_parms(pMac, pProfile, &pSession->bssParams);
12560 /* Use the first SSID */
12561 if (pProfile->SSIDs.numOfSSIDs) {
12562 cdf_mem_copy(&pSession->bssParams.ssId,
12563 pProfile->SSIDs.SSIDList,
12564 sizeof(tSirMacSSid));
12565 }
12566 /* For WDS station, use selfMac as the self BSSID */
12567 if (CSR_IS_WDS_STA(pProfile)) {
12568 cdf_mem_copy(&pSession->bssParams.bssid,
12569 &pSession->selfMacAddr,
12570 sizeof(struct cdf_mac_addr));
12571 }
12572 /* Use the first BSSID */
12573 else if (pProfile->BSSIDs.numOfBSSIDs) {
12574 cdf_mem_copy(&pSession->bssParams.bssid,
12575 pProfile->BSSIDs.bssid,
12576 sizeof(struct cdf_mac_addr));
12577 } else {
12578 cdf_mem_set(&pSession->bssParams.bssid,
12579 sizeof(struct cdf_mac_addr), 0);
12580 }
12581 }
12582 Channel = pSession->bssParams.operationChn;
12583 /* Set operating channel in pProfile which will be used */
12584 /* in csr_roam_set_bss_config_cfg() to determine channel bonding */
12585 /* mode and will be configured in CFG later */
12586 pProfile->operationChannel = Channel;
12587
12588 if (Channel == 0) {
12589 sms_log(pMac, LOGE,
12590 " CSR cannot find a channel to start IBSS");
12591 } else {
12592
12593 csr_roam_determine_max_rate_for_ad_hoc(pMac,
12594 &pSession->bssParams.
12595 operationalRateSet);
12596 if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS(pProfile)) {
12597 if (CDS_IS_CHANNEL_24GHZ(Channel)) {
12598 cbMode =
12599 pMac->roam.configParam.
12600 channelBondingMode24GHz;
12601 } else {
12602 cbMode =
12603 pMac->roam.configParam.
12604 channelBondingMode5GHz;
12605 }
12606 sms_log(pMac, LOG1, "## cbMode %d", cbMode);
12607 pBssConfig->cbMode = cbMode;
12608 pSession->bssParams.cbMode = cbMode;
12609 }
12610 }
12611}
12612
12613static CDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
12614 tCsrRoamProfile *pProfile,
12615 bool *pfSameIbss)
12616{
12617 CDF_STATUS status = CDF_STATUS_SUCCESS;
12618 bool fSameIbss = false;
12619
12620 if (csr_is_conn_state_ibss(pMac, sessionId)) {
12621 /* Check if any profile parameter has changed ? If any profile parameter */
12622 /* has changed then stop old BSS and start a new one with new parameters */
12623 if (csr_is_same_profile
12624 (pMac, &pMac->roam.roamSession[sessionId].connectedProfile,
12625 pProfile)) {
12626 fSameIbss = true;
12627 } else {
12628 status =
12629 csr_roam_issue_stop_bss(pMac, sessionId,
12630 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
12631 }
12632 } else if (csr_is_conn_state_connected_infra(pMac, sessionId)) {
12633 /* Disassociate from the connected Infrastructure network... */
12634 status =
12635 csr_roam_issue_disassociate(pMac, sessionId,
12636 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
12637 false);
12638 } else {
12639 tBssConfigParam *pBssConfig;
12640
12641 pBssConfig = cdf_mem_malloc(sizeof(tBssConfigParam));
12642 if (NULL == pBssConfig)
12643 status = CDF_STATUS_E_NOMEM;
12644 else
12645 status = CDF_STATUS_SUCCESS;
12646 if (CDF_IS_STATUS_SUCCESS(status)) {
12647 cdf_mem_set(pBssConfig, sizeof(tBssConfigParam), 0);
12648 /* there is no Bss description before we start an IBSS so we need to adopt */
12649 /* all Bss configuration parameters from the Profile. */
12650 status =
12651 csr_roam_prepare_bss_config_from_profile(pMac, pProfile,
12652 pBssConfig,
12653 NULL);
12654 if (CDF_IS_STATUS_SUCCESS(status)) {
12655 /* save dotMode */
12656 pMac->roam.roamSession[sessionId].bssParams.
12657 uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
12658 /* Prepare some more parameters for this IBSS */
12659 csr_roam_prepare_bss_params(pMac, sessionId,
12660 pProfile, NULL,
12661 pBssConfig, NULL);
12662 status =
12663 csr_roam_set_bss_config_cfg(pMac, sessionId,
12664 pProfile, NULL,
12665 pBssConfig, NULL,
12666 false);
12667 }
12668
12669 cdf_mem_free(pBssConfig);
12670 } /* Allocate memory */
12671 }
12672
12673 if (pfSameIbss) {
12674 *pfSameIbss = fSameIbss;
12675 }
12676 return status;
12677}
12678
12679static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
12680 uint32_t sessionId,
12681 tSirSmeNewBssInfo *pNewBss)
12682{
12683 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12684
12685 if (!pSession) {
12686 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12687 return;
12688 }
12689
12690 if (pNewBss) {
12691 /* Set the operating channel. */
12692 pSession->connectedProfile.operationChannel =
12693 pNewBss->channelNumber;
12694 /* move the BSSId from the BSS description into the connected state information. */
12695 cdf_mem_copy(&pSession->connectedProfile.bssid.bytes,
12696 &(pNewBss->bssId), sizeof(struct cdf_mac_addr));
12697 }
12698 return;
12699}
12700
12701#ifdef WLAN_FEATURE_ROAM_OFFLOAD
12702CDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId,
12703 uint8_t *pPSK_PMK, size_t pmk_len)
12704{
12705 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12706 if (!pSession) {
12707 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
12708 return CDF_STATUS_E_FAILURE;
12709 }
12710 cdf_mem_copy(pSession->psk_pmk, pPSK_PMK, sizeof(pSession->psk_pmk));
12711 pSession->pmk_len = pmk_len;
12712 return CDF_STATUS_SUCCESS;
12713}
12714#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
12715
12716#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
12717static void
12718csr_roam_diag_set_pmkid(tCsrRoamSession *pSession)
12719{
12720 WLAN_HOST_DIAG_EVENT_DEF(secEvent,
12721 host_event_wlan_security_payload_type);
12722 cdf_mem_set(&secEvent,
12723 sizeof(host_event_wlan_security_payload_type), 0);
12724 secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE;
12725 secEvent.encryptionModeMulticast =
12726 (uint8_t) diag_enc_type_from_csr_type(
12727 pSession->connectedProfile.mcEncryptionType);
12728 secEvent.encryptionModeUnicast =
12729 (uint8_t) diag_enc_type_from_csr_type(
12730 pSession->connectedProfile.EncryptionType);
12731 cdf_mem_copy(secEvent.bssid,
12732 pSession->connectedProfile.bssid.bytes,
12733 CDF_MAC_ADDR_SIZE);
12734 secEvent.authMode = (uint8_t) diag_auth_type_from_csr_type(
12735 pSession->connectedProfile.AuthType);
12736 WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
12737}
12738#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
12739
12740CDF_STATUS
12741csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
12742 tPmkidCacheInfo *pPMKIDCache, uint32_t numItems,
12743 bool update_entire_cache)
12744{
12745 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12746 uint32_t i = 0;
12747 tPmkidCacheInfo *pmksa;
12748
12749 if (!pSession) {
12750 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
12751 return CDF_STATUS_E_FAILURE;
12752 }
12753
12754 sms_log(pMac, LOGW, FL("numItems = %d"), numItems);
12755
12756 if (numItems > CSR_MAX_PMKID_ALLOWED)
12757 return CDF_STATUS_E_INVAL;
12758
12759#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
12760 csr_roam_diag_set_pmkid(pSession);
12761#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
12762
12763 if (update_entire_cache) {
12764 if (numItems && pPMKIDCache) {
12765 pSession->NumPmkidCache = (uint16_t) numItems;
12766 cdf_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache,
12767 sizeof(tPmkidCacheInfo) * numItems);
12768 pSession->curr_cache_idx = (uint16_t)numItems;
12769 }
12770 return CDF_STATUS_SUCCESS;
12771 }
12772
12773 for (i = 0; i < numItems; i++) {
12774 pmksa = &pPMKIDCache[i];
12775
12776 /* Delete the entry if present */
12777 csr_roam_del_pmkid_from_cache(pMac, sessionId,
12778 pmksa->BSSID.bytes, false);
12779
12780 /* Add entry to the cache */
12781 cdf_copy_macaddr(
12782 &pSession->PmkidCacheInfo[pSession->curr_cache_idx].BSSID,
12783 &pmksa->BSSID);
12784 cdf_mem_copy(
12785 pSession->PmkidCacheInfo[pSession->curr_cache_idx].PMKID,
12786 pmksa->PMKID, CSR_RSN_PMKID_SIZE);
12787
12788 /* Increment the CSR local cache index */
12789 if (pSession->curr_cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
12790 pSession->curr_cache_idx++;
12791 else
12792 pSession->curr_cache_idx = 0;
12793
12794 pSession->NumPmkidCache++;
12795 if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED)
12796 pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
12797 }
12798 return CDF_STATUS_SUCCESS;
12799}
12800
12801CDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
12802 uint32_t sessionId,
12803 const uint8_t *pBSSId,
12804 bool flush_cache)
12805{
12806 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12807 bool fMatchFound = false;
12808 uint32_t Index;
12809 uint32_t curr_idx;
12810 uint32_t i;
12811
12812 if (!pSession) {
12813 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12814 return CDF_STATUS_E_FAILURE;
12815 }
12816
12817 /* Check if there are no entries to delete */
12818 if (0 == pSession->NumPmkidCache) {
12819 sms_log(pMac, LOG1, FL("No entries to delete/Flush"));
12820 return CDF_STATUS_SUCCESS;
12821 }
12822
12823 if (flush_cache) {
12824 /* Flush the entire cache */
12825 cdf_mem_zero(pSession->PmkidCacheInfo,
12826 sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED);
12827 pSession->NumPmkidCache = 0;
12828 pSession->curr_cache_idx = 0;
12829 return CDF_STATUS_SUCCESS;
12830 }
12831
12832 /* !flush_cache - so look up in the cache */
12833 for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
12834 if (cdf_mem_compare(pSession->PmkidCacheInfo[Index].BSSID.bytes,
12835 pBSSId, CDF_MAC_ADDR_SIZE)) {
12836 fMatchFound = 1;
12837
12838 /* Clear this - the matched entry */
12839 cdf_mem_zero(&pSession->PmkidCacheInfo[Index],
12840 sizeof(tPmkidCacheInfo));
12841 break;
12842 }
12843 }
12844
12845 if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) {
12846 sms_log(pMac, LOG1, FL("No such PMKSA entry exists"
12847 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pBSSId));
12848 return CDF_STATUS_SUCCESS;
12849 }
12850
12851 /* Match Found, Readjust the other entries */
12852 curr_idx = pSession->curr_cache_idx;
12853 if (Index < curr_idx) {
12854 for (i = Index; i < (curr_idx - 1); i++) {
12855 cdf_mem_copy(&pSession->PmkidCacheInfo[i],
12856 &pSession->PmkidCacheInfo[i + 1],
12857 sizeof(tPmkidCacheInfo));
12858 }
12859
12860 pSession->curr_cache_idx--;
12861 cdf_mem_zero(&pSession->PmkidCacheInfo
12862 [pSession->curr_cache_idx],
12863 sizeof(tPmkidCacheInfo));
12864 } else if (Index > curr_idx) {
12865 for (i = Index; i > (curr_idx); i--) {
12866 cdf_mem_copy(&pSession->PmkidCacheInfo[i],
12867 &pSession->PmkidCacheInfo[i - 1],
12868 sizeof(tPmkidCacheInfo));
12869 }
12870
12871 cdf_mem_zero(&pSession->PmkidCacheInfo
12872 [pSession->curr_cache_idx],
12873 sizeof(tPmkidCacheInfo));
12874 }
12875
12876 /* Decrement the count since an entry has been deleted */
12877 pSession->NumPmkidCache--;
12878 return CDF_STATUS_SUCCESS;
12879}
12880
12881uint32_t csr_roam_get_num_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId)
12882{
12883 return pMac->roam.roamSession[sessionId].NumPmkidCache;
12884}
12885
12886CDF_STATUS csr_roam_get_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
12887 uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
12888{
12889 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12890 tPmkidCacheInfo *pmksa;
12891 uint16_t i, j;
12892
12893 if (!pSession) {
12894 sms_log(pMac, LOGE, FL("session %d not found "), sessionId);
12895 return CDF_STATUS_E_FAILURE;
12896 }
12897
12898 if (!pNum || !pPmkidCache) {
12899 sms_log(pMac, LOGE, FL("Either pNum or pPmkidCache is NULL"));
12900 return CDF_STATUS_E_FAILURE;
12901 }
12902
12903 if (pSession->NumPmkidCache == 0) {
12904 *pNum = 0;
12905 return CDF_STATUS_SUCCESS;
12906 }
12907
12908 if (*pNum < pSession->NumPmkidCache) {
12909 return CDF_STATUS_E_FAILURE;
12910 }
12911
12912 if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) {
12913 sms_log(pMac, LOGE,
12914 FL(
12915 "NumPmkidCache :%d is more than CSR_MAX_PMKID_ALLOWED, resetting to CSR_MAX_PMKID_ALLOWED"),
12916 pSession->NumPmkidCache);
12917 pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
12918 }
12919
12920 for (i = 0, j = 0; ((j < pSession->NumPmkidCache) &&
12921 (i < CSR_MAX_PMKID_ALLOWED)); i++) {
12922 /* Fill the valid entries */
12923 pmksa = &pSession->PmkidCacheInfo[i];
12924 if (!cdf_is_macaddr_zero(&pmksa->BSSID)) {
12925 cdf_mem_copy(pPmkidCache, pmksa,
12926 sizeof(tPmkidCacheInfo));
12927 pPmkidCache++;
12928 j++;
12929 }
12930 }
12931
12932 *pNum = pSession->NumPmkidCache;
12933 return CDF_STATUS_SUCCESS;
12934}
12935
12936CDF_STATUS csr_roam_get_wpa_rsn_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
12937 uint32_t *pLen, uint8_t *pBuf)
12938{
12939 CDF_STATUS status = CDF_STATUS_E_INVAL;
12940 uint32_t len;
12941 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12942
12943 if (!pSession) {
12944 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12945 return CDF_STATUS_E_FAILURE;
12946 }
12947
12948 if (pLen) {
12949 len = *pLen;
12950 *pLen = pSession->nWpaRsnReqIeLength;
12951 if (pBuf) {
12952 if (len >= pSession->nWpaRsnReqIeLength) {
12953 cdf_mem_copy(pBuf, pSession->pWpaRsnReqIE,
12954 pSession->nWpaRsnReqIeLength);
12955 status = CDF_STATUS_SUCCESS;
12956 }
12957 }
12958 }
12959 return status;
12960}
12961
12962CDF_STATUS csr_roam_get_wpa_rsn_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
12963 uint32_t *pLen, uint8_t *pBuf)
12964{
12965 CDF_STATUS status = CDF_STATUS_E_INVAL;
12966 uint32_t len;
12967 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12968
12969 if (!pSession) {
12970 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12971 return CDF_STATUS_E_FAILURE;
12972 }
12973
12974 if (pLen) {
12975 len = *pLen;
12976 *pLen = pSession->nWpaRsnRspIeLength;
12977 if (pBuf) {
12978 if (len >= pSession->nWpaRsnRspIeLength) {
12979 cdf_mem_copy(pBuf, pSession->pWpaRsnRspIE,
12980 pSession->nWpaRsnRspIeLength);
12981 status = CDF_STATUS_SUCCESS;
12982 }
12983 }
12984 }
12985 return status;
12986}
12987
12988#ifdef FEATURE_WLAN_WAPI
12989CDF_STATUS csr_roam_get_wapi_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
12990 uint32_t *pLen, uint8_t *pBuf)
12991{
12992 CDF_STATUS status = CDF_STATUS_E_INVAL;
12993 uint32_t len;
12994 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
12995
12996 if (!pSession) {
12997 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
12998 return CDF_STATUS_E_FAILURE;
12999 }
13000
13001 if (pLen) {
13002 len = *pLen;
13003 *pLen = pSession->nWapiReqIeLength;
13004 if (pBuf) {
13005 if (len >= pSession->nWapiReqIeLength) {
13006 cdf_mem_copy(pBuf, pSession->pWapiReqIE,
13007 pSession->nWapiReqIeLength);
13008 status = CDF_STATUS_SUCCESS;
13009 }
13010 }
13011 }
13012 return status;
13013}
13014
13015CDF_STATUS csr_roam_get_wapi_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
13016 uint32_t *pLen, uint8_t *pBuf)
13017{
13018 CDF_STATUS status = CDF_STATUS_E_INVAL;
13019 uint32_t len;
13020 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
13021
13022 if (!pSession) {
13023 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
13024 return CDF_STATUS_E_FAILURE;
13025 }
13026
13027 if (pLen) {
13028 len = *pLen;
13029 *pLen = pSession->nWapiRspIeLength;
13030 if (pBuf) {
13031 if (len >= pSession->nWapiRspIeLength) {
13032 cdf_mem_copy(pBuf, pSession->pWapiRspIE,
13033 pSession->nWapiRspIeLength);
13034 status = CDF_STATUS_SUCCESS;
13035 }
13036 }
13037 }
13038 return status;
13039}
13040#endif /* FEATURE_WLAN_WAPI */
13041eRoamCmdStatus csr_get_roam_complete_status(tpAniSirGlobal pMac, uint32_t sessionId)
13042{
13043 eRoamCmdStatus retStatus = eCSR_ROAM_CONNECT_COMPLETION;
13044 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
13045
13046 if (!pSession) {
13047 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
13048 return retStatus;
13049 }
13050
13051 if (CSR_IS_ROAMING(pSession)) {
13052 retStatus = eCSR_ROAM_ROAMING_COMPLETION;
13053 pSession->fRoaming = false;
13054 }
13055 return retStatus;
13056}
13057
13058/* This function remove the connected BSS from te cached scan result */
13059CDF_STATUS
13060csr_roam_remove_connected_bss_from_scan_cache(tpAniSirGlobal pMac,
13061 tCsrRoamConnectedProfile *pConnProfile)
13062{
13063 CDF_STATUS status = CDF_STATUS_E_FAILURE;
13064 tCsrScanResultFilter *pScanFilter = NULL;
13065 tListElem *pEntry;
13066 tCsrScanResult *pResult;
13067 tDot11fBeaconIEs *pIes;
13068 bool fMatch;
13069
13070 if ((cdf_is_macaddr_zero(&pConnProfile->bssid) ||
13071 cdf_is_macaddr_broadcast(&pConnProfile->bssid)))
13072 return status;
13073 /*
13074 * Prepare the filter. Only fill in the necessary fields. Not all fields
13075 * are needed
13076 */
13077 pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
13078 if (NULL == pScanFilter)
13079 return CDF_STATUS_E_NOMEM;
13080
13081 cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
13082 pScanFilter->BSSIDs.bssid = cdf_mem_malloc(sizeof(struct cdf_mac_addr));
13083 if (NULL == pScanFilter->BSSIDs.bssid) {
13084 cdf_mem_free(pScanFilter);
13085 return CDF_STATUS_E_NOMEM;
13086 }
13087 cdf_mem_copy(pScanFilter->BSSIDs.bssid,
13088 &pConnProfile->bssid, sizeof(struct cdf_mac_addr));
13089 pScanFilter->BSSIDs.numOfBSSIDs = 1;
13090 if (!csr_is_nullssid(pConnProfile->SSID.ssId,
13091 pConnProfile->SSID.length)) {
13092 pScanFilter->SSIDs.SSIDList = cdf_mem_malloc(
13093 sizeof(tCsrSSIDInfo));
13094 if (NULL == pScanFilter->SSIDs.SSIDList) {
13095 csr_free_scan_filter(pMac, pScanFilter);
13096 cdf_mem_free(pScanFilter);
13097 return CDF_STATUS_E_NOMEM;
13098 }
13099 cdf_mem_copy(&pScanFilter->SSIDs.SSIDList[0].SSID,
13100 &pConnProfile->SSID, sizeof(tSirMacSSid));
13101 }
13102 pScanFilter->authType.numEntries = 1;
13103 pScanFilter->authType.authType[0] = pConnProfile->AuthType;
13104 pScanFilter->BSSType = pConnProfile->BSSType;
13105 pScanFilter->EncryptionType.numEntries = 1;
13106 pScanFilter->EncryptionType.encryptionType[0] =
13107 pConnProfile->EncryptionType;
13108 pScanFilter->mcEncryptionType.numEntries = 1;
13109 pScanFilter->mcEncryptionType.encryptionType[0] =
13110 pConnProfile->mcEncryptionType;
13111 /* We ignore the channel for now, BSSID should be enough */
13112 pScanFilter->ChannelInfo.numOfChannels = 0;
13113 /* Also ignore the following fields */
13114 pScanFilter->uapsd_mask = 0;
13115 pScanFilter->bWPSAssociation = false;
13116 pScanFilter->bOSENAssociation = false;
13117 pScanFilter->countryCode[0] = 0;
13118 pScanFilter->phyMode = eCSR_DOT11_MODE_AUTO;
13119 csr_ll_lock(&pMac->scan.scanResultList);
13120 pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
13121 while (pEntry) {
13122 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
13123 pIes = (tDot11fBeaconIEs *) (pResult->Result.pvIes);
13124 fMatch = csr_match_bss(pMac, &pResult->Result.BssDescriptor,
13125 pScanFilter, NULL, NULL, NULL, &pIes);
13126 /* Release the IEs allocated by csr_match_bss is needed */
13127 if (!pResult->Result.pvIes) {
13128 /*
13129 * need to free the IEs since it is allocated
13130 * by csr_match_bss
13131 */
13132 cdf_mem_free(pIes);
13133 }
13134 if (fMatch) {
13135 /* We found the one */
13136 if (csr_ll_remove_entry(&pMac->scan.scanResultList,
13137 pEntry, LL_ACCESS_NOLOCK))
13138 /* Free the memory */
13139 csr_free_scan_result_entry(pMac, pResult);
13140 break;
13141 }
13142 pEntry = csr_ll_next(&pMac->scan.scanResultList,
13143 pEntry, LL_ACCESS_NOLOCK);
13144 } /* while */
13145 csr_ll_unlock(&pMac->scan.scanResultList);
13146 csr_free_scan_filter(pMac, pScanFilter);
13147 cdf_mem_free(pScanFilter);
13148 return status;
13149}
13150
13151static CDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac, uint32_t sessionId,
13152 tCsrRoamProfile *pProfile,
13153 tSirBssDescription *pBssDesc)
13154{
13155 CDF_STATUS status = CDF_STATUS_SUCCESS;
13156 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
13157 tBssConfigParam bssConfig;
13158
13159 if (!pSession) {
13160 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
13161 return CDF_STATUS_E_FAILURE;
13162 }
13163
13164 if (csr_is_conn_state_ibss(pMac, sessionId)) {
13165 status =
13166 csr_roam_issue_stop_bss(pMac, sessionId,
13167 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
13168 } else if (csr_is_conn_state_connected_infra(pMac, sessionId)) {
13169 /* Disassociate from the connected Infrastructure network... */
13170 status =
13171 csr_roam_issue_disassociate(pMac, sessionId,
13172 eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
13173 false);
13174 } else {
13175 /* We don't expect Bt-AMP HDD not to disconnect the last connection first at this time. */
13176 /* Otherwise we need to add code to handle the */
13177 /* situation just like IBSS. Though for WDS station, we need to send disassoc to PE first then */
13178 /* send stop_bss to PE, before we can continue. */
13179
13180 if (csr_is_conn_state_wds(pMac, sessionId)) {
13181 CDF_ASSERT(0);
13182 return CDF_STATUS_E_FAILURE;
13183 }
13184 cdf_mem_set(&bssConfig, sizeof(tBssConfigParam), 0);
13185 /* Assume HDD provide bssid in profile */
13186 cdf_copy_macaddr(&pSession->bssParams.bssid,
13187 pProfile->BSSIDs.bssid);
13188 /* there is no Bss description before we start an WDS so we need */
13189 /* to adopt all Bss configuration parameters from the Profile. */
13190 status =
13191 csr_roam_prepare_bss_config_from_profile(pMac, pProfile,
13192 &bssConfig, pBssDesc);
13193 if (CDF_IS_STATUS_SUCCESS(status)) {
13194 /* Save profile for late use */
13195 csr_free_roam_profile(pMac, sessionId);
13196 pSession->pCurRoamProfile =
13197 cdf_mem_malloc(sizeof(tCsrRoamProfile));
13198 if (pSession->pCurRoamProfile != NULL) {
13199 cdf_mem_set(pSession->pCurRoamProfile,
13200 sizeof(tCsrRoamProfile), 0);
13201 csr_roam_copy_profile(pMac,
13202 pSession->pCurRoamProfile,
13203 pProfile);
13204 }
13205 /* Prepare some more parameters for this WDS */
13206 csr_roam_prepare_bss_params(pMac, sessionId, pProfile, NULL,
13207 &bssConfig, NULL);
13208 status =
13209 csr_roam_set_bss_config_cfg(pMac, sessionId, pProfile,
13210 NULL, &bssConfig, NULL,
13211 false);
13212 }
13213 }
13214
13215 return status;
13216}
13217
13218/**
13219 * csr_add_supported_5Ghz_channels()- Add valid 5Ghz channels
13220 * in Join req.
13221 * @mac_ctx: pointer to global mac structure
13222 * @csr_join_req: join req sent to lim
13223 *
13224 * This function is called to update valid 5Ghz channels
13225 * in Join req.
13226 *
13227 * Return: void
13228 */
13229static void csr_add_supported_5Ghz_channels(tpAniSirGlobal mac_ctx,
13230 tSirSmeJoinReq *csr_join_req)
13231{
13232 uint16_t i, j;
13233 uint32_t size = 0;
13234
13235 if (!csr_join_req) {
13236 sms_log(mac_ctx, LOGE, FL(" csr_join_reqis NULL"));
13237 return;
13238 }
13239
13240 size = sizeof(mac_ctx->roam.validChannelList);
13241 if (CDF_IS_STATUS_SUCCESS
13242 (csr_get_cfg_valid_channels(mac_ctx,
13243 (uint8_t *) mac_ctx->roam.validChannelList,
13244 &size))) {
13245 for (i = 0, j = 0; i < size; i++) {
13246 /* Only add 5ghz channels.*/
13247 if (CDS_IS_CHANNEL_5GHZ
13248 (mac_ctx->roam.validChannelList[i])) {
13249 csr_join_req->supportedChannels.channelList[j] =
13250 mac_ctx->roam.validChannelList[i];
13251 j++;
13252 }
13253 }
13254 csr_join_req->supportedChannels.numChnl = j;
13255 } else {
13256 sms_log(mac_ctx, LOGE,
13257 FL("can not find any valid channel"));
13258 csr_join_req->supportedChannels.numChnl = 0;
13259 }
13260}
13261
13262/**
13263 * The communication between HDD and LIM is thru mailbox (MB).
13264 * Both sides will access the data structure "tSirSmeJoinReq".
13265 * The rule is, while the components of "tSirSmeJoinReq" can be accessed in the
13266 * regular way like tSirSmeJoinReq.assocType, this guideline stops at component
13267 * tSirRSNie;
13268 * any acces to the components after tSirRSNie is forbidden because the space
13269 * from tSirRSNie is squeezed with the component "tSirBssDescription" and since
13270 * the size of actual 'tSirBssDescription' varies, the receiving side should
13271 * keep in mind not to access the components DIRECTLY after tSirRSNie.
13272 */
13273CDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
13274 tSirBssDescription *pBssDescription,
13275 tCsrRoamProfile *pProfile,
13276 tDot11fBeaconIEs *pIes, uint16_t messageType)
13277{
13278 CDF_STATUS status = CDF_STATUS_SUCCESS;
13279 uint8_t acm_mask = 0, uapsd_mask;
13280 uint16_t msgLen, ieLen;
13281 tSirMacRateSet OpRateSet;
13282 tSirMacRateSet ExRateSet;
13283 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
13284 uint32_t dwTmp, ucDot11Mode = 0;
13285 /* RSN MAX is bigger than WPA MAX */
13286 uint8_t wpaRsnIE[DOT11F_IE_RSN_MAX_LEN];
13287 uint8_t txBFCsnValue = 0;
13288 tSirSmeJoinReq *csr_join_req;
13289 tSirMacCapabilityInfo *pAP_capabilityInfo;
13290 tAniBool fTmp;
13291 int8_t pwrLimit = 0;
13292 struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
13293 struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
13294 uint8_t ese_config = 0;
13295
13296
13297 if (!pSession) {
13298 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
13299 return CDF_STATUS_E_FAILURE;
13300 }
13301 /* To satisfy klockworks */
13302 if (NULL == pBssDescription) {
13303 sms_log(pMac, LOGE, FL(" pBssDescription is NULL"));
13304 return CDF_STATUS_E_FAILURE;
13305 }
13306
13307 do {
13308 pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
13309 pSession->joinFailStatusCode.reasonCode = 0;
13310 cdf_mem_copy(&pSession->joinFailStatusCode.bssId,
13311 &pBssDescription->bssId, sizeof(tSirMacAddr));
13312 /*
13313 * the tSirSmeJoinReq which includes a single
13314 * bssDescription. it includes a single uint32_t for the
13315 * IE fields, but the length field in the bssDescription
13316 * needs to be interpreted to determine length of IE fields
13317 * So, take the size of the tSirSmeJoinReq, subtract size of
13318 * bssDescription, add the number of bytes indicated by the
13319 * length field of the bssDescription, add the size of length
13320 * field because it not included in the lenghth field.
13321 */
13322 msgLen = sizeof(tSirSmeJoinReq) - sizeof(*pBssDescription) +
13323 pBssDescription->length +
13324 sizeof(pBssDescription->length) +
13325 /*
13326 * add in the size of the WPA IE that
13327 * we may build.
13328 */
13329 sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) +
13330 sizeof(uint16_t);
13331 csr_join_req = cdf_mem_malloc(msgLen);
13332 if (NULL == csr_join_req)
13333 status = CDF_STATUS_E_NOMEM;
13334 else
13335 status = CDF_STATUS_SUCCESS;
13336 if (!CDF_IS_STATUS_SUCCESS(status))
13337 break;
13338 cdf_mem_set(csr_join_req, msgLen, 0);
13339 csr_join_req->messageType = messageType;
13340 csr_join_req->length = msgLen;
13341 csr_join_req->sessionId = (uint8_t) sessionId;
13342 csr_join_req->transactionId = 0;
13343 if (pIes->SSID.present && pIes->SSID.num_ssid) {
13344 csr_join_req->ssId.length = pIes->SSID.num_ssid;
13345 cdf_mem_copy(&csr_join_req->ssId.ssId, pIes->SSID.ssid,
13346 pIes->SSID.num_ssid);
13347 } else
13348 csr_join_req->ssId.length = 0;
13349 cdf_mem_copy(&csr_join_req->selfMacAddr, &pSession->selfMacAddr,
13350 sizeof(tSirMacAddr));
13351 /* bsstype */
13352 dwTmp = csr_translate_bsstype_to_mac_type
13353 (pProfile->BSSType);
13354 /* Override BssType for BTAMP */
13355 if (dwTmp == eSIR_BTAMP_STA_MODE)
13356 dwTmp = eSIR_BTAMP_AP_MODE;
13357 csr_join_req->bsstype = dwTmp;
13358 /* dot11mode */
13359 ucDot11Mode =
13360 csr_translate_to_wni_cfg_dot11_mode(pMac,
13361 pSession->bssParams.
13362 uCfgDot11Mode);
13363 if (pBssDescription->channelId <= 14
13364 && false == pMac->roam.configParam.enableVhtFor24GHz
13365 && WNI_CFG_DOT11_MODE_11AC == ucDot11Mode) {
13366 /* Need to disable VHT operation in 2.4 GHz band */
13367 ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
13368 }
13369 csr_join_req->dot11mode = (uint8_t) ucDot11Mode;
13370#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
13371 csr_join_req->cc_switch_mode =
13372 pMac->roam.configParam.cc_switch_mode;
13373#endif
13374 csr_join_req->staPersona = (uint8_t) pProfile->csrPersona;
13375 csr_join_req->cbMode = (uint8_t) pSession->bssParams.cbMode;
13376 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13377 FL("CSR PERSONA=%d CSR CbMode %d"),
13378 pProfile->csrPersona, pSession->bssParams.cbMode);
13379 csr_join_req->uapsdPerAcBitmask = pProfile->uapsd_mask;
13380 status =
13381 csr_get_rate_set(pMac, pProfile,
13382 (eCsrPhyMode) pProfile->phyMode,
13383 pBssDescription, pIes, &OpRateSet,
13384 &ExRateSet);
13385 ps_param->uapsd_per_ac_bit_mask =
13386 pProfile->uapsd_mask;
13387 if (CDF_IS_STATUS_SUCCESS(status)) {
13388 /* OperationalRateSet */
13389 if (OpRateSet.numRates) {
13390 csr_join_req->operationalRateSet.numRates =
13391 OpRateSet.numRates;
13392 cdf_mem_copy(&csr_join_req->operationalRateSet.
13393 rate, OpRateSet.rate,
13394 OpRateSet.numRates);
13395 } else
13396 csr_join_req->operationalRateSet.numRates = 0;
13397
13398 /* ExtendedRateSet */
13399 if (ExRateSet.numRates) {
13400 csr_join_req->extendedRateSet.numRates =
13401 ExRateSet.numRates;
13402 cdf_mem_copy(&csr_join_req->extendedRateSet.
13403 rate, ExRateSet.rate,
13404 ExRateSet.numRates);
13405 } else
13406 csr_join_req->extendedRateSet.numRates = 0;
13407 } else {
13408 csr_join_req->operationalRateSet.numRates = 0;
13409 csr_join_req->extendedRateSet.numRates = 0;
13410 }
13411 /* rsnIE */
13412 if (csr_is_profile_wpa(pProfile)) {
13413 /* Insert the Wpa IE into the join request */
13414 ieLen =
13415 csr_retrieve_wpa_ie(pMac, pProfile,
13416 pBssDescription, pIes,
13417 (tCsrWpaIe *) (wpaRsnIE));
13418 } else if (csr_is_profile_rsn(pProfile)) {
13419 /* Insert the RSN IE into the join request */
13420 ieLen =
13421 csr_retrieve_rsn_ie(pMac, sessionId, pProfile,
13422 pBssDescription, pIes,
13423 (tCsrRSNIe *) (wpaRsnIE));
13424 }
13425#ifdef FEATURE_WLAN_WAPI
13426 else if (csr_is_profile_wapi(pProfile)) {
13427 /* Insert the WAPI IE into the join request */
13428 ieLen =
13429 csr_retrieve_wapi_ie(pMac, sessionId, pProfile,
13430 pBssDescription, pIes,
13431 (tCsrWapiIe *) (wpaRsnIE));
13432 }
13433#endif /* FEATURE_WLAN_WAPI */
13434 else {
13435 ieLen = 0;
13436 }
13437 /* remember the IE for future use */
13438 if (ieLen) {
13439 if (ieLen > DOT11F_IE_RSN_MAX_LEN) {
13440 sms_log(pMac, LOGE,
13441 FL
13442 (" WPA RSN IE length :%d is more than DOT11F_IE_RSN_MAX_LEN, resetting to %d"),
13443 ieLen, DOT11F_IE_RSN_MAX_LEN);
13444 ieLen = DOT11F_IE_RSN_MAX_LEN;
13445 }
13446#ifdef FEATURE_WLAN_WAPI
13447 if (csr_is_profile_wapi(pProfile)) {
13448 /* Check whether we need to allocate more mem */
13449 if (ieLen > pSession->nWapiReqIeLength) {
13450 if (pSession->pWapiReqIE
13451 && pSession->nWapiReqIeLength) {
13452 cdf_mem_free(pSession->
13453 pWapiReqIE);
13454 }
13455 pSession->pWapiReqIE =
13456 cdf_mem_malloc(ieLen);
13457 if (NULL == pSession->pWapiReqIE)
13458 status = CDF_STATUS_E_NOMEM;
13459 else
13460 status = CDF_STATUS_SUCCESS;
13461 if (!CDF_IS_STATUS_SUCCESS(status))
13462 break;
13463 }
13464 pSession->nWapiReqIeLength = ieLen;
13465 cdf_mem_copy(pSession->pWapiReqIE, wpaRsnIE,
13466 ieLen);
13467 csr_join_req->rsnIE.length = ieLen;
13468 cdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
13469 wpaRsnIE, ieLen);
13470 } else /* should be WPA/WPA2 otherwise */
13471#endif /* FEATURE_WLAN_WAPI */
13472 {
13473 /* Check whether we need to allocate more mem */
13474 if (ieLen > pSession->nWpaRsnReqIeLength) {
13475 if (pSession->pWpaRsnReqIE
13476 && pSession->nWpaRsnReqIeLength) {
13477 cdf_mem_free(pSession->
13478 pWpaRsnReqIE);
13479 }
13480 pSession->pWpaRsnReqIE =
13481 cdf_mem_malloc(ieLen);
13482 if (NULL == pSession->pWpaRsnReqIE)
13483 status = CDF_STATUS_E_NOMEM;
13484 else
13485 status = CDF_STATUS_SUCCESS;
13486 if (!CDF_IS_STATUS_SUCCESS(status))
13487 break;
13488 }
13489 pSession->nWpaRsnReqIeLength = ieLen;
13490 cdf_mem_copy(pSession->pWpaRsnReqIE, wpaRsnIE,
13491 ieLen);
13492 csr_join_req->rsnIE.length = ieLen;
13493 cdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
13494 wpaRsnIE, ieLen);
13495 }
13496 } else {
13497 /* free whatever old info */
13498 pSession->nWpaRsnReqIeLength = 0;
13499 if (pSession->pWpaRsnReqIE) {
13500 cdf_mem_free(pSession->pWpaRsnReqIE);
13501 pSession->pWpaRsnReqIE = NULL;
13502 }
13503#ifdef FEATURE_WLAN_WAPI
13504 pSession->nWapiReqIeLength = 0;
13505 if (pSession->pWapiReqIE) {
13506 cdf_mem_free(pSession->pWapiReqIE);
13507 pSession->pWapiReqIE = NULL;
13508 }
13509#endif /* FEATURE_WLAN_WAPI */
13510 csr_join_req->rsnIE.length = 0;
13511 }
13512#ifdef FEATURE_WLAN_ESE
13513 if (eWNI_SME_JOIN_REQ == messageType)
13514 csr_join_req->cckmIE.length = 0;
13515 else if (eWNI_SME_REASSOC_REQ == messageType) {
13516 /* cckmIE */
13517 if (csr_is_profile_ese(pProfile)) {
13518 /* Insert the CCKM IE into the join request */
13519#ifdef FEATURE_WLAN_ESE_UPLOAD
13520 ieLen = pSession->suppCckmIeInfo.cckmIeLen;
13521 cdf_mem_copy((void *)(wpaRsnIE),
13522 pSession->suppCckmIeInfo.cckmIe,
13523 ieLen);
13524#else
13525 ieLen = csrConstructEseCckmIe(pMac,
13526 pSession,
13527 pProfile,
13528 pBssDescription,
13529 pSession->
13530 pWpaRsnReqIE,
13531 pSession->
13532 nWpaRsnReqIeLength,
13533 (void *)(wpaRsnIE));
13534#endif /* FEATURE_WLAN_ESE_UPLOAD */
13535 } else
13536 ieLen = 0;
13537 /*
13538 * If present, copy the IE into the
13539 * eWNI_SME_REASSOC_REQ message buffer
13540 */
13541 if (ieLen) {
13542 /*
13543 * Copy the CCKM IE over from the temp
13544 * buffer (wpaRsnIE)
13545 */
13546 csr_join_req->cckmIE.length = ieLen;
13547 cdf_mem_copy(&csr_join_req->cckmIE.cckmIEdata,
13548 wpaRsnIE, ieLen);
13549 } else
13550 csr_join_req->cckmIE.length = 0;
13551 }
13552#endif /* FEATURE_WLAN_ESE */
13553 /* addIEScan */
13554 if (pProfile->nAddIEScanLength && pProfile->pAddIEScan) {
13555 ieLen = pProfile->nAddIEScanLength;
13556 if (ieLen > pSession->nAddIEScanLength) {
13557 if (pSession->pAddIEScan
13558 && pSession->nAddIEScanLength) {
13559 cdf_mem_free(pSession->pAddIEScan);
13560 }
13561 pSession->pAddIEScan = cdf_mem_malloc(ieLen);
13562 if (NULL == pSession->pAddIEScan)
13563 status = CDF_STATUS_E_NOMEM;
13564 else
13565 status = CDF_STATUS_SUCCESS;
13566 if (!CDF_IS_STATUS_SUCCESS(status))
13567 break;
13568 }
13569 pSession->nAddIEScanLength = ieLen;
13570 cdf_mem_copy(pSession->pAddIEScan, pProfile->pAddIEScan,
13571 ieLen);
13572 csr_join_req->addIEScan.length = ieLen;
13573 cdf_mem_copy(&csr_join_req->addIEScan.addIEdata,
13574 pProfile->pAddIEScan, ieLen);
13575 } else {
13576 pSession->nAddIEScanLength = 0;
13577 if (pSession->pAddIEScan) {
13578 cdf_mem_free(pSession->pAddIEScan);
13579 pSession->pAddIEScan = NULL;
13580 }
13581 csr_join_req->addIEScan.length = 0;
13582 }
13583 /* addIEAssoc */
13584 if (pProfile->nAddIEAssocLength && pProfile->pAddIEAssoc) {
13585 ieLen = pProfile->nAddIEAssocLength;
13586 if (ieLen > pSession->nAddIEAssocLength) {
13587 if (pSession->pAddIEAssoc
13588 && pSession->nAddIEAssocLength) {
13589 cdf_mem_free(pSession->pAddIEAssoc);
13590 }
13591 pSession->pAddIEAssoc = cdf_mem_malloc(ieLen);
13592 if (NULL == pSession->pAddIEAssoc)
13593 status = CDF_STATUS_E_NOMEM;
13594 else
13595 status = CDF_STATUS_SUCCESS;
13596 if (!CDF_IS_STATUS_SUCCESS(status))
13597 break;
13598 }
13599 pSession->nAddIEAssocLength = ieLen;
13600 cdf_mem_copy(pSession->pAddIEAssoc,
13601 pProfile->pAddIEAssoc, ieLen);
13602 csr_join_req->addIEAssoc.length = ieLen;
13603 cdf_mem_copy(&csr_join_req->addIEAssoc.addIEdata,
13604 pProfile->pAddIEAssoc, ieLen);
13605 } else {
13606 pSession->nAddIEAssocLength = 0;
13607 if (pSession->pAddIEAssoc) {
13608 cdf_mem_free(pSession->pAddIEAssoc);
13609 pSession->pAddIEAssoc = NULL;
13610 }
13611 csr_join_req->addIEAssoc.length = 0;
13612 }
13613
13614 if (eWNI_SME_REASSOC_REQ == messageType) {
13615 /* Unmask any AC in reassoc that is ACM-set */
13616 uapsd_mask = (uint8_t) pProfile->uapsd_mask;
13617 if (uapsd_mask && (NULL != pBssDescription)) {
13618 if (CSR_IS_QOS_BSS(pIes)
13619 && CSR_IS_UAPSD_BSS(pIes))
13620#ifndef WLAN_MDM_CODE_REDUCTION_OPT
13621 acm_mask =
13622 sme_qos_get_acm_mask(pMac,
13623 pBssDescription,
13624 pIes);
13625#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
13626 else
13627 uapsd_mask = 0;
13628 }
13629 }
13630
13631 csr_join_req->UCEncryptionType =
13632 csr_translate_encrypt_type_to_ed_type
13633 (pProfile->negotiatedUCEncryptionType);
13634
13635 csr_join_req->MCEncryptionType =
13636 csr_translate_encrypt_type_to_ed_type
13637 (pProfile->negotiatedMCEncryptionType);
13638#ifdef WLAN_FEATURE_11W
13639 if (pProfile->MFPEnabled)
13640 csr_join_req->MgmtEncryptionType = eSIR_ED_AES_128_CMAC;
13641 else
13642 csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
13643#endif
13644#ifdef FEATURE_WLAN_ESE
13645 ese_config = pMac->roam.configParam.isEseIniFeatureEnabled;
13646#endif
13647#ifdef WLAN_FEATURE_VOWIFI_11R
13648 pProfile->MDID.mdiePresent = pBssDescription->mdiePresent;
13649 if (csr_is_profile11r(pProfile)
13650#ifdef FEATURE_WLAN_ESE
13651 &&
13652 !((pProfile->negotiatedAuthType ==
13653 eCSR_AUTH_TYPE_OPEN_SYSTEM) && (pIes->ESEVersion.present)
13654 && (ese_config))
13655#endif
13656 )
13657 csr_join_req->is11Rconnection = true;
13658 else
13659 csr_join_req->is11Rconnection = false;
13660#endif
13661#ifdef FEATURE_WLAN_ESE
13662 if (true == ese_config)
13663 csr_join_req->isESEFeatureIniEnabled = true;
13664 else
13665 csr_join_req->isESEFeatureIniEnabled = false;
13666
13667 /* A profile can not be both ESE and 11R. But an 802.11R AP
13668 * may be advertising support for ESE as well. So if we are
13669 * associating Open or explicitly ESE then we will get ESE.
13670 * If we are associating explictly 11R only then we will get
13671 * 11R.
13672 */
13673 if ((csr_is_profile_ese(pProfile) ||
13674 ((pIes->ESEVersion.present) &&
13675 (pProfile->negotiatedAuthType ==
13676 eCSR_AUTH_TYPE_OPEN_SYSTEM)))
13677 && (ese_config))
13678 csr_join_req->isESEconnection = true;
13679 else
13680 csr_join_req->isESEconnection = false;
13681
13682 if (eWNI_SME_JOIN_REQ == messageType) {
13683 tESETspecInfo eseTspec;
13684 /*
13685 * ESE-Tspec IEs in the ASSOC request is presently not
13686 * supported. so nullify the TSPEC parameters
13687 */
13688 cdf_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
13689 cdf_mem_copy(&csr_join_req->eseTspecInfo,
13690 &eseTspec, sizeof(tESETspecInfo));
13691 } else if (eWNI_SME_REASSOC_REQ == messageType) {
13692 if ((csr_is_profile_ese(pProfile) ||
13693 ((pIes->ESEVersion.present)
13694 && (pProfile->negotiatedAuthType ==
13695 eCSR_AUTH_TYPE_OPEN_SYSTEM))) &&
13696 (ese_config)) {
13697 tESETspecInfo eseTspec;
13698 cdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
13699 0);
13700 eseTspec.numTspecs =
13701 sme_qos_ese_retrieve_tspec_info(pMac,
13702 sessionId,
13703 (tTspecInfo *) &eseTspec.
13704 tspec[0]);
13705 csr_join_req->eseTspecInfo.numTspecs =
13706 eseTspec.numTspecs;
13707 if (eseTspec.numTspecs) {
13708 cdf_mem_copy(&csr_join_req->eseTspecInfo
13709 .tspec[0],
13710 &eseTspec.tspec[0],
13711 (eseTspec.numTspecs *
13712 sizeof(tTspecInfo)));
13713 }
13714 } else {
13715 tESETspecInfo eseTspec;
13716 /**
13717 * ESE-Tspec IEs in the ASSOC request is
13718 * presently not supported. so nullify the TSPEC
13719 * parameters
13720 */
13721 cdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
13722 0);
13723 cdf_mem_copy(&csr_join_req->eseTspecInfo,
13724 &eseTspec,
13725 sizeof(tESETspecInfo));
13726 }
13727 }
13728#endif /* FEATURE_WLAN_ESE */
13729#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
13730 if (ese_config
13731#ifdef FEATURE_WLAN_LFR
13732 || csr_roam_is_fast_roam_enabled(pMac, sessionId)
13733#endif
13734 ) {
13735 csr_join_req->isFastTransitionEnabled = true;
13736 } else {
13737 csr_join_req->isFastTransitionEnabled = false;
13738 }
13739#endif
13740#ifdef FEATURE_WLAN_LFR
13741 if (csr_roam_is_fast_roam_enabled(pMac, sessionId))
13742 csr_join_req->isFastRoamIniFeatureEnabled = true;
13743 else
13744 csr_join_req->isFastRoamIniFeatureEnabled = false;
13745#endif
13746
13747 csr_join_req->txLdpcIniFeatureEnabled =
13748 (uint8_t) pMac->roam.configParam.txLdpcEnable;
13749
13750 if ((csr_is11h_supported(pMac))
13751 && (CDS_IS_CHANNEL_5GHZ(pBssDescription->channelId))
13752 && (pIes->Country.present)
13753 && (!pMac->roam.configParam.
13754 fSupplicantCountryCodeHasPriority)) {
13755 csr_save_to_channel_power2_g_5_g(pMac,
13756 pIes->Country.num_triplets *
13757 sizeof(tSirMacChanInfo),
13758 (tSirMacChanInfo *)
13759 (&pIes->Country.triplets[0]));
13760 csr_apply_power2_current(pMac);
13761 }
13762 cdf_mem_copy(&csr_join_req->htConfig,
13763 &pSession->htConfig, sizeof(tSirHTConfig));
13764#ifdef WLAN_FEATURE_11AC
13765 csr_join_req->txBFIniFeatureEnabled =
13766 (uint8_t) pMac->roam.configParam.txBFEnable;
13767
13768 if (pMac->roam.configParam.txBFEnable) {
13769 txBFCsnValue =
13770 (uint8_t)pMac->roam.configParam.txBFCsnValue;
13771 if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) &&
13772 pIes->VHTCaps.numSoundingDim)
13773 txBFCsnValue = CDF_MIN(txBFCsnValue,
13774 pIes->VHTCaps.numSoundingDim);
13775 else if (IS_BSS_VHT_CAPABLE(pIes->vendor2_ie.VHTCaps)
13776 && pIes->vendor2_ie.VHTCaps.numSoundingDim)
13777 txBFCsnValue = CDF_MIN(txBFCsnValue,
13778 pIes->vendor2_ie.VHTCaps.numSoundingDim);
13779 }
13780 csr_join_req->txBFCsnValue = txBFCsnValue;
13781
13782 csr_join_req->txMuBformee =
13783 (uint8_t) pMac->roam.configParam.txMuBformee;
13784
13785 csr_join_req->enableVhtpAid =
13786 (uint8_t) pMac->roam.configParam.enableVhtpAid;
13787
13788 csr_join_req->enableVhtGid =
13789 (uint8_t) pMac->roam.configParam.enableVhtGid;
13790
13791#endif
13792 csr_join_req->enableAmpduPs =
13793 (uint8_t) pMac->roam.configParam.enableAmpduPs;
13794
13795 csr_join_req->enableHtSmps =
13796 (uint8_t) pMac->roam.configParam.enableHtSmps;
13797
13798 csr_join_req->htSmps = (uint8_t) pMac->roam.configParam.htSmps;
13799
13800 csr_join_req->isAmsduSupportInAMPDU =
13801 (uint8_t) pMac->roam.configParam.isAmsduSupportInAMPDU;
13802
13803 if (pMac->roam.roamSession[sessionId].fWMMConnection)
13804 csr_join_req->isWMEenabled = true;
13805 else
13806 csr_join_req->isWMEenabled = false;
13807
13808 if (pMac->roam.roamSession[sessionId].fQOSConnection)
13809 csr_join_req->isQosEnabled = true;
13810 else
13811 csr_join_req->isQosEnabled = false;
13812
13813 if (pProfile->bOSENAssociation)
13814 csr_join_req->isOSENConnection = true;
13815 else
13816 csr_join_req->isOSENConnection = false;
13817
13818 pAP_capabilityInfo =
13819 (tSirMacCapabilityInfo *)
13820 &pBssDescription->capabilityInfo;
13821 /*
13822 * tell the target AP my 11H capability only if both AP and STA
13823 * support
13824 * 11H and the channel being used is 11a
13825 */
13826 if (csr_is11h_supported(pMac) && pAP_capabilityInfo->spectrumMgt
13827 && eSIR_11A_NW_TYPE == pBssDescription->nwType) {
13828 fTmp = (tAniBool) 1;
13829 } else
13830 fTmp = (tAniBool) 0;
13831
13832 csr_join_req->spectrumMgtIndicator = fTmp;
13833 csr_join_req->powerCap.minTxPower = MIN_TX_PWR_CAP;
13834 /*
13835 * This is required for 11k test VoWiFi Ent: Test 2.
13836 * We need the power capabilities for Assoc Req.
13837 * This macro is provided by the halPhyCfg.h. We pick our
13838 * max and min capability by the halPhy provided macros
13839 */
13840 pwrLimit = csr_get_cfg_max_tx_power(pMac,
13841 pBssDescription->channelId);
13842 if (0 != pwrLimit)
13843 csr_join_req->powerCap.maxTxPower = pwrLimit;
13844 else
13845 csr_join_req->powerCap.maxTxPower = MAX_TX_PWR_CAP;
13846
13847 csr_add_supported_5Ghz_channels(pMac, csr_join_req);
13848
13849 csr_join_req->uapsdPerAcBitmask = (uint8_t)pProfile->uapsd_mask;
13850 /* Move the entire BssDescription into the join request. */
13851 cdf_mem_copy(&csr_join_req->bssDescription, pBssDescription,
13852 pBssDescription->length +
13853 sizeof(pBssDescription->length));
13854
13855 /*
13856 * conc_custom_rule1:
13857 * If SAP comes up first and STA comes up later then SAP
13858 * need to follow STA's channel in 2.4Ghz. In following if
13859 * condition we are adding sanity check, just to make sure that
13860 * if this rule is enabled then don't allow STA to connect on
13861 * 5gz channel and also by this time SAP's channel should be the
13862 * same as STA's channel.
13863 */
13864 if (pMac->roam.configParam.conc_custom_rule1) {
13865 if ((0 ==
13866 pMac->
13867 roam.configParam.is_sta_connection_in_5gz_enabled)
13868 && CDS_IS_CHANNEL_5GHZ(pBssDescription->
13869 channelId)) {
13870 CDF_TRACE(CDF_MODULE_ID_SME,
13871 CDF_TRACE_LEVEL_ERROR,
13872 FL("STA-conn on 5G isn't allowed"));
13873 status = CDF_STATUS_E_FAILURE;
13874 break;
13875 }
13876 if (!CDS_IS_CHANNEL_5GHZ(pBssDescription->channelId) &&
13877 (false == csr_is_conn_allow_2g_band(pMac,
13878 pBssDescription->channelId))) {
13879 status = CDF_STATUS_E_FAILURE;
13880 break;
13881 }
13882 }
13883
13884 /*
13885 * conc_custom_rule2:
13886 * If P2PGO comes up first and STA comes up later then P2PGO
13887 * need to follow STA's channel in 5Ghz. In following if
13888 * condition we are just adding sanity check to make sure that
13889 * by this time P2PGO's channel is same as STA's channel.
13890 */
13891 if (pMac->roam.configParam.conc_custom_rule2) {
13892 if (!CDS_IS_CHANNEL_24GHZ(pBssDescription->channelId) &&
13893 (false == csr_is_conn_allow_5g_band(pMac,
13894 pBssDescription->channelId))) {
13895 status = CDF_STATUS_E_FAILURE;
13896 break;
13897 }
13898 }
13899 status = cds_send_mb_message_to_mac(csr_join_req);
13900 if (!CDF_IS_STATUS_SUCCESS(status)) {
13901 /*
13902 * cds_send_mb_message_to_mac would've released the mem
13903 * allocated by csr_join_req. Let's make it defensive by
13904 * assigning NULL to the pointer.
13905 */
13906 csr_join_req = NULL;
13907 break;
13908 } else {
13909#ifndef WLAN_MDM_CODE_REDUCTION_OPT
13910 if (eWNI_SME_JOIN_REQ == messageType) {
13911 /* Notify QoS module that join happening */
13912 pSession->join_bssid_count++;
13913 CDF_TRACE(CDF_MODULE_ID_SME,
13914 CDF_TRACE_LEVEL_DEBUG,
13915 "BSSID Count = %d",
13916 pSession->join_bssid_count);
13917 sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
13918 SME_QOS_CSR_JOIN_REQ, NULL);
13919 } else if (eWNI_SME_REASSOC_REQ == messageType) {
13920 /* Notify QoS module that reassoc happening */
13921 sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
13922 SME_QOS_CSR_REASSOC_REQ,
13923 NULL);
13924 }
13925#endif
13926 }
13927 } while (0);
13928
13929 /* Clean up the memory in case of any failure */
13930 if (!CDF_IS_STATUS_SUCCESS(status) && (NULL != csr_join_req))
13931 cdf_mem_free(csr_join_req);
13932
13933 return status;
13934}
13935
13936/* */
13937CDF_STATUS csr_send_mb_disassoc_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
13938 tSirMacAddr bssId, uint16_t reasonCode)
13939{
13940 tSirSmeDisassocReq *pMsg;
13941 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
13942
13943 if (!CSR_IS_SESSION_VALID(pMac, sessionId))
13944 return CDF_STATUS_E_FAILURE;
13945
13946 pMsg = cdf_mem_malloc(sizeof(tSirSmeDisassocReq));
13947 if (NULL == pMsg)
13948 return CDF_STATUS_E_NOMEM;
13949
13950 cdf_mem_set(pMsg, sizeof(tSirSmeDisassocReq), 0);
13951 pMsg->messageType = eWNI_SME_DISASSOC_REQ;
13952 pMsg->length = sizeof(tSirSmeDisassocReq);
13953 pMsg->sessionId = sessionId;
13954 pMsg->transactionId = 0;
13955 if ((pSession->pCurRoamProfile != NULL)
13956 && ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile))
13957 || (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))) {
13958 cdf_mem_copy(&pMsg->bssId,
13959 &pSession->selfMacAddr,
13960 sizeof(tSirMacAddr));
13961 cdf_mem_copy(&pMsg->peerMacAddr,
13962 bssId,
13963 sizeof(tSirMacAddr));
13964 } else {
13965 cdf_mem_copy(&pMsg->bssId,
13966 bssId,
13967 sizeof(tSirMacAddr));
13968 cdf_mem_copy(&pMsg->peerMacAddr,
13969 bssId,
13970 sizeof(tSirMacAddr));
13971 }
13972 pMsg->reasonCode = reasonCode;
13973 /*
13974 * The state will be DISASSOC_HANDOFF only when we are doing
13975 * handoff. Here we should not send the disassoc over the air
13976 * to the AP
13977 */
13978 if (CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
13979#ifdef WLAN_FEATURE_VOWIFI_11R
13980 && csr_roam_is11r_assoc(pMac, sessionId)
13981#endif
13982 ) {
13983 /* Set DoNotSendOverTheAir flag to 1 only for handoff case */
13984 pMsg->doNotSendOverTheAir = CSR_DONT_SEND_DISASSOC_OVER_THE_AIR;
13985 }
13986 return cds_send_mb_message_to_mac(pMsg);
13987}
13988
13989CDF_STATUS csr_send_mb_tkip_counter_measures_req_msg(tpAniSirGlobal pMac,
13990 uint32_t sessionId, bool bEnable,
13991 tSirMacAddr bssId)
13992{
13993 CDF_STATUS status = CDF_STATUS_SUCCESS;
13994 tSirSmeTkipCntrMeasReq *pMsg;
13995 do {
13996 pMsg = cdf_mem_malloc(sizeof(tSirSmeTkipCntrMeasReq));
13997 if (NULL == pMsg)
13998 status = CDF_STATUS_E_NOMEM;
13999 else
14000 status = CDF_STATUS_SUCCESS;
14001 if (!CDF_IS_STATUS_SUCCESS(status))
14002 break;
14003 cdf_mem_set(pMsg, sizeof(tSirSmeTkipCntrMeasReq), 0);
14004 pMsg->messageType = eWNI_SME_TKIP_CNTR_MEAS_REQ;
14005 pMsg->length = sizeof(tSirSmeTkipCntrMeasReq);
14006 pMsg->sessionId = sessionId;
14007 pMsg->transactionId = 0;
14008 cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
14009 pMsg->bEnable = bEnable;
14010 status = cds_send_mb_message_to_mac(pMsg);
14011 } while (0);
14012 return status;
14013}
14014
14015CDF_STATUS
14016csr_send_mb_get_associated_stas_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
14017 CDF_MODULE_ID modId, tSirMacAddr bssId,
14018 void *pUsrContext, void *pfnSapEventCallback,
14019 uint8_t *pAssocStasBuf)
14020{
14021 CDF_STATUS status = CDF_STATUS_SUCCESS;
14022 tSirSmeGetAssocSTAsReq *pMsg;
14023 do {
14024 pMsg = cdf_mem_malloc(sizeof(tSirSmeGetAssocSTAsReq));
14025 if (NULL == pMsg)
14026 status = CDF_STATUS_E_NOMEM;
14027 else
14028 status = CDF_STATUS_SUCCESS;
14029 if (!CDF_IS_STATUS_SUCCESS(status))
14030 break;
14031 cdf_mem_set(pMsg, sizeof(tSirSmeGetAssocSTAsReq), 0);
14032 pMsg->messageType = eWNI_SME_GET_ASSOC_STAS_REQ;
14033 cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
14034 pMsg->modId = modId;
14035 cdf_mem_copy(pMsg->pUsrContext,
14036 pUsrContext, sizeof(void *));
14037 cdf_mem_copy(pMsg->pSapEventCallback,
14038 pfnSapEventCallback, sizeof(void *));
14039 cdf_mem_copy(pMsg->pAssocStasArray,
14040 pAssocStasBuf, sizeof(void *));
14041 pMsg->length = sizeof(struct sSirSmeGetAssocSTAsReq);
14042 status = cds_send_mb_message_to_mac(pMsg);
14043 } while (0);
14044 return status;
14045}
14046
14047CDF_STATUS
14048csr_send_mb_get_wpspbc_sessions(tpAniSirGlobal pMac, uint32_t sessionId,
14049 tSirMacAddr bssId, void *pUsrContext,
14050 void *pfnSapEventCallback,
14051 struct cdf_mac_addr pRemoveMac)
14052{
14053 CDF_STATUS status = CDF_STATUS_SUCCESS;
14054 tSirSmeGetWPSPBCSessionsReq *pMsg;
14055
14056 do {
14057 pMsg = cdf_mem_malloc(sizeof(tSirSmeGetWPSPBCSessionsReq));
14058 if (NULL == pMsg)
14059 status = CDF_STATUS_E_NOMEM;
14060 else
14061 status = CDF_STATUS_SUCCESS;
14062 if (!CDF_IS_STATUS_SUCCESS(status))
14063 break;
14064 cdf_mem_set(pMsg, sizeof(tSirSmeGetWPSPBCSessionsReq), 0);
14065 pMsg->messageType = eWNI_SME_GET_WPSPBC_SESSION_REQ;
14066 cdf_mem_copy(pMsg->pUsrContext, pUsrContext, sizeof(void *));
14067 cdf_mem_copy(pMsg->pSapEventCallback, pfnSapEventCallback,
14068 sizeof(void *));
14069 cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
14070 cdf_mem_copy(pMsg->pRemoveMac, pRemoveMac.bytes,
14071 CDF_MAC_ADDR_SIZE);
14072 pMsg->length = sizeof(struct sSirSmeGetWPSPBCSessionsReq);
14073 status = cds_send_mb_message_to_mac(pMsg);
14074 } while (0);
14075 return status;
14076}
14077
14078CDF_STATUS csr_send_chng_mcc_beacon_interval(tpAniSirGlobal pMac, uint32_t sessionId)
14079{
14080 tpSirChangeBIParams pMsg;
14081 uint16_t len = 0;
14082 CDF_STATUS status = CDF_STATUS_SUCCESS;
14083 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14084
14085 if (!pSession) {
14086 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
14087 return CDF_STATUS_E_FAILURE;
14088 }
14089 /* NO need to update the Beacon Params if update beacon parameter flag is not set */
14090 if (!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)
14091 return CDF_STATUS_SUCCESS;
14092
14093 pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval =
14094 false;
14095
14096 /* Create the message and send to lim */
14097 len = sizeof(tSirChangeBIParams);
14098 pMsg = cdf_mem_malloc(len);
14099 if (NULL == pMsg)
14100 status = CDF_STATUS_E_NOMEM;
14101 else
14102 status = CDF_STATUS_SUCCESS;
14103 if (CDF_IS_STATUS_SUCCESS(status)) {
14104 cdf_mem_set(pMsg, sizeof(tSirChangeBIParams), 0);
14105 pMsg->messageType = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
14106 pMsg->length = len;
14107
14108 /* bssId */
14109 cdf_mem_copy((tSirMacAddr *) pMsg->bssId,
14110 &pSession->selfMacAddr, sizeof(tSirMacAddr));
14111 sms_log(pMac, LOG1,
14112 FL("CSR Attempting to change BI for Bssid= "
14113 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMsg->bssId));
14114 pMsg->sessionId = sessionId;
14115 sms_log(pMac, LOG1, FL(" session %d BeaconInterval %d"),
14116 sessionId,
14117 pMac->roam.roamSession[sessionId].bssParams.
14118 beaconInterval);
14119 pMsg->beaconInterval =
14120 pMac->roam.roamSession[sessionId].bssParams.beaconInterval;
14121 status = cds_send_mb_message_to_mac(pMsg);
14122 }
14123 return status;
14124}
14125
14126#ifdef QCA_HT_2040_COEX
14127CDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
14128 ePhyChanBondState cbMode, bool obssEnabled)
14129{
14130 tpSirSetHT2040Mode pMsg;
14131 uint16_t len = 0;
14132 CDF_STATUS status = CDF_STATUS_SUCCESS;
14133 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14134
14135 if (!pSession) {
14136 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
14137 return CDF_STATUS_E_FAILURE;
14138 }
14139
14140 /* Create the message and send to lim */
14141 len = sizeof(tSirSetHT2040Mode);
14142 pMsg = cdf_mem_malloc(len);
14143 if (NULL == pMsg)
14144 status = CDF_STATUS_E_NOMEM;
14145 else
14146 status = CDF_STATUS_SUCCESS;
14147 if (CDF_IS_STATUS_SUCCESS(status)) {
14148 cdf_mem_set(pMsg, sizeof(tSirSetHT2040Mode), 0);
14149 pMsg->messageType = eWNI_SME_SET_HT_2040_MODE;
14150 pMsg->length = len;
14151
14152 /* bssId */
14153 cdf_mem_copy((tSirMacAddr *) pMsg->bssId,
14154 &pSession->selfMacAddr, sizeof(tSirMacAddr));
14155 sms_log(pMac, LOG1,
14156 FL("CSR Attempting to set HT20/40 mode for Bssid= "
14157 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMsg->bssId));
14158 pMsg->sessionId = sessionId;
14159 sms_log(pMac, LOG1, FL(" session %d HT20/40 mode %d"),
14160 sessionId, cbMode);
14161 pMsg->cbMode = cbMode;
14162 pMsg->obssEnabled = obssEnabled;
14163 status = cds_send_mb_message_to_mac(pMsg);
14164 }
14165 return status;
14166}
14167#endif
14168
14169CDF_STATUS csr_send_mb_deauth_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
14170 tSirMacAddr bssId, uint16_t reasonCode)
14171{
14172 tSirSmeDeauthReq *pMsg;
14173 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14174
14175 if (!CSR_IS_SESSION_VALID(pMac, sessionId))
14176 return CDF_STATUS_E_FAILURE;
14177
14178 pMsg = cdf_mem_malloc(sizeof(tSirSmeDeauthReq));
14179 if (NULL == pMsg)
14180 return CDF_STATUS_E_NOMEM;
14181
14182 cdf_mem_set(pMsg, sizeof(tSirSmeDeauthReq), 0);
14183 pMsg->messageType = eWNI_SME_DEAUTH_REQ;
14184 pMsg->length = sizeof(tSirSmeDeauthReq);
14185 pMsg->sessionId = sessionId;
14186 pMsg->transactionId = 0;
14187
14188 if ((pSession->pCurRoamProfile != NULL)
14189 && ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile))
14190 || (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))) {
14191 cdf_mem_copy(&pMsg->bssId,
14192 &pSession->selfMacAddr,
14193 sizeof(tSirMacAddr));
14194 } else {
14195 cdf_mem_copy(&pMsg->bssId,
14196 bssId,
14197 sizeof(tSirMacAddr));
14198 }
14199
14200 /* Set the peer MAC address before sending the message to LIM */
14201 cdf_mem_copy(&pMsg->peerMacAddr,
14202 bssId,
14203 sizeof(tSirMacAddr));
14204 pMsg->reasonCode = reasonCode;
14205
14206 return cds_send_mb_message_to_mac(pMsg);
14207}
14208
14209CDF_STATUS csr_send_mb_disassoc_cnf_msg(tpAniSirGlobal pMac,
14210 tpSirSmeDisassocInd pDisassocInd)
14211{
14212 CDF_STATUS status = CDF_STATUS_SUCCESS;
14213 tSirSmeDisassocCnf *pMsg;
14214 do {
14215 pMsg = cdf_mem_malloc(sizeof(tSirSmeDisassocCnf));
14216 if (NULL == pMsg)
14217 status = CDF_STATUS_E_NOMEM;
14218 else
14219 status = CDF_STATUS_SUCCESS;
14220 if (!CDF_IS_STATUS_SUCCESS(status))
14221 break;
14222 cdf_mem_set(pMsg, sizeof(tSirSmeDisassocCnf), 0);
14223 pMsg->messageType = eWNI_SME_DISASSOC_CNF;
14224 pMsg->statusCode = eSIR_SME_SUCCESS;
14225 pMsg->length = sizeof(tSirSmeDisassocCnf);
14226 cdf_mem_copy(pMsg->peerMacAddr, pDisassocInd->peerMacAddr,
14227 sizeof(pMsg->peerMacAddr));
14228 status = CDF_STATUS_SUCCESS;
14229 if (!CDF_IS_STATUS_SUCCESS(status)) {
14230 cdf_mem_free(pMsg);
14231 break;
14232 }
14233
14234 cdf_mem_copy(pMsg->bssId, pDisassocInd->bssId,
14235 sizeof(pMsg->peerMacAddr));
14236 status = CDF_STATUS_SUCCESS;
14237 if (!CDF_IS_STATUS_SUCCESS(status)) {
14238 cdf_mem_free(pMsg);
14239 break;
14240 }
14241
14242 status = cds_send_mb_message_to_mac(pMsg);
14243 } while (0);
14244 return status;
14245}
14246
14247CDF_STATUS csr_send_mb_deauth_cnf_msg(tpAniSirGlobal pMac,
14248 tpSirSmeDeauthInd pDeauthInd)
14249{
14250 CDF_STATUS status = CDF_STATUS_SUCCESS;
14251 tSirSmeDeauthCnf *pMsg;
14252 do {
14253 pMsg = cdf_mem_malloc(sizeof(tSirSmeDeauthCnf));
14254 if (NULL == pMsg)
14255 status = CDF_STATUS_E_NOMEM;
14256 else
14257 status = CDF_STATUS_SUCCESS;
14258 if (!CDF_IS_STATUS_SUCCESS(status))
14259 break;
14260 cdf_mem_set(pMsg, sizeof(tSirSmeDeauthCnf), 0);
14261 pMsg->messageType = eWNI_SME_DEAUTH_CNF;
14262 pMsg->statusCode = eSIR_SME_SUCCESS;
14263 pMsg->length = sizeof(tSirSmeDeauthCnf);
14264 cdf_mem_copy(pMsg->bssId, pDeauthInd->bssId,
14265 sizeof(pMsg->bssId));
14266 status = CDF_STATUS_SUCCESS;
14267 if (!CDF_IS_STATUS_SUCCESS(status)) {
14268 cdf_mem_free(pMsg);
14269 break;
14270 }
14271 cdf_mem_copy(pMsg->peerMacAddr, pDeauthInd->peerMacAddr,
14272 sizeof(pMsg->peerMacAddr));
14273 status = CDF_STATUS_SUCCESS;
14274 if (!CDF_IS_STATUS_SUCCESS(status)) {
14275 cdf_mem_free(pMsg);
14276 break;
14277 }
14278 status = cds_send_mb_message_to_mac(pMsg);
14279 } while (0);
14280 return status;
14281}
14282
14283CDF_STATUS csr_send_assoc_cnf_msg(tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd,
14284 CDF_STATUS Halstatus)
14285{
14286 CDF_STATUS status = CDF_STATUS_SUCCESS;
14287 tSirSmeAssocCnf *pMsg;
14288
14289 sms_log(pMac, LOG1,
14290 FL("Posting eWNI_SME_ASSOC_CNF to LIM.HalStatus :%d"),
14291 Halstatus);
14292 do {
14293 pMsg = cdf_mem_malloc(sizeof(tSirSmeAssocCnf));
14294 if (NULL == pMsg)
14295 return CDF_STATUS_E_NOMEM;
14296 cdf_mem_set(pMsg, sizeof(tSirSmeAssocCnf), 0);
14297 pMsg->messageType = eWNI_SME_ASSOC_CNF;
14298 pMsg->length = sizeof(tSirSmeAssocCnf);
14299 if (CDF_IS_STATUS_SUCCESS(Halstatus))
14300 pMsg->statusCode = eSIR_SME_SUCCESS;
14301 else
14302 pMsg->statusCode = eSIR_SME_ASSOC_REFUSED;
14303 /* bssId */
14304 cdf_mem_copy(pMsg->bssId, pAssocInd->bssId,
14305 sizeof(tSirMacAddr));
14306 /* peerMacAddr */
14307 cdf_mem_copy(pMsg->peerMacAddr, pAssocInd->peerMacAddr,
14308 sizeof(tSirMacAddr));
14309 /* aid */
14310 pMsg->aid = pAssocInd->aid;
14311 /* alternateBssId */
14312 cdf_mem_copy(pMsg->alternateBssId, pAssocInd->bssId,
14313 sizeof(tSirMacAddr));
14314 /* alternateChannelId */
14315 pMsg->alternateChannelId = 11;
14316 /* pMsg is freed by cds_send_mb_message_to_mac in anycase*/
14317 status = cds_send_mb_message_to_mac(pMsg);
14318 } while (0);
14319 return status;
14320}
14321
14322CDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
14323 tpSirSmeAssocInd pAssocInd,
14324 CDF_STATUS Halstatus,
14325 uint8_t sessionId)
14326{
14327 tSirMsgQ msgQ;
14328 tSirSmeAssocIndToUpperLayerCnf *pMsg;
14329 uint8_t *pBuf;
14330 tSirResultCodes statusCode;
14331 uint16_t wTmp;
14332 do {
14333 pMsg = cdf_mem_malloc(sizeof(tSirSmeAssocIndToUpperLayerCnf));
14334 if (NULL == pMsg)
14335 return CDF_STATUS_E_NOMEM;
14336 cdf_mem_set(pMsg, sizeof(tSirSmeAssocIndToUpperLayerCnf), 0);
14337
14338 pMsg->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
14339 pMsg->length = sizeof(tSirSmeAssocIndToUpperLayerCnf);
14340
14341 pMsg->sessionId = sessionId;
14342
14343 pBuf = (uint8_t *) &pMsg->statusCode;
14344 if (CDF_IS_STATUS_SUCCESS(Halstatus))
14345 statusCode = eSIR_SME_SUCCESS;
14346 else
14347 statusCode = eSIR_SME_ASSOC_REFUSED;
14348 cdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
14349 pBuf += sizeof(tSirResultCodes);
14350 /* bssId */
14351 cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
14352 sizeof(tSirMacAddr));
14353 pBuf += sizeof(tSirMacAddr);
14354 /* peerMacAddr */
14355 cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->peerMacAddr,
14356 sizeof(tSirMacAddr));
14357 pBuf += sizeof(tSirMacAddr);
14358 /* StaId */
14359 wTmp = pAssocInd->staId;
14360 cdf_mem_copy(pBuf, &wTmp, sizeof(uint16_t));
14361 pBuf += sizeof(uint16_t);
14362 /* alternateBssId */
14363 cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
14364 sizeof(tSirMacAddr));
14365 pBuf += sizeof(tSirMacAddr);
14366 /* alternateChannelId */
14367 *pBuf = 11;
14368 pBuf += sizeof(uint8_t);
14369 /* Instead of copying roam Info, we just copy only WmmEnabled, RsnIE information */
14370 /* Wmm */
14371 *pBuf = pAssocInd->wmmEnabledSta;
14372 pBuf += sizeof(uint8_t);
14373 /* RSN IE */
14374 cdf_mem_copy((tSirRSNie *) pBuf, &pAssocInd->rsnIE,
14375 sizeof(tSirRSNie));
14376 pBuf += sizeof(tSirRSNie);
14377#ifdef FEATURE_WLAN_WAPI
14378 /* WAPI IE */
14379 cdf_mem_copy((tSirWAPIie *) pBuf, &pAssocInd->wapiIE,
14380 sizeof(tSirWAPIie));
14381 pBuf += sizeof(tSirWAPIie);
14382#endif
14383 /* Additional IE */
14384 cdf_mem_copy((void *)pBuf, &pAssocInd->addIE,
14385 sizeof(tSirAddie));
14386 pBuf += sizeof(tSirAddie);
14387 /* reassocReq */
14388 *pBuf = pAssocInd->reassocReq;
14389 pBuf += sizeof(uint8_t);
14390 /* timingMeasCap */
14391 *pBuf = pAssocInd->timingMeasCap;
14392 pBuf += sizeof(uint8_t);
14393 cdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
14394 sizeof(tSirSmeChanInfo));
14395 msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
14396 msgQ.bodyptr = pMsg;
14397 msgQ.bodyval = 0;
14398 sys_process_mmh_msg(pMac, &msgQ);
14399 } while (0);
14400 return CDF_STATUS_SUCCESS;
14401}
14402
14403CDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
14404 tSirMacAddr peerMacAddr, uint8_t numKeys,
14405 tAniEdType edType, bool fUnicast,
14406 tAniKeyDirection aniKeyDirection,
14407 uint8_t keyId, uint8_t keyLength,
14408 uint8_t *pKey, uint8_t paeRole,
14409 uint8_t *pKeyRsc)
14410{
14411 tSirSmeSetContextReq *pMsg;
14412 uint16_t msgLen;
14413 CDF_STATUS status = CDF_STATUS_E_FAILURE;
14414 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14415 sms_log(pMac, LOG1, FL("keylength is %d, Encry type is : %d"),
14416 keyLength, edType);
14417 do {
14418 if ((1 != numKeys) && (0 != numKeys))
14419 break;
14420 /*
14421 * All of these fields appear in every SET_CONTEXT message.
14422 * Below we'll add in the size for each key set. Since we only support
14423 * up to one key, we always allocate memory for 1 key.
14424 */
14425 msgLen = sizeof(struct sSirSmeSetContextReq);
14426
14427 pMsg = cdf_mem_malloc(msgLen);
14428 if (NULL == pMsg)
14429 return CDF_STATUS_E_NOMEM;
14430 cdf_mem_set(pMsg, msgLen, 0);
14431 pMsg->messageType = eWNI_SME_SETCONTEXT_REQ;
14432 pMsg->length = msgLen;
14433 pMsg->sessionId = (uint8_t) sessionId;
14434 pMsg->transactionId = 0;
14435 cdf_mem_copy(pMsg->peerMacAddr, peerMacAddr,
14436 sizeof(tSirMacAddr));
14437 cdf_mem_copy(pMsg->bssId,
14438 pSession->connectedProfile.bssid.bytes,
14439 sizeof(tSirMacAddr));
14440
14441 /**
14442 * Set the pMsg->keyMaterial.length field
14443 * (this length is defined as all data that follows the
14444 * edType field in the tSirKeyMaterial keyMaterial; field).
14445 *
14446 * NOTE: This keyMaterial.length contains the length of a
14447 * MAX size key, though the keyLength can be shorter than this
14448 * max size. Is LIM interpreting this ok ?
14449 */
14450 pMsg->keyMaterial.length =
14451 sizeof(pMsg->keyMaterial.numKeys) +
14452 (numKeys * sizeof(pMsg->keyMaterial.key));
14453 pMsg->keyMaterial.edType = edType;
14454 pMsg->keyMaterial.numKeys = numKeys;
14455 pMsg->keyMaterial.key[0].keyId = keyId;
14456 pMsg->keyMaterial.key[0].unicast = fUnicast;
14457 pMsg->keyMaterial.key[0].keyDirection = aniKeyDirection;
14458 cdf_mem_copy(pMsg->keyMaterial.key[0].keyRsc,
14459 pKeyRsc, CSR_MAX_RSC_LEN);
14460 /* 0 is Supplicant */
14461 pMsg->keyMaterial.key[0].paeRole = paeRole;
14462 pMsg->keyMaterial.key[0].keyLength = keyLength;
14463 if (keyLength && pKey) {
14464 cdf_mem_copy(pMsg->keyMaterial.key[0].key,
14465 pKey, keyLength);
14466 sms_log(pMac, LOG1,
14467 FL("SME set keyIndx (%d) encType (%d) key"),
14468 keyId, edType);
14469 sir_dump_buf(pMac, SIR_SMS_MODULE_ID, LOG1, pKey,
14470 keyLength);
14471 }
14472 status = cds_send_mb_message_to_mac(pMsg);
14473 } while (0);
14474 return status;
14475}
14476
14477CDF_STATUS csr_send_mb_start_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
14478 eCsrRoamBssType bssType,
14479 tCsrRoamStartBssParams *pParam,
14480 tSirBssDescription *pBssDesc)
14481{
14482 tSirSmeStartBssReq *pMsg;
14483 uint16_t wTmp;
14484 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14485
14486 if (!pSession) {
14487 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
14488 return CDF_STATUS_E_FAILURE;
14489 }
14490
14491 pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
14492 pSession->joinFailStatusCode.reasonCode = 0;
14493 pMsg = cdf_mem_malloc(sizeof(tSirSmeStartBssReq));
14494 if (NULL == pMsg)
14495 return CDF_STATUS_E_NOMEM;
14496
14497 cdf_mem_set(pMsg, sizeof(tSirSmeStartBssReq), 0);
14498 pMsg->messageType = eWNI_SME_START_BSS_REQ;
14499 pMsg->sessionId = sessionId;
14500 pMsg->length = sizeof(tSirSmeStartBssReq);
14501 pMsg->transactionId = 0;
14502 cdf_mem_copy(pMsg->bssId, pParam->bssid.bytes, sizeof(tSirMacAddr));
14503 /* selfMacAddr */
14504 cdf_mem_copy(pMsg->selfMacAddr,
14505 pSession->selfMacAddr.bytes,
14506 sizeof(tSirMacAddr));
14507 /* beaconInterval */
14508 if (pBssDesc && pBssDesc->beaconInterval)
14509 wTmp = pBssDesc->beaconInterval;
14510 else if (pParam->beaconInterval)
14511 wTmp = pParam->beaconInterval;
14512 else
14513 wTmp = WNI_CFG_BEACON_INTERVAL_STADEF;
14514
14515 if (csr_isconcurrentsession_valid(pMac, sessionId, pParam->bssPersona)
14516 == CDF_STATUS_SUCCESS) {
14517 csr_validate_mcc_beacon_interval(pMac,
14518 pParam->operationChn,
14519 &wTmp,
14520 sessionId,
14521 pParam->bssPersona);
14522 /* Update the beacon Interval */
14523 pParam->beaconInterval = wTmp;
14524 } else {
14525 sms_log(pMac, LOGE,
14526 FL("****Start BSS failed persona already exists***"));
14527 cdf_mem_free(pMsg);
14528 return CDF_STATUS_E_FAILURE;
14529 }
14530 pMsg->beaconInterval = wTmp;
14531 pMsg->dot11mode =
14532 csr_translate_to_wni_cfg_dot11_mode(pMac,
14533 pParam->uCfgDot11Mode);
14534#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
14535 pMsg->cc_switch_mode = pMac->roam.configParam.cc_switch_mode;
14536#endif
14537 pMsg->bssType = csr_translate_bsstype_to_mac_type(bssType);
14538 cdf_mem_copy(&pMsg->ssId, &pParam->ssId, sizeof(pParam->ssId));
14539 pMsg->channelId = pParam->operationChn;
14540 /* What should we really do for the cbmode. */
14541 pMsg->cbMode = (ePhyChanBondState) pParam->cbMode;
14542 pMsg->vht_channel_width = pParam->ch_params.ch_width;
14543 pMsg->center_freq_seg0 = pParam->ch_params.center_freq_seg0;
14544 pMsg->center_freq_seg1 = pParam->ch_params.center_freq_seg1;
14545 pMsg->sec_ch_offset = pParam->ch_params.sec_ch_offset;
14546 pMsg->privacy = pParam->privacy;
14547 pMsg->apUapsdEnable = pParam->ApUapsdEnable;
14548 pMsg->ssidHidden = pParam->ssidHidden;
14549 pMsg->fwdWPSPBCProbeReq = (uint8_t) pParam->fwdWPSPBCProbeReq;
14550 pMsg->protEnabled = (uint8_t) pParam->protEnabled;
14551 pMsg->obssProtEnabled = (uint8_t) pParam->obssProtEnabled;
14552 /* set cfg related to protection */
14553 pMsg->ht_capab = pParam->ht_protection;
14554 pMsg->authType = pParam->authType;
14555 pMsg->dtimPeriod = pParam->dtimPeriod;
14556 pMsg->wps_state = pParam->wps_state;
14557 pMsg->isCoalesingInIBSSAllowed = pMac->isCoalesingInIBSSAllowed;
14558 pMsg->bssPersona = pParam->bssPersona;
14559 pMsg->txLdpcIniFeatureEnabled = pMac->roam.configParam.txLdpcEnable;
14560#ifdef WLAN_FEATURE_11W
14561 pMsg->pmfCapable = pParam->mfpCapable;
14562 pMsg->pmfRequired = pParam->mfpRequired;
14563#endif
14564
14565 if (pParam->nRSNIELength > sizeof(pMsg->rsnIE.rsnIEdata)) {
14566 cdf_mem_free(pMsg);
14567 return CDF_STATUS_E_INVAL;
14568 }
14569 pMsg->rsnIE.length = pParam->nRSNIELength;
14570 cdf_mem_copy(pMsg->rsnIE.rsnIEdata,
14571 pParam->pRSNIE,
14572 pParam->nRSNIELength);
14573 pMsg->nwType = (tSirNwType)pParam->sirNwType;
14574 cdf_mem_copy(&pMsg->operationalRateSet,
14575 &pParam->operationalRateSet,
14576 sizeof(tSirMacRateSet));
14577 cdf_mem_copy(&pMsg->extendedRateSet,
14578 &pParam->extendedRateSet,
14579 sizeof(tSirMacRateSet));
14580 cdf_mem_copy(&pMsg->htConfig,
14581 &pSession->htConfig,
14582 sizeof(tSirHTConfig));
14583 cdf_mem_copy(&pMsg->addIeParams,
14584 &pParam->addIeParams,
14585 sizeof(pParam->addIeParams));
14586 pMsg->obssEnabled = pMac->roam.configParam.obssEnabled;
14587 pMsg->sap_dot11mc = pParam->sap_dot11mc;
14588
14589 return cds_send_mb_message_to_mac(pMsg);
14590}
14591
14592CDF_STATUS csr_send_mb_stop_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId)
14593{
14594 tSirSmeStopBssReq *pMsg;
14595 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14596
14597 if (!pSession) {
14598 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
14599 return CDF_STATUS_E_FAILURE;
14600 }
14601
14602 pMsg = cdf_mem_malloc(sizeof(tSirSmeStopBssReq));
14603 if (NULL == pMsg)
14604 return CDF_STATUS_E_NOMEM;
14605 cdf_mem_set(pMsg, sizeof(tSirSmeStopBssReq), 0);
14606 pMsg->messageType = eWNI_SME_STOP_BSS_REQ;
14607 pMsg->sessionId = sessionId;
14608 pMsg->length = sizeof(tSirSmeStopBssReq);
14609 pMsg->transactionId = 0;
14610 pMsg->reasonCode = 0;
14611 /*
14612 * if BSSType is WDS sta, use selfmacAddr as bssid,
14613 * else use bssid in connectedProfile
14614 */
14615 if (CSR_IS_CONN_WDS_STA(&pSession->connectedProfile))
14616 cdf_mem_copy(&pMsg->bssId,
14617 &pSession->selfMacAddr.bytes,
14618 sizeof(tSirMacAddr));
14619 else
14620 cdf_mem_copy(&pMsg->bssId,
14621 &pSession->connectedProfile.bssid.bytes,
14622 sizeof(tSirMacAddr));
14623 return cds_send_mb_message_to_mac(pMsg);
14624}
14625
14626CDF_STATUS csr_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
14627 tCsrRoamModifyProfileFields *pModProfileFields,
14628 uint32_t *pRoamId, bool fForce)
14629{
14630 CDF_STATUS status = CDF_STATUS_E_FAILURE;
14631 uint32_t roamId = 0;
14632 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
14633 if ((csr_is_conn_state_connected(pMac, sessionId)) &&
14634 (fForce || (!cdf_mem_compare(&pModProfileFields,
14635 &pSession->connectedProfile.
14636 modifyProfileFields,
14637 sizeof(tCsrRoamModifyProfileFields))))) {
14638 roamId = GET_NEXT_ROAM_ID(&pMac->roam);
14639 if (pRoamId) {
14640 *pRoamId = roamId;
14641 }
14642
14643 status =
14644 csr_roam_issue_reassoc(pMac, sessionId, NULL,
14645 pModProfileFields,
14646 eCsrSmeIssuedReassocToSameAP,
14647 roamId, false);
14648 }
14649 return status;
14650}
14651
14652static CDF_STATUS csr_roam_session_opened(tpAniSirGlobal pMac,
14653 uint32_t sessionId)
14654{
14655 CDF_STATUS status = CDF_STATUS_SUCCESS;
14656 tCsrRoamInfo roamInfo;
14657 cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
14658 status = csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
14659 eCSR_ROAM_SESSION_OPENED,
14660 eCSR_ROAM_RESULT_NONE);
14661 return status;
14662}
14663
14664CDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
14665{
14666 tListElem *pEntry = NULL;
14667 tSmeCmd *pCommand = NULL;
14668 struct add_sta_self_params *rsp;
14669 struct send_extcap_ie *msg;
14670 CDF_STATUS status;
14671
14672 if (pMsg == NULL) {
14673 sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
14674 return CDF_STATUS_E_FAILURE;
14675 }
14676 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
14677 if (!pEntry) {
14678 sms_log(pMac, LOGE, "in %s NO commands are ACTIVE ...",
14679 __func__);
14680 return CDF_STATUS_E_FAILURE;
14681 }
14682 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
14683 if (eSmeCommandAddStaSession != pCommand->command) {
14684 sms_log(pMac, LOGE, "in %s Cmd not in active list ...",
14685 __func__);
14686 return CDF_STATUS_E_FAILURE;
14687 }
14688 rsp = (struct add_sta_self_params *) pMsg;
14689 sms_log(pMac, LOG1, "Add Sta self rsp status = %d", rsp->status);
14690
14691 if (CDF_STATUS_SUCCESS == rsp->status &&
14692 (WMI_VDEV_TYPE_STA == rsp->type ||
14693 (WMI_VDEV_TYPE_AP == rsp->type &&
14694 WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) {
14695 sms_log(pMac, LOG1, FL("send SET IE msg to PE"));
14696 msg = cdf_mem_malloc(sizeof(*msg));
14697 if (NULL == msg) {
14698 sms_log(pMac, LOGE, FL("Memory allocation failed"));
14699 return CDF_STATUS_E_NOMEM;
14700 }
14701
14702 cdf_mem_set(msg, sizeof(*msg), 0);
14703 msg->msg_type = eWNI_SME_SET_IE_REQ;
14704 msg->session_id = rsp->session_id;
14705 msg->length = sizeof(*msg);
14706 status = cds_send_mb_message_to_mac(msg);
14707 if (!CDF_IS_STATUS_SUCCESS(status))
14708 sms_log(pMac, LOGE,
14709 FL("Failed to send down the set IE req "));
14710 }
14711
14712 csr_roam_session_opened(pMac, pCommand->sessionId);
14713 /* Remove this command out of the active list */
14714 if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, pEntry,
14715 LL_ACCESS_LOCK)) {
14716 /* Now put this command back on the avilable command list */
14717 csr_release_command(pMac, pCommand);
14718 }
14719 sme_process_pending_queue(pMac);
14720 return CDF_STATUS_SUCCESS;
14721}
14722
14723CDF_STATUS csr_issue_add_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId,
14724 tSirMacAddr sessionMacAddr,
14725 uint32_t type, uint32_t subType)
14726{
14727 CDF_STATUS status = CDF_STATUS_SUCCESS;
14728 tSmeCmd *pCommand;
14729 pCommand = csr_get_command_buffer(pMac);
14730 if (NULL == pCommand) {
14731 status = CDF_STATUS_E_RESOURCES;
14732 } else {
14733 pCommand->command = eSmeCommandAddStaSession;
14734 pCommand->sessionId = (uint8_t) sessionId;
14735 cdf_mem_copy(pCommand->u.addStaSessionCmd.selfMacAddr,
14736 sessionMacAddr, sizeof(tSirMacAddr));
14737 pCommand->u.addStaSessionCmd.currDeviceMode =
14738 pMac->sme.currDeviceMode;
14739 pCommand->u.addStaSessionCmd.type = type;
14740 pCommand->u.addStaSessionCmd.subType = subType;
14741 status = csr_queue_sme_command(pMac, pCommand, true);
14742 if (!CDF_IS_STATUS_SUCCESS(status)) {
14743 /* Should be panic?? */
14744 sms_log(pMac, LOGE,
14745 FL(" fail to send message status = %d"), status);
14746 }
14747 }
14748 return status;
14749}
14750
14751CDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac,
14752 tSmeCmd *pCommand)
14753{
14754 tAddStaForSessionCmd *pAddStaReq =
14755 &pCommand->u.addStaSessionCmd;
14756 uint8_t sessionId = pCommand->sessionId;
14757 struct add_sta_self_params *add_sta_self_req;
14758 CDF_STATUS status = CDF_STATUS_E_NOMEM;
14759 tSirMsgQ msg;
14760
14761 add_sta_self_req = cdf_mem_malloc(sizeof(struct add_sta_self_params));
14762 if (NULL == add_sta_self_req) {
14763 lim_log(pMac, LOGP,
14764 FL
14765 ("Unable to allocate memory for tAddSelfStaParams"));
14766 return status;
14767 }
14768
14769 cdf_mem_copy(add_sta_self_req->self_mac_addr, pAddStaReq->selfMacAddr,
14770 sizeof(tSirMacAddr));
14771 add_sta_self_req->curr_device_mode = pAddStaReq->currDeviceMode;
14772 add_sta_self_req->session_id = sessionId;
14773 add_sta_self_req->type = pAddStaReq->type;
14774 add_sta_self_req->sub_type = pAddStaReq->subType;
14775
14776 msg.type = WMA_ADD_STA_SELF_REQ;
14777 msg.reserved = 0;
14778 msg.bodyptr = add_sta_self_req;
14779 msg.bodyval = 0;
14780
14781 lim_log(pMac, LOG1,
14782 FL
14783 ("Send WMA_ADD_STA_SELF_REQ for selfMac=" MAC_ADDRESS_STR),
14784 MAC_ADDR_ARRAY(add_sta_self_req->self_mac_addr));
14785 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
14786 status = wma_post_ctrl_msg(pMac, &msg);
14787
14788 if (status != CDF_STATUS_SUCCESS) {
14789 lim_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
14790 cdf_mem_free(add_sta_self_req);
14791 add_sta_self_req = NULL;
14792 }
14793 return status;
14794}
14795
14796CDF_STATUS csr_roam_open_session(tpAniSirGlobal pMac,
14797 csr_roam_completeCallback callback,
14798 void *pContext,
14799 uint8_t *pSelfMacAddr, uint8_t *pbSessionId,
14800 uint32_t type, uint32_t subType)
14801{
14802 CDF_STATUS status = CDF_STATUS_SUCCESS;
14803 uint32_t i, value = 0;
14804 union {
14805 uint16_t nCfgValue16;
14806 tSirMacHTCapabilityInfo htCapInfo;
14807 } uHTCapabilityInfo;
14808 tCsrRoamSession *pSession;
14809 *pbSessionId = CSR_SESSION_ID_INVALID;
14810
14811 for (i = 0; i < pMac->sme.max_intf_count; i++) {
14812 if (!CSR_IS_SESSION_VALID(pMac, i)) {
14813 pSession = CSR_GET_SESSION(pMac, i);
14814 if (!pSession) {
14815 sms_log(pMac, LOGE,
14816 FL
14817 ("Session does not exist for interface %d"),
14818 i);
14819 break;
14820 }
14821 status = CDF_STATUS_SUCCESS;
14822 pSession->sessionActive = true;
14823 pSession->sessionId = (uint8_t) i;
14824
14825#ifdef WLAN_FEATURE_VOWIFI_11R
14826 /* Initialize FT related data structures only in STA mode */
14827 sme_ft_open(pMac, pSession->sessionId);
14828#endif
14829
14830 pSession->callback = callback;
14831 pSession->pContext = pContext;
14832 cdf_mem_copy(&pSession->selfMacAddr, pSelfMacAddr,
14833 sizeof(struct cdf_mac_addr));
14834 *pbSessionId = (uint8_t) i;
14835 status =
14836 cdf_mc_timer_init(&pSession->hTimerRoaming,
14837 CDF_TIMER_TYPE_SW,
14838 csr_roam_roaming_timer_handler,
14839 &pSession->roamingTimerInfo);
14840 if (!CDF_IS_STATUS_SUCCESS(status)) {
14841 sms_log(pMac, LOGE,
14842 FL
14843 ("cannot allocate memory for Roaming timer"));
14844 break;
14845 }
14846 /* get the HT capability info */
14847 if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &value)
14848 != eSIR_SUCCESS) {
14849 CDF_TRACE(CDF_MODULE_ID_CDF,
14850 CDF_TRACE_LEVEL_ERROR,
14851 "%s: could not get HT capability info",
14852 __func__);
14853 break;
14854 }
14855#ifdef FEATURE_WLAN_BTAMP_UT_RF
14856 status = cdf_mc_timer_init(&pSession->hTimerJoinRetry,
14857 CDF_TIMER_TYPE_SW,
14858 csr_roam_join_retry_timer_handler,
14859 &pSession->
14860 joinRetryTimerInfo);
14861 if (!CDF_IS_STATUS_SUCCESS(status)) {
14862 sms_log(pMac, LOGE,
14863 FL
14864 ("cannot allocate memory for join retry timer"));
14865 break;
14866 }
14867#endif
14868 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
14869 pSession->htConfig.ht_rx_ldpc =
14870 uHTCapabilityInfo.htCapInfo.advCodingCap;
14871 pSession->htConfig.ht_tx_stbc =
14872 uHTCapabilityInfo.htCapInfo.txSTBC;
14873 pSession->htConfig.ht_rx_stbc =
14874 uHTCapabilityInfo.htCapInfo.rxSTBC;
14875 pSession->htConfig.ht_sgi = true;
14876 status =
14877 csr_issue_add_sta_for_session_req(pMac, i, pSelfMacAddr,
14878 type, subType);
14879 break;
14880 }
14881 }
14882 if (pMac->sme.max_intf_count == i) {
14883 /* No session is available */
14884 sms_log(pMac, LOGE,
14885 "%s: Reached max interfaces: %d! Session creation will fail",
14886 __func__, pMac->sme.max_intf_count);
14887 status = CDF_STATUS_E_RESOURCES;
14888 }
14889 return status;
14890}
14891
14892CDF_STATUS csr_process_del_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
14893{
14894 CDF_STATUS status = CDF_STATUS_E_FAILURE;
14895 tListElem *pEntry = NULL;
14896 tSmeCmd *pCommand = NULL;
14897 struct del_sta_self_params *rsp;
14898 uint8_t sessionId;
14899
14900 if (pMsg == NULL) {
14901 sms_log(pMac, LOGE, FL("msg ptr is NULL"));
14902 return status;
14903 }
14904 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
14905 if (!pEntry) {
14906 sms_log(pMac, LOGE, FL("NO commands are ACTIVE ..."));
14907 return status;
14908 }
14909 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
14910 sessionId = pCommand->sessionId;
14911 if (eSmeCommandDelStaSession != pCommand->command) {
14912 sms_log(pMac, LOGE, FL("NO Del sta session command ACTIVE"));
14913 return status;
14914 }
14915 rsp = (struct del_sta_self_params *) pMsg;
14916 sms_log(pMac, LOG1, FL("Del Sta rsp status = %d"), rsp->status);
14917 /* This session is done. */
14918 csr_cleanup_session(pMac, sessionId);
14919 if (pCommand->u.delStaSessionCmd.callback) {
14920 status = sme_release_global_lock(&pMac->sme);
14921 if (!CDF_IS_STATUS_SUCCESS(status))
14922 sms_log(pMac, LOG1, FL("Failed to Release Lock"));
14923 else {
14924 pCommand->u.delStaSessionCmd.
14925 callback(pCommand->u.delStaSessionCmd.pContext);
14926 status = sme_acquire_global_lock(&pMac->sme);
14927 if (!CDF_IS_STATUS_SUCCESS(status)) {
14928 sms_log(pMac, LOG1, FL("Failed to get Lock"));
14929 return status;
14930 }
14931 }
14932 }
14933 /* Remove this command out of the active list */
14934 if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, pEntry,
14935 LL_ACCESS_LOCK)) {
14936 /* Now put this command back on the avilable command list */
14937 csr_release_command(pMac, pCommand);
14938 }
14939 sme_process_pending_queue(pMac);
14940 status = CDF_STATUS_SUCCESS;
14941 return status;
14942}
14943
14944
14945CDF_STATUS csr_issue_del_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId,
14946 tSirMacAddr sessionMacAddr,
14947 csr_roamSessionCloseCallback callback,
14948 void *pContext)
14949{
14950 CDF_STATUS status = CDF_STATUS_SUCCESS;
14951 tSmeCmd *pCommand;
14952 pCommand = csr_get_command_buffer(pMac);
14953 if (NULL == pCommand) {
14954 status = CDF_STATUS_E_RESOURCES;
14955 } else {
14956 pCommand->command = eSmeCommandDelStaSession;
14957 pCommand->sessionId = (uint8_t) sessionId;
14958 pCommand->u.delStaSessionCmd.callback = callback;
14959 pCommand->u.delStaSessionCmd.pContext = pContext;
14960 cdf_mem_copy(pCommand->u.delStaSessionCmd.selfMacAddr,
14961 sessionMacAddr, sizeof(tSirMacAddr));
14962 status = csr_queue_sme_command(pMac, pCommand, true);
14963 if (!CDF_IS_STATUS_SUCCESS(status)) {
14964 /* Should be panic?? */
14965 sms_log(pMac, LOGE,
14966 FL(" fail to send message status = %d"), status);
14967 }
14968 }
14969 return status;
14970}
14971
14972CDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal pMac,
14973 tSmeCmd *pCommand)
14974{
14975 struct del_sta_self_params *del_sta_self_req;
14976 tSirMsgQ msg;
14977 CDF_STATUS status = CDF_STATUS_E_FAILURE;
14978 del_sta_self_req = cdf_mem_malloc(sizeof(struct del_sta_self_params));
14979 if (NULL == del_sta_self_req) {
14980 lim_log(pMac, LOGP,
14981 FL(" mem alloc failed for tDelStaSelfParams"));
14982 return CDF_STATUS_E_NOMEM;
14983 }
14984
14985 cdf_mem_copy(del_sta_self_req->self_mac_addr,
14986 pCommand->u.delStaSessionCmd.selfMacAddr,
14987 sizeof(tSirMacAddr));
14988
14989 del_sta_self_req->session_id = pCommand->sessionId;
14990 msg.type = WMA_DEL_STA_SELF_REQ;
14991 msg.reserved = 0;
14992 msg.bodyptr = del_sta_self_req;
14993 msg.bodyval = 0;
14994
14995 sms_log(pMac, LOG1,
14996 FL("sending WMA_DEL_STA_SELF_REQ"));
14997 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
14998 status = wma_post_ctrl_msg(pMac, &msg);
14999 if (status != CDF_STATUS_SUCCESS) {
15000 sms_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
15001 cdf_mem_free(del_sta_self_req);
15002 }
15003 return status;
15004}
15005
15006static void purge_csr_session_cmd_list(tpAniSirGlobal pMac, uint32_t sessionId)
15007{
15008 tDblLinkList *pList = &pMac->roam.roamCmdPendingList;
15009 tListElem *pEntry, *pNext;
15010 tSmeCmd *pCommand;
15011 tDblLinkList localList;
15012
15013 cdf_mem_zero(&localList, sizeof(tDblLinkList));
15014 if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
15015 sms_log(pMac, LOGE, FL(" failed to open list"));
15016 return;
15017 }
15018 csr_ll_lock(pList);
15019 pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
15020 while (pEntry != NULL) {
15021 pNext = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
15022 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
15023 if (pCommand->sessionId == sessionId) {
15024 if (csr_ll_remove_entry(pList, pEntry, LL_ACCESS_NOLOCK)) {
15025 csr_ll_insert_tail(&localList, pEntry,
15026 LL_ACCESS_NOLOCK);
15027 }
15028 }
15029 pEntry = pNext;
15030 }
15031 csr_ll_unlock(pList);
15032
15033 while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
15034 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
15035 csr_abort_command(pMac, pCommand, true);
15036 }
15037 csr_ll_close(&localList);
15038}
15039
15040void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId)
15041{
15042 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
15043 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
15044
15045 csr_roam_stop(pMac, sessionId);
15046
15047 /* Clean up FT related data structures */
15048#if defined WLAN_FEATURE_VOWIFI_11R
15049 sme_ft_close(pMac, sessionId);
15050#endif
15051 csr_free_connect_bss_desc(pMac, sessionId);
15052 csr_roam_free_connect_profile(pMac, &pSession->connectedProfile);
15053 csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
15054 cdf_mc_timer_destroy(&pSession->hTimerRoaming);
15055#ifdef FEATURE_WLAN_BTAMP_UT_RF
15056 cdf_mc_timer_destroy(&pSession->hTimerJoinRetry);
15057#endif
15058 purge_sme_session_cmd_list(pMac, sessionId,
15059 &pMac->sme.smeCmdPendingList);
15060 purge_sme_session_cmd_list(pMac, sessionId,
15061 &pMac->sme.
15062 smeScanCmdPendingList);
15063
15064 purge_csr_session_cmd_list(pMac, sessionId);
15065 csr_init_session(pMac, sessionId);
15066 }
15067}
15068
15069CDF_STATUS csr_roam_close_session(tpAniSirGlobal pMac, uint32_t sessionId,
15070 bool fSync,
15071 csr_roamSessionCloseCallback callback,
15072 void *pContext)
15073{
15074 CDF_STATUS status = CDF_STATUS_SUCCESS;
15075 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
15076 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
15077 if (fSync) {
15078 csr_cleanup_session(pMac, sessionId);
15079 } else {
15080 purge_sme_session_cmd_list(pMac, sessionId,
15081 &pMac->sme.smeCmdPendingList);
15082 purge_sme_session_cmd_list(pMac, sessionId,
15083 &pMac->sme.smeScanCmdPendingList);
15084
15085 purge_csr_session_cmd_list(pMac, sessionId);
15086 status = csr_issue_del_sta_for_session_req(pMac,
15087 sessionId,
15088 pSession->selfMacAddr.bytes,
15089 callback, pContext);
15090 }
15091 } else {
15092 status = CDF_STATUS_E_INVAL;
15093 }
15094 return status;
15095}
15096
15097static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId)
15098{
15099 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
15100
15101 if (!pSession) {
15102 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
15103 return;
15104 }
15105
15106 pSession->sessionActive = false;
15107 pSession->sessionId = CSR_SESSION_ID_INVALID;
15108 pSession->callback = NULL;
15109 pSession->pContext = NULL;
15110 pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
15111 csr_free_roam_profile(pMac, sessionId);
15112 csr_roam_free_connect_profile(pMac, &pSession->connectedProfile);
15113 csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
15114 csr_free_connect_bss_desc(pMac, sessionId);
15115 csr_scan_enable(pMac);
15116 cdf_mem_set(&pSession->selfMacAddr, sizeof(struct cdf_mac_addr), 0);
15117 if (pSession->pWpaRsnReqIE) {
15118 cdf_mem_free(pSession->pWpaRsnReqIE);
15119 pSession->pWpaRsnReqIE = NULL;
15120 }
15121 pSession->nWpaRsnReqIeLength = 0;
15122 if (pSession->pWpaRsnRspIE) {
15123 cdf_mem_free(pSession->pWpaRsnRspIE);
15124 pSession->pWpaRsnRspIE = NULL;
15125 }
15126 pSession->nWpaRsnRspIeLength = 0;
15127#ifdef FEATURE_WLAN_WAPI
15128 if (pSession->pWapiReqIE) {
15129 cdf_mem_free(pSession->pWapiReqIE);
15130 pSession->pWapiReqIE = NULL;
15131 }
15132 pSession->nWapiReqIeLength = 0;
15133 if (pSession->pWapiRspIE) {
15134 cdf_mem_free(pSession->pWapiRspIE);
15135 pSession->pWapiRspIE = NULL;
15136 }
15137 pSession->nWapiRspIeLength = 0;
15138#endif /* FEATURE_WLAN_WAPI */
15139 if (pSession->pAddIEScan) {
15140 cdf_mem_free(pSession->pAddIEScan);
15141 pSession->pAddIEScan = NULL;
15142 }
15143 pSession->nAddIEScanLength = 0;
15144 if (pSession->pAddIEAssoc) {
15145 cdf_mem_free(pSession->pAddIEAssoc);
15146 pSession->pAddIEAssoc = NULL;
15147 }
15148 pSession->nAddIEAssocLength = 0;
15149}
15150
15151CDF_STATUS csr_roam_get_session_id_from_bssid(tpAniSirGlobal pMac,
15152 struct cdf_mac_addr *bssid,
15153 uint32_t *pSessionId)
15154{
15155 CDF_STATUS status = CDF_STATUS_E_FAILURE;
15156 uint32_t i;
15157 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
15158 if (CSR_IS_SESSION_VALID(pMac, i)) {
15159 if (cdf_is_macaddr_equal(bssid,
15160 &pMac->roam.roamSession[i].connectedProfile.
15161 bssid)) {
15162 /* Found it */
15163 status = CDF_STATUS_SUCCESS;
15164 *pSessionId = i;
15165 break;
15166 }
15167 }
15168 }
15169 return status;
15170}
15171
15172/* This function assumes that we only support one IBSS session. We cannot use BSSID to identify */
15173/* session because for IBSS, the bssid changes. */
15174static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac)
15175{
15176 uint32_t i, nRet = CSR_SESSION_ID_INVALID;
15177 tCsrRoamSession *pSession;
15178 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
15179 if (CSR_IS_SESSION_VALID(pMac, i)) {
15180 pSession = CSR_GET_SESSION(pMac, i);
15181 if (pSession->pCurRoamProfile
15182 &&
15183 (csr_is_bss_type_ibss
15184 (pSession->connectedProfile.BSSType))) {
15185 /* Found it */
15186 nRet = i;
15187 break;
15188 }
15189 }
15190 }
15191 return nRet;
15192}
15193
15194static void csr_roam_link_up(tpAniSirGlobal pMac, struct cdf_mac_addr bssid)
15195{
15196 /* Update the current BSS info in ho control block based on connected
15197 profile info from pmac global structure */
15198
15199 sms_log(pMac, LOGW,
15200 " csr_roam_link_up: WLAN link UP with AP= " MAC_ADDRESS_STR,
15201 MAC_ADDR_ARRAY(bssid.bytes));
15202 /* Check for user misconfig of RSSI trigger threshold */
15203 pMac->roam.configParam.vccRssiThreshold =
15204 (0 == pMac->roam.configParam.vccRssiThreshold) ?
15205 CSR_VCC_RSSI_THRESHOLD : pMac->roam.configParam.vccRssiThreshold;
15206 pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
15207 /* Check for user misconfig of UL MAC Loss trigger threshold */
15208 pMac->roam.configParam.vccUlMacLossThreshold =
15209 (0 == pMac->roam.configParam.vccUlMacLossThreshold) ?
15210 CSR_VCC_UL_MAC_LOSS_THRESHOLD : pMac->roam.configParam.
15211 vccUlMacLossThreshold;
15212#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
15213 {
15214 uint32_t sessionId = 0;
15215 /* Indicate the neighbor roal algorithm about the connect indication */
15216 csr_roam_get_session_id_from_bssid(pMac, &bssid,
15217 &sessionId);
15218 csr_neighbor_roam_indicate_connect(pMac, sessionId,
15219 CDF_STATUS_SUCCESS);
15220 }
15221#endif
15222}
15223
15224static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId)
15225{
15226 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
15227
15228 if (!pSession) {
15229 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
15230 return;
15231 }
15232 /* Only to handle the case for Handover on infra link */
15233 if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) {
15234 return;
15235 }
15236 /*
15237 * Incase of station mode, immediately stop data transmission whenever
15238 * link down is detected.
15239 */
15240 if (csr_roam_is_sta_mode(pMac, sessionId)
15241 && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
15242#ifdef WLAN_FEATURE_VOWIFI_11R
15243 && !csr_roam_is11r_assoc(pMac, sessionId)
15244#endif
15245 ) {
15246 sms_log(pMac, LOG1, FL("Inform Link lost for session %d"),
15247 sessionId);
15248 csr_roam_call_callback(pMac, sessionId, NULL, 0,
15249 eCSR_ROAM_LOSTLINK,
15250 eCSR_ROAM_RESULT_LOSTLINK);
15251 }
15252 /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers */
15253 csr_roam_dereg_statistics_req(pMac);
15254 pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
15255#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
15256 /* Indicate the neighbor roal algorithm about the disconnect indication */
15257 csr_neighbor_roam_indicate_disconnect(pMac, sessionId);
15258#endif
15259
15260 /* Remove this code once SLM_Sessionization is supported */
15261 /* BMPS_WORKAROUND_NOT_NEEDED */
15262 if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
15263 csr_is_infra_ap_started(pMac) &&
15264 pMac->roam.configParam.doBMPSWorkaround) {
15265 pMac->roam.configParam.doBMPSWorkaround = 0;
15266 }
15267
15268}
15269
15270void csr_roam_tl_stats_timer_handler(void *pv)
15271{
15272 tpAniSirGlobal pMac = PMAC_STRUCT(pv);
15273 CDF_STATUS status;
15274 pMac->roam.tlStatsReqInfo.timerRunning = false;
15275
15276 sms_log(pMac, LOG1,
15277 FL
15278 (" TL stat timer is no-op. It needs to support multiple stations"));
15279
15280 if (!pMac->roam.tlStatsReqInfo.timerRunning) {
15281 if (pMac->roam.tlStatsReqInfo.periodicity) {
15282 /* start timer */
15283 status =
15284 cdf_mc_timer_start(&pMac->roam.tlStatsReqInfo.
15285 hTlStatsTimer,
15286 pMac->roam.tlStatsReqInfo.
15287 periodicity);
15288 if (!CDF_IS_STATUS_SUCCESS(status)) {
15289 sms_log(pMac, LOGE,
15290 FL
15291 ("csr_roam_tl_stats_timer_handler:cannot start TlStatsTimer timer"));
15292 return;
15293 }
15294 pMac->roam.tlStatsReqInfo.timerRunning = true;
15295 }
15296 }
15297}
15298
15299void csr_roam_pe_stats_timer_handler(void *pv)
15300{
15301 tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *) pv;
15302 CDF_STATUS status;
15303 tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac;
15304 CDF_STATUS cdf_status;
15305 pPeStatsReqListEntry->timerRunning = false;
15306 if (pPeStatsReqListEntry->timerStopFailed == true) {
15307 /* If we entered here, meaning the timer could not be successfully */
15308 /* stopped in csr_roam_remove_entry_from_pe_stats_req_list(). So do it here. */
15309
15310 /* Destroy the timer */
15311 cdf_status =
15312 cdf_mc_timer_destroy(&pPeStatsReqListEntry->hPeStatsTimer);
15313 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
15314 sms_log(pMac, LOGE,
15315 FL
15316 ("csr_roam_pe_stats_timer_handler:failed to destroy hPeStatsTimer timer"));
15317 }
15318 /* Free the entry */
15319 cdf_mem_free(pPeStatsReqListEntry);
15320 pPeStatsReqListEntry = NULL;
15321 } else {
15322 if (!pPeStatsReqListEntry->rspPending) {
15323 status =
15324 csr_send_mb_stats_req_msg(pMac,
15325 pPeStatsReqListEntry->
15326 statsMask & ~(1 <<
15327 eCsrGlobalClassDStats),
15328 pPeStatsReqListEntry->staId,
15329 pPeStatsReqListEntry->
15330 sessionId);
15331 if (!CDF_IS_STATUS_SUCCESS(status)) {
15332 sms_log(pMac, LOGE,
15333 FL
15334 ("csr_roam_pe_stats_timer_handler:failed to send down stats req to PE"));
15335 } else {
15336 pPeStatsReqListEntry->rspPending = true;
15337 }
15338 }
15339 /* send down a req */
15340 if (pPeStatsReqListEntry->periodicity &&
15341 (CDF_TIMER_STATE_STOPPED ==
15342 cdf_mc_timer_get_current_state(&pPeStatsReqListEntry->
15343 hPeStatsTimer))) {
15344 if (pPeStatsReqListEntry->periodicity <
15345 pMac->roam.configParam.
15346 statsReqPeriodicityInPS) {
15347 pPeStatsReqListEntry->periodicity =
15348 pMac->roam.configParam.
15349 statsReqPeriodicityInPS;
15350 }
15351 /* start timer */
15352 cdf_status =
15353 cdf_mc_timer_start(&pPeStatsReqListEntry->
15354 hPeStatsTimer,
15355 pPeStatsReqListEntry->
15356 periodicity);
15357 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
15358 sms_log(pMac, LOGE,
15359 FL
15360 ("csr_roam_pe_stats_timer_handler:cannot start hPeStatsTimer timer"));
15361 return;
15362 }
15363 pPeStatsReqListEntry->timerRunning = true;
15364
15365 }
15366
15367 }
15368}
15369
15370void csr_roam_stats_client_timer_handler(void *pv)
15371{
15372 tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *) pv;
15373 if (CDF_TIMER_STATE_STOPPED ==
15374 cdf_mc_timer_get_current_state(&pStaEntry->timer)) {
15375 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
15376 FL("roam stats client timer is stopped"));
15377 }
15378}
15379
15380CDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
15381 uint8_t staId, uint8_t sessionId)
15382{
15383 tAniGetPEStatsReq *pMsg;
15384 CDF_STATUS status = CDF_STATUS_SUCCESS;
15385 pMsg = cdf_mem_malloc(sizeof(tAniGetPEStatsReq));
15386 if (NULL == pMsg) {
15387 sms_log(pMac, LOGE, FL("Failed to allocate mem for stats req "));
15388 return CDF_STATUS_E_NOMEM;
15389 }
15390 /* need to initiate a stats request to PE */
15391 pMsg->msgType = eWNI_SME_GET_STATISTICS_REQ;
15392 pMsg->msgLen = (uint16_t) sizeof(tAniGetPEStatsReq);
15393 pMsg->staId = staId;
15394 pMsg->statsMask = statsMask;
15395 pMsg->sessionId = sessionId;
15396 status = cds_send_mb_message_to_mac(pMsg);
15397 if (!CDF_IS_STATUS_SUCCESS(status)) {
15398 sms_log(pMac, LOG1, FL("Failed to send down the stats req "));
15399 }
15400 return status;
15401}
15402
15403/**
15404 * csr_update_stats() - updates correct stats struct in mac_ctx
15405 * @mac: mac global context
15406 * @stats_type: stats type
15407 * @sme_stats_rsp: stats rsp msg packet
15408 * @stats: input stats data buffer to fill in mac_ctx struct
15409 * @length: out param - stats length
15410 *
15411 * This function fills corresponding stats struct in mac_cts based on stats type
15412 * passed
15413 *
15414 * Return: void
15415 */
15416static void
15417csr_update_stats(tpAniSirGlobal mac, uint8_t stats_type,
15418 tAniGetPEStatsRsp *sme_stats_rsp,
15419 uint8_t **stats, uint32_t *length)
15420{
15421 switch (stats_type) {
15422 case eCsrSummaryStats:
15423 sms_log(mac, LOG2, FL("summary stats"));
15424 cdf_mem_copy((uint8_t *) &mac->roam.summaryStatsInfo, *stats,
15425 sizeof(tCsrSummaryStatsInfo));
15426 *stats += sizeof(tCsrSummaryStatsInfo);
15427 *length -= sizeof(tCsrSummaryStatsInfo);
15428 break;
15429 case eCsrGlobalClassAStats:
15430 sms_log(mac, LOG2, FL("ClassA stats"));
15431 cdf_mem_copy((uint8_t *) &mac->roam.classAStatsInfo, *stats,
15432 sizeof(tCsrGlobalClassAStatsInfo));
15433 *stats += sizeof(tCsrGlobalClassAStatsInfo);
15434 *length -= sizeof(tCsrGlobalClassAStatsInfo);
15435 break;
15436 case eCsrGlobalClassBStats:
15437 sms_log(mac, LOG2, FL("ClassB stats"));
15438 cdf_mem_copy((uint8_t *) &mac->roam.classBStatsInfo, *stats,
15439 sizeof(tCsrGlobalClassBStatsInfo));
15440 *stats += sizeof(tCsrGlobalClassBStatsInfo);
15441 *length -= sizeof(tCsrGlobalClassBStatsInfo);
15442 break;
15443 case eCsrGlobalClassCStats:
15444 sms_log(mac, LOG2, FL("ClassC stats"));
15445 cdf_mem_copy((uint8_t *) &mac->roam.classCStatsInfo, *stats,
15446 sizeof(tCsrGlobalClassCStatsInfo));
15447 *stats += sizeof(tCsrGlobalClassCStatsInfo);
15448 *length -= sizeof(tCsrGlobalClassCStatsInfo);
15449 break;
15450 case eCsrPerStaStats:
15451 sms_log(mac, LOG2, FL("PerSta stats"));
15452 if (CSR_MAX_STA > sme_stats_rsp->staId) {
15453 cdf_mem_copy(
15454 &mac->roam.perStaStatsInfo[sme_stats_rsp->staId],
15455 *stats, sizeof(tCsrPerStaStatsInfo));
15456 } else {
15457 sms_log(mac, LOGE, FL("out bound staId:%d. failed to copy PerSta stats"),
15458 sme_stats_rsp->staId);
15459 CDF_ASSERT(0);
15460 }
15461 *stats += sizeof(tCsrPerStaStatsInfo);
15462 *length -= sizeof(tCsrPerStaStatsInfo);
15463 break;
15464 default:
15465 sms_log(mac, LOGW, FL("unknown stats type"));
15466 break;
15467 }
15468}
15469
15470/**
15471 * csr_roam_stats_rsp_processor() - processes stats rsp msg
15472 * @pMac mac global context
15473 * @pSirMsg: incoming message
15474 *
15475 * Return: void
15476 */
15477void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg)
15478{
15479 tAniGetPEStatsRsp *pSmeStatsRsp;
15480 tListElem *pEntry = NULL;
15481 tCsrStatsClientReqInfo *pTempStaEntry = NULL;
15482 tCsrPeStatsReqInfo *pPeStaEntry = NULL;
15483 uint32_t tempMask = 0;
15484 uint8_t counter = 0;
15485 uint8_t *pStats = NULL;
15486 uint32_t length = 0;
15487 void *p_cds_gctx;
15488 int8_t rssi = 0, snr = 0;
15489 uint32_t *pRssi = NULL, *pSnr = NULL;
15490 uint32_t linkCapacity;
15491 pSmeStatsRsp = (tAniGetPEStatsRsp *) pSirMsg;
15492
15493 if (pSmeStatsRsp->rc) {
15494 sms_log(pMac, LOGW, FL("stats rsp from PE shows failure"));
15495 goto post_update;
15496 }
15497 tempMask = pSmeStatsRsp->statsMask;
15498 pStats = ((uint8_t *) &pSmeStatsRsp->statsMask) +
15499 sizeof(pSmeStatsRsp->statsMask);
15500 /*
15501 * subtract all statistics from this length, and after processing the
15502 * entire 'stat' part of the message, if the length is not zero, then
15503 * rssi is piggy packed in this 'stats' message.
15504 */
15505 length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp);
15506 /* new stats info from PE, fill up the stats strucutres in PMAC */
15507 while (tempMask) {
15508 if (tempMask & 1) {
15509 csr_update_stats(pMac, counter, pSmeStatsRsp,
15510 &pStats, &length);
15511 }
15512 tempMask >>= 1;
15513 counter++;
15514 }
15515 p_cds_gctx = cds_get_global_context();
15516 if (length != 0) {
15517 pRssi = (uint32_t *) pStats;
15518 rssi = (int8_t) *pRssi;
15519 pStats += sizeof(uint32_t);
15520 length -= sizeof(uint32_t);
15521 } else {
15522 /* If riva is not sending rssi, continue to use the hack */
15523 rssi = RSSI_HACK_BMPS;
15524 }
15525
15526 if (length != 0) {
15527 linkCapacity = *(uint32_t *) pStats;
15528 pStats += sizeof(uint32_t);
15529 length -= sizeof(uint32_t);
15530 } else {
15531 linkCapacity = 0;
15532 }
15533
15534 if (length != 0) {
15535 pSnr = (uint32_t *) pStats;
15536 snr = (int8_t) *pSnr;
15537 } else {
15538 snr = SNR_HACK_BMPS;
15539 }
15540
15541post_update:
15542 /* make sure to update the pe stats req list */
15543 pEntry = csr_roam_find_in_pe_stats_req_list(pMac, pSmeStatsRsp->statsMask);
15544 if (pEntry) {
15545 pPeStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
15546 pPeStaEntry->rspPending = false;
15547
15548 }
15549 /* check the one timer cases */
15550 pEntry = csr_roam_check_client_req_list(pMac, pSmeStatsRsp->statsMask);
15551 if (pEntry) {
15552 pTempStaEntry =
15553 GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
15554 if (pTempStaEntry->timerExpired) {
15555 /* send up the stats report */
15556 csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
15557 pTempStaEntry->callback,
15558 pTempStaEntry->staId,
15559 pTempStaEntry->pContext);
15560 /* also remove from the client list */
15561 csr_roam_remove_stat_list_entry(pMac, pEntry);
15562 pTempStaEntry = NULL;
15563 }
15564 }
15565}
15566
15567tListElem *csr_roam_find_in_pe_stats_req_list(tpAniSirGlobal pMac, uint32_t statsMask)
15568{
15569 tListElem *pEntry = NULL;
15570 tCsrPeStatsReqInfo *pTempStaEntry = NULL;
15571 pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
15572 if (!pEntry) {
15573 /* list empty */
15574 sms_log(pMac, LOG2,
15575 "csr_roam_find_in_pe_stats_req_list: List empty, no request to PE");
15576 return NULL;
15577 }
15578 while (pEntry) {
15579 pTempStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
15580 if (pTempStaEntry->statsMask == statsMask) {
15581 sms_log(pMac, LOG3,
15582 "csr_roam_find_in_pe_stats_req_list: match found");
15583 break;
15584 }
15585 pEntry =
15586 csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
15587 LL_ACCESS_NOLOCK);
15588 }
15589 return pEntry;
15590}
15591
15592tListElem *csr_roam_checkn_update_client_req_list(tpAniSirGlobal pMac,
15593 tCsrStatsClientReqInfo *pStaEntry,
15594 bool update)
15595{
15596 tListElem *pEntry;
15597 tCsrStatsClientReqInfo *pTempStaEntry;
15598 pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
15599 if (!pEntry) {
15600 /* list empty */
15601 sms_log(pMac, LOG2,
15602 "csr_roam_checkn_update_client_req_list: List empty, no request from "
15603 "upper layer client(s)");
15604 return NULL;
15605 }
15606 while (pEntry) {
15607 pTempStaEntry =
15608 GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
15609 if ((pTempStaEntry->requesterId == pStaEntry->requesterId)
15610 && (pTempStaEntry->statsMask == pStaEntry->statsMask)) {
15611 sms_log(pMac, LOG3,
15612 "csr_roam_checkn_update_client_req_list: match found");
15613 if (update) {
15614 pTempStaEntry->periodicity =
15615 pStaEntry->periodicity;
15616 pTempStaEntry->callback = pStaEntry->callback;
15617 pTempStaEntry->pContext = pStaEntry->pContext;
15618 }
15619 break;
15620 }
15621 pEntry =
15622 csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
15623 LL_ACCESS_NOLOCK);
15624 }
15625 return pEntry;
15626}
15627
15628tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac, uint32_t statsMask)
15629{
15630 tListElem *pEntry;
15631 tCsrStatsClientReqInfo *pTempStaEntry;
15632 pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
15633 if (!pEntry) {
15634 /* list empty */
15635 sms_log(pMac, LOG2,
15636 "csr_roam_check_client_req_list: List empty, no request from "
15637 "upper layer client(s)");
15638 return NULL;
15639 }
15640 while (pEntry) {
15641 pTempStaEntry =
15642 GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
15643 if ((pTempStaEntry->
15644 statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) {
15645 sms_log(pMac, LOG3,
15646 "csr_roam_check_client_req_list: match found");
15647 break;
15648 }
15649 pEntry =
15650 csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
15651 LL_ACCESS_NOLOCK);
15652 }
15653 return pEntry;
15654}
15655
15656void csr_roam_vcc_trigger(tpAniSirGlobal pMac)
15657{
15658 eCsrRoamLinkQualityInd newVccLinkQuality;
15659 uint32_t ul_mac_loss = 0;
15660 uint32_t ul_mac_loss_trigger_threshold;
15661 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
15662 /*-------------------------------------------------------------------------
15663 Link quality is currently binary based on OBIWAN recommended triggers
15664 Check for a change in link quality and notify client if necessary
15665 -------------------------------------------------------------------------*/
15666 ul_mac_loss_trigger_threshold =
15667 pMac->roam.configParam.vccUlMacLossThreshold;
15668 if (0 == ul_mac_loss_trigger_threshold) {
15669 CDF_ASSERT(ul_mac_loss_trigger_threshold != 0);
15670 return;
15671 }
15672 sms_log(pMac, LOGW, "csr_roam_vcc_trigger: UL_MAC_LOSS_THRESHOLD is %d",
15673 ul_mac_loss_trigger_threshold);
15674 if (ul_mac_loss_trigger_threshold < ul_mac_loss) {
15675 sms_log(pMac, LOGW, "csr_roam_vcc_trigger: link quality is POOR ");
15676 newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
15677 } else {
15678 sms_log(pMac, LOGW, "csr_roam_vcc_trigger: link quality is GOOD");
15679 newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND;
15680 }
15681 sms_log(pMac, LOGW,
15682 "csr_roam_vcc_trigger: link qual : *** UL_MAC_LOSS %d *** ",
15683 ul_mac_loss);
15684 if (newVccLinkQuality != pMac->roam.vccLinkQuality) {
15685 sms_log(pMac, LOGW,
15686 "csr_roam_vcc_trigger: link quality changed: trigger necessary");
15687 if (NULL != pMac->roam.linkQualityIndInfo.callback) {
15688 sms_log(pMac, LOGW,
15689 "csr_roam_vcc_trigger: link quality indication %d",
15690 newVccLinkQuality);
15691
15692 /* we now invoke the callback once to notify client of initial value */
15693 pMac->roam.linkQualityIndInfo.
15694 callback(newVccLinkQuality,
15695 pMac->roam.linkQualityIndInfo.context);
15696 /* event: EVENT_WLAN_VCC */
15697 }
15698 }
15699 pMac->roam.vccLinkQuality = newVccLinkQuality;
15700
15701}
15702
15703tCsrStatsClientReqInfo *csr_roam_insert_entry_into_list(tpAniSirGlobal pMac,
15704 tDblLinkList *pStaList,
15705 tCsrStatsClientReqInfo *
15706 pStaEntry)
15707{
15708 tCsrStatsClientReqInfo *pNewStaEntry = NULL;
15709 /* if same entity requested for same set of stats with different periodicity & */
15710 /* callback update it */
15711 if (NULL == csr_roam_checkn_update_client_req_list(pMac, pStaEntry, true)) {
15712
15713 pNewStaEntry = cdf_mem_malloc(sizeof(tCsrStatsClientReqInfo));
15714 if (NULL == pNewStaEntry) {
15715 sms_log(pMac, LOGW,
15716 "csr_roam_insert_entry_into_list: couldn't allocate memory for the "
15717 "entry");
15718 return NULL;
15719 }
15720
15721 pNewStaEntry->callback = pStaEntry->callback;
15722 pNewStaEntry->pContext = pStaEntry->pContext;
15723 pNewStaEntry->periodicity = pStaEntry->periodicity;
15724 pNewStaEntry->requesterId = pStaEntry->requesterId;
15725 pNewStaEntry->statsMask = pStaEntry->statsMask;
15726 pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry;
15727 pNewStaEntry->pMac = pStaEntry->pMac;
15728 pNewStaEntry->staId = pStaEntry->staId;
15729 pNewStaEntry->timerExpired = pStaEntry->timerExpired;
15730
15731 csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
15732 }
15733 return pNewStaEntry;
15734}
15735
15736tCsrPeStatsReqInfo *csr_roam_insert_entry_into_pe_stats_req_list(tpAniSirGlobal pMac,
15737 tDblLinkList *
15738 pStaList,
15739 tCsrPeStatsReqInfo *
15740 pStaEntry)
15741{
15742 tCsrPeStatsReqInfo *pNewStaEntry = NULL;
15743 pNewStaEntry = cdf_mem_malloc(sizeof(tCsrPeStatsReqInfo));
15744 if (NULL == pNewStaEntry) {
15745 sms_log(pMac, LOGW,
15746 "csr_roam_insert_entry_into_pe_stats_req_list: couldn't allocate memory for the "
15747 "entry");
15748 return NULL;
15749 }
15750
15751 pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer;
15752 pNewStaEntry->numClient = pStaEntry->numClient;
15753 pNewStaEntry->periodicity = pStaEntry->periodicity;
15754 pNewStaEntry->statsMask = pStaEntry->statsMask;
15755 pNewStaEntry->pMac = pStaEntry->pMac;
15756 pNewStaEntry->staId = pStaEntry->staId;
15757 pNewStaEntry->timerRunning = pStaEntry->timerRunning;
15758 pNewStaEntry->rspPending = pStaEntry->rspPending;
15759
15760 csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
15761 return pNewStaEntry;
15762}
15763
15764CDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
15765 tCsrRssiCallback callback,
15766 uint8_t staId,
15767 struct cdf_mac_addr bssId,
15768 int8_t lastRSSI, void *pContext, void *p_cds_context)
15769{
15770 CDF_STATUS status = CDF_STATUS_SUCCESS;
15771 cds_msg_t msg;
15772 uint32_t sessionId;
15773
15774 tAniGetRssiReq *pMsg;
15775 sms_log(pMac, LOG2, FL("called"));
15776
15777 status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
15778 if (!CDF_IS_STATUS_SUCCESS(status)) {
15779 callback(lastRSSI, staId, pContext);
15780 sms_log(pMac, LOGE, FL("Failed to get SessionId"));
15781 return CDF_STATUS_E_FAILURE;
15782 }
15783
15784 pMsg = cdf_mem_malloc(sizeof(tAniGetRssiReq));
15785 if (NULL == pMsg) {
15786 sms_log(pMac, LOGE,
15787 " csr_get_rssi: failed to allocate mem for req ");
15788 return CDF_STATUS_E_NOMEM;
15789 }
15790
15791 pMsg->msgType = eWNI_SME_GET_RSSI_REQ;
15792 pMsg->msgLen = (uint16_t) sizeof(tAniGetRssiReq);
15793 pMsg->sessionId = sessionId;
15794 pMsg->staId = staId;
15795 pMsg->rssiCallback = callback;
15796 pMsg->pDevContext = pContext;
15797 pMsg->p_cds_context = p_cds_context;
15798 /*
15799 * store RSSI at time of calling, so that if RSSI request cannot
15800 * be sent to firmware, this value can be used to return immediately
15801 */
15802 pMsg->lastRSSI = lastRSSI;
15803 msg.type = eWNI_SME_GET_RSSI_REQ;
15804 msg.bodyptr = pMsg;
15805 msg.reserved = 0;
15806 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
15807 sms_log(pMac, LOGE, " csr_get_rssi failed to post msg to self ");
15808 cdf_mem_free((void *)pMsg);
15809 status = CDF_STATUS_E_FAILURE;
15810 }
15811 sms_log(pMac, LOG2, FL("returned"));
15812 return status;
15813}
15814
15815CDF_STATUS csr_get_snr(tpAniSirGlobal pMac,
15816 tCsrSnrCallback callback,
15817 uint8_t staId, struct cdf_mac_addr bssId, void *pContext)
15818{
15819 CDF_STATUS status = CDF_STATUS_SUCCESS;
15820 cds_msg_t msg;
15821 uint32_t sessionId;
15822
15823 tAniGetSnrReq *pMsg;
15824
15825 sms_log(pMac, LOG2, FL("called"));
15826
15827 pMsg = (tAniGetSnrReq *) cdf_mem_malloc(sizeof(tAniGetSnrReq));
15828 if (NULL == pMsg) {
15829 sms_log(pMac, LOGE, "%s: failed to allocate mem for req",
15830 __func__);
15831 return CDF_STATUS_E_NOMEM;
15832 }
15833
15834 csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
15835
15836 pMsg->msgType = eWNI_SME_GET_SNR_REQ;
15837 pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq);
15838 pMsg->sessionId = sessionId;
15839 pMsg->staId = staId;
15840 pMsg->snrCallback = callback;
15841 pMsg->pDevContext = pContext;
15842 msg.type = eWNI_SME_GET_SNR_REQ;
15843 msg.bodyptr = pMsg;
15844 msg.reserved = 0;
15845
15846 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
15847 sms_log(pMac, LOGE, "%s failed to post msg to self", __func__);
15848 cdf_mem_free((void *)pMsg);
15849 status = CDF_STATUS_E_FAILURE;
15850 }
15851
15852 sms_log(pMac, LOG2, FL("returned"));
15853 return status;
15854}
15855
15856#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
15857CDF_STATUS csr_get_tsm_stats(tpAniSirGlobal pMac,
15858 tCsrTsmStatsCallback callback,
15859 uint8_t staId,
15860 struct cdf_mac_addr bssId,
15861 void *pContext, void *p_cds_context, uint8_t tid)
15862{
15863 CDF_STATUS status = CDF_STATUS_SUCCESS;
15864 tAniGetTsmStatsReq *pMsg = NULL;
15865 pMsg = cdf_mem_malloc(sizeof(tAniGetTsmStatsReq));
15866 if (!pMsg) {
15867 sms_log(pMac, LOGE,
15868 "csr_get_tsm_stats: failed to allocate mem for req");
15869 return CDF_STATUS_E_NOMEM;
15870 }
15871 /* need to initiate a stats request to PE */
15872 pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ;
15873 pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq);
15874 pMsg->staId = staId;
15875 pMsg->tid = tid;
15876 cdf_mem_copy(pMsg->bssId, bssId.bytes, sizeof(tSirMacAddr));
15877 pMsg->tsmStatsCallback = callback;
15878 pMsg->pDevContext = pContext;
15879 pMsg->p_cds_context = p_cds_context;
15880 status = cds_send_mb_message_to_mac(pMsg);
15881 if (!CDF_IS_STATUS_SUCCESS(status)) {
15882 sms_log(pMac, LOG1,
15883 " csr_get_tsm_stats: failed to send down the rssi req");
15884 /* pMsg is freed by cds_send_mb_message_to_mac */
15885 status = CDF_STATUS_E_FAILURE;
15886 }
15887 return status;
15888}
15889#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
15890
15891/**
15892 * csr_deregister_client_request() - deregisters a get stats request
15893 * @mac_ctx: mac global context
15894 * @sta_entry: stats request entry
15895 *
15896 * Return: status of operation
15897 */
15898static CDF_STATUS
15899csr_deregister_client_request(tpAniSirGlobal mac_ctx,
15900 tCsrStatsClientReqInfo *sta_entry)
15901{
15902 CDF_STATUS status;
15903 tListElem *entry = NULL;
15904 tCsrStatsClientReqInfo *ptr_sta_entry = NULL;
15905
15906 entry = csr_roam_checkn_update_client_req_list(mac_ctx, sta_entry,
15907 false);
15908 if (!entry) {
15909 sms_log(mac_ctx, LOGW,
15910 FL("callback is empty in the request & couldn't find any existing request in statsClientReqList"));
15911 return CDF_STATUS_E_FAILURE;
15912 }
15913 /* clean up & return */
15914 ptr_sta_entry = GET_BASE_ADDR(entry, tCsrStatsClientReqInfo, link);
15915 if (NULL != ptr_sta_entry->pPeStaEntry) {
15916 ptr_sta_entry->pPeStaEntry->numClient--;
15917 /* check if we need to delete the entry from peStatsReqList */
15918 if (!ptr_sta_entry->pPeStaEntry->numClient)
15919 csr_roam_remove_entry_from_pe_stats_req_list(mac_ctx,
15920 ptr_sta_entry->pPeStaEntry);
15921 }
15922 /* check if we need to stop the tl stats timer too */
15923 mac_ctx->roam.tlStatsReqInfo.numClient--;
15924 if (!mac_ctx->roam.tlStatsReqInfo.numClient) {
15925 if (mac_ctx->roam.tlStatsReqInfo.timerRunning) {
15926 status = cdf_mc_timer_stop(
15927 &mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer);
15928 if (!CDF_IS_STATUS_SUCCESS(status)) {
15929 sms_log(mac_ctx, LOGE,
15930 FL("cannot stop TlStatsTimer timer"));
15931 return status;
15932 }
15933 }
15934 mac_ctx->roam.tlStatsReqInfo.periodicity = 0;
15935 mac_ctx->roam.tlStatsReqInfo.timerRunning = false;
15936 }
15937 cdf_mc_timer_stop(&ptr_sta_entry->timer);
15938 /* Destroy the cdf timer... */
15939 status = cdf_mc_timer_destroy(&ptr_sta_entry->timer);
15940 if (!CDF_IS_STATUS_SUCCESS(status))
15941 sms_log(mac_ctx, LOGE,
15942 FL("failed to destroy Client req timer"));
15943
15944 csr_roam_remove_stat_list_entry(mac_ctx, entry);
15945 return CDF_STATUS_SUCCESS;
15946}
15947
15948/**
15949 * csr_insert_stats_request_to_list() - inserts request to existing list
15950 * @mac_ctx: mac global context
15951 * @sta_entry: stats request entry
15952 * @periodicity: periodicity of stats
15953 *
15954 * Return: status of operation
15955 */
15956static CDF_STATUS
15957csr_insert_stats_request_to_list(tpAniSirGlobal mac_ctx,
15958 tCsrStatsClientReqInfo *sta_entry,
15959 uint32_t periodicity)
15960{
15961 CDF_STATUS status = CDF_STATUS_SUCCESS;
15962 tCsrStatsClientReqInfo *ptr_sta_entry = csr_roam_insert_entry_into_list(
15963 mac_ctx, &mac_ctx->roam.statsClientReqList,
15964 sta_entry);
15965 if (!ptr_sta_entry) {
15966 sms_log(mac_ctx, LOGW,
15967 FL("Failed to insert req in statsClientReqList"));
15968 return CDF_STATUS_E_FAILURE;
15969 }
15970 /* Init & start timer if needed */
15971 ptr_sta_entry->periodicity = periodicity;
15972 if (ptr_sta_entry->periodicity) {
15973 status = cdf_mc_timer_init(&ptr_sta_entry->timer,
15974 CDF_TIMER_TYPE_SW,
15975 csr_roam_stats_client_timer_handler,
15976 ptr_sta_entry);
15977 if (!CDF_IS_STATUS_SUCCESS(status)) {
15978 sms_log(mac_ctx, LOGE,
15979 FL("cannot init StatsClient timer"));
15980 return CDF_STATUS_E_FAILURE;
15981 }
15982 status = cdf_mc_timer_start(&ptr_sta_entry->timer,
15983 ptr_sta_entry->periodicity);
15984 if (!CDF_IS_STATUS_SUCCESS(status)) {
15985 sms_log(mac_ctx, LOGE,
15986 FL("cannot start StatsClient timer"));
15987 return CDF_STATUS_E_FAILURE;
15988 }
15989 }
15990 return status;
15991}
15992
15993/**
15994 * csr_get_statistics_from_tl() - fetch stats from tl layer
15995 * @mac_ctx: mac global context
15996 * @cache: indicate if cached stats are required
15997 * @staId: station id
15998 * @periodicity: periodicity of stats
15999 *
16000 * Return: status of operation
16001 */
16002static CDF_STATUS
16003csr_get_statistics_from_tl(tpAniSirGlobal mac_ctx,
16004 bool cache,
16005 uint8_t staId,
16006 uint32_t periodicity)
16007{
16008 CDF_STATUS status;
16009
16010 if (cache && mac_ctx->roam.tlStatsReqInfo.numClient) {
16011 sms_log(mac_ctx, LOGE, FL("Looking for cached stats from TL"));
16012 mac_ctx->roam.tlStatsReqInfo.numClient++;
16013 return CDF_STATUS_SUCCESS;
16014 }
16015
16016 /* update periodicity */
16017 if (mac_ctx->roam.tlStatsReqInfo.periodicity)
16018 mac_ctx->roam.tlStatsReqInfo.periodicity =
16019 CDF_MIN(periodicity,
16020 mac_ctx->roam.tlStatsReqInfo.periodicity);
16021 else
16022 mac_ctx->roam.tlStatsReqInfo.periodicity = periodicity;
16023
16024 if (mac_ctx->roam.tlStatsReqInfo.periodicity
16025 < CSR_MIN_TL_STAT_QUERY_PERIOD) {
16026 mac_ctx->roam.tlStatsReqInfo.periodicity =
16027 CSR_MIN_TL_STAT_QUERY_PERIOD;
16028 }
16029
16030 if (!mac_ctx->roam.tlStatsReqInfo.timerRunning) {
16031
16032 if (mac_ctx->roam.tlStatsReqInfo.periodicity) {
16033 /* start timer */
16034 status = cdf_mc_timer_start(
16035 &mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer,
16036 mac_ctx->roam.tlStatsReqInfo.periodicity);
16037 if (!CDF_IS_STATUS_SUCCESS(status)) {
16038 sms_log(mac_ctx, LOGE,
16039 FL("cannot start TlStatsTimer timer"));
16040 return CDF_STATUS_E_FAILURE;
16041 }
16042 mac_ctx->roam.tlStatsReqInfo.timerRunning = true;
16043 }
16044 }
16045 mac_ctx->roam.tlStatsReqInfo.numClient++;
16046 return CDF_STATUS_SUCCESS;
16047}
16048
16049CDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
16050 eCsrStatsRequesterType requesterId,
16051 uint32_t statsMask,
16052 tCsrStatsCallback callback,
16053 uint32_t periodicity,
16054 bool cache,
16055 uint8_t staId,
16056 void *pContext,
16057 uint8_t sessionId)
16058{
16059 tCsrStatsClientReqInfo staEntry;
16060 tCsrPeStatsReqInfo *pPeStaEntry = NULL;
16061 bool found = false;
16062 CDF_STATUS status = CDF_STATUS_SUCCESS;
16063 bool insertInClientList = false;
16064 uint32_t temp_mask = 0;
16065
16066 if (csr_is_all_session_disconnected(pMac))
16067 return CDF_STATUS_E_FAILURE;
16068
16069 if (csr_neighbor_middle_of_roaming(pMac, sessionId)) {
16070 sms_log(pMac, LOG1, FL("in the middle of roaming states"));
16071 return CDF_STATUS_E_FAILURE;
16072 }
16073
16074 if ((!statsMask) && (!callback)) {
16075 sms_log(pMac, LOGW,
16076 FL("statsMask & callback empty in the request"));
16077 return CDF_STATUS_E_FAILURE;
16078 }
16079 /* for the search list method for deregister */
16080 staEntry.requesterId = requesterId;
16081 staEntry.statsMask = statsMask;
16082 /* requester wants to deregister or just an error */
16083 if ((statsMask) && (!callback))
16084 return csr_deregister_client_request(pMac, &staEntry);
16085
16086 if (cache && !periodicity) {
16087 /* return the cached stats */
16088 csr_roam_report_statistics(pMac, statsMask, callback, staId,
16089 pContext);
16090 return CDF_STATUS_SUCCESS;
16091 }
16092 /* add the request in the client req list */
16093 staEntry.callback = callback;
16094 staEntry.pContext = pContext;
16095 staEntry.periodicity = periodicity;
16096 staEntry.pPeStaEntry = NULL;
16097 staEntry.staId = staId;
16098 staEntry.pMac = pMac;
16099 staEntry.timerExpired = false;
16100 staEntry.sessionId = sessionId;
16101
16102 /* if periodic report requested with non cached result from PE/TL */
16103 if (periodicity) {
16104 /* if looking for stats from PE */
16105 temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
16106 if (temp_mask) {
16107 /* check if same req made already & waiting for rsp */
16108 pPeStaEntry = csr_roam_check_pe_stats_req_list(pMac,
16109 temp_mask, periodicity, &found,
16110 staId, sessionId);
16111 if (!pPeStaEntry)
16112 /* bail out, maxed out on num of req for PE */
16113 return CDF_STATUS_E_FAILURE;
16114 else
16115 staEntry.pPeStaEntry = pPeStaEntry;
16116 }
16117 /*
16118 * request stats from TL rightaway if requested by client,
16119 * update tlStatsReqInfo if needed
16120 */
16121 temp_mask = statsMask & (1 << eCsrGlobalClassDStats);
16122 if (temp_mask) {
16123 status = csr_get_statistics_from_tl(pMac, cache, staId,
16124 periodicity);
16125 if (!CDF_IS_STATUS_SUCCESS(status))
16126 return status;
16127 }
16128 insertInClientList = true;
16129 }
16130 /* if one time report requested with non cached result from PE/TL */
16131 else if (!cache && !periodicity) {
16132 temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
16133 if (temp_mask) {
16134 /* send down a req */
16135 status = csr_send_mb_stats_req_msg(pMac,
16136 temp_mask, staId, sessionId);
16137 if (!CDF_IS_STATUS_SUCCESS(status))
16138 sms_log(pMac, LOGE,
16139 FL("failed to send down stats req"));
16140 /*
16141 * so that when the stats rsp comes back from PE we
16142 * respond to upper layer right away
16143 */
16144 staEntry.timerExpired = true;
16145 insertInClientList = true;
16146 }
16147 /* if looking for stats from TL only */
16148 if (!insertInClientList) {
16149 /* return the stats */
16150 csr_roam_report_statistics(pMac, statsMask, callback,
16151 staId, pContext);
16152 return CDF_STATUS_SUCCESS;
16153 }
16154 }
16155 if (insertInClientList)
16156 return csr_insert_stats_request_to_list(pMac, &staEntry,
16157 periodicity);
16158
16159 return CDF_STATUS_SUCCESS;
16160}
16161
16162static tSirRetStatus
16163csr_roam_scan_offload_populate_mac_header(tpAniSirGlobal pMac,
16164 uint8_t *pBD,
16165 uint8_t type,
16166 uint8_t subType,
16167 tSirMacAddr peerAddr,
16168 tSirMacAddr selfMacAddr)
16169{
16170 tSirRetStatus statusCode = eSIR_SUCCESS;
16171 tpSirMacMgmtHdr pMacHdr;
16172
16173 /* Prepare MAC management header */
16174 pMacHdr = (tpSirMacMgmtHdr) (pBD);
16175
16176 /* Prepare FC */
16177 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
16178 pMacHdr->fc.type = type;
16179 pMacHdr->fc.subType = subType;
16180
16181 /* Prepare Address 1 */
16182 cdf_mem_copy((uint8_t *) pMacHdr->da, (uint8_t *) peerAddr,
16183 sizeof(tSirMacAddr));
16184
16185 sir_copy_mac_addr(pMacHdr->sa, selfMacAddr);
16186
16187 /* Prepare Address 3 */
16188 cdf_mem_copy((uint8_t *) pMacHdr->bssId, (uint8_t *) peerAddr,
16189 sizeof(tSirMacAddr));
16190 return statusCode;
16191} /*** csr_roam_scan_offload_populate_mac_header() ***/
16192
16193static tSirRetStatus
16194csr_roam_scan_offload_prepare_probe_req_template(tpAniSirGlobal pMac,
16195 uint8_t nChannelNum,
16196 uint32_t dot11mode,
16197 tSirMacAddr selfMacAddr,
16198 uint8_t *pFrame,
16199 uint16_t *pusLen,
16200 tCsrRoamSession *psession)
16201{
16202 tDot11fProbeRequest pr;
16203 uint32_t nStatus, nBytes, nPayload;
16204 tSirRetStatus nSirStatus;
16205 /*Bcast tx */
16206 tSirMacAddr bssId = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
16207 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
16208
16209 cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
16210
16211 populate_dot11f_supp_rates(pMac, nChannelNum, &pr.SuppRates, NULL);
16212
16213 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
16214 populate_dot11f_ext_supp_rates1(pMac, nChannelNum,
16215 &pr.ExtSuppRates);
16216 }
16217
16218 if (IS_DOT11_MODE_HT(dot11mode)) {
16219 populate_dot11f_ht_caps(pMac, NULL, &pr.HTCaps);
16220 pr.HTCaps.advCodingCap = psession->htConfig.ht_rx_ldpc;
16221 pr.HTCaps.txSTBC = psession->htConfig.ht_tx_stbc;
16222 pr.HTCaps.rxSTBC = psession->htConfig.ht_rx_stbc;
16223 if (!psession->htConfig.ht_sgi) {
16224 pr.HTCaps.shortGI20MHz = pr.HTCaps.shortGI40MHz = 0;
16225 }
16226 }
16227
16228 nStatus = dot11f_get_packed_probe_request_size(pMac, &pr, &nPayload);
16229 if (DOT11F_FAILED(nStatus)) {
16230 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16231 "Failed to calculate the packed size f"
16232 "or a Probe Request (0x%08x).\n", nStatus);
16233
16234 nPayload = sizeof(tDot11fProbeRequest);
16235 } else if (DOT11F_WARNED(nStatus)) {
16236 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16237 "There were warnings while calculating"
16238 "the packed size for a Probe Request ("
16239 "0x%08x).\n", nStatus);
16240 }
16241
16242 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
16243
16244 /* Prepare outgoing frame */
16245 cdf_mem_set(pFrame, nBytes, 0);
16246
16247 nSirStatus =
16248 csr_roam_scan_offload_populate_mac_header(pMac, pFrame,
16249 SIR_MAC_MGMT_FRAME,
16250 SIR_MAC_MGMT_PROBE_REQ, bssId,
16251 selfMacAddr);
16252
16253 if (eSIR_SUCCESS != nSirStatus) {
16254 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16255 "Failed to populate the buffer descriptor for a Probe Request (%d).\n",
16256 nSirStatus);
16257 return nSirStatus;
16258 }
16259
16260 nStatus = dot11f_pack_probe_request(pMac, &pr, pFrame +
16261 sizeof(tSirMacMgmtHdr),
16262 nPayload, &nPayload);
16263 if (DOT11F_FAILED(nStatus)) {
16264 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16265 "Failed to pack a Probe Request (0x%08x).\n",
16266 nStatus);
16267 return eSIR_FAILURE;
16268 } else if (DOT11F_WARNED(nStatus)) {
16269 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16270 "There were warnings while packing a Probe Request (0x%08x).\n",
16271 nStatus);
16272 }
16273
16274 *pusLen = nPayload + sizeof(tSirMacMgmtHdr);
16275 return eSIR_SUCCESS;
16276}
16277
16278#ifdef WLAN_FEATURE_ROAM_OFFLOAD
16279CDF_STATUS csr_roam_set_key_mgmt_offload(tpAniSirGlobal pMac,
16280 uint32_t sessionId,
16281 bool nRoamKeyMgmtOffloadEnabled)
16282{
16283 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
16284 if (!pSession) {
16285 sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
16286 return CDF_STATUS_E_FAILURE;
16287 }
16288 pSession->RoamKeyMgmtOffloadEnabled = nRoamKeyMgmtOffloadEnabled;
16289 return CDF_STATUS_SUCCESS;
16290}
16291
16292/**
16293 * csr_update_roam_scan_offload_request() - updates req msg with roam offload
16294 * paramters
16295 * @pMac: mac global context
16296 * @req_buf: out param, roam offload scan request packet
16297 * @session: roam session
16298 *
16299 * Return: void
16300 */
16301static void
16302csr_update_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
16303 tSirRoamOffloadScanReq *req_buf,
16304 tCsrRoamSession *session)
16305{
16306 cdf_mem_copy(req_buf->PSK_PMK, session->psk_pmk,
16307 sizeof(req_buf->PSK_PMK));
16308 req_buf->pmk_len = session->pmk_len;
16309 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16310 "LFR3: PMK Length = %d", req_buf->pmk_len);
16311 req_buf->R0KH_ID_Length = session->ftSmeContext.r0kh_id_len;
16312 cdf_mem_copy(req_buf->R0KH_ID,
16313 session->ftSmeContext.r0kh_id,
16314 req_buf->R0KH_ID_Length);
16315 req_buf->Prefer5GHz = mac_ctx->roam.configParam.nRoamPrefer5GHz;
16316 req_buf->RoamRssiCatGap = mac_ctx->roam.configParam.bCatRssiOffset;
16317 req_buf->Select5GHzMargin = mac_ctx->roam.configParam.nSelect5GHzMargin;
16318 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
16319 (uint32_t *) &req_buf->ReassocFailureTimeout)
16320 != eSIR_SUCCESS) {
16321 sms_log(mac_ctx, LOGE,
16322 FL("could not retrieve ReassocFailureTimeout value"));
16323 req_buf->ReassocFailureTimeout =
16324 DEFAULT_REASSOC_FAILURE_TIMEOUT;
16325 }
16326#ifdef FEATURE_WLAN_ESE
16327 if (csr_is_auth_type_ese(req_buf->ConnectedNetwork.authentication)) {
16328 cdf_mem_copy(req_buf->KRK, session->eseCckmInfo.krk,
16329 SIR_KRK_KEY_LEN);
16330 cdf_mem_copy(req_buf->BTK, session->eseCckmInfo.btk,
16331 SIR_BTK_KEY_LEN);
16332 }
16333#endif
16334 req_buf->AcUapsd.acbe_uapsd =
16335 SIR_UAPSD_GET(ACBE, mac_ctx->lim.gUapsdPerAcBitmask);
16336 req_buf->AcUapsd.acbk_uapsd =
16337 SIR_UAPSD_GET(ACBK, mac_ctx->lim.gUapsdPerAcBitmask);
16338 req_buf->AcUapsd.acvi_uapsd =
16339 SIR_UAPSD_GET(ACVI, mac_ctx->lim.gUapsdPerAcBitmask);
16340 req_buf->AcUapsd.acvo_uapsd =
16341 SIR_UAPSD_GET(ACVO, mac_ctx->lim.gUapsdPerAcBitmask);
16342}
16343#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
16344
16345/**
16346 * csr_check_band_channel_match() - check if passed band and channel match
16347 * paramters
16348 * @band: band to match with channel
16349 * @channel: channel to match with band
16350 *
16351 * Return: bool if match else false
16352 */
16353static bool
16354csr_check_band_channel_match(eCsrBand band, uint8_t channel)
16355{
16356 if (eCSR_BAND_ALL == band)
16357 return true;
16358
16359 if (eCSR_BAND_24 == band && CDS_IS_CHANNEL_24GHZ(channel))
16360 return true;
16361
16362 if (eCSR_BAND_5G == band && CDS_IS_CHANNEL_5GHZ(channel))
16363 return true;
16364
16365 return false;
16366}
16367
16368/**
16369 * csr_fetch_ch_lst_from_ini() - fetch channel list from ini and update req msg
16370 * paramters
16371 * @mac_ctx: global mac ctx
16372 * @roam_info: roam info struct
16373 * @req_buf: out param, roam offload scan request packet
16374 *
16375 * Return: result of operation
16376 */
16377static CDF_STATUS
16378csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx,
16379 tpCsrNeighborRoamControlInfo roam_info,
16380 tSirRoamOffloadScanReq *req_buf)
16381{
16382 eCsrBand band;
16383 uint8_t i = 0;
16384 uint8_t num_channels = 0;
16385 uint8_t *ch_lst = roam_info->cfgParams.channelInfo.ChannelList;
16386 /*
16387 * The INI channels need to be filtered with respect to the current band
16388 * that is supported.
16389 */
16390 band = mac_ctx->roam.configParam.bandCapability;
16391 if ((eCSR_BAND_24 != band) && (eCSR_BAND_5G != band)
16392 && (eCSR_BAND_ALL != band)) {
16393 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16394 FL("Invalid band(%d), roam scan offload req aborted"),
16395 band);
16396 return CDF_STATUS_E_FAILURE;
16397 }
16398
16399 for (i = 0; i < roam_info->cfgParams.channelInfo.numOfChannels; i++) {
16400 if (!csr_check_band_channel_match(band, *ch_lst))
16401 continue;
16402 /* Allow DFS channels only if the DFS roaming is enabled */
16403 if (((mac_ctx->roam.configParam.allowDFSChannelRoam !=
16404 CSR_ROAMING_DFS_CHANNEL_DISABLED)
16405 || (!CDS_IS_DFS_CH(*ch_lst)))
16406 && csr_roam_is_channel_valid(mac_ctx, *ch_lst)
16407 && *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) {
16408 req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
16409 *ch_lst;
16410 }
16411 ch_lst++;
16412 }
16413 req_buf->ConnectedNetwork.ChannelCount = num_channels;
16414 req_buf->ChannelCacheType = CHANNEL_LIST_STATIC;
16415 return CDF_STATUS_SUCCESS;
16416}
16417
16418/**
16419 * csr_fetch_ch_lst_from_occupied_lst() - fetch channel list from occupied list
16420 * and update req msg
16421 * paramters
16422 * @mac_ctx: global mac ctx
16423 * @session_id: session id
16424 * @reason: reason to roam
16425 * @req_buf: out param, roam offload scan request packet
16426 * @roam_info: roam info struct
16427 *
16428 * Return: void
16429 */
16430static void
16431csr_fetch_ch_lst_from_occupied_lst(tpAniSirGlobal mac_ctx,
16432 uint8_t session_id,
16433 uint8_t reason,
16434 tSirRoamOffloadScanReq *req_buf,
16435 tpCsrNeighborRoamControlInfo roam_info)
16436{
16437 uint8_t i = 0;
16438 uint8_t num_channels = 0;
16439 uint8_t *ch_lst =
16440 mac_ctx->scan.occupiedChannels[session_id].channelList;
16441 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16442 "Num of channels before filtering=%d",
16443 mac_ctx->scan.occupiedChannels[session_id].numChannels);
16444 for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels;
16445 i++) {
16446 if (((mac_ctx->roam.configParam.allowDFSChannelRoam !=
16447 CSR_ROAMING_DFS_CHANNEL_DISABLED)
16448 || (!CDS_IS_DFS_CH(*ch_lst)))
16449 && *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) {
16450 req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
16451 *ch_lst;
16452 }
16453 if (*ch_lst)
16454 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16455 "DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d",
16456 mac_ctx->roam.configParam.allowDFSChannelRoam,
16457 cds_get_channel_state(*ch_lst), *ch_lst,
16458 num_channels);
16459 ch_lst++;
16460 }
16461 req_buf->ConnectedNetwork.ChannelCount = num_channels;
16462 /*
16463 * If the profile changes as to what it was earlier, inform the FW
16464 * through FLUSH as ChannelCacheType in which case, the FW will flush
16465 * the occupied channels for the earlier profile and try to learn them
16466 * afresh
16467 */
16468 if (reason == REASON_FLUSH_CHANNEL_LIST)
16469 req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_FLUSH;
16470 else {
16471 if (csr_neighbor_roam_is_new_connected_profile(mac_ctx,
16472 session_id))
16473 req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT;
16474 else
16475 req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
16476 }
16477}
16478
16479#ifdef FEATURE_WLAN_ESE
16480/**
16481 * csr_fetch_ch_lst_from_received_list() - fetch channel list from received list
16482 * and update req msg
16483 * paramters
16484 * @mac_ctx: global mac ctx
16485 * @roam_info: roam info struct
16486 * @curr_ch_lst_info: current channel list info
16487 * @req_buf: out param, roam offload scan request packet
16488 *
16489 * Return: void
16490 */
16491static void
16492csr_fetch_ch_lst_from_received_list(tpAniSirGlobal mac_ctx,
16493 tpCsrNeighborRoamControlInfo roam_info,
16494 tpCsrChannelInfo curr_ch_lst_info,
16495 tSirRoamOffloadScanReq *req_buf)
16496{
16497 uint8_t i = 0;
16498 uint8_t num_channels = 0;
16499 uint8_t *ch_lst = NULL;
16500
16501 if (curr_ch_lst_info->numOfChannels == 0)
16502 return;
16503
16504 ch_lst = curr_ch_lst_info->ChannelList;
16505 for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) {
16506 if (((mac_ctx->roam.configParam.allowDFSChannelRoam
16507 != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
16508 (!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) {
16509 req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
16510 *ch_lst;
16511 }
16512 ch_lst++;
16513 }
16514 req_buf->ConnectedNetwork.ChannelCount = num_channels;
16515 req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
16516}
16517#endif
16518
16519/**
16520 * csr_fetch_valid_ch_lst() - fetch channel list from valid channel list and
16521 * update req msg
16522 * paramters
16523 * @mac_ctx: global mac ctx
16524 * @req_buf: out param, roam offload scan request packet
16525 *
16526 * Return: void
16527 */
16528static CDF_STATUS
16529csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx,
16530 tSirRoamOffloadScanReq *req_buf)
16531{
16532 CDF_STATUS status;
16533 uint32_t host_channels = 0;
16534 uint8_t *ch_lst = NULL;
16535 uint8_t i = 0, num_channels = 0;
16536
16537 host_channels = sizeof(mac_ctx->roam.validChannelList);
16538 status = csr_get_cfg_valid_channels(mac_ctx,
16539 mac_ctx->roam.validChannelList,
16540 &host_channels);
16541 if (!CDF_IS_STATUS_SUCCESS(status)) {
16542 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16543 FL("Failed to get the valid channel list"));
16544 return status;
16545 }
16546 ch_lst = mac_ctx->roam.validChannelList;
16547 mac_ctx->roam.numValidChannels = host_channels;
16548 for (i = 0; i < mac_ctx->roam.numValidChannels; i++) {
16549 if (((mac_ctx->roam.configParam.allowDFSChannelRoam
16550 != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
16551 (!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) {
16552 req_buf->ValidChannelList[num_channels++] = *ch_lst;
16553 }
16554 ch_lst++;
16555 }
16556 req_buf->ValidChannelCount = num_channels;
16557 return status;
16558}
16559
16560/**
16561 * csr_create_roam_scan_offload_request() - init roam offload scan request
16562 *
16563 * paramters
16564 * @mac_ctx: global mac ctx
16565 * @command: roam scan offload command input
16566 * @session_id: session id
16567 * @reason: reason to roam
16568 * @session: roam session
16569 * @roam_info: roam info struct
16570 *
16571 * Return: roam offload scan request packet buffer
16572 */
16573static tSirRoamOffloadScanReq *
16574csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
16575 uint8_t command,
16576 uint8_t session_id,
16577 uint8_t reason,
16578 tCsrRoamSession *session,
16579 tpCsrNeighborRoamControlInfo roam_info)
16580{
16581 CDF_STATUS status;
16582 uint8_t i, j, dot11_mode;
16583 bool ese_neighbor_list_recvd = false;
16584 uint8_t ch_cache_str[128] = { 0 };
16585 tSirRoamOffloadScanReq *req_buf = NULL;
16586 tpCsrChannelInfo curr_ch_lst_info =
16587 &roam_info->roamChannelInfo.currentChannelListInfo;
16588#ifdef FEATURE_WLAN_ESE
16589 /*
16590 * this flag will be true if connection is ESE and no neighbor
16591 * list received or if the connection is not ESE
16592 */
16593 ese_neighbor_list_recvd = ((roam_info->isESEAssoc)
16594 && (roam_info->roamChannelInfo.IAPPNeighborListReceived
16595 == false))
16596 || (roam_info->isESEAssoc == false);
16597#endif /* FEATURE_WLAN_ESE */
16598
16599 req_buf = cdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
16600 if (NULL == req_buf) {
16601 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16602 FL("Mem alloc for roam scan offload req failed."));
16603 return NULL;
16604 }
16605 cdf_mem_zero(req_buf, sizeof(tSirRoamOffloadScanReq));
16606 req_buf->Command = command;
16607 /*
16608 * If command is STOP, then pass down ScanOffloadEnabled as Zero. This
16609 * will handle the case of host driver reloads, but Riva still up and
16610 * running
16611 */
16612 if (command == ROAM_SCAN_OFFLOAD_STOP) {
16613 /*
16614 * clear the roaming parameters that are per connection.
16615 * For a new connection, they have to be programmed again.
16616 */
16617 if (csr_neighbor_middle_of_roaming((tHalHandle)mac_ctx,
16618 session_id))
16619 req_buf->middle_of_roaming = 1;
16620 else
16621 csr_roam_reset_roam_params(mac_ctx);
16622 req_buf->RoamScanOffloadEnabled = 0;
16623 } else {
16624 req_buf->RoamScanOffloadEnabled =
16625 mac_ctx->roam.configParam.isRoamOffloadScanEnabled;
16626 }
16627 cdf_mem_copy(req_buf->ConnectedNetwork.currAPbssid,
16628 roam_info->currAPbssid.bytes, sizeof(struct cdf_mac_addr));
16629 req_buf->ConnectedNetwork.ssId.length =
16630 mac_ctx->roam.roamSession[session_id].
16631 connectedProfile.SSID.length;
16632 cdf_mem_copy(req_buf->ConnectedNetwork.ssId.ssId,
16633 mac_ctx->roam.roamSession[session_id].
16634 connectedProfile.SSID.ssId,
16635 req_buf->ConnectedNetwork.ssId.length);
16636 req_buf->ConnectedNetwork.authentication =
16637 mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType;
16638 req_buf->ConnectedNetwork.encryption =
16639 mac_ctx->roam.roamSession[session_id].
16640 connectedProfile.EncryptionType;
16641 req_buf->ConnectedNetwork.mcencryption =
16642 mac_ctx->roam.roamSession[session_id].
16643 connectedProfile.mcEncryptionType;
16644#ifdef WLAN_FEATURE_11W
16645 req_buf->ConnectedNetwork.mfp_enabled =
16646 mac_ctx->roam.roamSession[session_id].connectedProfile.MFPEnabled;
16647#endif
16648 req_buf->delay_before_vdev_stop =
16649 roam_info->cfgParams.delay_before_vdev_stop;
16650 req_buf->OpportunisticScanThresholdDiff =
16651 roam_info->cfgParams.nOpportunisticThresholdDiff;
16652 req_buf->RoamRescanRssiDiff =
16653 roam_info->cfgParams.nRoamRescanRssiDiff;
16654 req_buf->RoamRssiDiff = mac_ctx->roam.configParam.RoamRssiDiff;
16655 req_buf->reason = reason;
16656 req_buf->NeighborScanTimerPeriod =
16657 roam_info->cfgParams.neighborScanPeriod;
16658 req_buf->NeighborRoamScanRefreshPeriod =
16659 roam_info->cfgParams.neighborResultsRefreshPeriod;
16660 req_buf->NeighborScanChannelMinTime =
16661 roam_info->cfgParams.minChannelScanTime;
16662 req_buf->NeighborScanChannelMaxTime =
16663 roam_info->cfgParams.maxChannelScanTime;
16664 req_buf->EmptyRefreshScanPeriod =
16665 roam_info->cfgParams.emptyScanRefreshPeriod;
16666 req_buf->RoamBmissFirstBcnt =
16667 roam_info->cfgParams.nRoamBmissFirstBcnt;
16668 req_buf->RoamBmissFinalBcnt =
16669 roam_info->cfgParams.nRoamBmissFinalBcnt;
16670 req_buf->RoamBeaconRssiWeight =
16671 roam_info->cfgParams.nRoamBeaconRssiWeight;
16672 /* MAWC feature */
16673 req_buf->MAWCEnabled = mac_ctx->roam.configParam.MAWCEnabled;
16674#ifdef FEATURE_WLAN_ESE
16675 req_buf->IsESEAssoc =
16676 csr_neighbor_roam_is_ese_assoc(mac_ctx, session_id) &&
16677 ((req_buf->ConnectedNetwork.authentication ==
16678 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
16679 (csr_is_auth_type_ese(req_buf->
16680 ConnectedNetwork.authentication)));
16681 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16682 FL("LFR3:IsEseAssoc=%d\n"), req_buf->IsESEAssoc);
16683#endif
16684 if (ese_neighbor_list_recvd || curr_ch_lst_info->numOfChannels == 0) {
16685 /*
16686 * Retrieve the Channel Cache either from ini or from the
16687 * occupied channels list. Give Preference to INI Channels
16688 */
16689 if (roam_info->cfgParams.channelInfo.numOfChannels) {
16690 status = csr_fetch_ch_lst_from_ini(mac_ctx, roam_info,
16691 req_buf);
16692 if (!CDF_IS_STATUS_SUCCESS(status)) {
16693 cdf_mem_free(req_buf);
16694 return NULL;
16695 }
16696 } else {
16697 csr_fetch_ch_lst_from_occupied_lst(mac_ctx, session_id,
16698 reason, req_buf, roam_info);
16699 }
16700 }
16701#ifdef FEATURE_WLAN_ESE
16702 else {
16703 /*
16704 * If ESE is enabled, and a neighbor Report is received,then
16705 * Ignore the INI Channels or the Occupied Channel List.
16706 * Consider the channels in the neighbor list sent by the ESE AP
16707 */
16708 csr_fetch_ch_lst_from_received_list(mac_ctx, roam_info,
16709 curr_ch_lst_info, req_buf);
16710 }
16711#endif
16712 for (i = 0, j = 0; i < req_buf->ConnectedNetwork.ChannelCount; i++) {
16713 if (j < sizeof(ch_cache_str)) {
16714 j += snprintf(ch_cache_str + j,
16715 sizeof(ch_cache_str) - j, " %d",
16716 req_buf->ConnectedNetwork.
16717 ChannelCache[i]);
16718 } else
16719 break;
16720 }
16721 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16722 FL("ChnlCacheType:%d, No of Chnls:%d,Channels: %s"),
16723 req_buf->ChannelCacheType,
16724 req_buf->ConnectedNetwork.ChannelCount, ch_cache_str);
16725
16726 /* Maintain the Valid Channels List */
16727 status = csr_fetch_valid_ch_lst(mac_ctx, req_buf);
16728 if (!CDF_IS_STATUS_SUCCESS(status)) {
16729 cdf_mem_free(req_buf);
16730 return NULL;
16731 }
16732
16733 req_buf->MDID.mdiePresent =
16734 mac_ctx->roam.roamSession[session_id].
16735 connectedProfile.MDID.mdiePresent;
16736 req_buf->MDID.mobilityDomain =
16737 mac_ctx->roam.roamSession[session_id].
16738 connectedProfile.MDID.mobilityDomain;
16739 req_buf->sessionId = session_id;
16740 req_buf->nProbes = mac_ctx->roam.configParam.nProbes;
16741 req_buf->HomeAwayTime = mac_ctx->roam.configParam.nRoamScanHomeAwayTime;
16742
16743 /*
16744 * Home Away Time should be at least equal to (MaxDwell time + (2*RFS)),
16745 * where RFS is the RF Switching time. It is twice RFS to consider the
16746 * time to go off channel and return to the home channel.
16747 */
16748 if (req_buf->HomeAwayTime < (req_buf->NeighborScanChannelMaxTime +
16749 (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))) {
16750 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_WARN,
16751 FL("Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d). Hence enforcing home away time to disable (0)"),
16752 req_buf->HomeAwayTime,
16753 (req_buf->NeighborScanChannelMaxTime +
16754 (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
16755 req_buf->HomeAwayTime = 0;
16756 }
16757 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16758 FL("HomeAwayTime:%d"), req_buf->HomeAwayTime);
16759
16760 /*Prepare a probe request for 2.4GHz band and one for 5GHz band */
16761 dot11_mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
16762 csr_find_best_phy_mode(mac_ctx,
16763 mac_ctx->roam.configParam.phyMode));
16764 csr_roam_scan_offload_prepare_probe_req_template(mac_ctx,
16765 SIR_ROAM_SCAN_24G_DEFAULT_CH, dot11_mode,
16766 session->selfMacAddr.bytes, req_buf->p24GProbeTemplate,
16767 &req_buf->us24GProbeTemplateLen, session);
16768
16769 csr_roam_scan_offload_prepare_probe_req_template(mac_ctx,
16770 SIR_ROAM_SCAN_5G_DEFAULT_CH, dot11_mode,
16771 session->selfMacAddr.bytes,
16772 req_buf->p5GProbeTemplate, &req_buf->us5GProbeTemplateLen,
16773 session);
16774 req_buf->allowDFSChannelRoam =
16775 mac_ctx->roam.configParam.allowDFSChannelRoam;
16776#ifdef WLAN_FEATURE_ROAM_OFFLOAD
16777 req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
16778 req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;
16779 /* Roam Offload piggybacks upon the Roam Scan offload command. */
16780 if (req_buf->RoamOffloadEnabled)
16781 csr_update_roam_scan_offload_request(mac_ctx, req_buf, session);
16782 cdf_mem_copy(&req_buf->roam_params,
16783 &mac_ctx->roam.configParam.roam_params,
16784 sizeof(req_buf->roam_params));
16785#endif
16786 return req_buf;
16787}
16788/**
16789 * check_allowed_ssid_list() - Check the WhiteList
16790 * @req_buffer: Buffer which contains the connected profile SSID.
16791 * @roam_params: Buffer which contains the whitelist SSID's.
16792 *
16793 * Check if the connected profile SSID exists in the whitelist.
16794 * It is assumed that the framework provides this also in the whitelist.
16795 * If it exists there is no issue. Otherwise add it to the list.
16796 *
16797 * Return: None
16798 */
16799static void check_allowed_ssid_list(tSirRoamOffloadScanReq *req_buffer,
16800 struct roam_ext_params *roam_params)
16801{
16802 int i = 0;
16803 bool match = false;
16804 for (i = 0; i < roam_params->num_ssid_allowed_list; i++) {
16805 if ((roam_params->ssid_allowed_list[i].length ==
16806 req_buffer->ConnectedNetwork.ssId.length) &&
16807 cdf_mem_compare(roam_params->ssid_allowed_list[i].ssId,
16808 req_buffer->ConnectedNetwork.ssId.ssId,
16809 roam_params->ssid_allowed_list[i].length)) {
16810 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16811 "Whitelist contains connected profile SSID");
16812 match = true;
16813 break;
16814 }
16815 }
16816 if (!match) {
16817 if (roam_params->num_ssid_allowed_list >=
16818 MAX_SSID_ALLOWED_LIST) {
16819 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16820 "Whitelist is FULL. Cannot Add another entry");
16821 return;
16822 }
16823 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16824 "Adding Connected profile SSID to whitelist");
16825 /* i is the next available index to add the entry.*/
16826 i = roam_params->num_ssid_allowed_list;
16827 cdf_mem_copy(roam_params->ssid_allowed_list[i].ssId,
16828 req_buffer->ConnectedNetwork.ssId.ssId,
16829 req_buffer->ConnectedNetwork.ssId.length);
16830 roam_params->ssid_allowed_list[i].length =
16831 req_buffer->ConnectedNetwork.ssId.length;
16832 roam_params->num_ssid_allowed_list++;
16833 }
16834}
16835
16836/*
16837 * Below Table describe whether RSO command can be send down to fimrware or not.
16838 * Host check it on the basis of previous RSO command sent down to firmware.
16839 *||==========================================================================||
16840 *|| New cmd | LAST SENT COMMAND ---> ||
16841 *||====|=====================================================================||
16842 *|| V | RSO_START | RSO_STOP | RSO_RESTART | RSO_UPDATE_CFG||
16843 *|| -------------------------------------------------------------------------||
16844 *|| RSO_START | NO | YES | NO | NO ||
16845 *|| RSO_STOP | YES | YES | YES | YES ||
16846 *|| RSO_RESTART | YES | NO | NO | YES ||
16847 *|| RSO_UPDATE_CFG | YES | NO | YES | YES ||
16848 *||==========================================================================||
16849 **/
16850#define RSO_START_BIT (1<<ROAM_SCAN_OFFLOAD_START)
16851#define RSO_STOP_BIT (1<<ROAM_SCAN_OFFLOAD_STOP)
16852#define RSO_RESTART_BIT (1<<ROAM_SCAN_OFFLOAD_RESTART)
16853#define RSO_UPDATE_CFG_BIT (1<<ROAM_SCAN_OFFLOAD_UPDATE_CFG)
16854#define RSO_START_ALLOW_MASK (RSO_STOP_BIT)
16855#define RSO_STOP_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_RESTART_BIT | \
16856 RSO_STOP_BIT | RSO_START_BIT)
16857#define RSO_RESTART_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_START_BIT)
16858#define RSO_UPDATE_CFG_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_STOP_BIT | \
16859 RSO_START_BIT)
16860
16861bool csr_is_RSO_cmd_allowed(tpAniSirGlobal mac_ctx, uint8_t command,
16862 uint8_t session_id)
16863{
16864 tpCsrNeighborRoamControlInfo neigh_roam_info =
16865 &mac_ctx->roam.neighborRoamInfo[session_id];
16866 uint8_t desiredMask = 0;
16867 bool ret_val;
16868
16869 switch (command) {
16870 case ROAM_SCAN_OFFLOAD_START:
16871 desiredMask = RSO_START_ALLOW_MASK;
16872 break;
16873 case ROAM_SCAN_OFFLOAD_STOP:
16874 desiredMask = RSO_STOP_ALLOW_MASK;
16875 break;
16876 case ROAM_SCAN_OFFLOAD_RESTART:
16877 desiredMask = RSO_RESTART_ALLOW_MASK;
16878 break;
16879 case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
16880 desiredMask = RSO_UPDATE_CFG_ALLOW_MASK;
16881 break;
16882 default:
16883 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16884 FL("Wrong RSO command %d, not allowed"), command);
16885 return 0;/*Cmd Not allowed*/
16886 }
16887 ret_val = desiredMask & (1 << neigh_roam_info->last_sent_cmd);
16888 return ret_val;
16889}
16890
16891/**
16892 * csr_roam_offload_scan() - populates roam offload scan request and sends to
16893 * WMA
16894 *
16895 * paramters
16896 * @mac_ctx: global mac ctx
16897 * @session_id: session id
16898 * @command: roam scan offload command input
16899 * @reason: reason to roam
16900 *
16901 * Return: result of operation
16902 */
16903CDF_STATUS
16904csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
16905 uint8_t command, uint8_t reason)
16906{
16907 uint8_t *state = NULL;
16908 cds_msg_t msg;
16909 tSirRoamOffloadScanReq *req_buf;
16910 CDF_STATUS status = CDF_STATUS_SUCCESS;
16911 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
16912 tpCsrNeighborRoamControlInfo roam_info =
16913 &mac_ctx->roam.neighborRoamInfo[session_id];
16914 struct roam_ext_params *roam_params_dst;
16915 struct roam_ext_params *roam_params_src;
16916 uint8_t i;
16917
16918 if (NULL == session) {
16919 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16920 FL("session is null"));
16921 return CDF_STATUS_E_FAILURE;
16922 }
16923#ifdef WLAN_FEATURE_ROAM_OFFLOAD
16924 if (session->roamOffloadSynchParams.bRoamSynchInProgress
16925 && (ROAM_SCAN_OFFLOAD_STOP == command)) {
16926 /*
16927 * When roam synch is in progress for propagation, there is no
16928 * need to send down the STOP command since the firmware is not
16929 * expecting any WMI commands when the roam synch is in progress
16930 */
16931 b_roam_scan_offload_started = false;
16932 return CDF_STATUS_SUCCESS;
16933 }
16934#endif
16935 if (0 == csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
16936 sms_log(mac_ctx, LOGE, "isRoamOffloadScanEnabled not set");
16937 return CDF_STATUS_E_FAILURE;
16938 }
16939 if (!csr_is_RSO_cmd_allowed(mac_ctx, command, session_id) &&
16940 reason != REASON_ROAM_SET_BLACKLIST_BSSID) {
16941 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16942 FL("RSO out-of-sync command %d lastSentCmd %d"),
16943 command, roam_info->last_sent_cmd);
16944 return CDF_STATUS_E_FAILURE;
16945 }
16946
16947 if ((true == b_roam_scan_offload_started)
16948 && (ROAM_SCAN_OFFLOAD_START == command)) {
16949 sms_log(mac_ctx, LOGE, "Roam Scan Offload is already started");
16950 return CDF_STATUS_E_FAILURE;
16951 }
16952 /*
16953 * The Dynamic Config Items Update may happen even if the state is in
16954 * INIT. It is important to ensure that the command is passed down to
16955 * the FW only if the Infra Station is in a connected state.A connected
16956 * station could also be in a PREAUTH or REASSOC states.So, consider not
16957 * sending the command down in INIT state. We also have to ensure that
16958 * if there is a STOP command we always have to inform Riva,
16959 * irrespective of whichever state we are in
16960 */
16961
16962 if ((roam_info->neighborRoamState ==
16963 eCSR_NEIGHBOR_ROAM_STATE_INIT) &&
16964 (command != ROAM_SCAN_OFFLOAD_STOP) &&
16965 (reason != REASON_ROAM_SET_BLACKLIST_BSSID)) {
16966 state = mac_trace_get_neighbour_roam_state(
16967 roam_info->neighborRoamState);
16968 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
16969 FL("Scan Command not sent to FW state=%s and cmd=%d"),
16970 state, command);
16971 return CDF_STATUS_E_FAILURE;
16972 }
16973
16974 req_buf = csr_create_roam_scan_offload_request(mac_ctx, command,
16975 session_id, reason,
16976 session, roam_info);
16977 if (!req_buf) {
16978 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
16979 FL("Failed to create req packet"));
16980 return CDF_STATUS_E_FAILURE;
16981 }
16982 roam_params_dst = &req_buf->roam_params;
16983 roam_params_src = &mac_ctx->roam.configParam.roam_params;
16984 if (reason == REASON_ROAM_SET_SSID_ALLOWED)
16985 check_allowed_ssid_list(req_buf, roam_params_src);
16986 /*
16987 * Configure the lookup threshold either from INI or from framework.
16988 * If both are present, give higher priority to the one from framework.
16989 */
16990 if (roam_params_src->alert_rssi_threshold)
16991 req_buf->LookupThreshold =
16992 roam_params_src->alert_rssi_threshold;
16993 else
16994 req_buf->LookupThreshold =
16995 (int8_t)roam_info->cfgParams.neighborLookupThreshold *
16996 (-1);
16997 cdf_mem_copy(roam_params_dst, roam_params_src,
16998 sizeof(struct roam_ext_params));
16999 /*
17000 * rssi_diff which is updated via framework is equivalent to the
17001 * INI RoamRssiDiff parameter and hence should be updated.
17002 */
17003 if (roam_params_src->rssi_diff)
17004 req_buf->RoamRssiDiff = roam_params_src->rssi_diff;
17005 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17006 "num_bssid_avoid_list: %d, num_ssid_allowed_list: %d, "
17007 "num_bssid_favored: %d, raise_rssi_thresh_5g: %d, "
17008 "drop_rssi_thresh_5g: %d, raise_rssi_type_5g: %d, "
17009 "raise_factor_5g: %d, drop_rssi_type_5g: %d, "
17010 "drop_factor_5g: %d, max_raise_rssi_5g: %d, "
17011 "max_drop_rssi_5g: %d, rssi_diff: %d, alert_rssi_threshold:%d",
17012 roam_params_dst->num_bssid_avoid_list,
17013 roam_params_dst->num_ssid_allowed_list,
17014 roam_params_dst->num_bssid_favored,
17015 roam_params_dst->raise_rssi_thresh_5g,
17016 roam_params_dst->drop_rssi_thresh_5g,
17017 roam_params_dst->raise_rssi_type_5g,
17018 roam_params_dst->raise_factor_5g,
17019 roam_params_dst->drop_rssi_type_5g,
17020 roam_params_dst->drop_factor_5g,
17021 roam_params_dst->max_raise_rssi_5g,
17022 roam_params_dst->max_drop_rssi_5g,
17023 req_buf->RoamRssiDiff, roam_params_dst->alert_rssi_threshold);
17024
17025 for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
17026 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17027 "Blacklist Bssid: ("MAC_ADDRESS_STR")",
17028 MAC_ADDR_ARRAY(roam_params_dst->bssid_avoid_list[i]));
17029 }
17030 for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
17031 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17032 "Whitelist: %.*s",
17033 roam_params_dst->ssid_allowed_list[i].length,
17034 roam_params_dst->ssid_allowed_list[i].ssId);
17035 }
17036 for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
17037 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17038 "Preferred Bssid: ("MAC_ADDRESS_STR") score: %d",
17039 MAC_ADDR_ARRAY(roam_params_dst->bssid_favored[i]),
17040 roam_params_dst->bssid_favored_factor[i]);
17041 }
17042
17043 req_buf->hi_rssi_scan_max_count =
17044 roam_info->cfgParams.hi_rssi_scan_max_count;
17045 req_buf->hi_rssi_scan_rssi_delta =
17046 roam_info->cfgParams.hi_rssi_scan_rssi_delta;
17047 req_buf->hi_rssi_scan_delay =
17048 roam_info->cfgParams.hi_rssi_scan_delay;
17049 req_buf->hi_rssi_scan_rssi_ub =
17050 roam_info->cfgParams.hi_rssi_scan_rssi_ub;
17051
17052 msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
17053 msg.reserved = 0;
17054 msg.bodyptr = req_buf;
17055 if (!CDF_IS_STATUS_SUCCESS
17056 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
17057 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
17058 "%s: Not able to post message to WMA",
17059 __func__);
17060 cdf_mem_free(req_buf);
17061 return CDF_STATUS_E_FAILURE;
17062 } else {
17063 if (ROAM_SCAN_OFFLOAD_START == command)
17064 b_roam_scan_offload_started = true;
17065 else if (ROAM_SCAN_OFFLOAD_STOP == command)
17066 b_roam_scan_offload_started = false;
17067 }
17068 /* update the last sent cmd */
17069 roam_info->last_sent_cmd = command;
17070
17071 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17072 "Roam Scan Offload Command %d, Reason %d", command, reason);
17073 return status;
17074}
17075
17076CDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
17077 tpSirRoamOffloadScanRsp scanOffloadRsp)
17078{
17079 switch (scanOffloadRsp->reason) {
17080 case 0:
17081 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
17082 "Rsp for Roam Scan Offload with failure status");
17083 break;
17084 case REASON_OS_REQUESTED_ROAMING_NOW:
17085 csr_neighbor_roam_proceed_with_handoff_req(pMac,
17086 scanOffloadRsp->sessionId);
17087 break;
17088
17089 default:
17090 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
17091 "Rsp for Roam Scan Offload with reason %d",
17092 scanOffloadRsp->reason);
17093 }
17094 return CDF_STATUS_SUCCESS;
17095}
17096
17097tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
17098 uint32_t statsMask,
17099 uint32_t periodicity,
17100 bool *pFound,
17101 uint8_t staId, uint8_t sessionId)
17102{
17103 bool found = false;
17104 CDF_STATUS status = CDF_STATUS_SUCCESS;
17105 tCsrPeStatsReqInfo staEntry;
17106 tCsrPeStatsReqInfo *pTempStaEntry = NULL;
17107 tListElem *pStaEntry = NULL;
17108 CDF_STATUS cdf_status;
17109 *pFound = false;
17110
17111 pStaEntry = csr_roam_find_in_pe_stats_req_list(pMac, statsMask);
17112 if (pStaEntry) {
17113 pTempStaEntry =
17114 GET_BASE_ADDR(pStaEntry, tCsrPeStatsReqInfo, link);
17115 if (pTempStaEntry->periodicity) {
17116 pTempStaEntry->periodicity =
17117 CDF_MIN(periodicity,
17118 pTempStaEntry->periodicity);
17119 } else {
17120 pTempStaEntry->periodicity = periodicity;
17121 }
17122 pTempStaEntry->numClient++;
17123 found = true;
17124 } else {
17125 cdf_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0);
17126 staEntry.numClient = 1;
17127 staEntry.periodicity = periodicity;
17128 staEntry.pMac = pMac;
17129 staEntry.rspPending = false;
17130 staEntry.staId = staId;
17131 staEntry.statsMask = statsMask;
17132 staEntry.timerRunning = false;
17133 staEntry.sessionId = sessionId;
17134 pTempStaEntry =
17135 csr_roam_insert_entry_into_pe_stats_req_list(pMac,
17136 &pMac->roam.
17137 peStatsReqList,
17138 &staEntry);
17139 if (!pTempStaEntry) {
17140 /* msg */
17141 sms_log(pMac, LOGW,
17142 "csr_roam_check_pe_stats_req_list: Failed to insert req in peStatsReqList");
17143 return NULL;
17144 }
17145 }
17146 pTempStaEntry->periodicity =
17147 pMac->roam.configParam.statsReqPeriodicityInPS;
17148
17149 if (!pTempStaEntry->timerRunning) {
17150 /* send down a req in case of one time req, for periodic ones wait for timer to expire */
17151 if (!pTempStaEntry->rspPending && !pTempStaEntry->periodicity) {
17152 status = csr_send_mb_stats_req_msg(pMac,
17153 statsMask & ~(1 <<
17154 eCsrGlobalClassDStats),
17155 staId, sessionId);
17156 if (!CDF_IS_STATUS_SUCCESS(status)) {
17157 sms_log(pMac, LOGE,
17158 FL
17159 ("csr_roam_check_pe_stats_req_list:failed to send down stats req to PE"));
17160 } else {
17161 pTempStaEntry->rspPending = true;
17162 }
17163 }
17164 if (pTempStaEntry->periodicity) {
17165 if (!found) {
17166
17167 cdf_status =
17168 cdf_mc_timer_init(&pTempStaEntry->
17169 hPeStatsTimer,
17170 CDF_TIMER_TYPE_SW,
17171 csr_roam_pe_stats_timer_handler,
17172 pTempStaEntry);
17173 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
17174 sms_log(pMac, LOGE,
17175 FL
17176 ("csr_roam_check_pe_stats_req_list:cannot init hPeStatsTimer timer"));
17177 return NULL;
17178 }
17179 }
17180 /* start timer */
17181 sms_log(pMac, LOG1,
17182 "csr_roam_check_pe_stats_req_list:peStatsTimer period %d",
17183 pTempStaEntry->periodicity);
17184 cdf_status =
17185 cdf_mc_timer_start(&pTempStaEntry->hPeStatsTimer,
17186 pTempStaEntry->periodicity);
17187 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
17188 sms_log(pMac, LOGE,
17189 FL
17190 ("csr_roam_check_pe_stats_req_list:cannot start hPeStatsTimer timer"));
17191 return NULL;
17192 }
17193 pTempStaEntry->timerRunning = true;
17194 }
17195 }
17196 *pFound = found;
17197 return pTempStaEntry;
17198}
17199
17200/*
17201 pStaEntry is no longer invalid upon the return of this function.
17202 */
17203static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac, tListElem *pEntry)
17204{
17205 if (pEntry) {
17206 if (csr_ll_remove_entry
17207 (&pMac->roam.statsClientReqList, pEntry, LL_ACCESS_LOCK)) {
17208 cdf_mem_free(GET_BASE_ADDR
17209 (pEntry, tCsrStatsClientReqInfo, link));
17210 }
17211 }
17212}
17213
17214void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
17215 tCsrPeStatsReqInfo *pPeStaEntry)
17216{
17217 tListElem *pEntry;
17218 tCsrPeStatsReqInfo *pTempStaEntry;
17219 CDF_STATUS cdf_status;
17220 pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
17221 if (!pEntry) {
17222 sms_log(pMac, LOGE, FL(" List empty, no stats req for PE"));
17223 return;
17224 }
17225 while (pEntry) {
17226 pTempStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
17227 if (NULL == pTempStaEntry
17228 || (pTempStaEntry->statsMask !=
17229 pPeStaEntry->statsMask)) {
17230 pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
17231 LL_ACCESS_NOLOCK);
17232 continue;
17233 }
17234 sms_log(pMac, LOGW, FL("Match found"));
17235 if (pTempStaEntry->timerRunning) {
17236 cdf_status = cdf_mc_timer_stop(
17237 &pTempStaEntry->hPeStatsTimer);
17238 /*
17239 * If we are not able to stop the timer here, just
17240 * remove the entry from the linked list. Destroy the
17241 * timer object and free the memory in the timer CB
17242 */
17243 if (cdf_status == CDF_STATUS_SUCCESS) {
17244 /* the timer is successfully stopped */
17245 pTempStaEntry->timerRunning = false;
17246 /* Destroy the timer */
17247 cdf_status = cdf_mc_timer_destroy(
17248 &pTempStaEntry->hPeStatsTimer);
17249 } else {
17250 /*
17251 * the timer could not be stopped. Hence destroy
17252 * and free the memory for the PE stat entry in
17253 * the timer CB.
17254 */
17255 pTempStaEntry->timerStopFailed = true;
17256 }
17257 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
17258 sms_log(pMac, LOGE,
17259 FL("failed to stop/destroy timer"));
17260 }
17261 }
17262
17263 if (csr_ll_remove_entry(&pMac->roam.peStatsReqList, pEntry,
17264 LL_ACCESS_LOCK)) {
17265 /*
17266 * Only free the memory if we could stop the timer
17267 * successfully
17268 */
17269 if (!pTempStaEntry->timerStopFailed) {
17270 cdf_mem_free(pTempStaEntry);
17271 pTempStaEntry = NULL;
17272 }
17273 break;
17274 }
17275 pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
17276 LL_ACCESS_NOLOCK);
17277 } /* end of while loop */
17278 return;
17279}
17280
17281void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
17282 tCsrStatsCallback callback, uint8_t staId,
17283 void *pContext)
17284{
17285 uint8_t stats[500];
17286 uint8_t *pStats = NULL;
17287 uint32_t tempMask = 0;
17288 uint8_t counter = 0;
17289 if (!callback) {
17290 sms_log(pMac, LOGE, FL("Cannot report callback NULL"));
17291 return;
17292 }
17293 if (!statsMask) {
17294 sms_log(pMac, LOGE, FL("Cannot report statsMask is 0"));
17295 return;
17296 }
17297 pStats = stats;
17298 tempMask = statsMask;
17299 while (tempMask) {
17300 if (tempMask & 1) {
17301 /* new stats info from PE, fill up the stats strucutres in PMAC */
17302 switch (counter) {
17303 case eCsrSummaryStats:
17304 sms_log(pMac, LOG2, FL("Summary stats"));
17305 cdf_mem_copy(pStats,
17306 (uint8_t *) &pMac->roam.
17307 summaryStatsInfo,
17308 sizeof(tCsrSummaryStatsInfo));
17309 pStats += sizeof(tCsrSummaryStatsInfo);
17310 break;
17311 case eCsrGlobalClassAStats:
17312 sms_log(pMac, LOG2, FL("ClassA stats"));
17313 cdf_mem_copy(pStats,
17314 (uint8_t *) &pMac->roam.
17315 classAStatsInfo,
17316 sizeof(tCsrGlobalClassAStatsInfo));
17317 pStats += sizeof(tCsrGlobalClassAStatsInfo);
17318 break;
17319 case eCsrGlobalClassBStats:
17320 sms_log(pMac, LOG2, FL("ClassB stats"));
17321 cdf_mem_copy(pStats,
17322 (uint8_t *) &pMac->roam.
17323 classBStatsInfo,
17324 sizeof(tCsrGlobalClassBStatsInfo));
17325 pStats += sizeof(tCsrGlobalClassBStatsInfo);
17326 break;
17327 case eCsrGlobalClassCStats:
17328 sms_log(pMac, LOG2, FL("ClassC stats"));
17329 cdf_mem_copy(pStats,
17330 (uint8_t *) &pMac->roam.
17331 classCStatsInfo,
17332 sizeof(tCsrGlobalClassCStatsInfo));
17333 pStats += sizeof(tCsrGlobalClassCStatsInfo);
17334 break;
17335 case eCsrGlobalClassDStats:
17336 sms_log(pMac, LOG2, FL("ClassD stats"));
17337 cdf_mem_copy(pStats,
17338 (uint8_t *) &pMac->roam.
17339 classDStatsInfo,
17340 sizeof(tCsrGlobalClassDStatsInfo));
17341 pStats += sizeof(tCsrGlobalClassDStatsInfo);
17342 break;
17343 case eCsrPerStaStats:
17344 sms_log(pMac, LOG2, FL("PerSta stats"));
17345 cdf_mem_copy(pStats,
17346 (uint8_t *) &pMac->roam.
17347 perStaStatsInfo[staId],
17348 sizeof(tCsrPerStaStatsInfo));
17349 pStats += sizeof(tCsrPerStaStatsInfo);
17350 break;
17351 default:
17352 sms_log(pMac, LOGE,
17353 FL("Unknown stats type and counter %d"),
17354 counter);
17355 break;
17356 }
17357 }
17358 tempMask >>= 1;
17359 counter++;
17360 }
17361 callback(stats, pContext);
17362}
17363
17364CDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac)
17365{
17366 tListElem *pEntry = NULL;
17367 tListElem *pPrevEntry = NULL;
17368 tCsrStatsClientReqInfo *pTempStaEntry = NULL;
17369 CDF_STATUS status = CDF_STATUS_SUCCESS;
17370 CDF_STATUS cdf_status;
17371 pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
17372 if (!pEntry) {
17373 /* list empty */
17374 sms_log(pMac, LOGW,
17375 "csr_roam_dereg_statistics_req: List empty, no request from "
17376 "upper layer client(s)");
17377 return status;
17378 }
17379 while (pEntry) {
17380 if (pPrevEntry) {
17381 pTempStaEntry =
17382 GET_BASE_ADDR(pPrevEntry, tCsrStatsClientReqInfo,
17383 link);
17384 /* send up the stats report */
17385 csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
17386 pTempStaEntry->callback,
17387 pTempStaEntry->staId,
17388 pTempStaEntry->pContext);
17389 csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
17390 }
17391 pTempStaEntry =
17392 GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
17393 if (pTempStaEntry->pPeStaEntry) {
17394 /* pPeStaEntry can be NULL */
17395 pTempStaEntry->pPeStaEntry->numClient--;
17396 /* check if we need to delete the entry from peStatsReqList too */
17397 if (!pTempStaEntry->pPeStaEntry->numClient) {
17398 csr_roam_remove_entry_from_pe_stats_req_list(pMac,
17399 pTempStaEntry->
17400 pPeStaEntry);
17401 }
17402 }
17403 /* check if we need to stop the tl stats timer too */
17404 pMac->roam.tlStatsReqInfo.numClient--;
17405 if (!pMac->roam.tlStatsReqInfo.numClient) {
17406 if (pMac->roam.tlStatsReqInfo.timerRunning) {
17407 status =
17408 cdf_mc_timer_stop(&pMac->roam.
17409 tlStatsReqInfo.
17410 hTlStatsTimer);
17411 if (!CDF_IS_STATUS_SUCCESS(status)) {
17412 sms_log(pMac, LOGE,
17413 FL
17414 ("csr_roam_dereg_statistics_req:cannot stop TlStatsTimer timer"));
17415 /* we will continue */
17416 }
17417 }
17418 pMac->roam.tlStatsReqInfo.periodicity = 0;
17419 pMac->roam.tlStatsReqInfo.timerRunning = false;
17420 }
17421 if (pTempStaEntry->periodicity) {
17422 /* While creating StaEntry in csr_get_statistics, */
17423 /* Initializing and starting timer only when periodicity is set. */
17424 /* So Stop and Destroy timer only when periodicity is set. */
17425
17426 cdf_mc_timer_stop(&pTempStaEntry->timer);
17427 /* Destroy the cdf timer... */
17428 cdf_status =
17429 cdf_mc_timer_destroy(&pTempStaEntry->timer);
17430 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
17431 sms_log(pMac, LOGE,
17432 FL
17433 ("csr_roam_dereg_statistics_req:failed to destroy Client req timer"));
17434 }
17435 }
17436
17437 pPrevEntry = pEntry;
17438 pEntry =
17439 csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
17440 LL_ACCESS_NOLOCK);
17441 }
17442 /* the last one */
17443 if (pPrevEntry) {
17444 pTempStaEntry =
17445 GET_BASE_ADDR(pPrevEntry, tCsrStatsClientReqInfo, link);
17446 /* send up the stats report */
17447 csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
17448 pTempStaEntry->callback,
17449 pTempStaEntry->staId,
17450 pTempStaEntry->pContext);
17451 csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
17452 }
17453 return status;
17454
17455}
17456
17457tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac)
17458{
17459 tSmeCmd *pCmd = sme_get_command_buffer(pMac);
17460 if (pCmd) {
17461 pMac->roam.sPendingCommands++;
17462 }
17463 return pCmd;
17464}
17465
17466void csr_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
17467{
17468 if (pMac->roam.sPendingCommands > 0) {
17469 /* All command allocated through csr_get_command_buffer need to */
17470 /* decrement the pending count when releasing. */
17471 pMac->roam.sPendingCommands--;
17472 sme_release_command(pMac, pCommand);
17473 } else {
17474 sms_log(pMac, LOGE, FL("no pending commands"));
17475 CDF_ASSERT(0);
17476 }
17477}
17478
17479/* Return SUCCESS is the command is queued, failed */
17480CDF_STATUS csr_queue_sme_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
17481 bool fHighPriority)
17482{
17483 bool fNoCmdPending;
17484
17485 if (!SME_IS_START(pMac)) {
17486 sms_log(pMac, LOGE, FL("Sme in stop state"));
17487 CDF_ASSERT(0);
17488 return CDF_STATUS_E_PERM;
17489 }
17490
17491 if ((eSmeCommandScan == pCommand->command) && pMac->scan.fDropScanCmd) {
17492 sms_log(pMac, LOGW, FL(" drop scan (scan reason %d) command"),
17493 pCommand->u.scanCmd.reason);
17494 return CDF_STATUS_CSR_WRONG_STATE;
17495 }
17496
17497 if ((pCommand->command == eSmeCommandScan)
17498 || (pCommand->command == eSmeCommandRemainOnChannel)) {
17499 sms_log(pMac, LOGW,
17500 FL("scan pending list count %d scan_id %d"),
17501 pMac->sme.smeScanCmdPendingList.Count,
17502 pCommand->u.scanCmd.scanID);
17503 csr_ll_insert_tail(&pMac->sme.smeScanCmdPendingList,
17504 &pCommand->Link, LL_ACCESS_LOCK);
17505 /* process the command queue... */
17506 sme_process_pending_queue(pMac);
17507 return CDF_STATUS_SUCCESS;
17508 }
17509 /* Make sure roamCmdPendingList is not empty first */
17510 fNoCmdPending =
17511 csr_ll_is_list_empty(&pMac->roam.roamCmdPendingList, false);
17512 if (fNoCmdPending) {
17513 sme_push_command(pMac, pCommand, fHighPriority);
17514 } else {
17515 /* no list lock is needed since SME lock is held */
17516 if (!fHighPriority) {
17517 csr_ll_insert_tail(&pMac->roam.roamCmdPendingList,
17518 &pCommand->Link, false);
17519 } else {
17520 csr_ll_insert_head(&pMac->roam.roamCmdPendingList,
17521 &pCommand->Link, false);
17522 }
17523 }
17524 return CDF_STATUS_SUCCESS;
17525}
17526
17527CDF_STATUS csr_roam_update_apwpsie(tpAniSirGlobal pMac, uint32_t sessionId,
17528 tSirAPWPSIEs *pAPWPSIES)
17529{
17530 CDF_STATUS status = CDF_STATUS_SUCCESS;
17531 tSirUpdateAPWPSIEsReq *pMsg;
17532
17533 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
17534 if (NULL == pSession) {
17535 sms_log(pMac, LOGE,
17536 FL(" Session does not exist for session id %d"),
17537 sessionId);
17538 return CDF_STATUS_E_FAILURE;
17539 }
17540
17541 do {
17542 pMsg = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
17543 if (NULL == pMsg)
17544 return CDF_STATUS_E_NOMEM;
17545 cdf_mem_set(pMsg, sizeof(tSirUpdateAPWPSIEsReq), 0);
17546 pMsg->messageType = eWNI_SME_UPDATE_APWPSIE_REQ;
17547 pMsg->transactionId = 0;
17548 cdf_mem_copy(pMsg->bssId, &pSession->selfMacAddr,
17549 sizeof(tSirMacAddr));
17550 pMsg->sessionId = sessionId;
17551 cdf_mem_copy(&pMsg->APWPSIEs, pAPWPSIES,
17552 sizeof(tSirAPWPSIEs));
17553 pMsg->length = sizeof(struct sSirUpdateAPWPSIEsReq);
17554 status = cds_send_mb_message_to_mac(pMsg);
17555 } while (0);
17556 return status;
17557}
17558
17559CDF_STATUS csr_roam_update_wparsni_es(tpAniSirGlobal pMac, uint32_t sessionId,
17560 tSirRSNie *pAPSirRSNie)
17561{
17562 CDF_STATUS status = CDF_STATUS_SUCCESS;
17563 tSirUpdateAPWPARSNIEsReq *pMsg;
17564 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
17565 if (NULL == pSession) {
17566 sms_log(pMac, LOGE,
17567 FL(" Session does not exist for session id %d"),
17568 sessionId);
17569 return CDF_STATUS_E_FAILURE;
17570 }
17571 do {
17572 pMsg = cdf_mem_malloc(sizeof(tSirUpdateAPWPARSNIEsReq));
17573 if (NULL == pMsg)
17574 return CDF_STATUS_E_NOMEM;
17575 cdf_mem_set(pMsg, sizeof(tSirUpdateAPWPARSNIEsReq), 0);
17576 pMsg->messageType = eWNI_SME_SET_APWPARSNIEs_REQ;
17577 pMsg->transactionId = 0;
17578 cdf_mem_copy(pMsg->bssId, &pSession->selfMacAddr,
17579 sizeof(tSirMacAddr));
17580 pMsg->sessionId = sessionId;
17581 cdf_mem_copy(&pMsg->APWPARSNIEs, pAPSirRSNie,
17582 sizeof(tSirRSNie));
17583 pMsg->length = sizeof(struct sSirUpdateAPWPARSNIEsReq);
17584 status = cds_send_mb_message_to_mac(pMsg);
17585 } while (0);
17586 return status;
17587}
17588
17589#ifdef WLAN_FEATURE_VOWIFI_11R
17590CDF_STATUS
17591csr_roam_issue_ft_preauth_req(tHalHandle hHal, uint32_t sessionId,
17592 tpSirBssDescription pBssDescription)
17593{
17594 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
17595 tpSirFTPreAuthReq pftPreAuthReq;
17596 uint16_t auth_req_len = 0;
17597 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
17598
17599 if (NULL == pSession) {
17600 sms_log(pMac, LOGE,
17601 FL("Session does not exist for session id(%d)"),
17602 sessionId);
17603 return CDF_STATUS_E_FAILURE;
17604 }
17605
17606 auth_req_len = sizeof(tSirFTPreAuthReq);
17607 pftPreAuthReq = (tpSirFTPreAuthReq) cdf_mem_malloc(auth_req_len);
17608 if (NULL == pftPreAuthReq) {
17609 sms_log(pMac, LOGE,
17610 FL("Memory allocation for FT Preauth request failed"));
17611 return CDF_STATUS_E_NOMEM;
17612 }
17613 /* Save the SME Session ID here. We need it while processing the preauth response */
17614 pSession->ftSmeContext.smeSessionId = sessionId;
17615 cdf_mem_zero(pftPreAuthReq, auth_req_len);
17616
17617 pftPreAuthReq->pbssDescription =
17618 (tpSirBssDescription) cdf_mem_malloc(sizeof(pBssDescription->length)
17619 + pBssDescription->length);
17620 if (NULL == pftPreAuthReq->pbssDescription) {
17621 sms_log(pMac, LOGE,
17622 FL("Memory allocation for FT Preauth request failed"));
17623 return CDF_STATUS_E_NOMEM;
17624 }
17625
17626 pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
17627
17628 pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId;
17629
17630 cdf_mem_copy((void *)&pftPreAuthReq->currbssId,
17631 (void *)pSession->connectedProfile.bssid.bytes,
17632 sizeof(tSirMacAddr));
17633 cdf_mem_copy((void *)&pftPreAuthReq->preAuthbssId,
17634 (void *)pBssDescription->bssId, sizeof(tSirMacAddr));
17635
17636#ifdef WLAN_FEATURE_VOWIFI_11R
17637 if (csr_roam_is11r_assoc(pMac, sessionId) &&
17638 (pMac->roam.roamSession[sessionId].connectedProfile.AuthType !=
17639 eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
17640 pftPreAuthReq->ft_ies_length =
17641 (uint16_t) pSession->ftSmeContext.auth_ft_ies_length;
17642 cdf_mem_copy(pftPreAuthReq->ft_ies,
17643 pSession->ftSmeContext.auth_ft_ies,
17644 pSession->ftSmeContext.auth_ft_ies_length);
17645 } else
17646#endif
17647 {
17648 pftPreAuthReq->ft_ies_length = 0;
17649 }
17650 cdf_mem_copy(pftPreAuthReq->pbssDescription, pBssDescription,
17651 sizeof(pBssDescription->length) + pBssDescription->length);
17652 pftPreAuthReq->length = auth_req_len;
17653 return cds_send_mb_message_to_mac(pftPreAuthReq);
17654}
17655
17656/*--------------------------------------------------------------------------
17657 * This will receive and process the FT Pre Auth Rsp from the current
17658 * associated ap.
17659 *
17660 * This will invoke the hdd call back. This is so that hdd can now
17661 * send the FTIEs from the Auth Rsp (Auth Seq 2) to the supplicant.
17662 ------------------------------------------------------------------------*/
17663void csr_roam_ft_pre_auth_rsp_processor(tHalHandle hHal,
17664 tpSirFTPreAuthRsp pFTPreAuthRsp)
17665{
17666 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
17667 CDF_STATUS status = CDF_STATUS_SUCCESS;
17668#if defined(FEATURE_WLAN_LFR) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD)
17669 tCsrRoamInfo roamInfo;
17670#endif
17671 eCsrAuthType conn_Auth_type;
17672 uint32_t sessionId = pFTPreAuthRsp->smeSessionId;
17673 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
17674
17675 if (NULL == pSession) {
17676 sms_log(pMac, LOGE, FL("pSession is NULL"));
17677 return;
17678 }
17679#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
17680 status =
17681 csr_neighbor_roam_preauth_rsp_handler(pMac, pFTPreAuthRsp->smeSessionId,
17682 pFTPreAuthRsp->status);
17683 if (status != CDF_STATUS_SUCCESS) {
17684 /*
17685 * Bail out if pre-auth was not even processed.
17686 */
17687 sms_log(pMac, LOGE,
17688 FL("Preauth was not processed: %d SessionID: %d"),
17689 status, sessionId);
17690 return;
17691 }
17692#endif
17693
17694 /* The below function calls/timers should be invoked only if the pre-auth is successful */
17695 if (CDF_STATUS_SUCCESS != (CDF_STATUS) pFTPreAuthRsp->status)
17696 return;
17697 /* Implies a success */
17698 pSession->ftSmeContext.FTState = eFT_AUTH_COMPLETE;
17699 /* Indicate SME QoS module the completion of Preauth success. This will trigger the creation of RIC IEs */
17700 pSession->ftSmeContext.psavedFTPreAuthRsp = pFTPreAuthRsp;
17701 /* No need to notify qos module if this is a non 11r & ESE roam */
17702 if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId)
17703#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD)
17704 || csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)
17705#endif
17706 ) {
17707 sme_qos_csr_event_ind(pMac,
17708 pSession->ftSmeContext.smeSessionId,
17709 SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
17710 }
17711 /* Start the pre-auth reassoc interval timer with a period of 400ms. When this expires,
17712 * actual transition from the current to handoff AP is triggered */
17713 status =
17714 cdf_mc_timer_start(&pSession->ftSmeContext.preAuthReassocIntvlTimer,
17715 60);
17716 if (CDF_STATUS_SUCCESS != status) {
17717 sms_log(pMac, LOGE,
17718 FL
17719 ("Preauth reassoc interval timer start failed to start with status %d"),
17720 status);
17721 return;
17722 }
17723 /* Save the received response */
17724 cdf_mem_copy((void *)&pSession->ftSmeContext.preAuthbssId,
17725 (void *)pFTPreAuthRsp->preAuthbssId, sizeof(struct cdf_mac_addr));
17726 if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId))
17727 csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId, NULL, 0,
17728 eCSR_ROAM_FT_RESPONSE,
17729 eCSR_ROAM_RESULT_NONE);
17730
17731#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
17732 if (csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)) {
17733 /* read TSF */
17734 csr_roam_read_tsf(pMac, (uint8_t *) roamInfo.timestamp,
17735 pFTPreAuthRsp->smeSessionId);
17736 /* Save the bssid from the received response */
17737 cdf_mem_copy((void *)&roamInfo.bssid,
17738 (void *)pFTPreAuthRsp->preAuthbssId,
17739 sizeof(struct cdf_mac_addr));
17740 csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
17741 &roamInfo, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
17742 0);
17743 }
17744#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
17745
17746#ifdef FEATURE_WLAN_LFR
17747 /* If Legacy Fast Roaming is enabled, signal the supplicant */
17748 /* So he can send us a PMK-ID for this candidate AP. */
17749 if (csr_roam_is_fast_roam_enabled(pMac, pFTPreAuthRsp->smeSessionId)) {
17750 /* Save the bssid from the received response */
17751 cdf_mem_copy((void *)&roamInfo.bssid,
17752 (void *)pFTPreAuthRsp->preAuthbssId,
17753 sizeof(struct cdf_mac_addr));
17754 csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
17755 &roamInfo, 0, eCSR_ROAM_PMK_NOTIFY, 0);
17756 }
17757#endif
17758
17759 /* If its an Open Auth, FT IEs are not provided by supplicant */
17760 /* Hence populate them here */
17761 conn_Auth_type =
17762 pMac->roam.roamSession[sessionId].connectedProfile.AuthType;
17763
17764 pSession->ftSmeContext.addMDIE = false;
17765 if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId) &&
17766 (conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
17767 uint16_t ft_ies_length;
17768 ft_ies_length = pFTPreAuthRsp->ric_ies_length;
17769
17770 if ((pSession->ftSmeContext.reassoc_ft_ies) &&
17771 (pSession->ftSmeContext.reassoc_ft_ies_length)) {
17772 cdf_mem_free(pSession->ftSmeContext.reassoc_ft_ies);
17773 pSession->ftSmeContext.reassoc_ft_ies_length = 0;
17774 pSession->ftSmeContext.reassoc_ft_ies = NULL;
17775 }
17776
17777 pSession->ftSmeContext.reassoc_ft_ies =
17778 cdf_mem_malloc(ft_ies_length);
17779 if (NULL == pSession->ftSmeContext.reassoc_ft_ies) {
17780 sms_log(pMac, LOGE,
17781 FL("Memory allocation failed for ft_ies"));
17782 return;
17783 } else {
17784 /* Copy the RIC IEs to reassoc IEs */
17785 cdf_mem_copy(((uint8_t *) pSession->ftSmeContext.
17786 reassoc_ft_ies),
17787 (uint8_t *) pFTPreAuthRsp->ric_ies,
17788 pFTPreAuthRsp->ric_ies_length);
17789 pSession->ftSmeContext.reassoc_ft_ies_length =
17790 ft_ies_length;
17791 pSession->ftSmeContext.addMDIE = true;
17792 }
17793 }
17794 /* Done with it, init it. */
17795 pSession->ftSmeContext.psavedFTPreAuthRsp = NULL;
17796}
17797#endif
17798
17799
17800/*
17801 pBuf points to the beginning of the message
17802 LIM packs disassoc rsp as below,
17803 messageType - 2 bytes
17804 messageLength - 2 bytes
17805 sessionId - 1 byte
17806 transactionId - 2 bytes (uint16_t)
17807 reasonCode - 4 bytes (sizeof(tSirResultCodes))
17808 peerMacAddr - 6 bytes
17809 The rest is conditionally defined of (WNI_POLARIS_FW_PRODUCT == AP) and not used
17810 */
17811static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf, tSirSmeDisassocRsp *pRsp)
17812{
17813 if (pBuf && pRsp) {
17814 pBuf += 4; /* skip type and length */
17815 pRsp->sessionId = *pBuf++;
17816 cdf_get_u16(pBuf, (uint16_t *) &pRsp->transactionId);
17817 pBuf += 2;
17818 cdf_get_u32(pBuf, (uint32_t *) &pRsp->statusCode);
17819 pBuf += 4;
17820 cdf_mem_copy(pRsp->peerMacAddr, pBuf, 6);
17821 }
17822}
17823
17824/* Returns whether a session is in CDF_STA_MODE...or not */
17825bool csr_roam_is_sta_mode(tpAniSirGlobal pMac, uint32_t sessionId)
17826{
17827 tCsrRoamSession *pSession = NULL;
17828 pSession = CSR_GET_SESSION(pMac, sessionId);
17829 if (!pSession) {
17830 sms_log(pMac, LOGE, FL(" %s: session %d not found "), __func__,
17831 sessionId);
17832 return false;
17833 }
17834 if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
17835 sms_log(pMac, LOGE, FL(" %s: Inactive session"), __func__);
17836 return false;
17837 }
17838 if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) {
17839 return false;
17840 }
17841 /* There is a possibility that the above check may fail,because
17842 * P2P CLI also uses the same BSSType (eCSR_BSS_TYPE_INFRASTRUCTURE)
17843 * when it is connected.So,we may sneak through the above check even
17844 * if we are not a STA mode INFRA station. So, if we sneak through
17845 * the above condition, we can use the following check if we are
17846 * really in STA Mode.*/
17847
17848 if (NULL != pSession->pCurRoamProfile) {
17849 if (pSession->pCurRoamProfile->csrPersona == CDF_STA_MODE) {
17850 return true;
17851 } else {
17852 sms_log(pMac, LOGE, FL(" %s: pCurRoamProfile is NULL\n"),
17853 __func__);
17854 return false;
17855 }
17856 }
17857
17858 return false;
17859}
17860
17861CDF_STATUS csr_handoff_request(tpAniSirGlobal pMac,
17862 uint8_t sessionId,
17863 tCsrHandoffRequest *pHandoffInfo)
17864{
17865 CDF_STATUS status = CDF_STATUS_SUCCESS;
17866 cds_msg_t msg;
17867
17868 tAniHandoffReq *pMsg;
17869 pMsg = cdf_mem_malloc(sizeof(tAniHandoffReq));
17870 if (NULL == pMsg) {
17871 sms_log(pMac, LOGE,
17872 " csr_handoff_request: failed to allocate mem for req ");
17873 return CDF_STATUS_E_NOMEM;
17874 }
17875 pMsg->msgType = eWNI_SME_HANDOFF_REQ;
17876 pMsg->msgLen = (uint16_t) sizeof(tAniHandoffReq);
17877 pMsg->sessionId = sessionId;
17878 pMsg->channel = pHandoffInfo->channel;
17879 pMsg->handoff_src = pHandoffInfo->src;
17880 cdf_mem_copy(pMsg->bssid, pHandoffInfo->bssid.bytes, CDF_MAC_ADDR_SIZE);
17881 msg.type = eWNI_SME_HANDOFF_REQ;
17882 msg.bodyptr = pMsg;
17883 msg.reserved = 0;
17884 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
17885 sms_log(pMac, LOGE,
17886 " csr_handoff_request failed to post msg to self ");
17887 cdf_mem_free((void *)pMsg);
17888 status = CDF_STATUS_E_FAILURE;
17889 }
17890 return status;
17891}
17892
17893#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
17894/* ---------------------------------------------------------------------------
17895 \fn csr_set_cckm_ie
17896 \brief This function stores the CCKM IE passed by the supplicant
17897 in a place holder data structure and this IE will be packed inside
17898 reassociation request
17899 \param pMac - pMac global structure
17900 \param sessionId - Current session id
17901 \param pCckmIe - pointer to CCKM IE data
17902 \param ccKmIeLen - length of the CCKM IE
17903 \- return Success or failure
17904 -------------------------------------------------------------------------*/
17905CDF_STATUS csr_set_cckm_ie(tpAniSirGlobal pMac, const uint8_t sessionId,
17906 const uint8_t *pCckmIe, const uint8_t ccKmIeLen)
17907{
17908 CDF_STATUS status = CDF_STATUS_SUCCESS;
17909 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
17910 if (!pSession) {
17911 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
17912 return CDF_STATUS_E_FAILURE;
17913 }
17914 cdf_mem_copy(pSession->suppCckmIeInfo.cckmIe, pCckmIe, ccKmIeLen);
17915 pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen;
17916 return status;
17917}
17918
17919/* ---------------------------------------------------------------------------
17920 \fn csr_roam_read_tsf
17921 \brief This function reads the TSF; and also add the time elapsed since
17922 last beacon or probe response reception from the hand off AP to arrive at
17923 the latest TSF value.
17924 \param pMac - pMac global structure
17925 \param pTimestamp - output TSF timestamp
17926 \- return Success or failure
17927 -------------------------------------------------------------------------*/
17928CDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
17929 uint8_t sessionId)
17930{
17931 CDF_STATUS status = CDF_STATUS_SUCCESS;
17932 tCsrNeighborRoamBSSInfo handoffNode;
17933 uint32_t timer_diff = 0;
17934 uint32_t timeStamp[2];
17935 tpSirBssDescription pBssDescription = NULL;
17936 csr_neighbor_roam_get_handoff_ap_info(pMac, &handoffNode, sessionId);
17937 pBssDescription = handoffNode.pBssDescription;
17938 /* Get the time diff in milli seconds */
17939 timer_diff =
17940 cdf_mc_timer_get_system_time() - pBssDescription->scanSysTimeMsec;
17941 /* Convert msec to micro sec timer */
17942 timer_diff = (uint32_t) (timer_diff * SYSTEM_TIME_MSEC_TO_USEC);
17943 timeStamp[0] = pBssDescription->timeStamp[0];
17944 timeStamp[1] = pBssDescription->timeStamp[1];
17945 update_cckmtsf(&(timeStamp[0]), &(timeStamp[1]), &timer_diff);
17946 cdf_mem_copy(pTimestamp, (void *)&timeStamp[0], sizeof(uint32_t) * 2);
17947 return status;
17948}
17949#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
17950
17951/*
17952 * Post Channel Change Request to LIM
17953 * This API is primarily used to post
17954 * Channel Change Req for SAP
17955 */
17956CDF_STATUS
17957csr_roam_channel_change_req(tpAniSirGlobal pMac, struct cdf_mac_addr bssid,
17958 uint8_t cbMode, tCsrRoamProfile *profile)
17959{
17960 CDF_STATUS status = CDF_STATUS_SUCCESS;
17961 tSirChanChangeRequest *pMsg;
17962 tCsrRoamStartBssParams param;
17963
17964 csr_roam_get_bss_start_parms(pMac, profile, &param);
17965 pMsg = cdf_mem_malloc(sizeof(tSirChanChangeRequest));
17966 if (!pMsg) {
17967 return CDF_STATUS_E_NOMEM;
17968 }
17969
17970 cdf_mem_set((void *)pMsg, sizeof(tSirChanChangeRequest), 0);
17971
17972 pMsg->messageType = eWNI_SME_CHANNEL_CHANGE_REQ;
17973 pMsg->messageLen = sizeof(tSirChanChangeRequest);
17974 pMsg->targetChannel = profile->ChannelInfo.ChannelList[0];
17975 pMsg->cbMode = cbMode;
17976 pMsg->channel_width = profile->ch_params.ch_width;
17977 pMsg->dot11mode = csr_translate_to_wni_cfg_dot11_mode(pMac,
17978 pMac->roam.configParam.uCfgDot11Mode);
17979 pMsg->center_freq_seg_0 = pMsg->targetChannel;
17980 pMsg->center_freq_seg_1 = 0;
17981 cdf_mem_copy(pMsg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
17982 cdf_mem_copy(&pMsg->operational_rateset,
17983 &param.operationalRateSet, sizeof(pMsg->operational_rateset));
17984 cdf_mem_copy(&pMsg->extended_rateset,
17985 &param.extendedRateSet, sizeof(pMsg->extended_rateset));
17986 status = cds_send_mb_message_to_mac(pMsg);
17987
17988 return status;
17989}
17990
17991/*
17992 * Post Beacon Tx Start request to LIM
17993 * immediately after SAP CAC WAIT is
17994 * completed without any RADAR indications.
17995 */
17996CDF_STATUS csr_roam_start_beacon_req(tpAniSirGlobal pMac,
17997 struct cdf_mac_addr bssid,
17998 uint8_t dfsCacWaitStatus)
17999{
18000 CDF_STATUS status = CDF_STATUS_SUCCESS;
18001 tSirStartBeaconIndication *pMsg;
18002
18003 pMsg = cdf_mem_malloc(sizeof(tSirStartBeaconIndication));
18004
18005 if (!pMsg) {
18006 return CDF_STATUS_E_NOMEM;
18007 }
18008
18009 cdf_mem_set((void *)pMsg, sizeof(tSirStartBeaconIndication), 0);
18010 pMsg->messageType = eWNI_SME_START_BEACON_REQ;
18011 pMsg->messageLen = sizeof(tSirStartBeaconIndication);
18012 pMsg->beaconStartStatus = dfsCacWaitStatus;
18013 cdf_mem_copy(pMsg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
18014
18015 status = cds_send_mb_message_to_mac(pMsg);
18016
18017 return status;
18018}
18019
18020/*----------------------------------------------------------------------------
18021 \fn csr_roam_modify_add_ies
18022 \brief This function sends msg to modify the additional IE buffers in PE
18023 \param pMac - pMac global structure
18024 \param pModifyIE - pointer to tSirModifyIE structure
18025 \param updateType - Type of buffer
18026 \- return Success or failure
18027 -----------------------------------------------------------------------------*/
18028CDF_STATUS
18029csr_roam_modify_add_ies(tpAniSirGlobal pMac,
18030 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
18031{
18032 tpSirModifyIEsInd pModifyAddIEInd = NULL;
18033 uint8_t *pLocalBuffer = NULL;
18034 CDF_STATUS status;
18035
18036 /* following buffer will be freed by consumer (PE) */
18037 pLocalBuffer = cdf_mem_malloc(pModifyIE->ieBufferlength);
18038
18039 if (NULL == pLocalBuffer) {
18040 sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
18041 return CDF_STATUS_E_NOMEM;
18042 }
18043
18044 pModifyAddIEInd = cdf_mem_malloc(sizeof(tSirModifyIEsInd));
18045 if (NULL == pModifyAddIEInd) {
18046 sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
18047 cdf_mem_free(pLocalBuffer);
18048 return CDF_STATUS_E_NOMEM;
18049 }
18050
18051 /*copy the IE buffer */
18052 cdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer,
18053 pModifyIE->ieBufferlength);
18054 cdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd));
18055
18056 pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES;
18057 pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd);
18058
18059 cdf_mem_copy(pModifyAddIEInd->modifyIE.bssid, pModifyIE->bssid,
18060 sizeof(tSirMacAddr));
18061
18062 pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId;
18063 pModifyAddIEInd->modifyIE.notify = pModifyIE->notify;
18064 pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID;
18065 pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen;
18066 pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer;
18067 pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength;
18068
18069 pModifyAddIEInd->updateType = updateType;
18070
18071 status = cds_send_mb_message_to_mac(pModifyAddIEInd);
18072 if (!CDF_IS_STATUS_SUCCESS(status)) {
18073 sms_log(pMac, LOGE,
18074 FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg"
18075 "!!! status %d"), status);
18076 cdf_mem_free(pLocalBuffer);
18077 }
18078 return status;
18079}
18080
18081/*----------------------------------------------------------------------------
18082 \fn csr_roam_update_add_ies
18083 \brief This function sends msg to updates the additional IE buffers in PE
18084 \param pMac - pMac global structure
18085 \param sessionId - SME session id
18086 \param bssid - BSSID
18087 \param additionIEBuffer - buffer containing addition IE from hostapd
18088 \param length - length of buffer
18089 \param updateType - Type of buffer
18090 \param append - append or replace completely
18091 \- return Success or failure
18092 -----------------------------------------------------------------------------*/
18093CDF_STATUS
18094csr_roam_update_add_ies(tpAniSirGlobal pMac,
18095 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
18096{
18097 tpSirUpdateIEsInd pUpdateAddIEs = NULL;
18098 uint8_t *pLocalBuffer = NULL;
18099 CDF_STATUS status;
18100
18101 if (pUpdateIE->ieBufferlength != 0) {
18102 /* Following buffer will be freed by consumer (PE) */
18103 pLocalBuffer = cdf_mem_malloc(pUpdateIE->ieBufferlength);
18104 if (NULL == pLocalBuffer) {
18105 sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
18106 return CDF_STATUS_E_NOMEM;
18107 }
18108 cdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
18109 pUpdateIE->ieBufferlength);
18110 }
18111
18112 pUpdateAddIEs = cdf_mem_malloc(sizeof(tSirUpdateIEsInd));
18113 if (NULL == pUpdateAddIEs) {
18114 sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
18115 if (pLocalBuffer != NULL) {
18116 cdf_mem_free(pLocalBuffer);
18117 }
18118 return CDF_STATUS_E_NOMEM;
18119 }
18120
18121 cdf_mem_zero(pUpdateAddIEs, sizeof(tSirUpdateIEsInd));
18122
18123 pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES;
18124 pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd);
18125
18126 cdf_mem_copy(pUpdateAddIEs->updateIE.bssid, pUpdateIE->bssid,
18127 sizeof(tSirMacAddr));
18128
18129 pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId;
18130 pUpdateAddIEs->updateIE.append = pUpdateIE->append;
18131 pUpdateAddIEs->updateIE.notify = pUpdateIE->notify;
18132 pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength;
18133 pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer;
18134
18135 pUpdateAddIEs->updateType = updateType;
18136
18137 status = cds_send_mb_message_to_mac(pUpdateAddIEs);
18138 if (!CDF_IS_STATUS_SUCCESS(status)) {
18139 sms_log(pMac, LOGE,
18140 FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg"
18141 "!!! status %d"), status);
18142 cdf_mem_free(pLocalBuffer);
18143 }
18144 return status;
18145}
18146
18147/**
18148 * csr_roam_send_chan_sw_ie_request() - Request to transmit CSA IE
18149 * @mac_ctx: Global MAC context
18150 * @bssid: BSSID
18151 * @target_channel: Channel on which to send the IE
18152 * @csa_ie_reqd: Include/Exclude CSA IE.
18153 * @ch_bandwidth: Channel offset
18154 *
18155 * This function sends request to transmit channel switch announcement
18156 * IE to lower layers
18157 *
18158 * Return: success or failure
18159 **/
18160CDF_STATUS
18161csr_roam_send_chan_sw_ie_request(tpAniSirGlobal mac_ctx,
18162 struct cdf_mac_addr bssid, uint8_t target_channel,
18163 uint8_t csa_ie_reqd, uint8_t ch_bandwidth)
18164{
18165 CDF_STATUS status = CDF_STATUS_SUCCESS;
18166 tSirDfsCsaIeRequest *msg;
18167
18168 msg = cdf_mem_malloc(sizeof(tSirDfsCsaIeRequest));
18169 if (!msg) {
18170 return CDF_STATUS_E_NOMEM;
18171 }
18172
18173 cdf_mem_set((void *)msg, sizeof(tSirDfsCsaIeRequest), 0);
18174 msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ;
18175 msg->msgLen = sizeof(tSirDfsCsaIeRequest);
18176
18177 msg->targetChannel = target_channel;
18178 msg->csaIeRequired = csa_ie_reqd;
18179 cdf_mem_copy(msg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
18180 msg->ch_bandwidth = ch_bandwidth;
18181
18182 status = cds_send_mb_message_to_mac(msg);
18183
18184 return status;
18185}
18186
18187#ifdef WLAN_FEATURE_ROAM_OFFLOAD
18188/*----------------------------------------------------------------------------
18189* fn csr_process_roam_offload_synch_ind
18190* brief This will process the roam synch indication received from
18191* lower layers.This function also calls another API to
18192* parse the beacon IE and fill the appropriate fields
18193* param pMac - pMac global structure
18194* param pMsgBuf - Message buffer received from lower layers
18195* --------------------------------------------------------------------------*/
18196void csr_process_roam_offload_synch_ind(tHalHandle hHal,
18197 roam_offload_synch_ind *roam_synch_ind_ptr)
18198{
18199 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
18200 tCsrRoamSession *session_ptr = NULL;
18201 uint8_t session_id = roam_synch_ind_ptr->roamedVdevId;
18202 session_ptr = CSR_GET_SESSION(pMac, roam_synch_ind_ptr->roamedVdevId);
18203 if (!session_ptr) {
18204 sms_log(pMac, LOGE, FL("LFR3: session %d not found "),
18205 roam_synch_ind_ptr->roamedVdevId);
18206 goto err_synch_rsp;
18207 }
18208 if (!CDF_IS_STATUS_SUCCESS(csr_scan_save_roam_offload_ap_to_scan_cache(
18209 pMac, roam_synch_ind_ptr))) {
18210 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18211 "fail to save roam offload AP to scan cache");
18212 goto err_synch_rsp;
18213 }
18214 session_ptr->roamOffloadSynchParams.rssi = roam_synch_ind_ptr->rssi;
18215 session_ptr->roamOffloadSynchParams.roamReason =
18216 roam_synch_ind_ptr->roamReason;
18217 session_ptr->roamOffloadSynchParams.roamedVdevId =
18218 roam_synch_ind_ptr->roamedVdevId;
18219 cdf_mem_copy(session_ptr->roamOffloadSynchParams.bssid,
18220 roam_synch_ind_ptr->bssId, sizeof(tSirMacAddr));
18221 session_ptr->roamOffloadSynchParams.txMgmtPower =
18222 roam_synch_ind_ptr->txMgmtPower;
18223 session_ptr->roamOffloadSynchParams.authStatus =
18224 roam_synch_ind_ptr->authStatus;
18225 session_ptr->roamOffloadSynchParams.bRoamSynchInProgress = true;
18226 /*Save the BSS descriptor for later use*/
18227 session_ptr->roamOffloadSynchParams.bss_desc_ptr =
18228 roam_synch_ind_ptr->bss_desc_ptr;
18229 pMac->roam.reassocRespLen = roam_synch_ind_ptr->reassocRespLength;
18230 pMac->roam.pReassocResp =
18231 cdf_mem_malloc(pMac->roam.reassocRespLen);
18232 if (NULL == pMac->roam.pReassocResp) {
18233 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18234 "Memory allocation for reassoc response failed");
18235 goto err_synch_rsp;
18236 }
18237 cdf_mem_copy(pMac->roam.pReassocResp,
18238 (uint8_t *)roam_synch_ind_ptr +
18239 roam_synch_ind_ptr->reassocRespOffset,
18240 pMac->roam.reassocRespLen);
18241
18242 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
18243 "LFR3:%s: the reassoc resp frame data:", __func__);
18244 CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
18245 pMac->roam.pReassocResp, pMac->roam.reassocRespLen);
18246
18247 cdf_mem_copy(session_ptr->roamOffloadSynchParams.kck,
18248 roam_synch_ind_ptr->kck, SIR_KCK_KEY_LEN);
18249 cdf_mem_copy(session_ptr->roamOffloadSynchParams.kek,
18250 roam_synch_ind_ptr->kek, SIR_KEK_KEY_LEN);
18251 cdf_mem_copy(session_ptr->roamOffloadSynchParams.replay_ctr,
18252 roam_synch_ind_ptr->replay_ctr, SIR_REPLAY_CTR_LEN);
18253 if (CDF_STATUS_SUCCESS != csr_neighbor_roam_offload_update_preauth_list(
18254 pMac, roam_synch_ind_ptr, session_id)) {
18255 /**
18256 *Bail out if Roam Offload Synch Response was not even handled.
18257 **/
18258 sms_log(pMac, LOGE, FL("Roam Offload Synch Response "
18259 "was not processed"));
18260 goto err_synch_rsp;
18261 }
18262
18263 csr_neighbor_roam_request_handoff(pMac, session_id);
18264
18265err_synch_rsp:
18266 cdf_mem_free(roam_synch_ind_ptr->bss_desc_ptr);
18267 roam_synch_ind_ptr->bss_desc_ptr = NULL;
18268}
18269
18270/*----------------------------------------------------------------------------
18271* fn csr_process_ho_fail_ind
18272* brief This function will process the Hand Off Failure indication
18273* received from the firmware. It will trigger a disconnect on
18274* the session which the firmware reported a hand off failure
18275* param pMac global structure
18276* param pMsgBuf - Contains the session ID for which the handler should apply
18277* --------------------------------------------------------------------------*/
18278void csr_process_ho_fail_ind(tpAniSirGlobal pMac, void *pMsgBuf)
18279{
18280 tSirSmeHOFailureInd *pSmeHOFailInd = (tSirSmeHOFailureInd *) pMsgBuf;
18281 uint32_t sessionId;
18282
18283 if (pSmeHOFailInd)
18284 sessionId = pSmeHOFailInd->sessionId;
18285 else {
18286 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18287 "LFR3: Hand-Off Failure Ind is NULL");
18288 return;
18289 }
18290 /* Roaming is supported only on Infra STA Mode. */
18291 if (!csr_roam_is_sta_mode(pMac, sessionId)) {
18292 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18293 "LFR3:HO Fail cannot be handled for session %d",
18294 sessionId);
18295 return;
18296 }
18297 csr_roam_synch_clean_up(pMac, sessionId);
18298 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18299 "LFR3:Issue Disconnect on session %d", sessionId);
18300 csr_roam_disconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
18301}
18302#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
18303
18304/**
18305 * csr_update_op_class_array() - update op class for each band
18306 * @mac_ctx: mac global context
18307 * @op_classes: out param, operating class array to update
18308 * @channel_info: channel info
18309 * @ch_name: channel band name to display in debug messages
18310 * @i: out param, stores number of operating classes
18311 *
18312 * Return: void
18313 */
18314static void
18315csr_update_op_class_array(tpAniSirGlobal mac_ctx,
18316 uint8_t *op_classes,
18317 tCsrChannel *channel_info,
18318 char *ch_name,
18319 uint8_t *i)
18320{
18321 uint8_t j = 0, idx = 0, class = 0;
18322 bool found = false;
18323 uint8_t num_channels = channel_info->numChannels;
18324
18325 sms_log(mac_ctx, LOG1,
18326 FL("Num of %s channels, %d"),
18327 ch_name, num_channels);
18328
18329 for (idx = 0; idx < num_channels
18330 && *i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); idx++) {
18331 class = cds_regdm_get_opclass_from_channel(
18332 mac_ctx->scan.countryCodeCurrent,
18333 channel_info->channelList[idx],
18334 BWALL);
18335 sms_log(mac_ctx, LOG4, FL("for chan %d, op class: %d"),
18336 channel_info->channelList[idx], class);
18337
18338 found = false;
18339 for (j = 0; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) {
18340 if (op_classes[j] == class) {
18341 found = true;
18342 break;
18343 }
18344 }
18345 if (!found) {
18346 op_classes[*i] = class;
18347 *i = *i + 1;
18348 }
18349 }
18350}
18351
18352/**
18353 * csr_update_op_class_array() - update op class for all bands
18354 * @hHal: global hal context
18355 *
18356 * Return: void
18357 */
18358void csr_init_operating_classes(tHalHandle hHal)
18359{
18360 uint8_t i = 0;
18361 uint8_t j = 0;
18362 uint8_t swap = 0;
18363 uint8_t numClasses = 0;
18364 uint8_t opClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES] = {0,};
18365 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
18366
18367 sms_log(pMac, LOG1, FL("Current Country = %c%c"),
18368 pMac->scan.countryCodeCurrent[0],
18369 pMac->scan.countryCodeCurrent[1]);
18370
18371 csr_update_op_class_array(pMac, opClasses,
18372 &pMac->scan.base_channels, "20MHz", &i);
18373 csr_update_op_class_array(pMac, opClasses,
18374 &pMac->scan.base40MHzChannels, "40MHz", &i);
18375 numClasses = i;
18376
18377 /* As per spec the operating classes should be in ascending order.
18378 * Bubble sort is fine since we don't have many classes
18379 */
18380 for (i = 0; i < (numClasses - 1); i++) {
18381 for (j = 0; j < (numClasses - i - 1); j++) {
18382 /* For decreasing order use < */
18383 if (opClasses[j] > opClasses[j + 1]) {
18384 swap = opClasses[j];
18385 opClasses[j] = opClasses[j + 1];
18386 opClasses[j + 1] = swap;
18387 }
18388 }
18389 }
18390
18391 sms_log(pMac, LOG1, FL("Number of unique supported op classes %d"),
18392 numClasses);
18393 for (i = 0; i < numClasses; i++) {
18394 sms_log(pMac, LOG1, FL("supported opClasses[%d] = %d"), i,
18395 opClasses[i]);
18396 }
18397
18398 /* Set the ordered list of op classes in regdomain
18399 * for use by other modules
18400 */
18401 cds_regdm_set_curr_opclasses(numClasses, &opClasses[0]);
18402}
18403
18404/**
18405 * csr_find_session_by_type() - This function will find given session type from
18406 * all sessions.
18407 * @mac_ctx: pointer to mac context.
18408 * @type: session type
18409 *
18410 * Return: session id for give session type.
18411 **/
18412static uint32_t
18413csr_find_session_by_type(tpAniSirGlobal mac_ctx, tCDF_CON_MODE type)
18414{
18415 uint32_t i, session_id = CSR_SESSION_ID_INVALID;
18416 tCsrRoamSession *session_ptr;
18417 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
18418 if (!CSR_IS_SESSION_VALID(mac_ctx, i))
18419 continue;
18420
18421 session_ptr = CSR_GET_SESSION(mac_ctx, i);
18422 if (type == session_ptr->bssParams.bssPersona) {
18423 session_id = i;
18424 break;
18425 }
18426 }
18427 return session_id;
18428}
18429/**
18430 * csr_is_conn_allow_2g_band() - This function will check if station's conn
18431 * is allowed in 2.4Ghz band.
18432 * @mac_ctx: pointer to mac context.
18433 * @chnl: station's channel.
18434 *
18435 * This function will check if station's connection is allowed in 5Ghz band
18436 * after comparing it with SAP's operating channel. If SAP's operating
18437 * channel and Station's channel is different than this function will return
18438 * false else true.
18439 *
18440 * Return: true or false.
18441 **/
18442static bool csr_is_conn_allow_2g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
18443{
18444 uint32_t sap_session_id;
18445 tCsrRoamSession *sap_session;
18446
18447 if (0 == chnl) {
18448 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18449 FL("channel is zero, connection not allowed"));
18450
18451 return false;
18452 }
18453
18454 sap_session_id = csr_find_session_by_type(mac_ctx, CDF_SAP_MODE);
18455 if (CSR_SESSION_ID_INVALID != sap_session_id) {
18456 sap_session = CSR_GET_SESSION(mac_ctx, sap_session_id);
18457 if ((0 != sap_session->bssParams.operationChn) &&
18458 (sap_session->bssParams.operationChn != chnl)) {
18459
18460 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18461 FL
18462 ("Can't allow STA to connect, chnls not same"));
18463 return false;
18464 }
18465 }
18466 return true;
18467}
18468
18469/**
18470 * csr_is_conn_allow_5g_band() - This function will check if station's conn
18471 * is allowed in 5Ghz band.
18472 * @mac_ctx: pointer to mac context.
18473 * @chnl: station's channel.
18474 *
18475 * This function will check if station's connection is allowed in 5Ghz band
18476 * after comparing it with P2PGO's operating channel. If P2PGO's operating
18477 * channel and Station's channel is different than this function will return
18478 * false else true.
18479 *
18480 * Return: true or false.
18481 **/
18482static bool csr_is_conn_allow_5g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
18483{
18484 uint32_t p2pgo_session_id;
18485 tCsrRoamSession *p2pgo_session;
18486
18487 if (0 == chnl) {
18488 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18489 FL
18490 ("channel is zero, connection not allowed"));
18491 return false;
18492 }
18493
18494 p2pgo_session_id = csr_find_session_by_type(mac_ctx, CDF_P2P_GO_MODE);
18495 if (CSR_SESSION_ID_INVALID != p2pgo_session_id) {
18496 p2pgo_session = CSR_GET_SESSION(mac_ctx, p2pgo_session_id);
18497 if ((0 != p2pgo_session->bssParams.operationChn) &&
18498 (eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED !=
18499 p2pgo_session->connectState) &&
18500 (p2pgo_session->bssParams.operationChn !=
18501 chnl)) {
18502
18503 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18504 FL
18505 ("Can't allow STA to connect, chnls not same"));
18506 return false;
18507 }
18508 }
18509 return true;
18510}
18511
18512/**
18513 * csr_clear_joinreq_param() - This function will clear station's params
18514 * for stored join request to csr.
18515 * @hal_handle: pointer to hal context.
18516 * @session_id: station's session id.
18517 *
18518 * This function will clear station's allocated memory for cached join
18519 * request.
18520 *
18521 * Return: true or false based on function's overall success.
18522 **/
18523bool csr_clear_joinreq_param(tpAniSirGlobal mac_ctx,
18524 uint32_t session_id)
18525{
18526 tCsrRoamSession *sta_session;
18527 tScanResultList *bss_list;
18528
18529 if (NULL == mac_ctx)
18530 return false;
18531
18532 sta_session = CSR_GET_SESSION(mac_ctx, session_id);
18533 if (NULL == sta_session)
18534 return false;
18535
18536 /* Release the memory allocated by previous join request */
18537 bss_list =
18538 (tScanResultList *)&sta_session->stored_roam_profile.
18539 bsslist_handle;
18540 if (NULL != bss_list) {
18541 csr_scan_result_purge(mac_ctx,
18542 sta_session->stored_roam_profile.bsslist_handle);
18543 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
18544 FL("bss list is released for session %d"), session_id);
18545 sta_session->stored_roam_profile.bsslist_handle = NULL;
18546 }
18547 sta_session->stored_roam_profile.bsslist_handle = NULL;
18548 csr_release_profile(mac_ctx, &sta_session->stored_roam_profile.profile);
18549 sta_session->stored_roam_profile.reason = 0;
18550 sta_session->stored_roam_profile.roam_id = 0;
18551 sta_session->stored_roam_profile.imediate_flag = false;
18552 sta_session->stored_roam_profile.clear_flag = false;
18553 return true;
18554}
18555
18556/**
18557 * csr_store_joinreq_param() - This function will store station's join
18558 * request to that station's session.
18559 * @mac_ctx: pointer to mac context.
18560 * @profile: pointer to station's roam profile.
18561 * @scan_cache: pointer to station's scan cache.
18562 * @roam_id: reference to roam_id variable being passed.
18563 * @session_id: station's session id.
18564 *
18565 * This function will store station's join request to one of the
18566 * csr structure and add it to station's session.
18567 *
18568 * Return: true or false based on function's overall success.
18569 **/
18570bool csr_store_joinreq_param(tpAniSirGlobal mac_ctx,
18571 tCsrRoamProfile *profile,
18572 tScanResultHandle scan_cache,
18573 uint32_t *roam_id,
18574 uint32_t session_id)
18575{
18576 tCsrRoamSession *sta_session;
18577
18578 if (NULL == mac_ctx)
18579 return false;
18580
18581 sta_session = CSR_GET_SESSION(mac_ctx, session_id);
18582 if (NULL == sta_session)
18583 return false;
18584
18585 sta_session->stored_roam_profile.session_id = session_id;
18586 csr_roam_copy_profile(mac_ctx,
18587 &sta_session->stored_roam_profile.profile, profile);
18588 /* new bsslist_handle's memory will be relased later */
18589 sta_session->stored_roam_profile.bsslist_handle = scan_cache;
18590 sta_session->stored_roam_profile.reason = eCsrHddIssued;
18591 sta_session->stored_roam_profile.roam_id = *roam_id;
18592 sta_session->stored_roam_profile.imediate_flag = false;
18593 sta_session->stored_roam_profile.clear_flag = false;
18594
18595 return true;
18596}
18597
18598/**
18599 * csr_issue_stored_joinreq() - This function will issues station's stored
18600 * the join request.
18601 * @mac_ctx: pointer to mac context.
18602 * @roam_id: reference to roam_id variable being passed.
18603 * @session_id: station's session id.
18604 *
18605 * This function will issue station's stored join request, from this point
18606 * onwards the flow will be just like normal connect request.
18607 *
18608 * Return: CDF_STATUS_SUCCESS or CDF_STATUS_E_FAILURE.
18609 **/
18610CDF_STATUS csr_issue_stored_joinreq(tpAniSirGlobal mac_ctx,
18611 uint32_t *roam_id,
18612 uint32_t session_id)
18613{
18614 CDF_STATUS status = CDF_STATUS_SUCCESS;
18615 tCsrRoamSession *sta_session;
18616 uint32_t new_roam_id;
18617
18618 sta_session = CSR_GET_SESSION(mac_ctx, session_id);
18619 if (NULL == sta_session)
18620 return CDF_STATUS_E_FAILURE;
18621 new_roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
18622 *roam_id = new_roam_id;
18623 status = csr_roam_issue_connect(mac_ctx,
18624 sta_session->stored_roam_profile.session_id,
18625 &sta_session->stored_roam_profile.profile,
18626 sta_session->stored_roam_profile.bsslist_handle,
18627 sta_session->stored_roam_profile.reason,
18628 new_roam_id,
18629 sta_session->stored_roam_profile.imediate_flag,
18630 sta_session->stored_roam_profile.clear_flag);
18631 if (CDF_STATUS_SUCCESS != status) {
18632 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
18633 FL
18634 ("CSR failed issuing connect cmd with status = 0x%08X"),
18635 status);
18636 csr_clear_joinreq_param(mac_ctx, session_id);
18637 }
18638 return status;
18639}
18640
18641/**
18642 * csr_process_set_hw_mode() - Set HW mode command to PE
18643 * @mac: Globacl MAC pointer
18644 * @command: Command received from SME
18645 *
18646 * Posts the set HW mode command to PE. This message passing
18647 * through PE is required for PE's internal management
18648 *
18649 * Return: None
18650 */
18651void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
18652{
18653 uint32_t len;
18654 struct s_sir_set_hw_mode *cmd;
18655 CDF_STATUS status;
18656 tSirMsgQ msg;
18657 struct sir_set_hw_mode_resp *param;
18658
18659 /* Setting HW mode is for the entire system.
18660 * So, no need to check session
18661 */
18662
18663 if (!command) {
18664 sms_log(mac, LOGE, FL("Set HW mode param is NULL"));
18665 goto fail;
18666 }
18667
18668 len = sizeof(*cmd);
18669 cmd = cdf_mem_malloc(len);
18670 if (!cmd) {
18671 sms_log(mac, LOGE, FL("Memory allocation failed"));
18672 /* Probably the fail response will also fail during malloc.
18673 * Still proceeding to send response!
18674 */
18675 goto fail;
18676 }
18677
18678 cdf_mem_set(cmd, len, 0);
18679
18680 cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
18681 cmd->length = len;
18682 cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
18683 /*
18684 * Below callback and context info are not needed for PE as of now.
18685 * Storing the passed value in the same s_sir_set_hw_mode format.
18686 */
18687 cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb;
18688
18689 sms_log(mac, LOG1,
18690 FL("Posting eWNI_SME_SET_HW_MODE_REQ to PE"));
18691
18692 status = cds_send_mb_message_to_mac(cmd);
18693 if (CDF_STATUS_SUCCESS != status) {
18694 sms_log(mac, LOGE, FL("Posting to PE failed"));
18695 return;
18696 }
18697 return;
18698fail:
18699 param = cdf_mem_malloc(sizeof(*param));
18700 if (!param) {
18701 sms_log(mac, LOGE,
18702 FL("Malloc fail: Fail to send response to SME"));
18703 return;
18704 }
18705 sms_log(mac, LOGE, FL("Sending set HW fail response to SME"));
18706 param->status = SET_HW_MODE_STATUS_ECANCELED;
18707 param->cfgd_hw_mode_index = 0;
18708 param->num_vdev_mac_entries = 0;
18709 msg.type = eWNI_SME_SET_HW_MODE_RESP;
18710 msg.bodyptr = param;
18711 msg.bodyval = 0;
18712 sys_process_mmh_msg(mac, &msg);
18713}
18714
18715/**
18716 * csr_process_set_dual_mac_config() - Set HW mode command to PE
18717 * @mac: Global MAC pointer
18718 * @command: Command received from SME
18719 *
18720 * Posts the set dual mac config command to PE.
18721 *
18722 * Return: None
18723 */
18724void csr_process_set_dual_mac_config(tpAniSirGlobal mac, tSmeCmd *command)
18725{
18726 uint32_t len;
18727 struct sir_set_dual_mac_cfg *cmd;
18728 CDF_STATUS status;
18729 tSirMsgQ msg;
18730 struct sir_dual_mac_config_resp *param;
18731
18732 /* Setting MAC configuration is for the entire system.
18733 * So, no need to check session
18734 */
18735
18736 if (!command) {
18737 sms_log(mac, LOGE, FL("Set HW mode param is NULL"));
18738 goto fail;
18739 }
18740
18741 len = sizeof(*cmd);
18742 cmd = cdf_mem_malloc(len);
18743 if (!cmd) {
18744 sms_log(mac, LOGE, FL("Memory allocation failed"));
18745 /* Probably the fail response will also fail during malloc.
18746 * Still proceeding to send response!
18747 */
18748 goto fail;
18749 }
18750
18751 cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ;
18752 cmd->length = len;
18753 cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config;
18754 cmd->set_dual_mac.fw_mode_config =
18755 command->u.set_dual_mac_cmd.fw_mode_config;
18756 /*
18757 * Below callback and context info are not needed for PE as of now.
18758 * Storing the passed value in the same sir_set_dual_mac_cfg format.
18759 */
18760 cmd->set_dual_mac.set_dual_mac_cb =
18761 command->u.set_dual_mac_cmd.set_dual_mac_cb;
18762
18763 sms_log(mac, LOG1,
18764 FL("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x"),
18765 cmd->set_dual_mac.scan_config,
18766 cmd->set_dual_mac.fw_mode_config);
18767
18768 status = cds_send_mb_message_to_mac(cmd);
18769 if (CDF_STATUS_SUCCESS != status) {
18770 sms_log(mac, LOGE, FL("Posting to PE failed"));
18771 return;
18772 }
18773 return;
18774fail:
18775 param = cdf_mem_malloc(sizeof(*param));
18776 if (!param) {
18777 sms_log(mac, LOGE,
18778 FL("Malloc fail: Fail to send response to SME"));
18779 return;
18780 }
18781 sms_log(mac, LOGE, FL("Sending set dual mac fail response to SME"));
18782 param->status = SET_HW_MODE_STATUS_ECANCELED;
18783 msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
18784 msg.bodyptr = param;
18785 msg.bodyval = 0;
18786 sys_process_mmh_msg(mac, &msg);
18787}
18788
18789/**
18790 * csr_process_nss_update_req() - Update nss command to PE
18791 * @mac: Globacl MAC pointer
18792 * @command: Command received from SME
18793 *
18794 * Posts the nss update command to PE. This message passing
18795 * through PE is required for PE's internal management
18796 *
18797 * Return: None
18798 */
18799void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command)
18800{
18801 uint32_t len;
18802 struct sir_nss_update_request *msg;
18803 CDF_STATUS status;
18804 tSirMsgQ msg_return;
18805 struct sir_beacon_tx_complete_rsp *param;
18806
18807 tCsrRoamSession *session =
18808 CSR_GET_SESSION(mac, command->sessionId);
18809
18810 if (!session) {
18811 sms_log(mac, LOGE, FL("Session not found"));
18812 goto fail;
18813 }
18814
18815 if (!command) {
18816 sms_log(mac, LOGE, FL("nss update param is NULL"));
18817 goto fail;
18818 }
18819
18820 len = sizeof(*msg);
18821 msg = cdf_mem_malloc(len);
18822 if (!msg) {
18823 sms_log(mac, LOGE, FL("Memory allocation failed"));
18824 /* Probably the fail response is also fail during malloc.
18825 * Still proceeding to send response!
18826 */
18827 goto fail;
18828 }
18829
18830 cdf_mem_set((void *)msg, sizeof(*msg), 0);
18831 msg->msgType = eWNI_SME_NSS_UPDATE_REQ;
18832 msg->msgLen = sizeof(*msg);
18833
18834 msg->new_nss = command->u.nss_update_cmd.new_nss;
18835 msg->vdev_id = command->u.nss_update_cmd.session_id;
18836
18837 sms_log(mac, LOG1,
18838 FL("Posting eWNI_SME_NSS_UPDATE_REQ to PE"));
18839
18840 status = cds_send_mb_message_to_mac(msg);
18841 if (CDF_STATUS_SUCCESS != status) {
18842 sms_log(mac, LOGE, FL("Posting to PE failed"));
18843 return;
18844 }
18845 return;
18846fail:
18847 param = cdf_mem_malloc(sizeof(*param));
18848 if (!param) {
18849 sms_log(mac, LOGE,
18850 FL("Malloc fail: Fail to send response to SME"));
18851 return;
18852 }
18853 sms_log(mac, LOGE, FL("Sending nss update fail response to SME"));
18854 param->tx_status = CDF_STATUS_E_FAILURE;
18855 param->session_id = command->u.nss_update_cmd.session_id;
18856 msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
18857 msg_return.bodyptr = param;
18858 msg_return.bodyval = 0;
18859 sys_process_mmh_msg(mac, &msg_return);
18860}