1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * DOC: csr_api_roam.c
22 *
23 * Implementation for the Common Roaming interfaces.
24 */
25 #include "ani_global.h" /* for struct mac_context **/
26 #include "wma_types.h"
27 #include "wma_if.h" /* for STA_INVALID_IDX. */
28 #include "csr_inside_api.h"
29 #include <include/wlan_psoc_mlme.h>
30 #include "sme_trace.h"
31 #include "sme_qos_internal.h"
32 #include "sme_inside.h"
33 #include "host_diag_core_event.h"
34 #include "host_diag_core_log.h"
35 #include "csr_api.h"
36 #include "csr_internal.h"
37 #include "cds_reg_service.h"
38 #include "mac_trace.h"
39 #include "cds_regdomain.h"
40 #include "cds_utils.h"
41 #include "sir_types.h"
42 #include "cfg_ucfg_api.h"
43 #include "sme_power_save_api.h"
44 #include "wma.h"
45 #include "wlan_policy_mgr_api.h"
46 #include "sme_nan_datapath.h"
47 #include "pld_common.h"
48 #include "wlan_reg_services_api.h"
49 #include "qdf_crypto.h"
50 #include <wlan_logging_sock_svc.h>
51 #include "wlan_objmgr_psoc_obj.h"
52 #include <wlan_scan_ucfg_api.h>
53 #include <wlan_cp_stats_mc_ucfg_api.h>
54 #include <wlan_tdls_tgt_api.h>
55 #include <wlan_cfg80211_scan.h>
56 #include <wlan_scan_public_structs.h>
57 #include <wlan_action_oui_public_struct.h>
58 #include <wlan_action_oui_ucfg_api.h>
59 #include "wlan_mlme_api.h"
60 #include "wlan_mlme_ucfg_api.h"
61 #include <wlan_utility.h>
62 #include "cfg_mlme.h"
63 #include "wlan_mlme_public_struct.h"
64 #include <wlan_crypto_global_api.h>
65 #include "wlan_qct_sys.h"
66 #include "wlan_dlm_api.h"
67 #include "wlan_policy_mgr_i.h"
68 #include "wlan_scan_utils_api.h"
69 #include "wlan_p2p_cfg_api.h"
70 #include "cfg_nan_api.h"
71 #include "nan_ucfg_api.h"
72 #include <../../core/src/wlan_cm_vdev_api.h>
73 #include "wlan_reg_ucfg_api.h"
74
75 #include <ol_defines.h>
76 #include "wlan_pkt_capture_ucfg_api.h"
77 #include "wlan_psoc_mlme_api.h"
78 #include "wlan_cm_roam_api.h"
79 #include "wlan_if_mgr_public_struct.h"
80 #include "wlan_if_mgr_ucfg_api.h"
81 #include "wlan_if_mgr_roam.h"
82 #include "wlan_roam_debug.h"
83 #include "wlan_cm_roam_public_struct.h"
84 #include "wlan_mlme_twt_api.h"
85 #include <wlan_serialization_api.h>
86 #include <wlan_vdev_mlme_ser_if.h>
87 #include "wlan_mlo_mgr_sta.h"
88 #include "wlan_mlo_mgr_roam.h"
89
90 #define MAX_PWR_FCC_CHAN_12 8
91 #define MAX_PWR_FCC_CHAN_13 2
92 #define MAX_CB_VALUE_IN_INI (2)
93
94 #define MAX_SOCIAL_CHANNELS 3
95
96 /* packet dump timer duration of 60 secs */
97 #define PKT_DUMP_TIMER_DURATION 60
98
99 #ifdef WLAN_FEATURE_SAE
100 /**
101 * csr_sae_callback - Update SAE info to CSR roam session
102 * @mac_ctx: MAC context
103 * @msg_ptr: pointer to SAE message
104 *
105 * API to update SAE info to roam csr session
106 *
107 * Return: QDF_STATUS
108 */
csr_sae_callback(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)109 static QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx,
110 tSirSmeRsp *msg_ptr)
111 {
112 struct csr_roam_info *roam_info;
113 uint32_t session_id;
114 struct sir_sae_info *sae_info;
115
116 sae_info = (struct sir_sae_info *) msg_ptr;
117 if (!sae_info) {
118 sme_err("SAE info is NULL");
119 return QDF_STATUS_E_FAILURE;
120 }
121
122 sme_debug("vdev_id %d "QDF_MAC_ADDR_FMT,
123 sae_info->vdev_id,
124 QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes));
125
126 session_id = sae_info->vdev_id;
127 if (session_id == WLAN_UMAC_VDEV_ID_MAX)
128 return QDF_STATUS_E_INVAL;
129
130 roam_info = qdf_mem_malloc(sizeof(*roam_info));
131 if (!roam_info)
132 return QDF_STATUS_E_FAILURE;
133
134 roam_info->sae_info = sae_info;
135
136 csr_roam_call_callback(mac_ctx, session_id, roam_info,
137 eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE);
138 qdf_mem_free(roam_info);
139
140 return QDF_STATUS_SUCCESS;
141 }
142 #else
csr_sae_callback(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)143 static inline QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx,
144 tSirSmeRsp *msg_ptr)
145 {
146 return QDF_STATUS_SUCCESS;
147 }
148 #endif
149
150 static const uint32_t
151 social_channel_freq[MAX_SOCIAL_CHANNELS] = { 2412, 2437, 2462 };
152
153 static void init_config_param(struct mac_context *mac);
154 static QDF_STATUS csr_roam_open(struct mac_context *mac);
155 static QDF_STATUS csr_roam_close(struct mac_context *mac);
156 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo);
157 static QDF_STATUS csr_init_channel_power_list(struct mac_context *mac,
158 tCsr11dinfo *ps11dinfo);
159 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac,
160 struct csr_roam_connectedinfo *
161 pConnectedInfo);
162 static void csr_init_session(struct mac_context *mac, uint32_t sessionId);
163
164 static void csr_init_operating_classes(struct mac_context *mac);
165
166 static void csr_add_len_of_social_channels(struct mac_context *mac,
167 uint8_t *num_chan);
168 static void csr_add_social_channels(struct mac_context *mac,
169 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
170 uint8_t *num_chan);
171
172 #ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
173 static struct csr_roam_session *csr_roam_roam_session;
174
175 /* Allocate and initialize global variables */
csr_roam_init_globals(struct mac_context * mac)176 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac)
177 {
178 uint32_t buf_size;
179 QDF_STATUS status;
180
181 buf_size = WLAN_MAX_VDEVS * sizeof(struct csr_roam_session);
182
183 csr_roam_roam_session = qdf_mem_malloc(buf_size);
184 if (csr_roam_roam_session) {
185 mac->roam.roamSession = csr_roam_roam_session;
186 status = QDF_STATUS_SUCCESS;
187 } else {
188 status = QDF_STATUS_E_NOMEM;
189 }
190
191 return status;
192 }
193
194 /* Free memory allocated dynamically */
csr_roam_free_globals(void)195 static inline void csr_roam_free_globals(void)
196 {
197 qdf_mem_free(csr_roam_roam_session);
198 csr_roam_roam_session = NULL;
199 }
200
201 #else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
202 static struct csr_roam_session csr_roam_roam_session[WLAN_MAX_VDEVS];
203
204 /* Initialize global variables */
csr_roam_init_globals(struct mac_context * mac)205 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac)
206 {
207 qdf_mem_zero(&csr_roam_roam_session,
208 sizeof(csr_roam_roam_session));
209 mac->roam.roamSession = csr_roam_roam_session;
210
211 return QDF_STATUS_SUCCESS;
212 }
213
csr_roam_free_globals(void)214 static inline void csr_roam_free_globals(void)
215 {
216 }
217 #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
218
csr_roam_de_init_globals(struct mac_context * mac)219 static void csr_roam_de_init_globals(struct mac_context *mac)
220 {
221 csr_roam_free_globals();
222 mac->roam.roamSession = NULL;
223 }
224
225 /**
226 * csr_roam_lost_link - Process lost link indication
227 * @mac: MAC context
228 * @session_id: Session id of the current session
229 * @type: Type of the indication
230 * @sir_msg: sme response message
231 *
232 * Return: QDF_STATUS
233 */
234 static
csr_roam_lost_link(struct mac_context * mac,uint32_t session_id,uint32_t type,tSirSmeRsp * sir_msg)235 QDF_STATUS csr_roam_lost_link(struct mac_context *mac, uint32_t session_id,
236 uint32_t type, tSirSmeRsp *sir_msg)
237 {
238 QDF_STATUS status = QDF_STATUS_SUCCESS;
239 struct deauth_ind *deauth_ind_msg = NULL;
240 struct disassoc_ind *disassoc_ind_msg = NULL;
241
242 sme_debug("vdev_id %d type %d ", session_id, type);
243
244 if (type == eWNI_SME_DISASSOC_IND) {
245 disassoc_ind_msg = (struct disassoc_ind *)sir_msg;
246 status = csr_send_mb_disassoc_cnf_msg(mac, disassoc_ind_msg);
247 } else if (type == eWNI_SME_DEAUTH_IND) {
248 deauth_ind_msg = (struct deauth_ind *)sir_msg;
249 status = csr_send_mb_deauth_cnf_msg(mac, deauth_ind_msg);
250 }
251
252 return status;
253 }
254
255 /**
256 * csr_process_deauth_disassoc_cmd - Process deauth/disassoc command
257 * @mac: MAC context
258 * @sme_cmd: sme command which needs to be processed
259 *
260 * This function processes deauth or disassoc command
261 *
262 * Return: None
263 */
csr_process_deauth_disassoc_cmd(struct mac_context * mac,tSmeCmd * sme_cmd)264 static void csr_process_deauth_disassoc_cmd(struct mac_context *mac,
265 tSmeCmd *sme_cmd)
266 {
267 if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta) {
268 sme_debug("Disassoc vdev_id %d with reason: %d peer "
269 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
270 sme_cmd->u.roamCmd.reason,
271 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
272 csr_send_mb_disassoc_req_msg(mac, sme_cmd->vdev_id,
273 sme_cmd->u.roamCmd.peerMac,
274 sme_cmd->u.roamCmd.reason);
275 } else if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) {
276 sme_debug("Deauth vdev_id %d with reason: %d peer "
277 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
278 sme_cmd->u.roamCmd.reason,
279 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
280 csr_send_mb_deauth_req_msg(mac, sme_cmd->vdev_id,
281 sme_cmd->u.roamCmd.peerMac,
282 sme_cmd->u.roamCmd.reason);
283 } else {
284 sme_info("Invalid command, vdev_id %d reason: %d peer "
285 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
286 sme_cmd->u.roamCmd.reason,
287 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
288 }
289 }
290
291 /**
292 * csr_process_wmm_status_change_cmd - Process wmm status change command
293 * @mac: MAC context
294 * @sme_cmd: sme command which needs to be processed
295 *
296 * Return: None
297 */
csr_process_wmm_status_change_cmd(struct mac_context * mac,tSmeCmd * sme_cmd)298 static void csr_process_wmm_status_change_cmd(struct mac_context *mac,
299 tSmeCmd *sme_cmd)
300 {
301 QDF_STATUS status = QDF_STATUS_E_FAILURE;
302 tSirSmeRsp *sir_msg;
303
304 if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDisassociated) {
305 sir_msg =
306 (tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u.
307 DisassocIndMsg;
308 status = csr_roam_lost_link(mac, sme_cmd->vdev_id,
309 eWNI_SME_DISASSOC_IND,
310 sir_msg);
311 } else if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDeauthenticated) {
312 sir_msg = (tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u.
313 DeauthIndMsg;
314 status = csr_roam_lost_link(mac, sme_cmd->vdev_id,
315 eWNI_SME_DEAUTH_IND,
316 sir_msg);
317 }
318 if (QDF_IS_STATUS_ERROR(status)) {
319 sme_info("Failed to issue lost link command, status %d",
320 status);
321 /*
322 * As status returned is not success, there is nothing else
323 * left to do so release WM status change command here.
324 */
325 csr_roam_wm_status_change_complete(mac, sme_cmd->vdev_id);
326 }
327 }
328
329 /**
330 * csr_get_active_peer_disconnect_command - Get active peer disconnect command
331 * from serialization.
332 * @mac: MAC context
333 * @vdev_id: Vdev id for which active command needs to be return
334 *
335 * Return: None
336 */
csr_get_active_peer_disconnect_command(struct mac_context * mac,uint8_t vdev_id)337 static tSmeCmd *csr_get_active_peer_disconnect_command(struct mac_context *mac,
338 uint8_t vdev_id)
339 {
340 tSmeCmd *sme_cmd;
341
342 sme_cmd = wlan_serialization_get_active_cmd(
343 mac->psoc, vdev_id,
344 WLAN_SER_CMD_FORCE_DEAUTH_STA);
345 if (sme_cmd)
346 return sme_cmd;
347
348 sme_cmd = wlan_serialization_get_active_cmd(
349 mac->psoc, vdev_id,
350 WLAN_SER_CMD_FORCE_DISASSOC_STA);
351 if (sme_cmd)
352 return sme_cmd;
353
354 return wlan_serialization_get_active_cmd(mac->psoc, vdev_id,
355 WLAN_SER_CMD_WM_STATUS_CHANGE);
356 }
357
358 /**
359 * csr_continue_peer_disconnect_after_get_stats - Continue peer disconnect after
360 * getting peer disconnect stats
361 * @mac: MAC context
362 *
363 * Process the active serialization command after getting disconnect peer
364 * stats or after peer stats request gets timed out
365 *
366 * Return: None
367 */
368 static void
csr_continue_peer_disconnect_after_get_stats(struct mac_context * mac)369 csr_continue_peer_disconnect_after_get_stats(struct mac_context *mac)
370 {
371 tSmeCmd *sme_cmd;
372 QDF_STATUS status;
373 struct wlan_mlme_psoc_ext_obj *mlme_obj;
374
375 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
376 if (!mlme_obj) {
377 sme_err("NULL mlme psoc object");
378 return;
379 }
380
381 status = sme_acquire_global_lock(&mac->sme);
382 if (QDF_IS_STATUS_ERROR(status)) {
383 sme_err("can't acquire sme global lock");
384 return;
385 }
386
387 sme_cmd = csr_get_active_peer_disconnect_command(
388 mac,
389 mlme_obj->disconnect_stats_param.vdev_id);
390 if (!sme_cmd) {
391 sme_err("sme_cmd is NULL");
392 goto release_lock;
393 }
394
395 if (qdf_atomic_inc_return(
396 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed) >
397 1) {
398 sme_info("Command %d already in process", sme_cmd->command);
399 goto release_lock;
400 }
401
402 switch (sme_cmd->command) {
403 case eSmeCommandRoam:
404 csr_process_deauth_disassoc_cmd(mac, sme_cmd);
405 break;
406
407 case eSmeCommandWmStatusChange:
408 csr_process_wmm_status_change_cmd(mac, sme_cmd);
409 break;
410 default:
411 sme_info("Invalid command %d vdev_id %d", sme_cmd->command,
412 mlme_obj->disconnect_stats_param.vdev_id);
413 }
414 release_lock:
415 sme_release_global_lock(&mac->sme);
416 }
417
418 /**
419 * csr_disconnect_stats_timer_cb - Disconnect stats timer callback
420 * @user_data: Void pointer to mac context
421 *
422 * Return: None
423 */
csr_disconnect_stats_timer_cb(void * user_data)424 static void csr_disconnect_stats_timer_cb(void *user_data)
425 {
426 struct mac_context *mac = (struct mac_context *)user_data;
427
428 if (!mac) {
429 sme_err("Invalid mac ctx");
430 return;
431 }
432
433 sme_debug("Disconnect peer stats timed out");
434 csr_continue_peer_disconnect_after_get_stats(mac);
435 }
436
437 /**
438 * csr_init_disconnect_stats_timer - Init Disconnect stats timer
439 * @mac: MAC context
440 *
441 * Return: None
442 */
csr_init_disconnect_stats_timer(struct mac_context * mac)443 static void csr_init_disconnect_stats_timer(struct mac_context *mac)
444 {
445 struct wlan_mlme_psoc_ext_obj *mlme_obj;
446
447 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
448 if (!mlme_obj) {
449 sme_err("NULL mlme psoc object");
450 return;
451 }
452
453 qdf_mc_timer_init(&mlme_obj->disconnect_stats_param.disconn_stats_timer,
454 QDF_TIMER_TYPE_SW,
455 csr_disconnect_stats_timer_cb, mac);
456
457 qdf_atomic_init(
458 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed);
459 }
460
461 /**
462 * csr_deinit_disconnect_stats_timer - Deinit Disconnect stats timer
463 * @mac: MAC context
464 *
465 * Return: None
466 */
csr_deinit_disconnect_stats_timer(struct mac_context * mac)467 static void csr_deinit_disconnect_stats_timer(struct mac_context *mac)
468 {
469 struct wlan_mlme_psoc_ext_obj *mlme_obj;
470
471 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
472 if (!mlme_obj) {
473 sme_err("NULL mlme psoc object");
474 return;
475 }
476
477 if (QDF_TIMER_STATE_RUNNING ==
478 qdf_mc_timer_get_current_state(
479 &mlme_obj->disconnect_stats_param.disconn_stats_timer))
480 qdf_mc_timer_stop(
481 &mlme_obj->disconnect_stats_param.disconn_stats_timer);
482
483 qdf_mc_timer_destroy(
484 &mlme_obj->disconnect_stats_param.disconn_stats_timer);
485 }
486
csr_open(struct mac_context * mac)487 QDF_STATUS csr_open(struct mac_context *mac)
488 {
489 QDF_STATUS status = QDF_STATUS_SUCCESS;
490 uint32_t i;
491
492 do {
493 /* Initialize CSR Roam Globals */
494 status = csr_roam_init_globals(mac);
495 if (!QDF_IS_STATUS_SUCCESS(status))
496 break;
497
498 for (i = 0; i < WLAN_MAX_VDEVS; i++)
499 csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, i);
500
501 init_config_param(mac);
502 status = csr_scan_open(mac);
503 if (!QDF_IS_STATUS_SUCCESS(status)) {
504 csr_roam_free_globals();
505 break;
506 }
507 status = csr_roam_open(mac);
508 if (!QDF_IS_STATUS_SUCCESS(status)) {
509 csr_roam_free_globals();
510 break;
511 }
512 csr_init_disconnect_stats_timer(mac);
513 } while (0);
514
515 return status;
516 }
517
csr_init_chan_list(struct mac_context * mac)518 QDF_STATUS csr_init_chan_list(struct mac_context *mac)
519 {
520 QDF_STATUS status;
521 uint8_t reg_cc[REG_ALPHA2_LEN + 1];
522
523 wlan_reg_read_current_country(mac->psoc, reg_cc);
524 sme_debug("init time country code %.2s", reg_cc);
525
526 status = csr_get_channel_and_power_list(mac);
527
528 return status;
529 }
530
csr_set_channels(struct mac_context * mac,struct csr_config_params * pParam)531 QDF_STATUS csr_set_channels(struct mac_context *mac,
532 struct csr_config_params *pParam)
533 {
534 QDF_STATUS status = QDF_STATUS_SUCCESS;
535 uint8_t index = 0;
536
537 for (index = 0; index < mac->scan.base_channels.numChannels;
538 index++) {
539 pParam->Csr11dinfo.Channels.channel_freq_list[index] =
540 mac->scan.base_channels.channel_freq_list[index];
541 pParam->Csr11dinfo.ChnPower[index].first_chan_freq =
542 mac->scan.base_channels.channel_freq_list[index];
543 pParam->Csr11dinfo.ChnPower[index].numChannels = 1;
544 pParam->Csr11dinfo.ChnPower[index].maxtxPower =
545 mac->scan.defaultPowerTable[index].tx_power;
546 }
547 pParam->Csr11dinfo.Channels.numChannels =
548 mac->scan.base_channels.numChannels;
549
550 return status;
551 }
552
csr_close(struct mac_context * mac)553 QDF_STATUS csr_close(struct mac_context *mac)
554 {
555 QDF_STATUS status = QDF_STATUS_SUCCESS;
556
557 csr_deinit_disconnect_stats_timer(mac);
558
559 csr_roam_close(mac);
560 csr_scan_close(mac);
561 /* DeInit Globals */
562 csr_roam_de_init_globals(mac);
563 return status;
564 }
565
566 static int8_t
csr_find_channel_pwr(struct channel_power * pdefaultPowerTable,uint32_t chan_freq)567 csr_find_channel_pwr(struct channel_power *pdefaultPowerTable,
568 uint32_t chan_freq)
569 {
570 uint8_t i;
571 /* TODO: if defaultPowerTable is guaranteed to be in ascending */
572 /* order of channel numbers, we can employ binary search */
573 for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) {
574 if (pdefaultPowerTable[i].center_freq == chan_freq)
575 return pdefaultPowerTable[i].tx_power;
576 }
577 /* could not find the channel list in default list */
578 /* this should not have occurred */
579 QDF_ASSERT(0);
580 return 0;
581 }
582
583 /**
584 * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy
585 * order for 5 Ghz preference and DFS channels.
586 * @mac_ctx: pointer to mac context.
587 * @chan_list: channel list updated with greedy channel order.
588 * @num_channel: Number of channels in list
589 *
590 * To allow Early Stop Roaming Scan feature to co-exist with 5G preference,
591 * this function moves 5G channels ahead of 2G channels. This function can
592 * also move 2G channels, ahead of DFS channel or vice versa. Order is
593 * maintained among same category channels
594 *
595 * Return: None
596 */
csr_roam_arrange_ch_list(struct mac_context * mac_ctx,tSirUpdateChanParam * chan_list,uint8_t num_channel)597 static void csr_roam_arrange_ch_list(struct mac_context *mac_ctx,
598 tSirUpdateChanParam *chan_list, uint8_t num_channel)
599 {
600 bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx);
601 bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx);
602 int i, j = 0;
603 tSirUpdateChanParam *tmp_list = NULL;
604
605 if (!prefer_5g)
606 return;
607
608 tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel);
609 if (!tmp_list)
610 return;
611
612 /* Fist copy Non-DFS 5g channels */
613 for (i = 0; i < num_channel; i++) {
614 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq) &&
615 !wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
616 chan_list[i].freq)) {
617 qdf_mem_copy(&tmp_list[j++],
618 &chan_list[i], sizeof(tSirUpdateChanParam));
619 chan_list[i].freq = 0;
620 }
621 }
622 if (prefer_dfs) {
623 /* next copy DFS channels (remaining channels in 5G) */
624 for (i = 0; i < num_channel; i++) {
625 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq)) {
626 qdf_mem_copy(&tmp_list[j++], &chan_list[i],
627 sizeof(tSirUpdateChanParam));
628 chan_list[i].freq = 0;
629 }
630 }
631 } else {
632 /* next copy 2G channels */
633 for (i = 0; i < num_channel; i++) {
634 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_list[i].freq)) {
635 qdf_mem_copy(&tmp_list[j++], &chan_list[i],
636 sizeof(tSirUpdateChanParam));
637 chan_list[i].freq = 0;
638 }
639 }
640 }
641 /* copy rest of the channels in same order to tmp list */
642 for (i = 0; i < num_channel; i++) {
643 if (chan_list[i].freq) {
644 qdf_mem_copy(&tmp_list[j++], &chan_list[i],
645 sizeof(tSirUpdateChanParam));
646 chan_list[i].freq = 0;
647 }
648 }
649 /* copy tmp list to original channel list buffer */
650 qdf_mem_copy(chan_list, tmp_list,
651 sizeof(tSirUpdateChanParam) * num_channel);
652 qdf_mem_free(tmp_list);
653 }
654
655 /**
656 * csr_roam_sort_channel_for_early_stop() - Sort the channels
657 * @mac_ctx: mac global context
658 * @chan_list: Original channel list from the upper layers
659 * @num_channel: Number of original channels
660 *
661 * For Early stop scan feature, the channel list should be in an order,
662 * where-in there is a maximum chance to detect an AP in the initial
663 * channels in the list so that the scanning can be stopped early as the
664 * feature demands.
665 * Below fixed greedy channel list has been provided
666 * based on most of the enterprise wifi installations across the globe.
667 *
668 * Identify all the greedy channels within the channel list from user space.
669 * Identify all the non-greedy channels in the user space channel list.
670 * Merge greedy channels followed by non-greedy channels back into the
671 * chan_list.
672 *
673 * Return: None
674 */
csr_roam_sort_channel_for_early_stop(struct mac_context * mac_ctx,tSirUpdateChanList * chan_list,uint8_t num_channel)675 static void csr_roam_sort_channel_for_early_stop(struct mac_context *mac_ctx,
676 tSirUpdateChanList *chan_list, uint8_t num_channel)
677 {
678 tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy;
679 uint8_t i, j;
680 static const uint32_t fixed_greedy_freq_list[] = {2412, 2437, 2462,
681 5180, 5240, 5200, 5220, 2457, 2417, 2452, 5745, 5785, 5805,
682 2422, 2427, 2447, 5765, 5825, 2442, 2432, 5680, 5700, 5260,
683 5580, 5280, 5520, 5320, 5300, 5500, 5600, 2472, 2484, 5560,
684 5660, 5755, 5775};
685 uint8_t num_fixed_greedy_chan;
686 uint8_t num_greedy_chan = 0;
687 uint8_t num_non_greedy_chan = 0;
688 uint8_t match_found = false;
689 uint32_t buf_size;
690
691 buf_size = sizeof(tSirUpdateChanList) +
692 (sizeof(tSirUpdateChanParam) * num_channel);
693 chan_list_greedy = qdf_mem_malloc(buf_size);
694 chan_list_non_greedy = qdf_mem_malloc(buf_size);
695 if (!chan_list_greedy || !chan_list_non_greedy)
696 goto scan_list_sort_error;
697 /*
698 * fixed_greedy_freq_list is an evaluated freq list based on most of
699 * the enterprise wifi deployments and the order of the channels
700 * determines the highest possibility of finding an AP.
701 * chan_list is the channel list provided by upper layers based on the
702 * regulatory domain.
703 */
704 num_fixed_greedy_chan = sizeof(fixed_greedy_freq_list) /
705 sizeof(uint32_t);
706 /*
707 * Browse through the chan_list and put all the non-greedy channels
708 * into a separate list by name chan_list_non_greedy
709 */
710 for (i = 0; i < num_channel; i++) {
711 for (j = 0; j < num_fixed_greedy_chan; j++) {
712 if (chan_list->chanParam[i].freq ==
713 fixed_greedy_freq_list[j]) {
714 match_found = true;
715 break;
716 }
717 }
718 if (!match_found) {
719 qdf_mem_copy(
720 &chan_list_non_greedy->chanParam[num_non_greedy_chan],
721 &chan_list->chanParam[i],
722 sizeof(tSirUpdateChanParam));
723 num_non_greedy_chan++;
724 } else {
725 match_found = false;
726 }
727 }
728 /*
729 * Browse through the fixed_greedy_chan_list and put all the greedy
730 * channels in the chan_list into a separate list by name
731 * chan_list_greedy
732 */
733 for (i = 0; i < num_fixed_greedy_chan; i++) {
734 for (j = 0; j < num_channel; j++) {
735 if (fixed_greedy_freq_list[i] ==
736 chan_list->chanParam[j].freq) {
737 qdf_mem_copy(
738 &chan_list_greedy->chanParam[num_greedy_chan],
739 &chan_list->chanParam[j],
740 sizeof(tSirUpdateChanParam));
741 num_greedy_chan++;
742 break;
743 }
744 }
745 }
746 sme_debug("greedy=%d, non-greedy=%d, tot=%d", num_greedy_chan,
747 num_non_greedy_chan, num_channel);
748 if ((num_greedy_chan + num_non_greedy_chan) != num_channel) {
749 sme_err("incorrect sorting of channels");
750 goto scan_list_sort_error;
751 }
752 /* Copy the Greedy channels first */
753 i = 0;
754 qdf_mem_copy(&chan_list->chanParam[i],
755 &chan_list_greedy->chanParam[i],
756 num_greedy_chan * sizeof(tSirUpdateChanParam));
757 /* Copy the remaining Non Greedy channels */
758 i = num_greedy_chan;
759 j = 0;
760 qdf_mem_copy(&chan_list->chanParam[i],
761 &chan_list_non_greedy->chanParam[j],
762 num_non_greedy_chan * sizeof(tSirUpdateChanParam));
763
764 /* Update channel list for 5g preference and allow DFS roam */
765 csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel);
766 scan_list_sort_error:
767 qdf_mem_free(chan_list_greedy);
768 qdf_mem_free(chan_list_non_greedy);
769 }
770
771 /**
772 * csr_emu_chan_req() - update the required channel list for emulation
773 * @channel: channel number to check
774 *
775 * To reduce scan time during emulation platforms, this function
776 * restricts the scanning to be done on selected channels
777 *
778 * Return: QDF_STATUS enumeration
779 */
780 #ifdef QCA_WIFI_EMULATION
781 #define SCAN_CHAN_LIST_5G_LEN 6
782 #define SCAN_CHAN_LIST_2G_LEN 3
783 #define SCAN_CHAN_LIST_6G_LEN 3
784 static const uint16_t
785 csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 5180, 5220, 5260, 5280, 5700, 5745 };
786 static const uint16_t
787 csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 2412, 2437, 2462 };
788 static const uint16_t
789 csr_scan_chan_list_6g[SCAN_CHAN_LIST_6G_LEN] = { 6055, 6135, 6215 };
790
csr_emu_chan_req(uint32_t channel)791 static QDF_STATUS csr_emu_chan_req(uint32_t channel)
792 {
793 int i;
794
795 if (WLAN_REG_IS_24GHZ_CH_FREQ(channel)) {
796 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) {
797 if (csr_scan_chan_list_2g[i] == channel)
798 return QDF_STATUS_SUCCESS;
799 }
800 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(channel)) {
801 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) {
802 if (csr_scan_chan_list_5g[i] == channel)
803 return QDF_STATUS_SUCCESS;
804 }
805 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(channel)) {
806 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_6g); i++) {
807 if (csr_scan_chan_list_6g[i] == channel)
808 return QDF_STATUS_SUCCESS;
809 }
810 }
811 return QDF_STATUS_E_FAILURE;
812 }
813 #else
csr_emu_chan_req(uint32_t channel_num)814 static QDF_STATUS csr_emu_chan_req(uint32_t channel_num)
815 {
816 return QDF_STATUS_SUCCESS;
817 }
818 #endif
819
820 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
csr_add_len_of_social_channels(struct mac_context * mac,uint8_t * num_chan)821 static void csr_add_len_of_social_channels(struct mac_context *mac,
822 uint8_t *num_chan)
823 {
824 uint8_t i;
825 uint8_t no_chan = *num_chan;
826
827 sme_debug("add len of social channels, before adding - num_chan:%hu",
828 *num_chan);
829 if (CSR_IS_5G_BAND_ONLY(mac)) {
830 for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
831 if (wlan_reg_get_channel_state_for_pwrmode(
832 mac->pdev, social_channel_freq[i],
833 REG_CURRENT_PWR_MODE) ==
834 CHANNEL_STATE_ENABLE)
835 no_chan++;
836 }
837 }
838 *num_chan = no_chan;
839 sme_debug("after adding - num_chan:%hu", *num_chan);
840 }
841
csr_add_social_channels(struct mac_context * mac,tSirUpdateChanList * chan_list,struct csr_scanstruct * pScan,uint8_t * num_chan)842 static void csr_add_social_channels(struct mac_context *mac,
843 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
844 uint8_t *num_chan)
845 {
846 uint8_t i;
847 uint8_t no_chan = *num_chan;
848
849 sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list,
850 *num_chan);
851 if (CSR_IS_5G_BAND_ONLY(mac)) {
852 for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
853 if (wlan_reg_get_channel_state_for_pwrmode(
854 mac->pdev, social_channel_freq[i],
855 REG_CURRENT_PWR_MODE) !=
856 CHANNEL_STATE_ENABLE)
857 continue;
858 chan_list->chanParam[no_chan].freq =
859 social_channel_freq[i];
860 chan_list->chanParam[no_chan].pwr =
861 csr_find_channel_pwr(pScan->defaultPowerTable,
862 social_channel_freq[i]);
863 chan_list->chanParam[no_chan].dfsSet = false;
864 if (cds_is_5_mhz_enabled())
865 chan_list->chanParam[no_chan].quarter_rate
866 = 1;
867 else if (cds_is_10_mhz_enabled())
868 chan_list->chanParam[no_chan].half_rate = 1;
869 no_chan++;
870 }
871 sme_debug("after adding -num_chan %hu", no_chan);
872 }
873 *num_chan = no_chan;
874 }
875 #else
csr_add_len_of_social_channels(struct mac_context * mac,uint8_t * num_chan)876 static void csr_add_len_of_social_channels(struct mac_context *mac,
877 uint8_t *num_chan)
878 {
879 sme_debug("skip adding len of social channels");
880 }
csr_add_social_channels(struct mac_context * mac,tSirUpdateChanList * chan_list,struct csr_scanstruct * pScan,uint8_t * num_chan)881 static void csr_add_social_channels(struct mac_context *mac,
882 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
883 uint8_t *num_chan)
884 {
885 sme_debug("skip social channels");
886 }
887 #endif
888
889 /**
890 * csr_scan_event_handler() - callback for scan event
891 * @vdev: wlan objmgr vdev pointer
892 * @event: scan event
893 * @arg: global mac context pointer
894 *
895 * Return: void
896 */
csr_scan_event_handler(struct wlan_objmgr_vdev * vdev,struct scan_event * event,void * arg)897 static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev,
898 struct scan_event *event,
899 void *arg)
900 {
901 bool success = false;
902 QDF_STATUS lock_status;
903 struct mac_context *mac = arg;
904
905 if (!mac)
906 return;
907
908 if (!util_is_scan_completed(event, &success))
909 return;
910
911 lock_status = sme_acquire_global_lock(&mac->sme);
912 if (QDF_IS_STATUS_ERROR(lock_status))
913 return;
914
915 if (mac->scan.pending_channel_list_req)
916 csr_update_channel_list(mac);
917 sme_release_global_lock(&mac->sme);
918 }
919
920 /**
921 * csr_update_roam_pcl_per_connected_sta_vdev() - Update roam pcl per connected
922 * STA
923 * @psoc: pointer to psoc object
924 *
925 * Return: None
926 */
csr_update_roam_pcl_per_connected_sta_vdev(struct wlan_objmgr_psoc * psoc)927 static void csr_update_roam_pcl_per_connected_sta_vdev(
928 struct wlan_objmgr_psoc *psoc)
929 {
930 struct wlan_objmgr_vdev *vdev;
931 uint32_t vdev_id;
932
933 for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
934 vdev =
935 wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
936 WLAN_LEGACY_SME_ID);
937
938 if (!vdev)
939 continue;
940
941 if (vdev->vdev_mlme.vdev_opmode != QDF_STA_MODE)
942 goto next;
943
944 if (!wlan_cm_is_vdev_connected(vdev))
945 goto next;
946
947 policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE,
948 vdev_id);
949 next:
950 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
951 }
952 }
953
csr_update_channel_list(struct mac_context * mac)954 QDF_STATUS csr_update_channel_list(struct mac_context *mac)
955 {
956 tSirUpdateChanList *pChanList;
957 struct csr_scanstruct *pScan = &mac->scan;
958 uint8_t numChan = pScan->base_channels.numChannels;
959 uint8_t num_channel = 0;
960 uint32_t bufLen;
961 struct scheduler_msg msg = {0};
962 uint8_t i;
963 uint8_t channel_state;
964 uint16_t unsafe_chan[NUM_CHANNELS];
965 uint16_t unsafe_chan_cnt = 0;
966 uint16_t cnt = 0;
967 uint32_t channel_freq;
968 bool is_unsafe_chan;
969 bool is_same_band;
970 bool is_5mhz_enabled;
971 bool is_10mhz_enabled;
972 enum scm_scan_status scan_status;
973 QDF_STATUS lock_status;
974 struct rso_roam_policy_params *roam_policy;
975 struct wlan_mlme_psoc_ext_obj *mlme_obj;
976
977 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
978
979 if (!qdf_ctx)
980 return QDF_STATUS_E_FAILURE;
981
982 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
983 if (!mlme_obj)
984 return QDF_STATUS_E_FAILURE;
985 roam_policy = &mlme_obj->cfg.lfr.rso_user_config.policy_params;
986 lock_status = sme_acquire_global_lock(&mac->sme);
987 if (QDF_IS_STATUS_ERROR(lock_status))
988 return lock_status;
989
990 if (mac->mlme_cfg->reg.enable_pending_chan_list_req) {
991 scan_status = wlan_get_pdev_status(mac->pdev);
992 if (scan_status == SCAN_IS_ACTIVE ||
993 scan_status == SCAN_IS_ACTIVE_AND_PENDING) {
994 mac->scan.pending_channel_list_req = true;
995 sme_release_global_lock(&mac->sme);
996 sme_debug("scan in progress postpone channel list req ");
997 return QDF_STATUS_SUCCESS;
998 }
999 mac->scan.pending_channel_list_req = false;
1000 }
1001 sme_release_global_lock(&mac->sme);
1002
1003 pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
1004 &unsafe_chan_cnt,
1005 sizeof(unsafe_chan));
1006
1007 csr_add_len_of_social_channels(mac, &numChan);
1008
1009 bufLen = sizeof(tSirUpdateChanList) +
1010 (sizeof(tSirUpdateChanParam) * (numChan));
1011
1012 csr_init_operating_classes(mac);
1013 pChanList = qdf_mem_malloc(bufLen);
1014 if (!pChanList)
1015 return QDF_STATUS_E_NOMEM;
1016
1017 is_5mhz_enabled = cds_is_5_mhz_enabled();
1018 if (is_5mhz_enabled)
1019 sme_nofl_debug("quarter_rate enabled");
1020 is_10mhz_enabled = cds_is_10_mhz_enabled();
1021 if (is_10mhz_enabled)
1022 sme_nofl_debug("half_rate enabled");
1023
1024 for (i = 0; i < pScan->base_channels.numChannels; i++) {
1025 if (QDF_STATUS_SUCCESS !=
1026 csr_emu_chan_req(pScan->base_channels.channel_freq_list[i]))
1027 continue;
1028
1029 channel_freq = pScan->base_channels.channel_freq_list[i];
1030 /* Scan is not performed on DSRC channels*/
1031 if (wlan_reg_is_dsrc_freq(channel_freq))
1032 continue;
1033
1034 channel_state =
1035 wlan_reg_get_channel_state_for_pwrmode(
1036 mac->pdev, channel_freq,
1037 REG_CURRENT_PWR_MODE);
1038 if ((CHANNEL_STATE_ENABLE == channel_state) ||
1039 mac->scan.fEnableDFSChnlScan) {
1040 if (wlan_reg_is_6ghz_chan_freq(channel_freq) &&
1041 !wlan_reg_is_6ghz_band_set(mac->pdev)) {
1042 sme_debug("skip 6ghz frequency %d",
1043 channel_freq);
1044 continue;
1045 }
1046 if ((roam_policy->dfs_mode ==
1047 STA_ROAM_POLICY_DFS_DISABLED) &&
1048 (channel_state == CHANNEL_STATE_DFS)) {
1049 sme_debug("skip dfs channel frequency %d",
1050 channel_freq);
1051 continue;
1052 }
1053 if (roam_policy->skip_unsafe_channels &&
1054 unsafe_chan_cnt) {
1055 is_unsafe_chan = false;
1056 for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
1057 if (unsafe_chan[cnt] == channel_freq) {
1058 is_unsafe_chan = true;
1059 break;
1060 }
1061 }
1062 is_same_band =
1063 (WLAN_REG_IS_24GHZ_CH_FREQ(
1064 channel_freq) &&
1065 roam_policy->sap_operating_band ==
1066 BAND_2G) ||
1067 (WLAN_REG_IS_5GHZ_CH_FREQ(
1068 channel_freq) &&
1069 roam_policy->sap_operating_band ==
1070 BAND_5G);
1071 if (is_unsafe_chan && is_same_band) {
1072 sme_debug("ignoring unsafe channel freq %d",
1073 channel_freq);
1074 continue;
1075 }
1076 }
1077 pChanList->chanParam[num_channel].freq =
1078 pScan->base_channels.channel_freq_list[i];
1079 pChanList->chanParam[num_channel].pwr =
1080 csr_find_channel_pwr(
1081 pScan->defaultPowerTable,
1082 pScan->base_channels.channel_freq_list[i]);
1083
1084 if (pScan->fcc_constraint) {
1085 if (2467 ==
1086 pScan->base_channels.channel_freq_list[i]) {
1087 pChanList->chanParam[num_channel].pwr =
1088 MAX_PWR_FCC_CHAN_12;
1089 sme_debug("txpow for channel 12 is %d",
1090 MAX_PWR_FCC_CHAN_12);
1091 }
1092 if (2472 ==
1093 pScan->base_channels.channel_freq_list[i]) {
1094 pChanList->chanParam[num_channel].pwr =
1095 MAX_PWR_FCC_CHAN_13;
1096 sme_debug("txpow for channel 13 is %d",
1097 MAX_PWR_FCC_CHAN_13);
1098 }
1099 }
1100
1101 if (!ucfg_is_nan_allowed_on_freq(mac->pdev,
1102 pChanList->chanParam[num_channel].freq))
1103 pChanList->chanParam[num_channel].nan_disabled =
1104 true;
1105
1106 if (CHANNEL_STATE_DFS == channel_state)
1107 pChanList->chanParam[num_channel].dfsSet =
1108 true;
1109
1110 pChanList->chanParam[num_channel].quarter_rate =
1111 is_5mhz_enabled;
1112
1113 pChanList->chanParam[num_channel].half_rate =
1114 is_10mhz_enabled;
1115
1116 num_channel++;
1117 }
1118 }
1119
1120 csr_add_social_channels(mac, pChanList, pScan, &num_channel);
1121
1122 if (mac->mlme_cfg->lfr.early_stop_scan_enable)
1123 csr_roam_sort_channel_for_early_stop(mac, pChanList,
1124 num_channel);
1125 else
1126 sme_debug("Early Stop Scan Feature not supported");
1127
1128 if ((mac->roam.configParam.uCfgDot11Mode ==
1129 eCSR_CFG_DOT11_MODE_AUTO) ||
1130 (mac->roam.configParam.uCfgDot11Mode ==
1131 eCSR_CFG_DOT11_MODE_11AC) ||
1132 (mac->roam.configParam.uCfgDot11Mode ==
1133 eCSR_CFG_DOT11_MODE_11AC_ONLY)) {
1134 pChanList->vht_en = true;
1135 if (mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band)
1136 pChanList->vht_24_en = true;
1137 }
1138 if ((mac->roam.configParam.uCfgDot11Mode ==
1139 eCSR_CFG_DOT11_MODE_AUTO) ||
1140 (mac->roam.configParam.uCfgDot11Mode ==
1141 eCSR_CFG_DOT11_MODE_11N) ||
1142 (mac->roam.configParam.uCfgDot11Mode ==
1143 eCSR_CFG_DOT11_MODE_11N_ONLY)) {
1144 pChanList->ht_en = true;
1145 }
1146 if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
1147 (mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) ||
1148 (mac->roam.configParam.uCfgDot11Mode ==
1149 eCSR_CFG_DOT11_MODE_11AX_ONLY))
1150 pChanList->he_en = true;
1151 #ifdef WLAN_FEATURE_11BE
1152 if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
1153 CSR_IS_CFG_DOT11_PHY_MODE_11BE(
1154 mac->roam.configParam.uCfgDot11Mode) ||
1155 CSR_IS_CFG_DOT11_PHY_MODE_11BE_ONLY(
1156 mac->roam.configParam.uCfgDot11Mode))
1157 pChanList->eht_en = true;
1158 #endif
1159
1160 pChanList->numChan = num_channel;
1161 mlme_store_fw_scan_channels(mac->psoc, pChanList);
1162
1163 msg.type = WMA_UPDATE_CHAN_LIST_REQ;
1164 msg.reserved = 0;
1165 msg.bodyptr = pChanList;
1166 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
1167 NO_SESSION, msg.type));
1168 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
1169 QDF_MODULE_ID_WMA,
1170 QDF_MODULE_ID_WMA,
1171 &msg)) {
1172 qdf_mem_free(pChanList);
1173 return QDF_STATUS_E_FAILURE;
1174 }
1175
1176 csr_update_roam_pcl_per_connected_sta_vdev(mac->psoc);
1177 return QDF_STATUS_SUCCESS;
1178 }
1179
csr_start(struct mac_context * mac)1180 QDF_STATUS csr_start(struct mac_context *mac)
1181 {
1182 QDF_STATUS status = QDF_STATUS_SUCCESS;
1183 uint32_t i;
1184
1185 do {
1186 for (i = 0; i < WLAN_MAX_VDEVS; i++)
1187 csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, i);
1188
1189 mac->roam.sPendingCommands = 0;
1190
1191 if (mac->mlme_cfg->reg.enable_pending_chan_list_req) {
1192 status = ucfg_scan_register_event_handler(mac->pdev,
1193 csr_scan_event_handler, mac);
1194
1195 if (QDF_IS_STATUS_ERROR(status))
1196 sme_err("scan event registration failed ");
1197 }
1198 } while (0);
1199 return status;
1200 }
1201
csr_stop(struct mac_context * mac)1202 QDF_STATUS csr_stop(struct mac_context *mac)
1203 {
1204 uint32_t sessionId;
1205
1206 if (mac->mlme_cfg->reg.enable_pending_chan_list_req)
1207 ucfg_scan_unregister_event_handler(mac->pdev,
1208 csr_scan_event_handler,
1209 mac);
1210 wlan_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN);
1211
1212 /*
1213 * purge all serialization command if there are any pending to make
1214 * sure memory and vdev ref are freed.
1215 */
1216 csr_purge_pdev_all_ser_cmd_list(mac);
1217 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++)
1218 csr_cleanup_vdev_session(mac, sessionId);
1219
1220 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++)
1221 if (CSR_IS_SESSION_VALID(mac, sessionId))
1222 ucfg_scan_flush_results(mac->pdev, NULL);
1223
1224 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) {
1225 csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, sessionId);
1226 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
1227 sessionId);
1228 }
1229
1230 return QDF_STATUS_SUCCESS;
1231 }
1232
csr_ready(struct mac_context * mac)1233 QDF_STATUS csr_ready(struct mac_context *mac)
1234 {
1235 QDF_STATUS status = QDF_STATUS_SUCCESS;
1236 /* If the gScanAgingTime is set to '0' then scan results aging timeout
1237 * based on timer feature is not enabled
1238 */
1239 status = csr_apply_channel_and_power_list(mac);
1240 if (!QDF_IS_STATUS_SUCCESS(status))
1241 sme_err("csr_apply_channel_and_power_list failed status: %d",
1242 status);
1243
1244 return status;
1245 }
1246
csr_set_default_dot11_mode(struct mac_context * mac)1247 void csr_set_default_dot11_mode(struct mac_context *mac)
1248 {
1249 mac->mlme_cfg->dot11_mode.dot11_mode =
1250 csr_translate_to_wni_cfg_dot11_mode(mac,
1251 mac->roam.configParam.uCfgDot11Mode);
1252 }
1253
csr_set_global_cfgs(struct mac_context * mac)1254 void csr_set_global_cfgs(struct mac_context *mac)
1255 {
1256 wlan_mlme_set_frag_threshold(mac->psoc, csr_get_frag_thresh(mac));
1257 wlan_mlme_set_rts_threshold(mac->psoc, csr_get_rts_thresh(mac));
1258 /* For now we will just use the 5GHz CB mode ini parameter to decide
1259 * whether CB supported or not in Probes when there is no session
1260 * Once session is established we will use the session related params
1261 * stored in PE session for CB mode
1262 */
1263 if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_5GHZ,
1264 mac->roam.configParam.channelBondingMode5GHz))
1265 ucfg_mlme_set_channel_bonding_5ghz(mac->psoc,
1266 mac->roam.configParam.
1267 channelBondingMode5GHz);
1268 if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_24GHZ,
1269 mac->roam.configParam.channelBondingMode24GHz))
1270 ucfg_mlme_set_channel_bonding_24ghz(mac->psoc,
1271 mac->roam.configParam.
1272 channelBondingMode24GHz);
1273
1274 mac->mlme_cfg->timeouts.heart_beat_threshold =
1275 cfg_default(CFG_HEART_BEAT_THRESHOLD);
1276
1277 /* Update the operating mode to configured value during
1278 * initialization, So that client can advertise full
1279 * capabilities in Probe request frame.
1280 */
1281 csr_set_default_dot11_mode(mac);
1282 }
1283
1284 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \
1285 defined(CONNECTIVITY_PKTLOG)
1286 /**
1287 * csr_packetdump_timer_handler() - packet dump timer
1288 * handler
1289 * @pv: user data
1290 *
1291 * This function is used to handle packet dump timer
1292 *
1293 * Return: None
1294 *
1295 */
csr_packetdump_timer_handler(void * pv)1296 static void csr_packetdump_timer_handler(void *pv)
1297 {
1298 sme_debug("Invoking packetdump deregistration API");
1299 wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID);
1300 }
1301
csr_packetdump_timer_start(void)1302 void csr_packetdump_timer_start(void)
1303 {
1304 QDF_STATUS status;
1305 mac_handle_t mac_handle;
1306 struct mac_context *mac;
1307 QDF_TIMER_STATE cur_state;
1308
1309 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1310 mac = MAC_CONTEXT(mac_handle);
1311 if (!mac) {
1312 QDF_ASSERT(0);
1313 return;
1314 }
1315 cur_state = qdf_mc_timer_get_current_state(&mac->roam.packetdump_timer);
1316 if (cur_state == QDF_TIMER_STATE_STARTING ||
1317 cur_state == QDF_TIMER_STATE_STARTING) {
1318 sme_debug("packetdump_timer is already started: %d", cur_state);
1319 return;
1320 }
1321
1322 status = qdf_mc_timer_start(&mac->roam.packetdump_timer,
1323 (PKT_DUMP_TIMER_DURATION *
1324 QDF_MC_TIMER_TO_SEC_UNIT) /
1325 QDF_MC_TIMER_TO_MS_UNIT);
1326 if (!QDF_IS_STATUS_SUCCESS(status))
1327 sme_debug("cannot start packetdump timer status: %d", status);
1328 }
1329
csr_packetdump_timer_stop(void)1330 void csr_packetdump_timer_stop(void)
1331 {
1332 QDF_STATUS status;
1333 mac_handle_t mac_handle;
1334 struct mac_context *mac;
1335
1336 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1337 mac = MAC_CONTEXT(mac_handle);
1338 if (!mac) {
1339 QDF_ASSERT(0);
1340 return;
1341 }
1342
1343 status = qdf_mc_timer_stop(&mac->roam.packetdump_timer);
1344 if (!QDF_IS_STATUS_SUCCESS(status))
1345 sme_err("cannot stop packetdump timer");
1346 }
1347
csr_packetdump_timer_init(struct mac_context * mac)1348 static QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac)
1349 {
1350 QDF_STATUS status = QDF_STATUS_SUCCESS;
1351
1352 if (!mac) {
1353 QDF_ASSERT(0);
1354 return -EINVAL;
1355 }
1356
1357 status = qdf_mc_timer_init(&mac->roam.packetdump_timer,
1358 QDF_TIMER_TYPE_SW,
1359 csr_packetdump_timer_handler,
1360 mac);
1361 if (!QDF_IS_STATUS_SUCCESS(status)) {
1362 sme_err("cannot allocate memory for packetdump timer");
1363 return status;
1364 }
1365
1366 return status;
1367 }
1368
csr_packetdump_timer_deinit(struct mac_context * mac)1369 static void csr_packetdump_timer_deinit(struct mac_context *mac)
1370 {
1371 if (!mac) {
1372 QDF_ASSERT(0);
1373 return;
1374 }
1375
1376 qdf_mc_timer_stop(&mac->roam.packetdump_timer);
1377 qdf_mc_timer_destroy(&mac->roam.packetdump_timer);
1378 }
1379 #else
csr_packetdump_timer_init(struct mac_context * mac)1380 static inline QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac)
1381 {
1382 return QDF_STATUS_SUCCESS;
1383 }
1384
csr_packetdump_timer_deinit(struct mac_context * mac)1385 static inline void csr_packetdump_timer_deinit(struct mac_context *mac) {}
1386 #endif
1387
csr_roam_open(struct mac_context * mac)1388 static QDF_STATUS csr_roam_open(struct mac_context *mac)
1389 {
1390 QDF_STATUS status = QDF_STATUS_SUCCESS;
1391
1392 status = csr_packetdump_timer_init(mac);
1393 if (QDF_IS_STATUS_ERROR(status))
1394 return status;
1395
1396 spin_lock_init(&mac->roam.roam_state_lock);
1397
1398 return status;
1399 }
1400
csr_roam_close(struct mac_context * mac)1401 static QDF_STATUS csr_roam_close(struct mac_context *mac)
1402 {
1403 uint32_t sessionId;
1404 struct csr_roam_session *session;
1405
1406 /*
1407 * purge all serialization command if there are any pending to make
1408 * sure memory and vdev ref are freed.
1409 */
1410 csr_purge_pdev_all_ser_cmd_list(mac);
1411 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) {
1412 session = CSR_GET_SESSION(mac, sessionId);
1413 if (!session)
1414 continue;
1415 csr_cleanup_vdev_session(mac, sessionId);
1416 }
1417
1418 csr_packetdump_timer_deinit(mac);
1419 return QDF_STATUS_SUCCESS;
1420 }
1421
csr_roam_free_connected_info(struct mac_context * mac,struct csr_roam_connectedinfo * pConnectedInfo)1422 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac,
1423 struct csr_roam_connectedinfo *
1424 pConnectedInfo)
1425 {
1426 QDF_STATUS status = QDF_STATUS_SUCCESS;
1427
1428 if (pConnectedInfo->pbFrames) {
1429 qdf_mem_free(pConnectedInfo->pbFrames);
1430 pConnectedInfo->pbFrames = NULL;
1431 }
1432 pConnectedInfo->nBeaconLength = 0;
1433 pConnectedInfo->nAssocReqLength = 0;
1434 pConnectedInfo->nAssocRspLength = 0;
1435 pConnectedInfo->nRICRspLength = 0;
1436 #ifdef FEATURE_WLAN_ESE
1437 pConnectedInfo->nTspecIeLength = 0;
1438 #endif
1439 return status;
1440 }
1441
csr_release_command_roam(struct mac_context * mac,tSmeCmd * pCommand)1442 void csr_release_command_roam(struct mac_context *mac, tSmeCmd *pCommand)
1443 {
1444 csr_reinit_roam_cmd(mac, pCommand);
1445 }
1446
csr_release_command_wm_status_change(struct mac_context * mac,tSmeCmd * pCommand)1447 void csr_release_command_wm_status_change(struct mac_context *mac,
1448 tSmeCmd *pCommand)
1449 {
1450 csr_reinit_wm_status_change_cmd(mac, pCommand);
1451 }
1452
csr_roam_substate_change(struct mac_context * mac,enum csr_roam_substate NewSubstate,uint32_t sessionId)1453 void csr_roam_substate_change(struct mac_context *mac,
1454 enum csr_roam_substate NewSubstate, uint32_t sessionId)
1455 {
1456 if (sessionId >= WLAN_MAX_VDEVS) {
1457 sme_err("Invalid no of concurrent sessions %d",
1458 sessionId);
1459 return;
1460 }
1461 if (mac->roam.curSubState[sessionId] == NewSubstate)
1462 return;
1463 sme_nofl_debug("CSR RoamSubstate: [ %s <== %s ]",
1464 mac_trace_getcsr_roam_sub_state(NewSubstate),
1465 mac_trace_getcsr_roam_sub_state(mac->roam.
1466 curSubState[sessionId]));
1467 spin_lock(&mac->roam.roam_state_lock);
1468 mac->roam.curSubState[sessionId] = NewSubstate;
1469 spin_unlock(&mac->roam.roam_state_lock);
1470 }
1471
csr_roam_state_change(struct mac_context * mac,enum csr_roam_state NewRoamState,uint8_t sessionId)1472 enum csr_roam_state csr_roam_state_change(struct mac_context *mac,
1473 enum csr_roam_state NewRoamState,
1474 uint8_t sessionId)
1475 {
1476 enum csr_roam_state PreviousState;
1477
1478 PreviousState = mac->roam.curState[sessionId];
1479
1480 if (NewRoamState == mac->roam.curState[sessionId])
1481 return PreviousState;
1482
1483 sme_nofl_debug("CSR RoamState[%d]: [ %s <== %s ]", sessionId,
1484 mac_trace_getcsr_roam_state(NewRoamState),
1485 mac_trace_getcsr_roam_state(
1486 mac->roam.curState[sessionId]));
1487 /*
1488 * Whenever we transition OUT of the Roaming state,
1489 * clear the Roaming substate.
1490 */
1491 if (CSR_IS_ROAM_JOINING(mac, sessionId)) {
1492 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
1493 sessionId);
1494 }
1495
1496 mac->roam.curState[sessionId] = NewRoamState;
1497
1498 return PreviousState;
1499 }
1500
init_config_param(struct mac_context * mac)1501 static void init_config_param(struct mac_context *mac)
1502 {
1503 mac->roam.configParam.channelBondingMode24GHz =
1504 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
1505 mac->roam.configParam.channelBondingMode5GHz =
1506 WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
1507
1508 mac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO;
1509 mac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
1510 mac->roam.configParam.HeartbeatThresh50 = 40;
1511 mac->roam.configParam.Is11eSupportEnabled = true;
1512 mac->roam.configParam.WMMSupportMode = WMM_USER_MODE_AUTO;
1513 mac->roam.configParam.ProprietaryRatesEnabled = true;
1514
1515 mac->roam.configParam.nVhtChannelWidth =
1516 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
1517 }
1518
1519 /**
1520 * csr_flush_roam_scan_chan_lists() - Flush the roam channel lists
1521 * @mac: Global MAC context
1522 * @vdev_id: vdev id
1523 *
1524 * Flush the roam channel lists pref_chan_info and specific_chan_info.
1525 *
1526 * Return: None
1527 */
1528 static void
csr_flush_roam_scan_chan_lists(struct mac_context * mac,uint8_t vdev_id)1529 csr_flush_roam_scan_chan_lists(struct mac_context *mac, uint8_t vdev_id)
1530 {
1531 struct wlan_objmgr_vdev *vdev;
1532 struct rso_config *rso_cfg;
1533 struct rso_cfg_params *cfg_params;
1534
1535 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
1536 WLAN_LEGACY_SME_ID);
1537 if (!vdev)
1538 return;
1539
1540 rso_cfg = wlan_cm_get_rso_config(vdev);
1541 if (!rso_cfg) {
1542 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1543 return;
1544 }
1545 cfg_params = &rso_cfg->cfg_param;
1546 wlan_cm_flush_roam_channel_list(&cfg_params->pref_chan_info);
1547 wlan_cm_flush_roam_channel_list(&cfg_params->specific_chan_info);
1548 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1549 }
1550
1551 #ifdef FEATURE_WLAN_ESE
1552 /**
1553 * csr_roam_is_ese_assoc() - is this ese association
1554 * @mac_ctx: Global MAC context
1555 * @session_id: session identifier
1556 *
1557 * Returns whether the current association is a ESE assoc or not.
1558 *
1559 * Return: true if ese association; false otherwise
1560 */
csr_roam_is_ese_assoc(struct mac_context * mac_ctx,uint32_t session_id)1561 bool csr_roam_is_ese_assoc(struct mac_context *mac_ctx, uint32_t session_id)
1562 {
1563 return wlan_cm_get_ese_assoc(mac_ctx->pdev, session_id);
1564 }
1565
1566
1567 /**
1568 * csr_tsm_stats_rsp_processor() - tsm stats response processor
1569 * @mac: Global MAC context
1570 * @pMsg: Message pointer
1571 *
1572 * Return: None
1573 */
csr_tsm_stats_rsp_processor(struct mac_context * mac,void * pMsg)1574 static void csr_tsm_stats_rsp_processor(struct mac_context *mac, void *pMsg)
1575 {
1576 tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg;
1577
1578 if (pTsmStatsRsp) {
1579 /*
1580 * Get roam Rssi request is backed up and passed back
1581 * to the response, Extract the request message
1582 * to fetch callback.
1583 */
1584 tpAniGetTsmStatsReq reqBkp
1585 = (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq;
1586
1587 if (reqBkp) {
1588 if (reqBkp->tsmStatsCallback) {
1589 ((tCsrTsmStatsCallback)
1590 (reqBkp->tsmStatsCallback))(pTsmStatsRsp->
1591 tsmMetrics,
1592 reqBkp->
1593 pDevContext);
1594 reqBkp->tsmStatsCallback = NULL;
1595 }
1596 qdf_mem_free(reqBkp);
1597 pTsmStatsRsp->tsmStatsReq = NULL;
1598 } else {
1599 if (reqBkp) {
1600 qdf_mem_free(reqBkp);
1601 pTsmStatsRsp->tsmStatsReq = NULL;
1602 }
1603 }
1604 } else {
1605 sme_err("pTsmStatsRsp is NULL");
1606 }
1607 }
1608
1609 /**
1610 * csr_send_ese_adjacent_ap_rep_ind() - ese send adjacent ap report
1611 * @mac: Global MAC context
1612 * @pSession: Session pointer
1613 *
1614 * Return: None
1615 */
csr_send_ese_adjacent_ap_rep_ind(struct mac_context * mac,struct csr_roam_session * pSession)1616 static void csr_send_ese_adjacent_ap_rep_ind(struct mac_context *mac,
1617 struct csr_roam_session *pSession)
1618 {
1619 uint32_t roamTS2 = 0;
1620 struct csr_roam_info *roam_info;
1621 struct pe_session *pe_session = NULL;
1622 uint8_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
1623 struct qdf_mac_addr connected_bssid;
1624
1625 if (!pSession) {
1626 sme_err("pSession is NULL");
1627 return;
1628 }
1629
1630 roam_info = qdf_mem_malloc(sizeof(*roam_info));
1631 if (!roam_info)
1632 return;
1633 roamTS2 = qdf_mc_timer_get_system_time();
1634 roam_info->tsmRoamDelay = roamTS2 - pSession->roamTS1;
1635 wlan_mlme_get_bssid_vdev_id(mac->pdev, pSession->vdev_id,
1636 &connected_bssid);
1637 sme_debug("Bssid(" QDF_MAC_ADDR_FMT ") Roaming Delay(%u ms)",
1638 QDF_MAC_ADDR_REF(connected_bssid.bytes),
1639 roam_info->tsmRoamDelay);
1640
1641 pe_session = pe_find_session_by_bssid(mac, connected_bssid.bytes,
1642 &sessionId);
1643 if (!pe_session) {
1644 sme_err("session %d not found", sessionId);
1645 qdf_mem_free(roam_info);
1646 return;
1647 }
1648
1649 pe_session->eseContext.tsm.tsmMetrics.RoamingDly
1650 = roam_info->tsmRoamDelay;
1651
1652 csr_roam_call_callback(mac, pSession->vdev_id, roam_info,
1653 eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0);
1654 qdf_mem_free(roam_info);
1655 }
1656
1657 /**
1658 * csr_get_tsm_stats() - get tsm stats
1659 * @mac: Global MAC context
1660 * @callback: TSM stats callback
1661 * @staId: Station id
1662 * @bssId: bssid
1663 * @pContext: pointer to context
1664 * @tid: traffic id
1665 *
1666 * Return: QDF_STATUS enumeration
1667 */
csr_get_tsm_stats(struct mac_context * mac,tCsrTsmStatsCallback callback,struct qdf_mac_addr bssId,void * pContext,uint8_t tid)1668 QDF_STATUS csr_get_tsm_stats(struct mac_context *mac,
1669 tCsrTsmStatsCallback callback,
1670 struct qdf_mac_addr bssId,
1671 void *pContext, uint8_t tid)
1672 {
1673 QDF_STATUS status = QDF_STATUS_SUCCESS;
1674 tAniGetTsmStatsReq *pMsg = NULL;
1675
1676 pMsg = qdf_mem_malloc(sizeof(tAniGetTsmStatsReq));
1677 if (!pMsg) {
1678 return QDF_STATUS_E_NOMEM;
1679 }
1680 /* need to initiate a stats request to PE */
1681 pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ;
1682 pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq);
1683 pMsg->tid = tid;
1684 qdf_copy_macaddr(&pMsg->bssId, &bssId);
1685 pMsg->tsmStatsCallback = callback;
1686 pMsg->pDevContext = pContext;
1687 status = umac_send_mb_message_to_mac(pMsg);
1688 if (!QDF_IS_STATUS_SUCCESS(status)) {
1689 sme_debug("Failed to send down the TSM req (status=%d)", status);
1690 /* pMsg is freed by cds_send_mb_message_to_mac */
1691 status = QDF_STATUS_E_FAILURE;
1692 }
1693 return status;
1694 }
1695 #endif /* FEATURE_WLAN_ESE */
1696
1697 /* The funcns csr_convert_cb_ini_value_to_phy_cb_state and
1698 * csr_convert_phy_cb_state_to_ini_value have been introduced
1699 * to convert the ini value to the ENUM used in csr and MAC for CB state
1700 * Ideally we should have kept the ini value and enum value same and
1701 * representing the same cb values as in 11n standard i.e.
1702 * Set to 1 (SCA) if the secondary channel is above the primary channel
1703 * Set to 3 (SCB) if the secondary channel is below the primary channel
1704 * Set to 0 (SCN) if no secondary channel is present
1705 * However, since our driver is already distributed we will keep the ini
1706 * definition as it is which is:
1707 * 0 - secondary none
1708 * 1 - secondary LOW
1709 * 2 - secondary HIGH
1710 * and convert to enum value used within the driver in
1711 * csr_change_default_config_param using this funcn
1712 * The enum values are as follows:
1713 * PHY_SINGLE_CHANNEL_CENTERED = 0
1714 * PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1
1715 * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3
1716 */
csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)1717 ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)
1718 {
1719
1720 ePhyChanBondState phyCbState;
1721
1722 switch (cbIniValue) {
1723 /* secondary none */
1724 case eCSR_INI_SINGLE_CHANNEL_CENTERED:
1725 phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1726 break;
1727 /* secondary LOW */
1728 case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
1729 phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1730 break;
1731 /* secondary HIGH */
1732 case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
1733 phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1734 break;
1735 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1736 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1737 break;
1738 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1739 phyCbState =
1740 PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1741 break;
1742 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1743 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1744 break;
1745 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1746 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1747 break;
1748 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1749 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1750 break;
1751 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1752 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1753 break;
1754 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1755 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1756 break;
1757 default:
1758 /* If an invalid value is passed, disable CHANNEL BONDING */
1759 phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1760 break;
1761 }
1762 return phyCbState;
1763 }
1764
1765 static
csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)1766 uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)
1767 {
1768 uint32_t cbIniValue;
1769
1770 switch (phyCbState) {
1771 /* secondary none */
1772 case PHY_SINGLE_CHANNEL_CENTERED:
1773 cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED;
1774 break;
1775 /* secondary LOW */
1776 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1777 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
1778 break;
1779 /* secondary HIGH */
1780 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1781 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
1782 break;
1783 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1784 cbIniValue =
1785 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1786 break;
1787 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1788 cbIniValue =
1789 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1790 break;
1791 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1792 cbIniValue =
1793 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1794 break;
1795 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1796 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1797 break;
1798 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1799 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1800 break;
1801 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1802 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1803 break;
1804 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1805 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1806 break;
1807 default:
1808 /* return some invalid value */
1809 cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX;
1810 break;
1811 }
1812 return cbIniValue;
1813 }
1814
1815 #ifdef WLAN_FEATURE_11BE
csr_update_session_eht_cap(struct mac_context * mac_ctx,struct csr_roam_session * session)1816 void csr_update_session_eht_cap(struct mac_context *mac_ctx,
1817 struct csr_roam_session *session)
1818 {
1819 tDot11fIEeht_cap *eht_cap;
1820 struct wlan_objmgr_vdev *vdev;
1821 struct mlme_legacy_priv *mlme_priv;
1822
1823 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1824 session->vdev_id,
1825 WLAN_LEGACY_SME_ID);
1826 if (!vdev)
1827 return;
1828 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1829 if (!mlme_priv) {
1830 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1831 return;
1832 }
1833 qdf_mem_copy(&mlme_priv->eht_config,
1834 &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap,
1835 sizeof(mlme_priv->eht_config));
1836 eht_cap = &mlme_priv->eht_config;
1837 eht_cap->present = true;
1838 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1839 }
1840 #endif
1841
1842 #ifdef WLAN_FEATURE_11AX
csr_update_session_he_cap(struct mac_context * mac_ctx,struct csr_roam_session * session)1843 void csr_update_session_he_cap(struct mac_context *mac_ctx,
1844 struct csr_roam_session *session)
1845 {
1846 enum QDF_OPMODE persona;
1847 tDot11fIEhe_cap *he_cap;
1848 struct wlan_objmgr_vdev *vdev;
1849 struct mlme_legacy_priv *mlme_priv;
1850
1851 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1852 session->vdev_id,
1853 WLAN_LEGACY_SME_ID);
1854 if (!vdev)
1855 return;
1856 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1857 if (!mlme_priv) {
1858 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1859 return;
1860 }
1861 qdf_mem_copy(&mlme_priv->he_config,
1862 &mac_ctx->mlme_cfg->he_caps.dot11_he_cap,
1863 sizeof(mlme_priv->he_config));
1864 he_cap = &mlme_priv->he_config;
1865 he_cap->present = true;
1866 /*
1867 * Do not advertise requester role for SAP & responder role
1868 * for STA
1869 */
1870 persona = wlan_vdev_mlme_get_opmode(vdev);
1871 if (persona == QDF_SAP_MODE || persona == QDF_P2P_GO_MODE) {
1872 he_cap->twt_request = false;
1873 if (!he_cap->twt_responder)
1874 he_cap->flex_twt_sched = false;
1875
1876 } else if (persona == QDF_STA_MODE || persona == QDF_P2P_CLIENT_MODE) {
1877 he_cap->twt_responder = false;
1878 if (!he_cap->twt_request)
1879 he_cap->flex_twt_sched = false;
1880 }
1881
1882 if (he_cap->ppet_present) {
1883 /* till now operating channel is not decided yet, use 5g cap */
1884 qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th,
1885 mac_ctx->mlme_cfg->he_caps.he_ppet_5g,
1886 WNI_CFG_HE_PPET_LEN);
1887 he_cap->ppet.ppe_threshold.num_ppe_th =
1888 lim_truncate_ppet(he_cap->ppet.ppe_threshold.ppe_th,
1889 WNI_CFG_HE_PPET_LEN);
1890 } else {
1891 he_cap->ppet.ppe_threshold.num_ppe_th = 0;
1892 }
1893 mlme_priv->he_sta_obsspd = mac_ctx->mlme_cfg->he_caps.he_sta_obsspd;
1894 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1895 }
1896 #endif
1897
csr_change_default_config_param(struct mac_context * mac,struct csr_config_params * pParam)1898 QDF_STATUS csr_change_default_config_param(struct mac_context *mac,
1899 struct csr_config_params *pParam)
1900 {
1901 QDF_STATUS status = QDF_STATUS_SUCCESS;
1902
1903 if (pParam) {
1904 mac->roam.configParam.is_force_1x1 =
1905 pParam->is_force_1x1;
1906 mac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode;
1907 mac->mlme_cfg->wmm_params.wme_enabled =
1908 (pParam->WMMSupportMode == WMM_USER_MODE_NO_QOS) ? 0 : 1;
1909 mac->roam.configParam.Is11eSupportEnabled =
1910 pParam->Is11eSupportEnabled;
1911
1912 mac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode;
1913 mac->roam.configParam.mcc_rts_cts_prot_enable =
1914 pParam->mcc_rts_cts_prot_enable;
1915 mac->roam.configParam.mcc_bcast_prob_resp_enable =
1916 pParam->mcc_bcast_prob_resp_enable;
1917 mac->roam.configParam.fAllowMCCGODiffBI =
1918 pParam->fAllowMCCGODiffBI;
1919
1920 /* channelBondingMode5GHz plays a dual role right now
1921 * INFRA STA will use this non zero value as CB enabled
1922 * and SOFTAP will use this non-zero value to determine
1923 * the secondary channel offset. This is how
1924 * channelBondingMode5GHz works now and this is kept intact
1925 * to avoid any cfg.ini change.
1926 */
1927 if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI)
1928 sme_warn("Invalid CB value from ini in 2.4GHz band %d, CB DISABLED",
1929 pParam->channelBondingMode24GHz);
1930 mac->roam.configParam.channelBondingMode24GHz =
1931 csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1932 channelBondingMode24GHz);
1933 if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI)
1934 sme_warn("Invalid CB value from ini in 5GHz band %d, CB DISABLED",
1935 pParam->channelBondingMode5GHz);
1936 mac->roam.configParam.channelBondingMode5GHz =
1937 csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1938 channelBondingMode5GHz);
1939 sme_debug("cb mode 2g %d 5g %d",
1940 mac->roam.configParam.channelBondingMode24GHz,
1941 mac->roam.configParam.channelBondingMode5GHz);
1942 mac->roam.configParam.phyMode = pParam->phyMode;
1943 mac->roam.configParam.HeartbeatThresh50 =
1944 pParam->HeartbeatThresh50;
1945 mac->roam.configParam.ProprietaryRatesEnabled =
1946 pParam->ProprietaryRatesEnabled;
1947
1948 mac->roam.configParam.wep_tkip_in_he = pParam->wep_tkip_in_he;
1949
1950 mac->roam.configParam.uCfgDot11Mode =
1951 csr_get_cfg_dot11_mode_from_csr_phy_mode(false,
1952 mac->roam.configParam.
1953 phyMode);
1954
1955 /* Assign this before calling csr_init11d_info */
1956 if (wlan_reg_11d_enabled_on_host(mac->psoc))
1957 status = csr_init11d_info(mac, &pParam->Csr11dinfo);
1958
1959 /* Initialize the power + channel information if 11h is
1960 * enabled. If 11d is enabled this information has already
1961 * been initialized
1962 */
1963 if (csr_is11h_supported(mac) &&
1964 !wlan_reg_11d_enabled_on_host(mac->psoc))
1965 csr_init_channel_power_list(mac, &pParam->Csr11dinfo);
1966
1967 mac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan;
1968 mac->roam.configParam.send_smps_action =
1969 pParam->send_smps_action;
1970 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1971 mac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode;
1972 #endif
1973 mac->roam.configParam.obssEnabled = pParam->obssEnabled;
1974 mac->roam.configParam.conc_custom_rule1 =
1975 pParam->conc_custom_rule1;
1976 mac->roam.configParam.conc_custom_rule2 =
1977 pParam->conc_custom_rule2;
1978 mac->roam.configParam.is_sta_connection_in_5gz_enabled =
1979 pParam->is_sta_connection_in_5gz_enabled;
1980
1981 /* update interface configuration */
1982 mac->sme.max_intf_count = pParam->max_intf_count;
1983
1984 mac->f_sta_miracast_mcc_rest_time_val =
1985 pParam->f_sta_miracast_mcc_rest_time_val;
1986 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1987 mac->sap.sap_channel_avoidance =
1988 pParam->sap_channel_avoidance;
1989 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1990 }
1991 return status;
1992 }
1993
csr_get_config_param(struct mac_context * mac,struct csr_config_params * pParam)1994 QDF_STATUS csr_get_config_param(struct mac_context *mac,
1995 struct csr_config_params *pParam)
1996 {
1997 struct csr_config *cfg_params = &mac->roam.configParam;
1998
1999 if (!pParam)
2000 return QDF_STATUS_E_INVAL;
2001
2002 pParam->is_force_1x1 = cfg_params->is_force_1x1;
2003 pParam->WMMSupportMode = cfg_params->WMMSupportMode;
2004 pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled;
2005 pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value(
2006 cfg_params->channelBondingMode24GHz);
2007 pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value(
2008 cfg_params->channelBondingMode5GHz);
2009 pParam->phyMode = cfg_params->phyMode;
2010 pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50;
2011 pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled;
2012 pParam->fEnableDFSChnlScan = mac->scan.fEnableDFSChnlScan;
2013 pParam->fEnableMCCMode = cfg_params->fenableMCCMode;
2014 pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI;
2015
2016 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2017 pParam->cc_switch_mode = cfg_params->cc_switch_mode;
2018 #endif
2019 pParam->wep_tkip_in_he = cfg_params->wep_tkip_in_he;
2020 csr_set_channels(mac, pParam);
2021 pParam->obssEnabled = cfg_params->obssEnabled;
2022 pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
2023 pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
2024 pParam->is_sta_connection_in_5gz_enabled =
2025 cfg_params->is_sta_connection_in_5gz_enabled;
2026 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2027 pParam->sap_channel_avoidance = mac->sap.sap_channel_avoidance;
2028 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2029 pParam->max_intf_count = mac->sme.max_intf_count;
2030 pParam->f_sta_miracast_mcc_rest_time_val =
2031 mac->f_sta_miracast_mcc_rest_time_val;
2032 pParam->send_smps_action = mac->roam.configParam.send_smps_action;
2033
2034 return QDF_STATUS_SUCCESS;
2035 }
2036
2037 /**
2038 * csr_prune_ch_list() - prunes the channel list to keep only a type of channels
2039 * @ch_lst: existing channel list
2040 * @is_24_GHz: indicates if 2.5 GHz or 5 GHz channels are required
2041 *
2042 * Return: void
2043 */
csr_prune_ch_list(struct csr_channel * ch_lst,bool is_24_GHz)2044 static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz)
2045 {
2046 uint8_t idx = 0, num_channels = 0;
2047
2048 for ( ; idx < ch_lst->numChannels; idx++) {
2049 if (is_24_GHz) {
2050 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) {
2051 ch_lst->channel_freq_list[num_channels] =
2052 ch_lst->channel_freq_list[idx];
2053 num_channels++;
2054 }
2055 } else {
2056 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) {
2057 ch_lst->channel_freq_list[num_channels] =
2058 ch_lst->channel_freq_list[idx];
2059 num_channels++;
2060 }
2061 }
2062 }
2063 /*
2064 * Cleanup the rest of channels. Note we only need to clean up the
2065 * channels if we had to trim the list. Calling qdf_mem_set() with a 0
2066 * size is going to throw asserts on the debug builds so let's be a bit
2067 * smarter about that. Zero out the reset of the channels only if we
2068 * need to. The amount of memory to clear is the number of channesl that
2069 * we trimmed (ch_lst->numChannels - num_channels) times the size of a
2070 * channel in the structure.
2071 */
2072 if (ch_lst->numChannels > num_channels) {
2073 qdf_mem_zero(&ch_lst->channel_freq_list[num_channels],
2074 sizeof(ch_lst->channel_freq_list[0]) *
2075 (ch_lst->numChannels - num_channels));
2076 }
2077 ch_lst->numChannels = num_channels;
2078 }
2079
2080 /**
2081 * csr_prune_channel_list_for_mode() - prunes the channel list
2082 * @mac_ctx: global mac context
2083 * @ch_lst: existing channel list
2084 *
2085 * Prunes the channel list according to band stored in mac_ctx
2086 *
2087 * Return: void
2088 */
csr_prune_channel_list_for_mode(struct mac_context * mac_ctx,struct csr_channel * ch_lst)2089 void csr_prune_channel_list_for_mode(struct mac_context *mac_ctx,
2090 struct csr_channel *ch_lst)
2091 {
2092 /* for dual band NICs, don't need to trim the channel list.... */
2093 if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx))
2094 return;
2095 /*
2096 * 2.4 GHz band operation requires the channel list to be trimmed to
2097 * the 2.4 GHz channels only
2098 */
2099 if (CSR_IS_24_BAND_ONLY(mac_ctx))
2100 csr_prune_ch_list(ch_lst, true);
2101 else if (CSR_IS_5G_BAND_ONLY(mac_ctx))
2102 csr_prune_ch_list(ch_lst, false);
2103 }
2104
2105 #define INFRA_AP_DEFAULT_CHAN_FREQ 2437
2106
csr_get_channel_and_power_list(struct mac_context * mac)2107 QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac)
2108 {
2109 QDF_STATUS status = QDF_STATUS_SUCCESS;
2110 uint8_t num20MHzChannelsFound = 0;
2111 QDF_STATUS qdf_status;
2112 uint8_t Index = 0;
2113
2114 qdf_status = wlan_reg_get_channel_list_with_power_for_freq(
2115 mac->pdev,
2116 mac->scan.defaultPowerTable,
2117 &num20MHzChannelsFound);
2118
2119 if ((QDF_STATUS_SUCCESS != qdf_status) ||
2120 (num20MHzChannelsFound == 0)) {
2121 sme_err("failed to get channels");
2122 status = QDF_STATUS_E_FAILURE;
2123 } else {
2124 if (num20MHzChannelsFound > CFG_VALID_CHANNEL_LIST_LEN)
2125 num20MHzChannelsFound = CFG_VALID_CHANNEL_LIST_LEN;
2126 /* Move the channel list to the global data */
2127 /* structure -- this will be used as the scan list */
2128 for (Index = 0; Index < num20MHzChannelsFound; Index++)
2129 mac->scan.base_channels.channel_freq_list[Index] =
2130 mac->scan.defaultPowerTable[Index].center_freq;
2131 mac->scan.base_channels.numChannels =
2132 num20MHzChannelsFound;
2133 }
2134 return status;
2135 }
2136
csr_apply_channel_and_power_list(struct mac_context * mac)2137 QDF_STATUS csr_apply_channel_and_power_list(struct mac_context *mac)
2138 {
2139 QDF_STATUS status = QDF_STATUS_SUCCESS;
2140
2141 csr_prune_channel_list_for_mode(mac, &mac->scan.base_channels);
2142 csr_save_channel_power_for_band(mac, false);
2143 csr_save_channel_power_for_band(mac, true);
2144 csr_apply_channel_power_info_to_fw(mac,
2145 &mac->scan.base_channels);
2146
2147 csr_init_operating_classes(mac);
2148 return status;
2149 }
2150
csr_init11d_info(struct mac_context * mac,tCsr11dinfo * ps11dinfo)2151 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo)
2152 {
2153 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2154 uint8_t index;
2155 uint32_t count = 0;
2156 struct pwr_channel_info *pChanInfo;
2157 struct pwr_channel_info *pChanInfoStart;
2158 bool applyConfig = true;
2159
2160 if (!ps11dinfo)
2161 return status;
2162
2163 if (ps11dinfo->Channels.numChannels
2164 && (CFG_VALID_CHANNEL_LIST_LEN >=
2165 ps11dinfo->Channels.numChannels)) {
2166 mac->scan.base_channels.numChannels =
2167 ps11dinfo->Channels.numChannels;
2168 qdf_mem_copy(mac->scan.base_channels.channel_freq_list,
2169 ps11dinfo->Channels.channel_freq_list,
2170 ps11dinfo->Channels.numChannels);
2171 } else {
2172 /* No change */
2173 return QDF_STATUS_SUCCESS;
2174 }
2175 /* legacy maintenance */
2176
2177 /* need to add the max power channel list */
2178 pChanInfo =
2179 qdf_mem_malloc(sizeof(struct pwr_channel_info) *
2180 CFG_VALID_CHANNEL_LIST_LEN);
2181 if (pChanInfo) {
2182 pChanInfoStart = pChanInfo;
2183 for (index = 0; index < ps11dinfo->Channels.numChannels;
2184 index++) {
2185 pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq;
2186 pChanInfo->num_chan =
2187 ps11dinfo->ChnPower[index].numChannels;
2188 pChanInfo->max_tx_pwr =
2189 ps11dinfo->ChnPower[index].maxtxPower;
2190 pChanInfo++;
2191 count++;
2192 }
2193 if (count) {
2194 status = csr_save_to_channel_power2_g_5_g(mac,
2195 count *
2196 sizeof(struct pwr_channel_info),
2197 pChanInfoStart);
2198 }
2199 qdf_mem_free(pChanInfoStart);
2200 }
2201 /* Only apply them to CFG when not in STOP state.
2202 * Otherwise they will be applied later
2203 */
2204 if (QDF_IS_STATUS_SUCCESS(status)) {
2205 for (index = 0; index < WLAN_MAX_VDEVS; index++) {
2206 if ((CSR_IS_SESSION_VALID(mac, index))
2207 && CSR_IS_ROAM_STOP(mac, index)) {
2208 applyConfig = false;
2209 }
2210 }
2211
2212 if (true == applyConfig) {
2213 /* Apply the base channel list, power info,
2214 * and set the Country code.
2215 */
2216 csr_apply_channel_power_info_to_fw(mac,
2217 &mac->scan.
2218 base_channels);
2219 }
2220 }
2221 return status;
2222 }
2223
2224 /* Initialize the Channel + Power List in the local cache and in the CFG */
csr_init_channel_power_list(struct mac_context * mac,tCsr11dinfo * ps11dinfo)2225 QDF_STATUS csr_init_channel_power_list(struct mac_context *mac,
2226 tCsr11dinfo *ps11dinfo)
2227 {
2228 uint8_t index;
2229 uint32_t count = 0;
2230 struct pwr_channel_info *pChanInfo;
2231 struct pwr_channel_info *pChanInfoStart;
2232
2233 if (!ps11dinfo || !mac)
2234 return QDF_STATUS_E_FAILURE;
2235
2236 pChanInfo =
2237 qdf_mem_malloc(sizeof(struct pwr_channel_info) *
2238 CFG_VALID_CHANNEL_LIST_LEN);
2239 if (pChanInfo) {
2240 pChanInfoStart = pChanInfo;
2241
2242 for (index = 0; index < ps11dinfo->Channels.numChannels;
2243 index++) {
2244 pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq;
2245 pChanInfo->num_chan =
2246 ps11dinfo->ChnPower[index].numChannels;
2247 pChanInfo->max_tx_pwr =
2248 ps11dinfo->ChnPower[index].maxtxPower;
2249 pChanInfo++;
2250 count++;
2251 }
2252 if (count) {
2253 csr_save_to_channel_power2_g_5_g(mac,
2254 count *
2255 sizeof(struct pwr_channel_info),
2256 pChanInfoStart);
2257 }
2258 qdf_mem_free(pChanInfoStart);
2259 }
2260
2261 return QDF_STATUS_SUCCESS;
2262 }
2263
2264 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2265 #ifdef WLAN_UNIT_TEST
csr_cm_get_sta_cxn_info(struct mac_context * mac_ctx,uint8_t vdev_id,char * buf,uint32_t buf_sz)2266 void csr_cm_get_sta_cxn_info(struct mac_context *mac_ctx, uint8_t vdev_id,
2267 char *buf, uint32_t buf_sz)
2268 {
2269 struct wlan_objmgr_vdev *vdev;
2270
2271 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
2272 WLAN_LEGACY_MAC_ID);
2273 if (!vdev) {
2274 sme_err("vdev object is NULL for vdev %d", vdev_id);
2275 return;
2276 }
2277
2278 cm_get_sta_cxn_info(vdev, buf, buf_sz);
2279 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
2280
2281 }
2282 #endif
2283 #endif
2284
csr_roam_call_callback(struct mac_context * mac,uint32_t sessionId,struct csr_roam_info * roam_info,eRoamCmdStatus u1,eCsrRoamResult u2)2285 QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId,
2286 struct csr_roam_info *roam_info,
2287 eRoamCmdStatus u1, eCsrRoamResult u2)
2288 {
2289 QDF_STATUS status = QDF_STATUS_SUCCESS;
2290 struct csr_roam_session *pSession;
2291 qdf_freq_t chan_freq;
2292
2293 if (!CSR_IS_SESSION_VALID(mac, sessionId)) {
2294 sme_err("Session ID: %d is not valid", sessionId);
2295 QDF_ASSERT(0);
2296 return QDF_STATUS_E_FAILURE;
2297 }
2298 pSession = CSR_GET_SESSION(mac, sessionId);
2299
2300 if (false == pSession->sessionActive) {
2301 sme_debug("Session is not Active");
2302 return QDF_STATUS_E_FAILURE;
2303 }
2304 chan_freq = wlan_get_operation_chan_freq_vdev_id(mac->pdev, sessionId);
2305
2306 if (mac->session_roam_complete_cb)
2307 status = mac->session_roam_complete_cb(mac->psoc, sessionId,
2308 roam_info, u1, u2);
2309
2310 return status;
2311 }
2312
csr_peer_mac_match_cmd(tSmeCmd * sme_cmd,struct qdf_mac_addr * peer_macaddr,struct qdf_mac_addr * peer_mld_addr,uint8_t vdev_id)2313 static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd,
2314 struct qdf_mac_addr *peer_macaddr,
2315 struct qdf_mac_addr *peer_mld_addr,
2316 uint8_t vdev_id)
2317 {
2318 if (sme_cmd->command == eSmeCommandRoam &&
2319 (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta ||
2320 sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) &&
2321 (qdf_is_macaddr_equal(
2322 peer_macaddr,
2323 (struct qdf_mac_addr *)sme_cmd->u.roamCmd.peerMac) ||
2324 (!qdf_is_macaddr_zero(peer_mld_addr) &&
2325 qdf_is_macaddr_equal(peer_mld_addr,
2326 &sme_cmd->u.roamCmd.peer_mld_addr))))
2327 return true;
2328
2329 if (sme_cmd->command == eSmeCommandWmStatusChange) {
2330 struct wmstatus_changecmd *wms_cmd;
2331
2332 wms_cmd = &sme_cmd->u.wmStatusChangeCmd;
2333 if (wms_cmd->Type == eCsrDisassociated &&
2334 (qdf_is_macaddr_equal(
2335 peer_macaddr,
2336 &wms_cmd->u.DisassocIndMsg.peer_macaddr) ||
2337 (!qdf_is_macaddr_zero(peer_mld_addr) &&
2338 qdf_is_macaddr_equal(
2339 peer_mld_addr,
2340 &wms_cmd->u.DisassocIndMsg.peer_mld_addr))))
2341 return true;
2342
2343 if (wms_cmd->Type == eCsrDeauthenticated &&
2344 (qdf_is_macaddr_equal(
2345 peer_macaddr,
2346 &wms_cmd->u.DeauthIndMsg.peer_macaddr) ||
2347 (!qdf_is_macaddr_zero(peer_mld_addr) &&
2348 qdf_is_macaddr_equal(
2349 peer_mld_addr,
2350 &wms_cmd->u.DeauthIndMsg.peer_mld_addr))))
2351 return true;
2352 }
2353
2354 return false;
2355 }
2356
2357 static bool
csr_is_deauth_disassoc_in_pending_q(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr * peer_macaddr,struct qdf_mac_addr * peer_mld_addr)2358 csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx,
2359 uint8_t vdev_id,
2360 struct qdf_mac_addr *peer_macaddr,
2361 struct qdf_mac_addr *peer_mld_addr)
2362 {
2363 tListElem *entry = NULL;
2364 tSmeCmd *sme_cmd;
2365
2366 entry = csr_nonscan_pending_ll_peek_head(mac_ctx, LL_ACCESS_NOLOCK);
2367 while (entry) {
2368 sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
2369 if ((sme_cmd->vdev_id == vdev_id) &&
2370 csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
2371 peer_mld_addr, vdev_id))
2372 return true;
2373 entry = csr_nonscan_pending_ll_next(mac_ctx, entry,
2374 LL_ACCESS_NOLOCK);
2375 }
2376
2377 return false;
2378 }
2379
2380 static bool
csr_is_deauth_disassoc_in_active_q(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr * peer_macaddr,struct qdf_mac_addr * peer_mld_addr)2381 csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
2382 uint8_t vdev_id,
2383 struct qdf_mac_addr *peer_macaddr,
2384 struct qdf_mac_addr *peer_mld_addr)
2385 {
2386 tSmeCmd *sme_cmd;
2387
2388 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2389 WLAN_SER_CMD_FORCE_DEAUTH_STA);
2390
2391 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
2392 peer_mld_addr, vdev_id))
2393 return true;
2394
2395 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2396 WLAN_SER_CMD_FORCE_DISASSOC_STA);
2397
2398 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
2399 peer_mld_addr, vdev_id))
2400 return true;
2401
2402 /*
2403 * WLAN_SER_CMD_WM_STATUS_CHANGE is of two type, the handling
2404 * should take care of both the types.
2405 */
2406 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2407 WLAN_SER_CMD_WM_STATUS_CHANGE);
2408 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
2409 peer_mld_addr, vdev_id))
2410 return true;
2411
2412 return false;
2413 }
2414
2415 /*
2416 * csr_is_deauth_disassoc_already_active() - Function to check if deauth or
2417 * disassoc is already in progress.
2418 * @mac_ctx: Global MAC context
2419 * @vdev_id: vdev id
2420 * @peer_macaddr: Peer MAC address to check
2421 * @peer_mld_addr: peer MLD address to check
2422 *
2423 * Return: True if deauth/disassoc indication can be dropped
2424 * else false
2425 */
2426 static bool
csr_is_deauth_disassoc_already_active(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr * peer_macaddr,struct qdf_mac_addr * peer_mld_addr)2427 csr_is_deauth_disassoc_already_active(struct mac_context *mac_ctx,
2428 uint8_t vdev_id,
2429 struct qdf_mac_addr *peer_macaddr,
2430 struct qdf_mac_addr *peer_mld_addr)
2431 {
2432 char mld_log_str[MAC_ADDR_DUMP_LEN] = {0};
2433
2434 bool ret = csr_is_deauth_disassoc_in_pending_q(
2435 mac_ctx, vdev_id, peer_macaddr,
2436 peer_mld_addr);
2437 if (!ret)
2438 /**
2439 * commands are not found in pending queue, check in active
2440 * queue as well
2441 */
2442 ret = csr_is_deauth_disassoc_in_active_q(
2443 mac_ctx, vdev_id,
2444 peer_macaddr, peer_mld_addr);
2445
2446 if (ret) {
2447 if (!qdf_is_macaddr_zero((struct qdf_mac_addr *)&peer_mld_addr))
2448 qdf_scnprintf(mld_log_str, MAC_ADDR_DUMP_LEN,
2449 " mld: " QDF_MAC_ADDR_FMT,
2450 QDF_MAC_ADDR_REF(peer_mld_addr->bytes));
2451 sme_debug("Deauth/Disassoc already in progress for " QDF_MAC_ADDR_FMT "%s",
2452 QDF_MAC_ADDR_REF(peer_macaddr->bytes), mld_log_str);
2453 }
2454
2455 return ret;
2456 }
2457
2458 /*
2459 * csr_is_deauth_disassoc_cmd_active() - Function to check if deauth or
2460 * disassoc is already in progress.
2461 * @mac_ctx: Global MAC context
2462 * @vdev_id: vdev ID
2463 * @macaddr: mac address provided (mld/link/mac for the peer to check)
2464 * @peer_mac: found peer mac
2465 * @peer_mld_mac: found peer mld if ML connection
2466 *
2467 * Return: True if deauth/disassoc indication can be dropped else false
2468 */
2469 static bool
csr_is_deauth_disassoc_cmd_active(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr macaddr,struct qdf_mac_addr * peer_mac,struct qdf_mac_addr * peer_mld_mac)2470 csr_is_deauth_disassoc_cmd_active(struct mac_context *mac_ctx,
2471 uint8_t vdev_id, struct qdf_mac_addr macaddr,
2472 struct qdf_mac_addr *peer_mac,
2473 struct qdf_mac_addr *peer_mld_mac)
2474 {
2475 struct peer_mac_addresses peer_mac_info;
2476
2477 qdf_mem_zero(&peer_mac_info, sizeof(struct peer_mac_addresses));
2478 qdf_copy_macaddr(&peer_mac_info.mac, &macaddr);
2479 wlan_find_peer_and_get_mac_and_mld_addr(mac_ctx->psoc, &peer_mac_info);
2480 if (csr_is_deauth_disassoc_already_active(mac_ctx, vdev_id,
2481 &peer_mac_info.peer_mac,
2482 &peer_mac_info.peer_mld))
2483 return true;
2484
2485 if (peer_mac && peer_mld_mac) {
2486 if (!qdf_is_macaddr_equal(&macaddr, &peer_mac_info.peer_mac))
2487 sme_debug("Vdev %d, given mac " QDF_MAC_ADDR_FMT " found peer mac " QDF_MAC_ADDR_FMT,
2488 vdev_id, QDF_MAC_ADDR_REF(macaddr.bytes),
2489 QDF_MAC_ADDR_REF(peer_mac_info.peer_mac.bytes));
2490 qdf_copy_macaddr(peer_mac, &peer_mac_info.peer_mac);
2491 qdf_copy_macaddr(peer_mld_mac, &peer_mac_info.peer_mld);
2492 }
2493
2494 return false;
2495 }
2496
2497 static QDF_STATUS
csr_roam_issue_discon_sta_roam_cmd(struct mac_context * mac,uint8_t vdev_id,enum csr_roam_reason discon_reason,struct csr_del_sta_params * del_sta_params)2498 csr_roam_issue_discon_sta_roam_cmd(struct mac_context *mac,
2499 uint8_t vdev_id,
2500 enum csr_roam_reason discon_reason,
2501 struct csr_del_sta_params *del_sta_params)
2502 {
2503 tSmeCmd *cmd;
2504 QDF_STATUS status = QDF_STATUS_SUCCESS;
2505 struct qdf_mac_addr peer_mac = QDF_MAC_ADDR_ZERO_INIT;
2506 struct qdf_mac_addr peer_mld_mac = QDF_MAC_ADDR_ZERO_INIT;
2507
2508 if (csr_is_deauth_disassoc_cmd_active(mac, vdev_id,
2509 del_sta_params->peerMacAddr,
2510 &peer_mac, &peer_mld_mac))
2511 return status;
2512
2513 cmd = csr_get_command_buffer(mac);
2514 if (!cmd) {
2515 sme_err("Vdev %d " QDF_MAC_ADDR_FMT " fails to get command buffer for reason %d",
2516 vdev_id,
2517 QDF_MAC_ADDR_REF(del_sta_params->peerMacAddr.bytes),
2518 discon_reason);
2519 return QDF_STATUS_E_RESOURCES;
2520 }
2521
2522 cmd->command = eSmeCommandRoam;
2523 cmd->vdev_id = vdev_id;
2524 cmd->u.roamCmd.roamReason = discon_reason;
2525 qdf_copy_macaddr((struct qdf_mac_addr *)&cmd->u.roamCmd.peerMac,
2526 &peer_mac);
2527 qdf_copy_macaddr(&cmd->u.roamCmd.peer_mld_addr, &peer_mld_mac);
2528 cmd->u.roamCmd.reason = del_sta_params->reason_code;
2529
2530 status = csr_queue_sme_command(mac, cmd, false);
2531 if (QDF_IS_STATUS_ERROR(status))
2532 sme_err("Vdev %d " QDF_MAC_ADDR_FMT " fails to get send message status: %d",
2533 vdev_id,
2534 QDF_MAC_ADDR_REF(del_sta_params->peerMacAddr.bytes),
2535 status);
2536
2537 return status;
2538 }
2539
2540 QDF_STATUS
csr_roam_issue_disassociate_sta_cmd(struct mac_context * mac,uint8_t vdev_id,struct csr_del_sta_params * del_sta_params)2541 csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
2542 uint8_t vdev_id,
2543 struct csr_del_sta_params *del_sta_params)
2544
2545 {
2546 return csr_roam_issue_discon_sta_roam_cmd(mac, vdev_id,
2547 eCsrForcedDisassocSta,
2548 del_sta_params);
2549 }
2550
2551 QDF_STATUS
csr_roam_issue_deauth_sta_cmd(struct mac_context * mac,uint8_t vdev_id,struct csr_del_sta_params * del_sta_params)2552 csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
2553 uint8_t vdev_id,
2554 struct csr_del_sta_params *del_sta_params)
2555 {
2556 return csr_roam_issue_discon_sta_roam_cmd(mac, vdev_id,
2557 eCsrForcedDeauthSta,
2558 del_sta_params);
2559 }
2560
2561 /**
2562 * csr_get_peer_stats_cb - Peer stats callback
2563 * @ev: stats event
2564 * @cookie: Void pointer to mac contaxt
2565 *
2566 * Return: None
2567 */
csr_get_peer_stats_cb(struct stats_event * ev,void * cookie)2568 static void csr_get_peer_stats_cb(struct stats_event *ev, void *cookie)
2569 {
2570 struct mac_context *mac = (struct mac_context *)cookie;
2571 struct wlan_mlme_psoc_ext_obj *mlme_obj;
2572
2573 if (!mac) {
2574 sme_err("Invalid mac ctx");
2575 return;
2576 }
2577
2578 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
2579 if (!mlme_obj) {
2580 sme_err("NULL mlme psoc object");
2581 return;
2582 }
2583
2584 qdf_mc_timer_stop(
2585 &mlme_obj->disconnect_stats_param.disconn_stats_timer);
2586
2587 if (!ev->peer_stats) {
2588 sme_debug("no peer stats");
2589 goto disconnect_stats_complete;
2590 }
2591
2592 mac->peer_rssi = ev->peer_stats->peer_rssi;
2593 mac->peer_txrate = ev->peer_stats->tx_rate;
2594 mac->peer_rxrate = ev->peer_stats->rx_rate;
2595 if (!ev->peer_extended_stats) {
2596 sme_debug("no peer extended stats");
2597 goto disconnect_stats_complete;
2598 }
2599 mac->rx_mc_bc_cnt = ev->peer_extended_stats->rx_mc_bc_cnt;
2600
2601 disconnect_stats_complete:
2602 sme_debug("peer rssi %d tx_rate %d rx_rate %d rx_mc_bc_cnt %d",
2603 mac->peer_rssi, mac->peer_txrate, mac->peer_rxrate,
2604 mac->rx_mc_bc_cnt);
2605 csr_continue_peer_disconnect_after_get_stats(mac);
2606 }
2607
2608 /**
2609 * csr_get_peer_stats - Get Peer stats
2610 * @mac: MAC contaxt
2611 * @session_id: Current session id
2612 * @peer_mac: Peer mac address
2613 *
2614 * Return: None
2615 */
csr_get_peer_stats(struct mac_context * mac,uint32_t session_id,struct qdf_mac_addr peer_mac)2616 static void csr_get_peer_stats(struct mac_context *mac, uint32_t session_id,
2617 struct qdf_mac_addr peer_mac)
2618 {
2619 struct wlan_objmgr_vdev *vdev;
2620 struct request_info info = {0};
2621 QDF_STATUS status;
2622 struct wlan_mlme_psoc_ext_obj *mlme_obj;
2623
2624 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
2625 if (!mlme_obj) {
2626 sme_err("NULL mlme psoc object");
2627 return;
2628 }
2629 /* Reset is_disconn_stats_completed before error handing. */
2630 qdf_atomic_set(
2631 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed,
2632 0);
2633
2634 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session_id,
2635 WLAN_LEGACY_SME_ID);
2636
2637 if (!vdev) {
2638 csr_continue_peer_disconnect_after_get_stats(mac);
2639 return;
2640 }
2641
2642 info.cookie = mac;
2643 info.u.get_peer_rssi_cb = csr_get_peer_stats_cb;
2644 info.vdev_id = wlan_vdev_get_id(vdev);
2645 info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
2646 qdf_mem_copy(info.peer_mac_addr, &peer_mac, QDF_MAC_ADDR_SIZE);
2647 sme_debug("peer_mac" QDF_MAC_ADDR_FMT,
2648 QDF_MAC_ADDR_REF(peer_mac.bytes));
2649 mlme_obj->disconnect_stats_param.vdev_id = info.vdev_id;
2650 status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_PEER_STATS,
2651 &info);
2652 if (QDF_IS_STATUS_ERROR(status)) {
2653 sme_err("stats req failed: %d", status);
2654 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2655 csr_continue_peer_disconnect_after_get_stats(mac);
2656 return;
2657 }
2658
2659 qdf_mc_timer_start(
2660 &mlme_obj->disconnect_stats_param.disconn_stats_timer,
2661 SME_CMD_GET_DISCONNECT_STATS_TIMEOUT);
2662
2663 wma_get_rx_retry_cnt(mac, session_id, info.peer_mac_addr);
2664 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2665 }
2666
csr_roam_process_command(struct mac_context * mac,tSmeCmd * pCommand)2667 QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand)
2668 {
2669 QDF_STATUS status = QDF_STATUS_SUCCESS;
2670 uint32_t sessionId = pCommand->vdev_id;
2671 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
2672 struct qdf_mac_addr peer_mac;
2673
2674 if (!pSession) {
2675 sme_err("session %d not found", sessionId);
2676 return QDF_STATUS_E_FAILURE;
2677 }
2678 sme_debug("Roam Reason: %d sessionId: %d",
2679 pCommand->u.roamCmd.roamReason, sessionId);
2680
2681 switch (pCommand->u.roamCmd.roamReason) {
2682 case eCsrForcedDisassocSta:
2683 case eCsrForcedDeauthSta:
2684 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING,
2685 sessionId);
2686 if (pCommand->u.roamCmd.roamReason == eCsrForcedDeauthSta)
2687 csr_roam_substate_change(mac,
2688 eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
2689 sessionId);
2690 else
2691 csr_roam_substate_change(
2692 mac,
2693 eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
2694 sessionId);
2695
2696 qdf_mem_copy(&peer_mac, &pCommand->u.roamCmd.peerMac,
2697 QDF_MAC_ADDR_SIZE);
2698 /*
2699 * Get peer stats before peer gets deleted so that these stats
2700 * can be given to user space when big data stats are queried.
2701 * Once peer stats are retrieved deauth sta will continue
2702 */
2703 csr_get_peer_stats(mac, sessionId, peer_mac);
2704 break;
2705 }
2706 return status;
2707 }
2708
csr_reinit_roam_cmd(struct mac_context * mac,tSmeCmd * pCommand)2709 void csr_reinit_roam_cmd(struct mac_context *mac, tSmeCmd *pCommand)
2710 {
2711 /* Because u.roamCmd is union and share with scanCmd and StatusChange */
2712 qdf_mem_zero(&pCommand->u.roamCmd, sizeof(struct roam_cmd));
2713 }
2714
csr_reinit_wm_status_change_cmd(struct mac_context * mac,tSmeCmd * pCommand)2715 void csr_reinit_wm_status_change_cmd(struct mac_context *mac,
2716 tSmeCmd *pCommand)
2717 {
2718 qdf_mem_zero(&pCommand->u.wmStatusChangeCmd,
2719 sizeof(struct wmstatus_changecmd));
2720 }
2721
csr_roam_complete(struct mac_context * mac_ctx,uint8_t session_id)2722 void csr_roam_complete(struct mac_context *mac_ctx, uint8_t session_id)
2723 {
2724 tSmeCmd *sme_cmd;
2725 struct wlan_serialization_command *cmd;
2726
2727 cmd = wlan_serialization_peek_head_active_cmd_using_psoc(
2728 mac_ctx->psoc, false);
2729 if (!cmd) {
2730 sme_err("Roam completion called but cmd is not active");
2731 return;
2732 }
2733 sme_cmd = cmd->umac_cmd;
2734 if (!sme_cmd) {
2735 sme_err("sme_cmd is NULL");
2736 return;
2737 }
2738 if (eSmeCommandRoam == sme_cmd->command) {
2739 csr_roam_process_results_default(mac_ctx, sme_cmd);
2740 csr_release_command(mac_ctx, sme_cmd);
2741 }
2742 }
2743
2744 /* Returns whether the current association is a 11r assoc or not */
csr_roam_is11r_assoc(struct mac_context * mac,uint8_t sessionId)2745 bool csr_roam_is11r_assoc(struct mac_context *mac, uint8_t sessionId)
2746 {
2747 struct cm_roam_values_copy config;
2748
2749 wlan_cm_roam_cfg_get_value(mac->psoc, sessionId, IS_11R_CONNECTION,
2750 &config);
2751
2752 return config.bool_value;
2753 }
2754
csr_roam_process_results_default(struct mac_context * mac_ctx,tSmeCmd * cmd)2755 void csr_roam_process_results_default(struct mac_context *mac_ctx,
2756 tSmeCmd *cmd)
2757 {
2758 uint32_t session_id = cmd->vdev_id;
2759 struct csr_roam_session *session;
2760 struct csr_roam_info *roam_info;
2761 QDF_STATUS status;
2762 enum QDF_OPMODE opmode;
2763
2764 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
2765 sme_err("Invalid session id %d", session_id);
2766 return;
2767 }
2768 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id);
2769 roam_info = qdf_mem_malloc(sizeof(*roam_info));
2770 if (!roam_info)
2771 return;
2772 session = CSR_GET_SESSION(mac_ctx, session_id);
2773 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) {
2774 /*
2775 * do not free for the other profiles as we need
2776 * to send down stop BSS later
2777 */
2778 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
2779 csr_set_default_dot11_mode(mac_ctx);
2780 }
2781
2782 switch (cmd->u.roamCmd.roamReason) {
2783 case eCsrForcedDisassocSta:
2784 case eCsrForcedDeauthSta:
2785 roam_info->rssi = mac_ctx->peer_rssi;
2786 roam_info->tx_rate = mac_ctx->peer_txrate;
2787 roam_info->rx_rate = mac_ctx->peer_rxrate;
2788 roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt;
2789 roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt;
2790
2791 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
2792 session_id);
2793 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
2794 qdf_mem_copy(roam_info->peerMac.bytes,
2795 cmd->u.roamCmd.peerMac,
2796 sizeof(tSirMacAddr));
2797 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
2798 /* Update the MAC reason code */
2799 roam_info->disassoc_reason = cmd->u.roamCmd.reason;
2800 roam_info->status_code = eSIR_SME_SUCCESS;
2801 status = csr_roam_call_callback(mac_ctx, session_id,
2802 roam_info,
2803 eCSR_ROAM_LOSTLINK,
2804 eCSR_ROAM_RESULT_FORCED);
2805 }
2806 break;
2807 default:
2808 csr_roam_state_change(mac_ctx,
2809 eCSR_ROAMING_STATE_IDLE, session_id);
2810 break;
2811 }
2812 qdf_mem_free(roam_info);
2813 }
2814
2815 /**
2816 * csr_roam_process_start_bss_success() - Process the result for start bss
2817 * @mac_ctx: Global MAC Context
2818 * @context: Additional data in context of the cmd
2819 * @vdev_id: vdev id
2820 *
2821 * Return: None
2822 */
csr_roam_process_start_bss_success(struct mac_context * mac_ctx,struct csr_roam_info * roam_info,void * context,uint8_t vdev_id)2823 static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx,
2824 struct csr_roam_info *roam_info,
2825 void *context, uint8_t vdev_id)
2826 {
2827 struct csr_roam_session *session;
2828 struct start_bss_rsp *start_bss_rsp = NULL;
2829 eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND;
2830 eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_STARTED;
2831 tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2832 QDF_STATUS status;
2833 enum QDF_OPMODE opmode;
2834 uint8_t wmm_mode = 0, value = 0;
2835
2836 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
2837 sme_err("Invalid session id %d", vdev_id);
2838 return;
2839 }
2840 session = CSR_GET_SESSION(mac_ctx, vdev_id);
2841
2842 sme_debug("Start BSS success");
2843 start_bss_rsp = (struct start_bss_rsp *)context;
2844
2845 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
2846 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE)
2847 session->connectState =
2848 eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
2849 else if (opmode == QDF_NDI_MODE)
2850 session->connectState = eCSR_CONNECT_STATE_TYPE_NDI_STARTED;
2851 else
2852 session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
2853
2854 if (opmode == QDF_NDI_MODE) {
2855 status = ucfg_mlme_get_wmm_mode(mac_ctx->psoc, &wmm_mode);
2856 if (!QDF_IS_STATUS_SUCCESS(status))
2857 return;
2858 if (wmm_mode == WMM_USER_MODE_NO_QOS) {
2859 session->modifyProfileFields.uapsd_mask = 0;
2860 } else {
2861 status =
2862 ucfg_mlme_get_wmm_uapsd_mask(mac_ctx->psoc, &value);
2863 if (!QDF_IS_STATUS_SUCCESS(status))
2864 return;
2865 session->modifyProfileFields.uapsd_mask = value;
2866 }
2867 }
2868 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, vdev_id);
2869 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
2870 wlan_mlme_get_mac_vdev_id(mac_ctx->pdev, vdev_id, &roam_info->bssid);
2871
2872 /* We are done with the IEs so free it */
2873 /*
2874 * Only set context for non-WDS_STA. We don't even need it for
2875 * WDS_AP. But since the encryption.
2876 * is WPA2-PSK so it won't matter.
2877 */
2878 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
2879 if (wlan_is_open_wep_cipher(mac_ctx->pdev, vdev_id)) {
2880 csr_issue_set_context_req_helper(mac_ctx, vdev_id,
2881 &bcast_mac, false,
2882 false, 0);
2883 }
2884 }
2885
2886 /*
2887 * Only tell upper layer is we start the BSS because Vista doesn't like
2888 * multiple connection indications. If we don't start the BSS ourself,
2889 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start
2890 * indication in Vista
2891 */
2892 roam_info->staId = (uint8_t)start_bss_rsp->staId;
2893 if (opmode == QDF_NDI_MODE) {
2894 csr_roam_update_ndp_return_params(mac_ctx,
2895 CSR_SAP_START_BSS_SUCCESS,
2896 &roam_status,
2897 &roam_result,
2898 roam_info);
2899 }
2900 /*
2901 * Only tell upper layer is we start the BSS because Vista
2902 * doesn't like multiple connection indications. If we don't
2903 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS
2904 * will trigger the connection start indication in Vista
2905 */
2906 roam_info->status_code = eSIR_SME_SUCCESS;
2907 csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
2908 roam_status, roam_result);
2909 }
2910
csr_flush_pending_start_bss_cmd(struct mac_context * mac_ctx,uint8_t vdev_id)2911 static void csr_flush_pending_start_bss_cmd(struct mac_context *mac_ctx,
2912 uint8_t vdev_id)
2913 {
2914 struct wlan_serialization_queued_cmd_info cmd = {0};
2915 struct wlan_objmgr_vdev *vdev;
2916
2917 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
2918 WLAN_LEGACY_SME_ID);
2919 if (!vdev) {
2920 sme_err("vdev not found for id %d", vdev_id);
2921 return;
2922 }
2923
2924 /* Flush any pending vdev start command */
2925 cmd.vdev = vdev;
2926 cmd.cmd_type = WLAN_SER_CMD_VDEV_START_BSS;
2927 cmd.req_type = WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE;
2928 cmd.requestor = WLAN_UMAC_COMP_MLME;
2929 cmd.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE;
2930
2931 wlan_serialization_cancel_request(&cmd);
2932
2933 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2934 }
2935
cm_csr_is_ss_wait_for_key(uint8_t vdev_id)2936 bool cm_csr_is_ss_wait_for_key(uint8_t vdev_id)
2937 {
2938 struct mac_context *mac;
2939 bool is_wait_for_key = false;
2940
2941 mac = sme_get_mac_context();
2942 if (!mac) {
2943 sme_err("mac_ctx is NULL");
2944 return is_wait_for_key;
2945 }
2946
2947 spin_lock(&mac->roam.roam_state_lock);
2948 if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id))
2949 is_wait_for_key = true;
2950 spin_unlock(&mac->roam.roam_state_lock);
2951
2952 return is_wait_for_key;
2953 }
2954
cm_csr_set_ss_wait_for_key(uint8_t vdev_id)2955 void cm_csr_set_ss_wait_for_key(uint8_t vdev_id)
2956 {
2957 struct mac_context *mac;
2958
2959 mac = sme_get_mac_context();
2960 if (!mac) {
2961 sme_err("mac_ctx is NULL");
2962 return;
2963 }
2964
2965 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
2966 vdev_id);
2967 }
2968
cm_csr_set_joining(uint8_t vdev_id)2969 void cm_csr_set_joining(uint8_t vdev_id)
2970 {
2971 struct mac_context *mac;
2972
2973 mac = sme_get_mac_context();
2974 if (!mac) {
2975 sme_err("mac_ctx is NULL");
2976 return;
2977 }
2978
2979 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, vdev_id);
2980 }
2981
cm_csr_set_joined(uint8_t vdev_id)2982 void cm_csr_set_joined(uint8_t vdev_id)
2983 {
2984 struct mac_context *mac;
2985
2986 mac = sme_get_mac_context();
2987 if (!mac) {
2988 sme_err("mac_ctx is NULL");
2989 return;
2990 }
2991
2992 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINED, vdev_id);
2993 }
2994
cm_csr_set_idle(uint8_t vdev_id)2995 void cm_csr_set_idle(uint8_t vdev_id)
2996 {
2997 struct mac_context *mac;
2998
2999 mac = sme_get_mac_context();
3000 if (!mac) {
3001 sme_err("mac_ctx is NULL");
3002 return;
3003 }
3004
3005 csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, vdev_id);
3006 }
3007
cm_csr_set_ss_none(uint8_t vdev_id)3008 void cm_csr_set_ss_none(uint8_t vdev_id)
3009 {
3010 struct mac_context *mac;
3011
3012 mac = sme_get_mac_context();
3013 if (!mac) {
3014 sme_err("mac_ctx is NULL");
3015 return;
3016 }
3017
3018 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
3019 vdev_id);
3020 }
3021
csr_roam_ndi_stop(struct mac_context * mac_ctx,uint8_t vdev_id)3022 QDF_STATUS csr_roam_ndi_stop(struct mac_context *mac_ctx, uint8_t vdev_id)
3023 {
3024 QDF_STATUS status = QDF_STATUS_E_FAILURE;
3025 bool is_vdev_up;
3026 bool is_start_bss_in_active_q = false;
3027
3028 csr_flush_pending_start_bss_cmd(mac_ctx, vdev_id);
3029
3030 is_vdev_up = wlan_is_vdev_id_up(mac_ctx->pdev, vdev_id);
3031 if (wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
3032 WLAN_SER_CMD_VDEV_START_BSS))
3033 is_start_bss_in_active_q = true;
3034
3035 sme_debug("vdev_id: %d is_vdev_up %d is_start_bss_in_active_q %d",
3036 vdev_id, is_vdev_up, is_start_bss_in_active_q);
3037
3038 if (is_vdev_up || is_start_bss_in_active_q)
3039 status = csr_roam_issue_stop_bss_cmd(mac_ctx, vdev_id,
3040 eCSR_BSS_TYPE_NDI);
3041 return status;
3042 }
3043
3044 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
csr_fill_single_pmk(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct bss_description * bss_desc)3045 static void csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3046 struct bss_description *bss_desc)
3047 {
3048 struct cm_roam_values_copy src_cfg = {};
3049
3050 src_cfg.bool_value = bss_desc->is_single_pmk;
3051 wlan_cm_roam_cfg_set_value(psoc, vdev_id,
3052 IS_SINGLE_PMK, &src_cfg);
3053 }
3054 #else
3055 static inline void
csr_fill_single_pmk(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct bss_description * bss_desc)3056 csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3057 struct bss_description *bss_desc)
3058 {}
3059 #endif
3060
csr_roam_roaming_state_stop_bss_rsp_processor(struct mac_context * mac,void * msg)3061 void csr_roam_roaming_state_stop_bss_rsp_processor(struct mac_context *mac,
3062 void *msg)
3063 {
3064 struct stop_bss_rsp *stop_bss_rsp = (struct stop_bss_rsp *)msg;
3065 uint8_t vdev_id = stop_bss_rsp->vdev_id;
3066 enum csr_sap_response_type result_code = CSR_SAP_STOP_BSS_SUCCESS;
3067
3068 sme_debug("Received stop bss rsp on vdev: %d", vdev_id);
3069 mac->roam.roamSession[vdev_id].connectState =
3070 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
3071 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac, vdev_id)) {
3072 if (stop_bss_rsp->status_code != eSIR_SME_SUCCESS)
3073 result_code = CSR_SAP_STOP_BSS_FAILURE;
3074 csr_process_sap_response(mac, result_code, NULL, vdev_id);
3075 }
3076 }
3077
3078 static
csr_roam_roaming_state_disassoc_rsp_processor(struct mac_context * mac,struct disassoc_rsp * rsp)3079 void csr_roam_roaming_state_disassoc_rsp_processor(struct mac_context *mac,
3080 struct disassoc_rsp *rsp)
3081 {
3082 struct csr_roam_session *pSession;
3083
3084 sme_debug("Received disassoc response for vdev : %d status : %d",
3085 rsp->sessionId, rsp->status_code);
3086
3087 pSession = CSR_GET_SESSION(mac, rsp->sessionId);
3088 if (!pSession) {
3089 sme_err("session not found");
3090 return;
3091 }
3092
3093 csr_roam_complete(mac, rsp->sessionId);
3094 }
3095
csr_roam_roaming_state_deauth_rsp_processor(struct mac_context * mac,struct deauth_rsp * rsp)3096 static void csr_roam_roaming_state_deauth_rsp_processor(struct mac_context *mac,
3097 struct deauth_rsp *rsp)
3098 {
3099 csr_roam_complete(mac, rsp->sessionId);
3100 }
3101
3102 void
csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context * mac,void * msg)3103 csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context *mac,
3104 void *msg)
3105 {
3106 enum csr_sap_response_type result;
3107 struct start_bss_rsp *start_bss_rsp = (struct start_bss_rsp *)msg;
3108
3109 if (!CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(mac, start_bss_rsp->vdev_id)) {
3110 sme_err(" Start bss received in invalid state");
3111 return;
3112 }
3113
3114 sme_debug("Start Bss response status : %d",
3115 start_bss_rsp->status_code);
3116 if (start_bss_rsp->status_code == eSIR_SME_SUCCESS)
3117 result = CSR_SAP_START_BSS_SUCCESS;
3118 else
3119 result = CSR_SAP_START_BSS_FAILURE;
3120
3121 csr_process_sap_response(mac, result, start_bss_rsp,
3122 start_bss_rsp->vdev_id);
3123 }
3124
3125
3126 /**
3127 * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD.
3128 *
3129 * @mac_ctx: mac global context
3130 * @msg_ptr: incoming message
3131 *
3132 * This function gives final disconnect event to HDD after all cleanup in
3133 * lower layers is done.
3134 *
3135 * Return: None
3136 */
3137 static void
csr_roam_send_disconnect_done_indication(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)3138 csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx,
3139 tSirSmeRsp *msg_ptr)
3140 {
3141 struct sir_sme_discon_done_ind *discon_ind =
3142 (struct sir_sme_discon_done_ind *)(msg_ptr);
3143 struct csr_roam_info *roam_info;
3144 uint8_t vdev_id;
3145
3146 vdev_id = discon_ind->session_id;
3147 roam_info = qdf_mem_malloc(sizeof(*roam_info));
3148 if (!roam_info)
3149 return;
3150
3151 sme_debug("DISCONNECT_DONE_IND RC:%d", discon_ind->reason_code);
3152
3153 if (CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
3154 roam_info->reasonCode = discon_ind->reason_code;
3155 roam_info->status_code = eSIR_SME_STA_NOT_ASSOCIATED;
3156 qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac,
3157 ETH_ALEN);
3158
3159 roam_info->rssi = mac_ctx->peer_rssi;
3160 roam_info->tx_rate = mac_ctx->peer_txrate;
3161 roam_info->rx_rate = mac_ctx->peer_rxrate;
3162 roam_info->disassoc_reason = discon_ind->reason_code;
3163 roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt;
3164 roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt;
3165 csr_roam_call_callback(mac_ctx, vdev_id,
3166 roam_info, eCSR_ROAM_LOSTLINK,
3167 eCSR_ROAM_RESULT_DISASSOC_IND);
3168 } else {
3169 sme_err("Inactive vdev_id %d", vdev_id);
3170 }
3171
3172 /*
3173 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND
3174 * has been sent to HDD and there is nothing else left to do.
3175 */
3176 csr_roam_wm_status_change_complete(mac_ctx, vdev_id);
3177 qdf_mem_free(roam_info);
3178 }
3179
3180 /**
3181 * csr_roaming_state_msg_processor() - process roaming messages
3182 * @mac: mac global context
3183 * @msg_buf: message buffer
3184 *
3185 * We need to be careful on whether to cast msg_buf (pSmeRsp) to other type of
3186 * structures. It depends on how the message is constructed. If the message is
3187 * sent by lim_send_sme_rsp, the msg_buf is only a generic response and can only
3188 * be used as pointer to tSirSmeRsp. For the messages where sender allocates
3189 * memory for specific structures, then it can be cast accordingly.
3190 *
3191 * Return: status of operation
3192 */
csr_roaming_state_msg_processor(struct mac_context * mac,void * msg_buf)3193 void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf)
3194 {
3195 tSirSmeRsp *pSmeRsp;
3196
3197 pSmeRsp = (tSirSmeRsp *)msg_buf;
3198
3199 switch (pSmeRsp->messageType) {
3200 case eWNI_SME_DISASSOC_RSP:
3201 /* or the Disassociate response message... */
3202 if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(mac, pSmeRsp->vdev_id)) {
3203 sme_debug("eWNI_SME_DISASSOC_RSP subState = %s",
3204 mac_trace_getcsr_roam_sub_state(
3205 mac->roam.curSubState[pSmeRsp->vdev_id]));
3206 csr_roam_roaming_state_disassoc_rsp_processor(mac,
3207 (struct disassoc_rsp *) pSmeRsp);
3208 }
3209 break;
3210 case eWNI_SME_DEAUTH_RSP:
3211 /* or the Deauthentication response message... */
3212 if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(mac, pSmeRsp->vdev_id))
3213 csr_roam_roaming_state_deauth_rsp_processor(mac,
3214 (struct deauth_rsp *) pSmeRsp);
3215 break;
3216 /* In case CSR issues STOP_BSS, we need to tell HDD about peer departed
3217 * because PE is removing them
3218 */
3219 case eWNI_SME_TRIGGER_SAE:
3220 sme_debug("Invoke SAE callback");
3221 csr_sae_callback(mac, pSmeRsp);
3222 break;
3223
3224 case eWNI_SME_SETCONTEXT_RSP:
3225 csr_roam_check_for_link_status_change(mac, pSmeRsp);
3226 break;
3227
3228 case eWNI_SME_DISCONNECT_DONE_IND:
3229 csr_roam_send_disconnect_done_indication(mac, pSmeRsp);
3230 break;
3231
3232 case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
3233 csr_roam_joined_state_msg_processor(mac, pSmeRsp);
3234 break;
3235 default:
3236 sme_debug("Unexpected message type: %d[0x%X] received in substate %s",
3237 pSmeRsp->messageType, pSmeRsp->messageType,
3238 mac_trace_getcsr_roam_sub_state(
3239 mac->roam.curSubState[pSmeRsp->vdev_id]));
3240 /* If we are connected, check the link status change */
3241 if (!csr_is_conn_state_disconnected(mac, pSmeRsp->vdev_id))
3242 csr_roam_check_for_link_status_change(mac, pSmeRsp);
3243 break;
3244 }
3245 }
3246
3247 #ifdef WLAN_FEATURE_11BE_MLO
3248 static void
csr_roam_assoc_cnf_mld_copy(struct csr_roam_info * roam_info,tSirSmeAssocIndToUpperLayerCnf * pUpperLayerAssocCnf,uint32_t num_bytes)3249 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info,
3250 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf,
3251 uint32_t num_bytes)
3252 {
3253 qdf_mem_copy(roam_info->peer_mld.bytes,
3254 pUpperLayerAssocCnf->peer_mld_addr,
3255 num_bytes);
3256 }
3257 #else /* WLAN_FEATURE_11BE_MLO */
3258 static inline void
csr_roam_assoc_cnf_mld_copy(struct csr_roam_info * roam_info,tSirSmeAssocIndToUpperLayerCnf * pUpperLayerAssocCnf,uint32_t num_bytes)3259 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info,
3260 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf,
3261 uint32_t num_bytes)
3262 {
3263 }
3264 #endif /* WLAN_FEATURE_11BE_MLO */
3265
csr_roam_joined_state_msg_processor(struct mac_context * mac,void * msg_buf)3266 void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *msg_buf)
3267 {
3268 tSirSmeRsp *pSirMsg = (tSirSmeRsp *)msg_buf;
3269
3270 switch (pSirMsg->messageType) {
3271 case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
3272 {
3273 struct csr_roam_session *pSession;
3274 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
3275 struct csr_roam_info *roam_info;
3276 uint32_t sessionId;
3277 QDF_STATUS status;
3278 enum QDF_OPMODE opmode;
3279
3280 sme_debug("ASSOCIATION confirmation can be given to upper layer ");
3281 pUpperLayerAssocCnf =
3282 (tSirSmeAssocIndToUpperLayerCnf *)msg_buf;
3283 status = csr_roam_get_session_id_from_bssid(mac,
3284 (struct qdf_mac_addr *)
3285 pUpperLayerAssocCnf->
3286 bssId, &sessionId);
3287 pSession = CSR_GET_SESSION(mac, sessionId);
3288
3289 if (!pSession) {
3290 sme_err("session %d not found", sessionId);
3291 if (pUpperLayerAssocCnf->ies)
3292 qdf_mem_free(pUpperLayerAssocCnf->ies);
3293 return;
3294 }
3295
3296 roam_info = qdf_mem_malloc(sizeof(*roam_info));
3297 if (!roam_info) {
3298 if (pUpperLayerAssocCnf->ies)
3299 qdf_mem_free(pUpperLayerAssocCnf->ies);
3300 return;
3301 }
3302 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, sessionId);
3303 /* send the status code as Success */
3304 roam_info->status_code = eSIR_SME_SUCCESS;
3305 roam_info->staId = (uint8_t) pUpperLayerAssocCnf->aid;
3306 roam_info->rsnIELen =
3307 (uint8_t) pUpperLayerAssocCnf->rsnIE.length;
3308 roam_info->prsnIE =
3309 pUpperLayerAssocCnf->rsnIE.rsnIEdata;
3310 #ifdef FEATURE_WLAN_WAPI
3311 roam_info->wapiIELen =
3312 (uint8_t) pUpperLayerAssocCnf->wapiIE.length;
3313 roam_info->pwapiIE =
3314 pUpperLayerAssocCnf->wapiIE.wapiIEdata;
3315 #endif
3316 roam_info->addIELen =
3317 (uint8_t) pUpperLayerAssocCnf->addIE.length;
3318 roam_info->paddIE =
3319 pUpperLayerAssocCnf->addIE.addIEdata;
3320 qdf_mem_copy(roam_info->peerMac.bytes,
3321 pUpperLayerAssocCnf->peerMacAddr,
3322 sizeof(tSirMacAddr));
3323 csr_roam_assoc_cnf_mld_copy(roam_info,
3324 pUpperLayerAssocCnf,
3325 sizeof(tSirMacAddr));
3326 qdf_mem_copy(&roam_info->bssid,
3327 pUpperLayerAssocCnf->bssId,
3328 sizeof(struct qdf_mac_addr));
3329 roam_info->wmmEnabledSta =
3330 pUpperLayerAssocCnf->wmmEnabledSta;
3331 roam_info->timingMeasCap =
3332 pUpperLayerAssocCnf->timingMeasCap;
3333 qdf_mem_copy(&roam_info->chan_info,
3334 &pUpperLayerAssocCnf->chan_info,
3335 sizeof(struct oem_channel_info));
3336
3337 roam_info->ampdu = pUpperLayerAssocCnf->ampdu;
3338 roam_info->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
3339 roam_info->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
3340 roam_info->rx_stbc = pUpperLayerAssocCnf->rx_stbc;
3341 roam_info->ch_width = pUpperLayerAssocCnf->ch_width;
3342 roam_info->mode = pUpperLayerAssocCnf->mode;
3343 roam_info->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
3344 roam_info->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
3345 roam_info->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
3346 roam_info->max_real_mcs_idx =
3347 pUpperLayerAssocCnf->max_real_mcs_idx;
3348 roam_info->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
3349 roam_info->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
3350 roam_info->ecsa_capable = pUpperLayerAssocCnf->ecsa_capable;
3351 roam_info->ext_cap = pUpperLayerAssocCnf->ext_cap;
3352 roam_info->supported_band =
3353 pUpperLayerAssocCnf->supported_band;
3354 if (pUpperLayerAssocCnf->ht_caps.present)
3355 roam_info->ht_caps = pUpperLayerAssocCnf->ht_caps;
3356 if (pUpperLayerAssocCnf->vht_caps.present)
3357 roam_info->vht_caps = pUpperLayerAssocCnf->vht_caps;
3358 roam_info->capability_info =
3359 pUpperLayerAssocCnf->capability_info;
3360 roam_info->he_caps_present =
3361 pUpperLayerAssocCnf->he_caps_present;
3362 roam_info->eht_caps_present =
3363 pUpperLayerAssocCnf->eht_caps_present;
3364 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
3365 if (pUpperLayerAssocCnf->ies_len > 0) {
3366 roam_info->assocReqLength =
3367 pUpperLayerAssocCnf->ies_len;
3368 roam_info->assocReqPtr =
3369 pUpperLayerAssocCnf->ies;
3370 }
3371
3372 mac->roam.roamSession[sessionId].connectState =
3373 eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
3374 roam_info->fReassocReq =
3375 pUpperLayerAssocCnf->reassocReq;
3376 status = csr_roam_call_callback(mac, sessionId,
3377 roam_info,
3378 eCSR_ROAM_INFRA_IND,
3379 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
3380 }
3381 if (pUpperLayerAssocCnf->ies)
3382 qdf_mem_free(pUpperLayerAssocCnf->ies);
3383 qdf_mem_free(roam_info);
3384 }
3385 break;
3386 default:
3387 csr_roam_check_for_link_status_change(mac, pSirMsg);
3388 break;
3389 }
3390 }
3391
3392 /**
3393 * csr_update_wep_key_peer_macaddr() - Update wep key peer mac addr
3394 * @vdev: vdev object
3395 * @crypto_key: crypto key info
3396 * @unicast: uncast or broadcast
3397 * @mac_addr: peer mac address
3398 *
3399 * Update peer mac address to key context before set wep key to target.
3400 *
3401 * Return void
3402 */
3403 static void
csr_update_wep_key_peer_macaddr(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_key * crypto_key,bool unicast,struct qdf_mac_addr * mac_addr)3404 csr_update_wep_key_peer_macaddr(struct wlan_objmgr_vdev *vdev,
3405 struct wlan_crypto_key *crypto_key,
3406 bool unicast,
3407 struct qdf_mac_addr *mac_addr)
3408 {
3409 if (!crypto_key || !vdev) {
3410 sme_err("vdev or crytpo_key null");
3411 return;
3412 }
3413
3414 if (unicast) {
3415 qdf_mem_copy(&crypto_key->macaddr, mac_addr,
3416 QDF_MAC_ADDR_SIZE);
3417 } else {
3418 if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE ||
3419 vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE)
3420 qdf_mem_copy(&crypto_key->macaddr, mac_addr,
3421 QDF_MAC_ADDR_SIZE);
3422 else
3423 qdf_mem_copy(&crypto_key->macaddr,
3424 vdev->vdev_mlme.macaddr,
3425 QDF_MAC_ADDR_SIZE);
3426 }
3427 }
3428
3429 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3430 static void
csr_roam_diag_set_ctx_rsp(struct mac_context * mac_ctx,struct csr_roam_session * session,struct set_context_rsp * pRsp)3431 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx,
3432 struct csr_roam_session *session,
3433 struct set_context_rsp *pRsp)
3434 {
3435 WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
3436 host_event_wlan_security_payload_type);
3437 struct wlan_objmgr_vdev *vdev;
3438
3439 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev,
3440 session->vdev_id,
3441 WLAN_LEGACY_SME_ID);
3442 if (!vdev)
3443 return;
3444 if (cm_is_open_mode(vdev)) {
3445 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
3446 return;
3447 }
3448 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
3449
3450 qdf_mem_zero(&setKeyEvent,
3451 sizeof(host_event_wlan_security_payload_type));
3452 if (qdf_is_macaddr_group(&pRsp->peer_macaddr))
3453 setKeyEvent.eventId =
3454 WLAN_SECURITY_EVENT_SET_BCAST_RSP;
3455 else
3456 setKeyEvent.eventId =
3457 WLAN_SECURITY_EVENT_SET_UNICAST_RSP;
3458 cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc,
3459 &setKeyEvent.authMode,
3460 &setKeyEvent.encryptionModeUnicast,
3461 &setKeyEvent.encryptionModeMulticast,
3462 session->vdev_id);
3463 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session->vdev_id,
3464 (struct qdf_mac_addr *)&setKeyEvent.bssid);
3465 if (eSIR_SME_SUCCESS != pRsp->status_code)
3466 setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
3467 WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
3468 }
3469 #else /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
3470 static void
csr_roam_diag_set_ctx_rsp(struct mac_context * mac_ctx,struct csr_roam_session * session,struct set_context_rsp * pRsp)3471 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx,
3472 struct csr_roam_session *session,
3473 struct set_context_rsp *pRsp)
3474 {
3475 }
3476 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
3477
3478 #ifdef WLAN_FEATURE_11BE_MLO
3479 static QDF_STATUS
csr_roam_send_rso_enable(struct mac_context * mac_ctx,uint8_t vdev_id)3480 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id)
3481 {
3482 struct wlan_objmgr_vdev *vdev = NULL;
3483 struct wlan_objmgr_vdev *assoc_vdev = NULL;
3484
3485 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
3486 vdev_id,
3487 WLAN_MLME_OBJMGR_ID);
3488 if (!vdev) {
3489 sme_err("vdev object is NULL for vdev %d", vdev_id);
3490 return QDF_STATUS_E_FAILURE;
3491 }
3492
3493 if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
3494 mlo_check_if_all_links_up(vdev)) {
3495 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
3496 if (!assoc_vdev) {
3497 sme_err("Assoc vdev is null");
3498 wlan_objmgr_vdev_release_ref(vdev,
3499 WLAN_MLME_OBJMGR_ID);
3500 return QDF_STATUS_E_FAILURE;
3501 }
3502 cm_roam_start_init_on_connect(mac_ctx->pdev,
3503 wlan_vdev_get_id(assoc_vdev));
3504 } else if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
3505 cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id);
3506 }
3507 wlan_objmgr_vdev_release_ref(vdev,
3508 WLAN_MLME_OBJMGR_ID);
3509 return QDF_STATUS_SUCCESS;
3510 }
3511 #else
3512 static QDF_STATUS
csr_roam_send_rso_enable(struct mac_context * mac_ctx,uint8_t vdev_id)3513 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id)
3514 {
3515 cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id);
3516 return QDF_STATUS_SUCCESS;
3517 }
3518 #endif
3519
3520 static void
csr_roam_chk_lnk_set_ctx_rsp(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)3521 csr_roam_chk_lnk_set_ctx_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3522 {
3523 struct csr_roam_session *session;
3524 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
3525 QDF_STATUS status;
3526 qdf_freq_t chan_freq;
3527 struct csr_roam_info *roam_info;
3528 eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
3529 struct set_context_rsp *pRsp = (struct set_context_rsp *)msg_ptr;
3530 struct qdf_mac_addr connected_bssid;
3531
3532 if (!pRsp) {
3533 sme_err("set key response is NULL");
3534 return;
3535 }
3536
3537 roam_info = qdf_mem_malloc(sizeof(*roam_info));
3538 if (!roam_info)
3539 return;
3540 sessionId = pRsp->sessionId;
3541 session = CSR_GET_SESSION(mac_ctx, sessionId);
3542 if (!session) {
3543 sme_err("session %d not found", sessionId);
3544 qdf_mem_free(roam_info);
3545 return;
3546 }
3547
3548 csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp);
3549 chan_freq = wlan_get_operation_chan_freq_vdev_id(mac_ctx->pdev,
3550 sessionId);
3551 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId,
3552 &connected_bssid);
3553 sme_debug("vdev %d, Status %d, peer_macaddr "QDF_MAC_ADDR_FMT " obss offload %d freq %d opmode %d",
3554 pRsp->sessionId, pRsp->status_code,
3555 QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes),
3556 mac_ctx->obss_scan_offload, chan_freq,
3557 wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId));
3558
3559 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) {
3560 /* We are done with authentication, whethere succeed or not */
3561 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
3562 sessionId);
3563 cm_stop_wait_for_key_timer(mac_ctx->psoc, sessionId);
3564 if (QDF_IS_STATUS_ERROR(csr_roam_send_rso_enable(mac_ctx,
3565 sessionId))) {
3566 qdf_mem_free(roam_info);
3567 return;
3568 }
3569 }
3570 if (eSIR_SME_SUCCESS == pRsp->status_code) {
3571 qdf_copy_macaddr(&roam_info->peerMac, &pRsp->peer_macaddr);
3572 /* Make sure we install the GTK before indicating to HDD as
3573 * authenticated. This is to prevent broadcast packets go out
3574 * after PTK and before GTK.
3575 */
3576 if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) {
3577 /*
3578 * OBSS SCAN Indication will be sent to Firmware
3579 * to start OBSS Scan
3580 */
3581 if (mac_ctx->obss_scan_offload &&
3582 wlan_reg_is_24ghz_ch_freq(chan_freq) &&
3583 cm_is_vdevid_connected(mac_ctx->pdev, sessionId)) {
3584 struct sme_obss_ht40_scanind_msg *msg;
3585
3586 msg = qdf_mem_malloc(sizeof(
3587 struct sme_obss_ht40_scanind_msg));
3588 if (!msg) {
3589 qdf_mem_free(roam_info);
3590 return;
3591 }
3592
3593 msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND;
3594 msg->length =
3595 sizeof(struct sme_obss_ht40_scanind_msg);
3596 qdf_copy_macaddr(&msg->mac_addr,
3597 &connected_bssid);
3598 status = umac_send_mb_message_to_mac(msg);
3599 }
3600 result = eCSR_ROAM_RESULT_AUTHENTICATED;
3601 } else {
3602 result = eCSR_ROAM_RESULT_NONE;
3603 }
3604 } else {
3605 result = eCSR_ROAM_RESULT_FAILURE;
3606 sme_err(
3607 "CSR: setkey command failed(err=%d) PeerMac "
3608 QDF_MAC_ADDR_FMT,
3609 pRsp->status_code,
3610 QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes));
3611 }
3612 csr_roam_call_callback(mac_ctx, sessionId, roam_info,
3613 eCSR_ROAM_SET_KEY_COMPLETE, result);
3614 /* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS
3615 * can go ahead and initiate the TSPEC if any are pending
3616 */
3617 sme_qos_csr_event_ind(mac_ctx, (uint8_t)sessionId,
3618 SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL);
3619 #ifdef FEATURE_WLAN_ESE
3620 /* Send Adjacent AP repot to new AP. */
3621 if (result == eCSR_ROAM_RESULT_AUTHENTICATED &&
3622 session->isPrevApInfoValid &&
3623 wlan_cm_get_ese_assoc(mac_ctx->pdev, sessionId)) {
3624 csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session);
3625 session->isPrevApInfoValid = false;
3626 }
3627 #endif
3628 qdf_mem_free(roam_info);
3629 }
3630
csr_roam_issue_set_context_req(struct mac_context * mac_ctx,uint32_t session_id,bool add_key,bool unicast,uint8_t key_idx,struct qdf_mac_addr * mac_addr)3631 static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx,
3632 uint32_t session_id,
3633 bool add_key, bool unicast,
3634 uint8_t key_idx,
3635 struct qdf_mac_addr *mac_addr)
3636 {
3637 enum wlan_crypto_cipher_type cipher;
3638 struct wlan_crypto_key *crypto_key;
3639 uint8_t wep_key_idx = 0;
3640 struct wlan_objmgr_vdev *vdev;
3641
3642 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id,
3643 WLAN_LEGACY_MAC_ID);
3644 if (!vdev) {
3645 sme_err("VDEV object not found for session_id %d", session_id);
3646 return QDF_STATUS_E_INVAL;
3647 }
3648 cipher = wlan_crypto_get_cipher(vdev, unicast, key_idx);
3649 if (IS_WEP_CIPHER(cipher)) {
3650 wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast);
3651 crypto_key = wlan_crypto_get_key(vdev, wep_key_idx);
3652 csr_update_wep_key_peer_macaddr(vdev, crypto_key, unicast,
3653 mac_addr);
3654 } else {
3655 crypto_key = wlan_crypto_get_key(vdev, key_idx);
3656 }
3657
3658 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
3659
3660 sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d",
3661 session_id, cipher, unicast, key_idx, wep_key_idx, add_key);
3662 if (!IS_WEP_CIPHER(cipher) && !add_key)
3663 return QDF_STATUS_E_INVAL;
3664
3665 return ucfg_crypto_set_key_req(vdev, crypto_key, (unicast ?
3666 WLAN_CRYPTO_KEY_TYPE_UNICAST :
3667 WLAN_CRYPTO_KEY_TYPE_GROUP));
3668 }
3669
3670 QDF_STATUS
csr_issue_set_context_req_helper(struct mac_context * mac_ctx,uint32_t vdev_id,tSirMacAddr * bssid,bool addkey,bool unicast,uint8_t key_id)3671 csr_issue_set_context_req_helper(struct mac_context *mac_ctx,
3672 uint32_t vdev_id, tSirMacAddr *bssid,
3673 bool addkey, bool unicast, uint8_t key_id)
3674 {
3675 return csr_roam_issue_set_context_req(mac_ctx, vdev_id, addkey,
3676 unicast, key_id,
3677 (struct qdf_mac_addr *)bssid);
3678 }
3679
3680 static
csr_roam_issue_wm_status_change(struct mac_context * mac,uint32_t sessionId,enum csr_roam_wmstatus_changetypes Type,tSirSmeRsp * pSmeRsp)3681 bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId,
3682 enum csr_roam_wmstatus_changetypes Type,
3683 tSirSmeRsp *pSmeRsp)
3684 {
3685 bool fCommandQueued = false;
3686 tSmeCmd *pCommand;
3687
3688 do {
3689 /* Validate the type is ok... */
3690 if ((eCsrDisassociated != Type)
3691 && (eCsrDeauthenticated != Type))
3692 break;
3693 pCommand = csr_get_command_buffer(mac);
3694 if (!pCommand) {
3695 sme_err(" fail to get command buffer");
3696 break;
3697 }
3698
3699 pCommand->command = eSmeCommandWmStatusChange;
3700 pCommand->vdev_id = (uint8_t) sessionId;
3701 pCommand->u.wmStatusChangeCmd.Type = Type;
3702 if (eCsrDisassociated == Type) {
3703 qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
3704 DisassocIndMsg, pSmeRsp,
3705 sizeof(pCommand->u.wmStatusChangeCmd.u.
3706 DisassocIndMsg));
3707 } else {
3708 qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
3709 DeauthIndMsg, pSmeRsp,
3710 sizeof(pCommand->u.wmStatusChangeCmd.u.
3711 DeauthIndMsg));
3712 }
3713 if (QDF_IS_STATUS_SUCCESS
3714 (csr_queue_sme_command(mac, pCommand, false)))
3715 fCommandQueued = true;
3716 else
3717 sme_err("fail to send message");
3718 } while (0);
3719 return fCommandQueued;
3720 }
3721
csr_update_snr(struct mac_context * mac,void * pMsg)3722 static void csr_update_snr(struct mac_context *mac, void *pMsg)
3723 {
3724 tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg;
3725
3726 if (pGetSnrReq) {
3727 if (QDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) {
3728 sme_err("Error in wma_get_snr");
3729 return;
3730 }
3731
3732 } else
3733 sme_err("pGetSnrReq is NULL");
3734 }
3735
3736 /**
3737 * csr_translate_akm_type() - Convert ani_akm_type value to equivalent
3738 * enum csr_akm_type
3739 * @akm_type: value of type ani_akm_type
3740 *
3741 * Return: enum csr_akm_type value
3742 */
csr_translate_akm_type(enum ani_akm_type akm_type)3743 static enum csr_akm_type csr_translate_akm_type(enum ani_akm_type akm_type)
3744 {
3745 enum csr_akm_type csr_akm_type;
3746
3747 switch (akm_type)
3748 {
3749 case ANI_AKM_TYPE_NONE:
3750 csr_akm_type = eCSR_AUTH_TYPE_NONE;
3751 break;
3752 #ifdef WLAN_FEATURE_SAE
3753 case ANI_AKM_TYPE_SAE:
3754 csr_akm_type = eCSR_AUTH_TYPE_SAE;
3755 break;
3756 #endif
3757 case ANI_AKM_TYPE_WPA:
3758 csr_akm_type = eCSR_AUTH_TYPE_WPA;
3759 break;
3760 case ANI_AKM_TYPE_WPA_PSK:
3761 csr_akm_type = eCSR_AUTH_TYPE_WPA_PSK;
3762 break;
3763 case ANI_AKM_TYPE_RSN:
3764 csr_akm_type = eCSR_AUTH_TYPE_RSN;
3765 break;
3766 case ANI_AKM_TYPE_RSN_PSK:
3767 csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK;
3768 break;
3769 case ANI_AKM_TYPE_FT_RSN:
3770 csr_akm_type = eCSR_AUTH_TYPE_FT_RSN;
3771 break;
3772 case ANI_AKM_TYPE_FT_RSN_PSK:
3773 csr_akm_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
3774 break;
3775 #ifdef FEATURE_WLAN_ESE
3776 case ANI_AKM_TYPE_CCKM:
3777 csr_akm_type = eCSR_AUTH_TYPE_CCKM_RSN;
3778 break;
3779 #endif
3780 case ANI_AKM_TYPE_RSN_PSK_SHA256:
3781 csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
3782 break;
3783 case ANI_AKM_TYPE_RSN_8021X_SHA256:
3784 csr_akm_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
3785 break;
3786 case ANI_AKM_TYPE_FILS_SHA256:
3787 csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA256;
3788 break;
3789 case ANI_AKM_TYPE_FILS_SHA384:
3790 csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA384;
3791 break;
3792 case ANI_AKM_TYPE_FT_FILS_SHA256:
3793 csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
3794 break;
3795 case ANI_AKM_TYPE_FT_FILS_SHA384:
3796 csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
3797 break;
3798 case ANI_AKM_TYPE_DPP_RSN:
3799 csr_akm_type = eCSR_AUTH_TYPE_DPP_RSN;
3800 break;
3801 case ANI_AKM_TYPE_OWE:
3802 csr_akm_type = eCSR_AUTH_TYPE_OWE;
3803 break;
3804 case ANI_AKM_TYPE_SUITEB_EAP_SHA256:
3805 csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
3806 break;
3807 case ANI_AKM_TYPE_SUITEB_EAP_SHA384:
3808 csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
3809 break;
3810 case ANI_AKM_TYPE_OSEN:
3811 csr_akm_type = eCSR_AUTH_TYPE_OSEN;
3812 break;
3813 default:
3814 csr_akm_type = eCSR_AUTH_TYPE_UNKNOWN;
3815 }
3816
3817 return csr_akm_type;
3818 }
3819
3820 #ifdef WLAN_FEATURE_11BE_MLO
3821 static void
csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf * cnf,struct assoc_ind * ind)3822 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf,
3823 struct assoc_ind *ind)
3824 {
3825 qdf_mem_copy(&cnf->peer_mld_addr, &ind->peer_mld_addr,
3826 sizeof(cnf->peer_mld_addr));
3827 }
3828 #else /* WLAN_FEATURE_11BE_MLO */
3829 static inline void
csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf * cnf,struct assoc_ind * ind)3830 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf,
3831 struct assoc_ind *ind)
3832 {
3833 }
3834 #endif /* WLAN_FEATURE_11BE_MLO */
3835
3836 static QDF_STATUS
csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context * mac,struct assoc_ind * ind,QDF_STATUS status,uint8_t vdev_id)3837 csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac,
3838 struct assoc_ind *ind,
3839 QDF_STATUS status,
3840 uint8_t vdev_id)
3841 {
3842 struct scheduler_msg msg = {0};
3843 tSirSmeAssocIndToUpperLayerCnf *cnf;
3844
3845 cnf = qdf_mem_malloc(sizeof(*cnf));
3846 if (!cnf)
3847 return QDF_STATUS_E_NOMEM;
3848
3849 cnf->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
3850 cnf->length = sizeof(*cnf);
3851 cnf->sessionId = vdev_id;
3852
3853 if (QDF_IS_STATUS_SUCCESS(status))
3854 cnf->status_code = eSIR_SME_SUCCESS;
3855 else
3856 cnf->status_code = eSIR_SME_ASSOC_REFUSED;
3857 qdf_mem_copy(&cnf->bssId, &ind->bssId, sizeof(cnf->bssId));
3858 qdf_mem_copy(&cnf->peerMacAddr, &ind->peerMacAddr,
3859 sizeof(cnf->peerMacAddr));
3860 csr_send_assoc_ind_to_upper_layer_mac_copy(cnf, ind);
3861 cnf->aid = ind->staId;
3862 cnf->wmmEnabledSta = ind->wmmEnabledSta;
3863 cnf->rsnIE = ind->rsnIE;
3864 #ifdef FEATURE_WLAN_WAPI
3865 cnf->wapiIE = ind->wapiIE;
3866 #endif
3867 cnf->addIE = ind->addIE;
3868 cnf->reassocReq = ind->reassocReq;
3869 cnf->timingMeasCap = ind->timingMeasCap;
3870 cnf->chan_info = ind->chan_info;
3871 cnf->ampdu = ind->ampdu;
3872 cnf->sgi_enable = ind->sgi_enable;
3873 cnf->tx_stbc = ind->tx_stbc;
3874 cnf->ch_width = ind->ch_width;
3875 cnf->mode = ind->mode;
3876 cnf->rx_stbc = ind->rx_stbc;
3877 cnf->max_supp_idx = ind->max_supp_idx;
3878 cnf->max_ext_idx = ind->max_ext_idx;
3879 cnf->max_mcs_idx = ind->max_mcs_idx;
3880 cnf->max_real_mcs_idx = ind->max_real_mcs_idx;
3881 cnf->rx_mcs_map = ind->rx_mcs_map;
3882 cnf->tx_mcs_map = ind->tx_mcs_map;
3883 cnf->ecsa_capable = ind->ecsa_capable;
3884 cnf->ext_cap = ind->ext_cap;
3885 cnf->supported_band = ind->supported_band;
3886 if (ind->HTCaps.present)
3887 cnf->ht_caps = ind->HTCaps;
3888 if (ind->VHTCaps.present)
3889 cnf->vht_caps = ind->VHTCaps;
3890 cnf->capability_info = ind->capability_info;
3891 cnf->he_caps_present = ind->he_caps_present;
3892 cnf->eht_caps_present = ind->eht_caps_present;
3893 if (ind->assocReqPtr) {
3894 if (ind->assocReqLength < MAX_ASSOC_REQ_IE_LEN) {
3895 cnf->ies = qdf_mem_malloc(ind->assocReqLength);
3896 if (!cnf->ies) {
3897 qdf_mem_free(cnf);
3898 return QDF_STATUS_E_NOMEM;
3899 }
3900 cnf->ies_len = ind->assocReqLength;
3901 qdf_mem_copy(cnf->ies, ind->assocReqPtr,
3902 cnf->ies_len);
3903 } else {
3904 sme_err("Assoc Ie length is too long");
3905 }
3906 }
3907
3908 msg.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
3909 msg.bodyptr = cnf;
3910 sys_process_mmh_msg(mac, &msg);
3911
3912 return QDF_STATUS_SUCCESS;
3913 }
3914
3915 static void
csr_roam_chk_lnk_assoc_ind_upper_layer(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)3916 csr_roam_chk_lnk_assoc_ind_upper_layer(
3917 struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3918 {
3919 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
3920 struct assoc_ind *assoc_ind;
3921 QDF_STATUS status;
3922
3923 assoc_ind = (struct assoc_ind *)msg_ptr;
3924 status = csr_roam_get_session_id_from_bssid(
3925 mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId,
3926 &session_id);
3927 if (!QDF_IS_STATUS_SUCCESS(status)) {
3928 sme_debug("Couldn't find session_id for given BSSID");
3929 goto free_mem;
3930 }
3931 csr_send_assoc_ind_to_upper_layer_cnf_msg(
3932 mac_ctx, assoc_ind, status, session_id);
3933 /*in the association response tx compete case,
3934 *memory for assoc_ind->assocReqPtr will be malloced
3935 *in the lim_assoc_rsp_tx_complete -> lim_fill_sme_assoc_ind_params
3936 *and then assoc_ind will pass here, so after using it
3937 *in the csr_send_assoc_ind_to_upper_layer_cnf_msg and
3938 *then free the memory here.
3939 */
3940 free_mem:
3941 if (assoc_ind->assocReqLength != 0 && assoc_ind->assocReqPtr)
3942 qdf_mem_free(assoc_ind->assocReqPtr);
3943 }
3944
3945 static void
csr_roam_chk_lnk_assoc_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)3946 csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3947 {
3948 struct csr_roam_session *session;
3949 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
3950 QDF_STATUS status;
3951 struct csr_roam_info *roam_info;
3952 struct assoc_ind *pAssocInd;
3953 enum wlan_status_code mac_status_code = STATUS_SUCCESS;
3954 enum csr_akm_type csr_akm_type;
3955 enum QDF_OPMODE opmode;
3956
3957 sme_debug("Receive WNI_SME_ASSOC_IND from SME");
3958 pAssocInd = (struct assoc_ind *) msg_ptr;
3959 sme_debug("Receive WNI_SME_ASSOC_IND from SME vdev id %d",
3960 pAssocInd->sessionId);
3961 status = csr_roam_get_session_id_from_bssid(mac_ctx,
3962 (struct qdf_mac_addr *) pAssocInd->bssId,
3963 &sessionId);
3964 if (!QDF_IS_STATUS_SUCCESS(status)) {
3965 sme_debug("Couldn't find session_id for given BSSID" QDF_MAC_ADDR_FMT,
3966 QDF_MAC_ADDR_REF(pAssocInd->bssId));
3967 return;
3968 }
3969 session = CSR_GET_SESSION(mac_ctx, sessionId);
3970 if (!session) {
3971 sme_err("session %d not found", sessionId);
3972 return;
3973 }
3974 csr_akm_type = csr_translate_akm_type(pAssocInd->akm_type);
3975
3976 roam_info = qdf_mem_malloc(sizeof(*roam_info));
3977 if (!roam_info)
3978 return;
3979 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
3980 /* Required for indicating the frames to upper layer */
3981 roam_info->assocReqLength = pAssocInd->assocReqLength;
3982 roam_info->assocReqPtr = pAssocInd->assocReqPtr;
3983 roam_info->status_code = eSIR_SME_SUCCESS;
3984 roam_info->staId = (uint8_t)pAssocInd->staId;
3985 roam_info->rsnIELen = (uint8_t)pAssocInd->rsnIE.length;
3986 roam_info->prsnIE = pAssocInd->rsnIE.rsnIEdata;
3987 #ifdef FEATURE_WLAN_WAPI
3988 roam_info->wapiIELen = (uint8_t)pAssocInd->wapiIE.length;
3989 roam_info->pwapiIE = pAssocInd->wapiIE.wapiIEdata;
3990 #endif
3991 roam_info->addIELen = (uint8_t)pAssocInd->addIE.length;
3992 roam_info->paddIE = pAssocInd->addIE.addIEdata;
3993 roam_info->fReassocReq = pAssocInd->reassocReq;
3994 qdf_mem_copy(roam_info->peerMac.bytes,
3995 pAssocInd->peerMacAddr,
3996 sizeof(tSirMacAddr));
3997 qdf_mem_copy(roam_info->bssid.bytes,
3998 pAssocInd->bssId,
3999 sizeof(struct qdf_mac_addr));
4000 roam_info->wmmEnabledSta = pAssocInd->wmmEnabledSta;
4001 roam_info->timingMeasCap = pAssocInd->timingMeasCap;
4002 roam_info->ecsa_capable = pAssocInd->ecsa_capable;
4003 qdf_mem_copy(&roam_info->chan_info,
4004 &pAssocInd->chan_info,
4005 sizeof(struct oem_channel_info));
4006
4007 if (pAssocInd->HTCaps.present)
4008 qdf_mem_copy(&roam_info->ht_caps,
4009 &pAssocInd->HTCaps,
4010 sizeof(tDot11fIEHTCaps));
4011 if (pAssocInd->VHTCaps.present)
4012 qdf_mem_copy(&roam_info->vht_caps,
4013 &pAssocInd->VHTCaps,
4014 sizeof(tDot11fIEVHTCaps));
4015 roam_info->capability_info = pAssocInd->capability_info;
4016 roam_info->he_caps_present = pAssocInd->he_caps_present;
4017 roam_info->eht_caps_present = pAssocInd->eht_caps_present;
4018 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
4019 if (wlan_is_open_wep_cipher(mac_ctx->pdev, sessionId)) {
4020 csr_issue_set_context_req_helper(mac_ctx, sessionId,
4021 &roam_info->peerMac.bytes, false, true,
4022 0);
4023 roam_info->fAuthRequired = false;
4024 } else {
4025 roam_info->fAuthRequired = true;
4026 }
4027 sme_debug("Receive AUTH_TYPE of %d", csr_akm_type);
4028 if (csr_akm_type == eCSR_AUTH_TYPE_OWE) {
4029 roam_info->owe_pending_assoc_ind = qdf_mem_malloc(
4030 sizeof(*pAssocInd));
4031 if (roam_info->owe_pending_assoc_ind)
4032 qdf_mem_copy(roam_info->owe_pending_assoc_ind,
4033 pAssocInd, sizeof(*pAssocInd));
4034 } else if (csr_akm_type == eCSR_AUTH_TYPE_FT_RSN_PSK) {
4035 roam_info->ft_pending_assoc_ind = qdf_mem_malloc(
4036 sizeof(*pAssocInd));
4037 if (roam_info->ft_pending_assoc_ind)
4038 qdf_mem_copy(roam_info->ft_pending_assoc_ind,
4039 pAssocInd, sizeof(*pAssocInd));
4040 }
4041 status = csr_roam_call_callback(mac_ctx, sessionId,
4042 roam_info, eCSR_ROAM_INFRA_IND,
4043 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
4044 if (!QDF_IS_STATUS_SUCCESS(status)) {
4045 /* Refused due to Mac filtering */
4046 if (roam_info->owe_pending_assoc_ind) {
4047 qdf_mem_free(roam_info->owe_pending_assoc_ind);
4048 roam_info->owe_pending_assoc_ind = NULL;
4049 } else if (roam_info->ft_pending_assoc_ind) {
4050 qdf_mem_free(roam_info->ft_pending_assoc_ind);
4051 roam_info->ft_pending_assoc_ind = NULL;
4052 }
4053 roam_info->status_code = eSIR_SME_ASSOC_REFUSED;
4054 }
4055 }
4056 sme_debug("csr_akm_type: %d", csr_akm_type);
4057
4058 if (csr_akm_type != eCSR_AUTH_TYPE_OWE &&
4059 csr_akm_type != eCSR_AUTH_TYPE_FT_RSN_PSK) {
4060 if ((opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) &&
4061 roam_info->status_code != eSIR_SME_ASSOC_REFUSED)
4062 pAssocInd->need_assoc_rsp_tx_cb = true;
4063 /* Send Association completion message to PE */
4064 status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
4065 mac_status_code);
4066 }
4067
4068 qdf_mem_free(roam_info);
4069 }
4070
4071 /* csr_if_peer_present() - Check whether peer is present or not
4072 * @mac_ctx: Pointer to mac context
4073 * @bssid: Pointer to bssid address
4074 * @peer_macaddr: Pointer to peer mac address
4075 *
4076 * Consider a case
4077 * 1. SAP received south bound disconnect command
4078 * 2. At same time, SAP CSA to DFS channel happened and thus peers are deleted.
4079 * 3. Later same peer got re-added and south bound disconnect command becomes
4080 * active for same peer.
4081 *
4082 * When SAP receives south bound disconnect command req, driver will post to
4083 * schedular thread and it will wait in SME message queue. When SAP CSA to DFS
4084 * channel happens, driver will post to schedular thread and it will wait in PE
4085 * message queue. Since PE has higher priority than SME message queue, so it
4086 * will process first. As part of CSA, it will delete all peer including sta
4087 * hash entry.
4088 * After CSA, south bound disconnect command got queue to serialization and
4089 * same peer got re-added again. When south bound disconnect command becomes
4090 * active, the states will not be proper because for old peer, disassocTrigger
4091 * is eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and when new peer gets
4092 * re-added, disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH and
4093 * thus response to CSR will not be proper. Due to this south bound disconnect
4094 * command will not remove from active queue which leads to active command
4095 * timeout.
4096 * Validate the peer before sending to serialization to avoid queuing command
4097 * if peer is already deleted.
4098 *
4099 * Return: True if peer is present otherwise return false
4100 */
csr_if_peer_present(struct mac_context * mac_ctx,uint8_t * bssid,uint8_t * peer_macaddr)4101 static bool csr_if_peer_present(struct mac_context *mac_ctx,
4102 uint8_t *bssid,
4103 uint8_t *peer_macaddr)
4104 {
4105 struct wlan_objmgr_peer *peer;
4106 uint8_t pdev_id;
4107
4108 pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
4109
4110 peer = wlan_objmgr_get_peer_by_mac_n_vdev(mac_ctx->psoc, pdev_id,
4111 bssid, peer_macaddr,
4112 WLAN_LEGACY_SME_ID);
4113
4114 if (!peer) {
4115 sme_info("peer not found for mac: " QDF_MAC_ADDR_FMT "and bssid: "
4116 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr),
4117 QDF_MAC_ADDR_REF(bssid));
4118 return false;
4119 }
4120
4121 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
4122 return true;
4123 }
4124
4125 static void
csr_roam_chk_lnk_disassoc_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4126 csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4127 {
4128 struct csr_roam_session *session;
4129 uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
4130 struct disassoc_ind *disassoc_ind;
4131
4132 /*
4133 * Check if AP dis-associated us because of MIC failure. If so,
4134 * then we need to take action immediately and not wait till the
4135 * the WmStatusChange requests is pushed and processed
4136 */
4137 disassoc_ind = (struct disassoc_ind *)msg_ptr;
4138 vdev_id = disassoc_ind->vdev_id;
4139
4140 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
4141 sme_err("vdev:%d Invalid session. BSSID: " QDF_MAC_ADDR_FMT,
4142 vdev_id, QDF_MAC_ADDR_REF(disassoc_ind->bssid.bytes));
4143
4144 return;
4145 }
4146
4147 if (!csr_if_peer_present(mac_ctx, &disassoc_ind->bssid.bytes[0],
4148 &disassoc_ind->peer_macaddr.bytes[0]))
4149 return;
4150
4151 if (csr_is_deauth_disassoc_cmd_active(mac_ctx, vdev_id,
4152 disassoc_ind->peer_macaddr,
4153 &disassoc_ind->peer_macaddr,
4154 &disassoc_ind->peer_mld_addr))
4155 return;
4156
4157 session = CSR_GET_SESSION(mac_ctx, vdev_id);
4158 if (!session) {
4159 sme_err("vdev %d session not found", vdev_id);
4160 return;
4161 }
4162 sme_debug("Vdev %d, peer " QDF_MAC_ADDR_FMT " reason: %d status: %d",
4163 vdev_id, QDF_MAC_ADDR_REF(disassoc_ind->peer_macaddr.bytes),
4164 disassoc_ind->reasonCode, disassoc_ind->status_code);
4165 /* Update the disconnect stats */
4166 session->disconnect_stats.disconnection_cnt++;
4167 session->disconnect_stats.disassoc_by_peer++;
4168
4169 csr_roam_issue_wm_status_change(mac_ctx, vdev_id,
4170 eCsrDisassociated, msg_ptr);
4171 }
4172
4173 static void
csr_roam_chk_lnk_deauth_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4174 csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4175 {
4176 struct csr_roam_session *session;
4177 uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
4178 struct deauth_ind *deauth_ind;
4179
4180 deauth_ind = (struct deauth_ind *)msg_ptr;
4181
4182 vdev_id = deauth_ind->vdev_id;
4183 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
4184 sme_err("vdev %d: Invalid session BSSID: " QDF_MAC_ADDR_FMT,
4185 deauth_ind->vdev_id,
4186 QDF_MAC_ADDR_REF(deauth_ind->bssid.bytes));
4187 return;
4188 }
4189
4190 if (!csr_if_peer_present(mac_ctx, &deauth_ind->bssid.bytes[0],
4191 &deauth_ind->peer_macaddr.bytes[0]))
4192 return;
4193
4194 if (csr_is_deauth_disassoc_cmd_active(mac_ctx, vdev_id,
4195 deauth_ind->peer_macaddr,
4196 &deauth_ind->peer_macaddr,
4197 &deauth_ind->peer_mld_addr))
4198 return;
4199
4200 session = CSR_GET_SESSION(mac_ctx, vdev_id);
4201 if (!session) {
4202 sme_err("vdev %d session not found", vdev_id);
4203 return;
4204 }
4205 sme_debug("vdev %d bssid " QDF_MAC_ADDR_FMT " reason: %d status: %d",
4206 deauth_ind->vdev_id,
4207 QDF_MAC_ADDR_REF(deauth_ind->bssid.bytes),
4208 deauth_ind->reasonCode, deauth_ind->status_code);
4209 /* Update the disconnect stats */
4210 switch (deauth_ind->reasonCode) {
4211 case REASON_DISASSOC_DUE_TO_INACTIVITY:
4212 session->disconnect_stats.disconnection_cnt++;
4213 session->disconnect_stats.peer_kickout++;
4214 break;
4215 case REASON_UNSPEC_FAILURE:
4216 case REASON_PREV_AUTH_NOT_VALID:
4217 case REASON_DEAUTH_NETWORK_LEAVING:
4218 case REASON_CLASS2_FRAME_FROM_NON_AUTH_STA:
4219 case REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA:
4220 case REASON_STA_NOT_AUTHENTICATED:
4221 session->disconnect_stats.disconnection_cnt++;
4222 session->disconnect_stats.deauth_by_peer++;
4223 break;
4224 case REASON_BEACON_MISSED:
4225 session->disconnect_stats.disconnection_cnt++;
4226 session->disconnect_stats.bmiss++;
4227 break;
4228 default:
4229 /* Unknown reason code */
4230 break;
4231 }
4232
4233 csr_roam_issue_wm_status_change(mac_ctx, vdev_id,
4234 eCsrDeauthenticated,
4235 msg_ptr);
4236 }
4237
4238 static void
csr_roam_chk_lnk_swt_ch_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4239 csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4240 {
4241 struct csr_roam_session *session;
4242 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4243 QDF_STATUS status;
4244 struct switch_channel_ind *pSwitchChnInd;
4245 struct csr_roam_info *roam_info;
4246
4247 /* in case of STA, the SWITCH_CHANNEL originates from its AP */
4248 sme_debug("eWNI_SME_SWITCH_CHL_IND from SME");
4249 pSwitchChnInd = (struct switch_channel_ind *)msg_ptr;
4250 /* Update with the new channel id. The channel id is hidden in the
4251 * status_code.
4252 */
4253 status = csr_roam_get_session_id_from_bssid(mac_ctx,
4254 &pSwitchChnInd->bssid, &sessionId);
4255 if (QDF_IS_STATUS_ERROR(status))
4256 return;
4257
4258 session = CSR_GET_SESSION(mac_ctx, sessionId);
4259 if (!session) {
4260 sme_err("session %d not found", sessionId);
4261 return;
4262 }
4263
4264 if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) {
4265 sme_err("Channel switch failed");
4266 return;
4267 }
4268 /* Update the occupied channel list with the new switched channel */
4269 wlan_cm_init_occupied_ch_freq_list(mac_ctx->pdev, mac_ctx->psoc,
4270 sessionId);
4271 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4272 if (!roam_info)
4273 return;
4274 roam_info->chan_info.mhz = pSwitchChnInd->freq;
4275 roam_info->chan_info.ch_width = pSwitchChnInd->chan_params.ch_width;
4276 roam_info->chan_info.sec_ch_offset =
4277 pSwitchChnInd->chan_params.sec_ch_offset;
4278 roam_info->chan_info.band_center_freq1 =
4279 pSwitchChnInd->chan_params.mhz_freq_seg0;
4280 roam_info->chan_info.band_center_freq2 =
4281 pSwitchChnInd->chan_params.mhz_freq_seg1;
4282
4283 if (IS_WLAN_PHYMODE_HT(pSwitchChnInd->ch_phymode))
4284 roam_info->mode = SIR_SME_PHY_MODE_HT;
4285 else if (IS_WLAN_PHYMODE_VHT(pSwitchChnInd->ch_phymode) ||
4286 IS_WLAN_PHYMODE_HE(pSwitchChnInd->ch_phymode))
4287 roam_info->mode = SIR_SME_PHY_MODE_VHT;
4288 #ifdef WLAN_FEATURE_11BE
4289 else if (IS_WLAN_PHYMODE_EHT(pSwitchChnInd->ch_phymode))
4290 roam_info->mode = SIR_SME_PHY_MODE_VHT;
4291 #endif
4292 else
4293 roam_info->mode = SIR_SME_PHY_MODE_LEGACY;
4294
4295 status = csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4296 eCSR_ROAM_STA_CHANNEL_SWITCH,
4297 eCSR_ROAM_RESULT_NONE);
4298 qdf_mem_free(roam_info);
4299 }
4300
4301 static void
csr_roam_chk_lnk_deauth_rsp(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4302 csr_roam_chk_lnk_deauth_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4303 {
4304 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4305 QDF_STATUS status;
4306 struct csr_roam_info *roam_info;
4307 struct deauth_rsp *pDeauthRsp = (struct deauth_rsp *) msg_ptr;
4308 enum QDF_OPMODE opmode;
4309
4310 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4311 if (!roam_info)
4312 return;
4313 sme_debug("eWNI_SME_DEAUTH_RSP from SME");
4314 sessionId = pDeauthRsp->sessionId;
4315 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4316 qdf_mem_free(roam_info);
4317 return;
4318 }
4319 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
4320 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
4321 qdf_copy_macaddr(&roam_info->peerMac,
4322 &pDeauthRsp->peer_macaddr);
4323 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
4324 roam_info->status_code = pDeauthRsp->status_code;
4325 status = csr_roam_call_callback(mac_ctx, sessionId,
4326 roam_info, eCSR_ROAM_LOSTLINK,
4327 eCSR_ROAM_RESULT_FORCED);
4328 }
4329 qdf_mem_free(roam_info);
4330 }
4331
4332 static void
csr_roam_chk_lnk_disassoc_rsp(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4333 csr_roam_chk_lnk_disassoc_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4334 {
4335 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4336 QDF_STATUS status;
4337 struct csr_roam_info *roam_info;
4338 enum QDF_OPMODE opmode;
4339 /*
4340 * session id is invalid here so cant use it to access the array
4341 * curSubstate as index
4342 */
4343 struct disassoc_rsp *pDisassocRsp = (struct disassoc_rsp *) msg_ptr;
4344
4345 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4346 if (!roam_info)
4347 return;
4348 sme_debug("eWNI_SME_DISASSOC_RSP from SME ");
4349 sessionId = pDisassocRsp->sessionId;
4350 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4351 qdf_mem_free(roam_info);
4352 return;
4353 }
4354 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
4355 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
4356 qdf_copy_macaddr(&roam_info->peerMac,
4357 &pDisassocRsp->peer_macaddr);
4358 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
4359 roam_info->status_code = pDisassocRsp->status_code;
4360 status = csr_roam_call_callback(mac_ctx, sessionId,
4361 roam_info,
4362 eCSR_ROAM_LOSTLINK,
4363 eCSR_ROAM_RESULT_FORCED);
4364 }
4365 qdf_mem_free(roam_info);
4366 }
4367
4368 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4369 static void
csr_roam_diag_mic_fail(struct mac_context * mac_ctx,uint32_t sessionId)4370 csr_roam_diag_mic_fail(struct mac_context *mac_ctx, uint32_t sessionId)
4371 {
4372 WLAN_HOST_DIAG_EVENT_DEF(secEvent,
4373 host_event_wlan_security_payload_type);
4374 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId);
4375
4376 if (!session) {
4377 sme_err("session %d not found", sessionId);
4378 return;
4379 }
4380 qdf_mem_zero(&secEvent, sizeof(host_event_wlan_security_payload_type));
4381 secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR;
4382 cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc,
4383 &secEvent.authMode,
4384 &secEvent.encryptionModeUnicast,
4385 &secEvent.encryptionModeMulticast,
4386 sessionId);
4387 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId,
4388 (struct qdf_mac_addr *)&secEvent.bssid);
4389 WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
4390 }
4391 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
4392
4393 static void
csr_roam_chk_lnk_mic_fail_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4394 csr_roam_chk_lnk_mic_fail_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4395 {
4396 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4397 QDF_STATUS status;
4398 struct csr_roam_info *roam_info;
4399 struct mic_failure_ind *mic_ind = (struct mic_failure_ind *)msg_ptr;
4400 eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
4401
4402 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4403 if (!roam_info)
4404 return;
4405 status = csr_roam_get_session_id_from_bssid(mac_ctx,
4406 &mic_ind->bssId, &sessionId);
4407 if (QDF_IS_STATUS_SUCCESS(status)) {
4408 roam_info->u.pMICFailureInfo = &mic_ind->info;
4409 if (mic_ind->info.multicast)
4410 result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP;
4411 else
4412 result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
4413 csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4414 eCSR_ROAM_MIC_ERROR_IND, result);
4415 }
4416 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4417 csr_roam_diag_mic_fail(mac_ctx, sessionId);
4418 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
4419 qdf_mem_free(roam_info);
4420 }
4421
4422 static void
csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4423 csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4424 {
4425 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4426 QDF_STATUS status;
4427 struct csr_roam_info *roam_info;
4428 tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr;
4429
4430 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4431 if (!roam_info)
4432 return;
4433 sme_debug("WPS PBC Probe request Indication from SME");
4434
4435 status = csr_roam_get_session_id_from_bssid(mac_ctx,
4436 &pProbeReqInd->bssid, &sessionId);
4437 if (QDF_IS_STATUS_SUCCESS(status)) {
4438 roam_info->u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq;
4439 csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4440 eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
4441 eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
4442 }
4443 qdf_mem_free(roam_info);
4444 }
4445
4446 static void
csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context * mac_ctx,tSirSmeRsp * msg_ptr)4447 csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4448 {
4449 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4450 tSmeMaxAssocInd *pSmeMaxAssocInd;
4451 struct csr_roam_info *roam_info;
4452
4453 roam_info = qdf_mem_malloc(sizeof(*roam_info));
4454 if (!roam_info)
4455 return;
4456 pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr;
4457 sme_debug(
4458 "max assoc have been reached, new peer cannot be accepted");
4459 sessionId = pSmeMaxAssocInd->sessionId;
4460 qdf_copy_macaddr(&roam_info->peerMac, &pSmeMaxAssocInd->peer_mac);
4461 csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4462 eCSR_ROAM_INFRA_IND,
4463 eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
4464 qdf_mem_free(roam_info);
4465 }
4466
csr_roam_check_for_link_status_change(struct mac_context * mac,tSirSmeRsp * pSirMsg)4467 void csr_roam_check_for_link_status_change(struct mac_context *mac,
4468 tSirSmeRsp *pSirMsg)
4469 {
4470 if (!pSirMsg) {
4471 sme_err("pSirMsg is NULL");
4472 return;
4473 }
4474 switch (pSirMsg->messageType) {
4475 case eWNI_SME_ASSOC_IND:
4476 csr_roam_chk_lnk_assoc_ind(mac, pSirMsg);
4477 break;
4478 case eWNI_SME_ASSOC_IND_UPPER_LAYER:
4479 csr_roam_chk_lnk_assoc_ind_upper_layer(mac, pSirMsg);
4480 break;
4481 case eWNI_SME_DISASSOC_IND:
4482 csr_roam_chk_lnk_disassoc_ind(mac, pSirMsg);
4483 break;
4484 case eWNI_SME_DISCONNECT_DONE_IND:
4485 csr_roam_send_disconnect_done_indication(mac, pSirMsg);
4486 break;
4487 case eWNI_SME_DEAUTH_IND:
4488 csr_roam_chk_lnk_deauth_ind(mac, pSirMsg);
4489 break;
4490 case eWNI_SME_SWITCH_CHL_IND:
4491 csr_roam_chk_lnk_swt_ch_ind(mac, pSirMsg);
4492 break;
4493 case eWNI_SME_DEAUTH_RSP:
4494 csr_roam_chk_lnk_deauth_rsp(mac, pSirMsg);
4495 break;
4496 case eWNI_SME_DISASSOC_RSP:
4497 csr_roam_chk_lnk_disassoc_rsp(mac, pSirMsg);
4498 break;
4499 case eWNI_SME_MIC_FAILURE_IND:
4500 csr_roam_chk_lnk_mic_fail_ind(mac, pSirMsg);
4501 break;
4502 case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
4503 csr_roam_chk_lnk_pbs_probe_req_ind(mac, pSirMsg);
4504 break;
4505 case eWNI_SME_SETCONTEXT_RSP:
4506 csr_roam_chk_lnk_set_ctx_rsp(mac, pSirMsg);
4507 break;
4508 #ifdef FEATURE_WLAN_ESE
4509 case eWNI_SME_GET_TSM_STATS_RSP:
4510 sme_debug("TSM Stats rsp from PE");
4511 csr_tsm_stats_rsp_processor(mac, pSirMsg);
4512 break;
4513 #endif /* FEATURE_WLAN_ESE */
4514 case eWNI_SME_GET_SNR_REQ:
4515 sme_debug("GetSnrReq from self");
4516 csr_update_snr(mac, pSirMsg);
4517 break;
4518 case eWNI_SME_MAX_ASSOC_EXCEEDED:
4519 csr_roam_chk_lnk_max_assoc_exceeded(mac, pSirMsg);
4520 break;
4521 default:
4522 break;
4523 } /* end switch on message type */
4524 }
4525
csr_roam_wm_status_change_complete(struct mac_context * mac,uint8_t session_id)4526 void csr_roam_wm_status_change_complete(struct mac_context *mac,
4527 uint8_t session_id)
4528 {
4529 tListElem *pEntry;
4530 tSmeCmd *pCommand;
4531
4532 pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
4533 if (pEntry) {
4534 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
4535 if (eSmeCommandWmStatusChange == pCommand->command) {
4536 /* Nothing to process in a Lost Link completion.... It just kicks off a */
4537 /* roaming sequence. */
4538 if (csr_nonscan_active_ll_remove_entry(mac, pEntry,
4539 LL_ACCESS_LOCK)) {
4540 csr_release_command(mac, pCommand);
4541 } else {
4542 sme_err("Failed to release command");
4543 }
4544 } else {
4545 sme_warn("CSR: LOST LINK command is not ACTIVE ...");
4546 }
4547 } else {
4548 sme_warn("CSR: NO commands are ACTIVE ...");
4549 }
4550 }
4551
csr_roam_process_wm_status_change_command(struct mac_context * mac,tSmeCmd * pCommand)4552 void csr_roam_process_wm_status_change_command(
4553 struct mac_context *mac, tSmeCmd *pCommand)
4554 {
4555 struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
4556 pCommand->vdev_id);
4557 struct qdf_mac_addr peer_mac;
4558
4559 if (!pSession) {
4560 sme_err("session %d not found", pCommand->vdev_id);
4561 csr_roam_wm_status_change_complete(mac, pCommand->vdev_id);
4562 }
4563 sme_debug("session:%d, CmdType : %d",
4564 pCommand->vdev_id, pCommand->u.wmStatusChangeCmd.Type);
4565
4566 switch (pCommand->u.wmStatusChangeCmd.Type) {
4567 case eCsrDisassociated:
4568 qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd.
4569 u.DisassocIndMsg.peer_macaddr,
4570 QDF_MAC_ADDR_SIZE);
4571 /*
4572 * Get peer stats before peer gets deleted so that these stats
4573 * can be given to user space when big data stats are queried.
4574 * Once peer stats are retrieved disassoc sta will continue
4575 */
4576 csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac);
4577 break;
4578 case eCsrDeauthenticated:
4579 qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd.
4580 u.DeauthIndMsg.peer_macaddr,
4581 QDF_MAC_ADDR_SIZE);
4582 /*
4583 * Get peer stats before peer gets deleted so that these stats
4584 * can be given to user space when big data stats are queried.
4585 * Once peer stats are retrieved deauth sta will continue
4586 */
4587 csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac);
4588 break;
4589 default:
4590 sme_warn("gets an unknown command %d",
4591 pCommand->u.wmStatusChangeCmd.Type);
4592 csr_roam_wm_status_change_complete(mac, pCommand->vdev_id);
4593 break;
4594 }
4595 }
4596
4597 /**
4598 * csr_compute_mode_and_band() - computes dot11mode
4599 * @mac: mac global context
4600 * @dot11_mode: out param, do11 mode calculated
4601 * @band: out param, band caclculated
4602 * @opr_ch_freq: operating channel freq in MHz
4603 *
4604 * This function finds dot11 mode based on current mode, operating channel and
4605 * fw supported modes.
4606 *
4607 * Return: void
4608 */
4609 static void
csr_compute_mode_and_band(struct mac_context * mac_ctx,enum csr_cfgdot11mode * dot11_mode,enum reg_wifi_band * band,uint32_t opr_ch_freq)4610 csr_compute_mode_and_band(struct mac_context *mac_ctx,
4611 enum csr_cfgdot11mode *dot11_mode,
4612 enum reg_wifi_band *band,
4613 uint32_t opr_ch_freq)
4614 {
4615 bool vht_24_ghz = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band;
4616
4617 switch (mac_ctx->roam.configParam.uCfgDot11Mode) {
4618 case eCSR_CFG_DOT11_MODE_11A:
4619 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4620 *band = REG_BAND_5G;
4621 break;
4622 case eCSR_CFG_DOT11_MODE_11B:
4623 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4624 *band = REG_BAND_2G;
4625 break;
4626 case eCSR_CFG_DOT11_MODE_11G:
4627 *dot11_mode = eCSR_CFG_DOT11_MODE_11G;
4628 *band = REG_BAND_2G;
4629 break;
4630 case eCSR_CFG_DOT11_MODE_11N:
4631 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4632 *band = wlan_reg_freq_to_band(opr_ch_freq);
4633 break;
4634 case eCSR_CFG_DOT11_MODE_11AC:
4635 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4636 /*
4637 * If the operating channel is in 2.4 GHz band, check
4638 * for INI item to disable VHT operation in 2.4 GHz band
4639 */
4640 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4641 !vht_24_ghz)
4642 /* Disable 11AC operation */
4643 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4644 else
4645 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4646 } else {
4647 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4648 }
4649 *band = wlan_reg_freq_to_band(opr_ch_freq);
4650 break;
4651 case eCSR_CFG_DOT11_MODE_11AC_ONLY:
4652 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4653 /*
4654 * If the operating channel is in 2.4 GHz band, check
4655 * for INI item to disable VHT operation in 2.4 GHz band
4656 */
4657 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4658 !vht_24_ghz)
4659 /* Disable 11AC operation */
4660 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4661 else
4662 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
4663 } else {
4664 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4665 }
4666 *band = wlan_reg_freq_to_band(opr_ch_freq);
4667 break;
4668 case eCSR_CFG_DOT11_MODE_11AX:
4669 case eCSR_CFG_DOT11_MODE_11AX_ONLY:
4670 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4671 *dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
4672 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4673 /*
4674 * If the operating channel is in 2.4 GHz band, check
4675 * for INI item to disable VHT operation in 2.4 GHz band
4676 */
4677 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4678 !vht_24_ghz)
4679 /* Disable 11AC operation */
4680 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4681 else
4682 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4683 } else {
4684 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4685 }
4686 *band = wlan_reg_freq_to_band(opr_ch_freq);
4687 break;
4688 #ifdef WLAN_FEATURE_11BE
4689 case eCSR_CFG_DOT11_MODE_11BE:
4690 case eCSR_CFG_DOT11_MODE_11BE_ONLY:
4691 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
4692 *dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
4693 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4694 *dot11_mode = eCSR_CFG_DOT11_MODE_11AX;
4695 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4696 /*
4697 * If the operating channel is in 2.4 GHz band, check
4698 * for INI item to disable VHT operation in 2.4 GHz band
4699 */
4700 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4701 !vht_24_ghz)
4702 /* Disable 11AC operation */
4703 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4704 else
4705 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4706 } else {
4707 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4708 }
4709 *band = wlan_reg_freq_to_band(opr_ch_freq);
4710 break;
4711 #endif
4712 case eCSR_CFG_DOT11_MODE_AUTO:
4713 #ifdef WLAN_FEATURE_11BE
4714 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
4715 *dot11_mode = eCSR_CFG_DOT11_MODE_11BE;
4716 } else
4717 #endif
4718 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4719 *dot11_mode = eCSR_CFG_DOT11_MODE_11AX;
4720 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4721 /*
4722 * If the operating channel is in 2.4 GHz band,
4723 * check for INI item to disable VHT operation
4724 * in 2.4 GHz band
4725 */
4726 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4727 !vht_24_ghz)
4728 /* Disable 11AC operation */
4729 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4730 else
4731 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4732 } else {
4733 *dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4734 }
4735 *band = wlan_reg_freq_to_band(opr_ch_freq);
4736 break;
4737 default:
4738 /*
4739 * Global dot11 Mode setting is 11a/b/g. use the channel number
4740 * to determine the Mode setting.
4741 */
4742 if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch_freq) {
4743 *band = (mac_ctx->mlme_cfg->gen.band == BAND_2G ?
4744 REG_BAND_2G : REG_BAND_5G);
4745 if (REG_BAND_2G == *band) {
4746 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4747 } else {
4748 /* prefer 5GHz */
4749 *band = REG_BAND_5G;
4750 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4751 }
4752 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq)) {
4753 *dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4754 *band = REG_BAND_2G;
4755 } else {
4756 /* else, it's a 5.0GHz channel. Set mode to 11a. */
4757 *dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4758 *band = REG_BAND_5G;
4759 }
4760 break;
4761 } /* switch */
4762 }
4763
4764 /**
4765 * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode
4766 * information.
4767 * @mac_ctx: mac global context
4768 * dot11_cfg: pointer to dot11 config
4769 *
4770 * This function finds dot11 mode based on current mode, operating channel and
4771 * fw supported modes. The only tricky part is that if phyMode is set to 11abg,
4772 * this function may return eCSR_CFG_DOT11_MODE_11B instead of
4773 * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick.
4774 *
4775 * Return: dot11mode
4776 */
4777 enum csr_cfgdot11mode
csr_roam_get_phy_mode_band_for_bss(struct mac_context * mac_ctx,struct bss_dot11_config * dot11_cfg)4778 csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac_ctx,
4779 struct bss_dot11_config *dot11_cfg)
4780 {
4781 enum reg_wifi_band band = REG_BAND_2G;
4782 qdf_freq_t opr_freq = 0;
4783 bool is_11n_allowed;
4784 enum csr_cfgdot11mode curr_mode =
4785 mac_ctx->roam.configParam.uCfgDot11Mode;
4786 enum csr_cfgdot11mode cfg_dot11_mode;
4787 enum QDF_OPMODE opmode;
4788 bool is_ap = false;
4789 uint8_t privacy;
4790 uint8_t vdev_id = dot11_cfg->vdev_id;
4791
4792 if (dot11_cfg->bss_op_ch_freq)
4793 opr_freq = dot11_cfg->bss_op_ch_freq;
4794
4795 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
4796 is_ap = (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE);
4797 cfg_dot11_mode =
4798 csr_get_cfg_dot11_mode_from_csr_phy_mode(is_ap,
4799 dot11_cfg->phy_mode);
4800 privacy = dot11_cfg->privacy;
4801
4802 /*
4803 * If the global setting for dot11Mode is set to auto/abg, we overwrite
4804 * the setting in the profile.
4805 */
4806 if ((!is_ap && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode) ||
4807 (eCSR_CFG_DOT11_MODE_ABG == curr_mode))) ||
4808 (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode) ||
4809 (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) {
4810 csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode,
4811 &band, opr_freq);
4812 } /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */
4813 else {
4814 /* dot11 mode is set, lets pick the band */
4815 if (0 == opr_freq) {
4816 /* channel is Auto also. */
4817 if (mac_ctx->mlme_cfg->gen.band == BAND_ALL) {
4818 /* prefer 5GHz */
4819 band = REG_BAND_5G;
4820 }
4821 } else{
4822 band = wlan_reg_freq_to_band(opr_freq);
4823 }
4824 }
4825
4826 dot11_cfg->p_band = band;
4827 if (opr_freq == 2484 && wlan_reg_is_24ghz_ch_freq(opr_freq)) {
4828 sme_err("Switching to Dot11B mode");
4829 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4830 }
4831
4832 if (wlan_reg_is_24ghz_ch_freq(opr_freq) &&
4833 !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
4834 (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode ||
4835 eCSR_CFG_DOT11_MODE_11AC_ONLY == cfg_dot11_mode))
4836 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4837 /*
4838 * Incase of WEP Security encryption type is coming as part of add key.
4839 * So while STart BSS dont have information
4840 */
4841 is_11n_allowed = wlan_vdev_id_is_11n_allowed(mac_ctx->pdev, vdev_id);
4842 if ((!is_11n_allowed || (privacy &&
4843 wlan_vdev_id_is_open_cipher(mac_ctx->pdev, vdev_id))) &&
4844 ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) ||
4845 (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode) ||
4846 (eCSR_CFG_DOT11_MODE_11AX == cfg_dot11_mode) ||
4847 CSR_IS_CFG_DOT11_PHY_MODE_11BE(cfg_dot11_mode))) {
4848 /* We cannot do 11n here */
4849 if (wlan_reg_is_24ghz_ch_freq(opr_freq))
4850 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
4851 else
4852 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4853 }
4854 sme_debug("dot11mode: %d phyMode %d is_11n_allowed %d privacy %d chan freq %d fw sup AX %d",
4855 cfg_dot11_mode, dot11_cfg->phy_mode, is_11n_allowed,
4856 privacy, opr_freq,
4857 IS_FEATURE_SUPPORTED_BY_FW(DOT11AX));
4858
4859 #ifdef WLAN_FEATURE_11BE
4860 sme_debug("BE :%d", IS_FEATURE_SUPPORTED_BY_FW(DOT11BE));
4861 #endif
4862 return cfg_dot11_mode;
4863 }
4864
csr_get_cfg_valid_channels(struct mac_context * mac,qdf_freq_t * ch_freq_list,uint32_t * num_ch_freq)4865 QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac,
4866 qdf_freq_t *ch_freq_list,
4867 uint32_t *num_ch_freq)
4868 {
4869 uint8_t num_chan_temp = 0;
4870 int i;
4871 uint32_t *valid_ch_freq_list =
4872 mac->mlme_cfg->reg.valid_channel_freq_list;
4873
4874 *num_ch_freq = mac->mlme_cfg->reg.valid_channel_list_num;
4875
4876 for (i = 0; i < *num_ch_freq; i++) {
4877 if (!wlan_reg_is_dsrc_freq(valid_ch_freq_list[i])) {
4878 ch_freq_list[num_chan_temp] = valid_ch_freq_list[i];
4879 num_chan_temp++;
4880 }
4881 }
4882
4883 *num_ch_freq = num_chan_temp;
4884 return QDF_STATUS_SUCCESS;
4885 }
4886
4887 /**
4888 * csr_convert_mode_to_nw_type() - convert mode into network type
4889 * @dot11_mode: dot11_mode
4890 * @band: 2.4 or 5 GHz
4891 *
4892 * Return: tSirNwType
4893 */
4894 tSirNwType
csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode,enum reg_wifi_band band)4895 csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode,
4896 enum reg_wifi_band band)
4897 {
4898 switch (dot11_mode) {
4899 case eCSR_CFG_DOT11_MODE_11G:
4900 return eSIR_11G_NW_TYPE;
4901 case eCSR_CFG_DOT11_MODE_11B:
4902 return eSIR_11B_NW_TYPE;
4903 case eCSR_CFG_DOT11_MODE_11A:
4904 return eSIR_11A_NW_TYPE;
4905 case eCSR_CFG_DOT11_MODE_11N:
4906 default:
4907 /*
4908 * Because LIM only verifies it against 11a, 11b or 11g, set
4909 * only 11g or 11a here
4910 */
4911 if (REG_BAND_2G == band)
4912 return eSIR_11G_NW_TYPE;
4913 else
4914 return eSIR_11A_NW_TYPE;
4915 }
4916 return eSIR_DONOT_USE_NW_TYPE;
4917 }
4918
4919 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
4920 #ifdef WLAN_FEATURE_11BE_MLO
csr_pmk_match_mlo_address(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * pmksa)4921 static bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev,
4922 struct wlan_crypto_pmksa *pmksa)
4923 {
4924 struct qdf_mac_addr bss_peer_mld_mac = {0};
4925
4926 wlan_vdev_get_bss_peer_mld_mac(vdev, &bss_peer_mld_mac);
4927
4928 return qdf_is_macaddr_equal(&bss_peer_mld_mac, &pmksa->bssid);
4929 }
4930 #else
csr_pmk_match_mlo_address(struct wlan_objmgr_vdev * vdev,struct wlan_crypto_pmksa * pmksa)4931 static inline bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev,
4932 struct wlan_crypto_pmksa *pmksa)
4933 {
4934 return false;
4935 }
4936 #endif
4937
csr_get_pmk_info(struct mac_context * mac_ctx,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache)4938 void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
4939 struct wlan_crypto_pmksa *pmk_cache)
4940 {
4941 if (!mac_ctx) {
4942 sme_err("Mac_ctx is NULL");
4943 return;
4944 }
4945 wlan_cm_get_psk_pmk(mac_ctx->pdev, session_id, pmk_cache->pmk,
4946 &pmk_cache->pmk_len);
4947 }
4948
csr_roam_set_psk_pmk(struct mac_context * mac,struct wlan_crypto_pmksa * pmksa,uint8_t vdev_id,bool update_to_fw)4949 QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac,
4950 struct wlan_crypto_pmksa *pmksa,
4951 uint8_t vdev_id, bool update_to_fw)
4952 {
4953 struct wlan_objmgr_vdev *vdev;
4954 struct qdf_mac_addr connected_bssid = {0};
4955 QDF_STATUS status;
4956
4957 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
4958 WLAN_LEGACY_SME_ID);
4959 if (!vdev) {
4960 sme_err("vdev is NULL");
4961 return QDF_STATUS_E_FAILURE;
4962 }
4963
4964 wlan_mlme_get_bssid_vdev_id(mac->pdev, vdev_id, &connected_bssid);
4965
4966 /*
4967 * If the set_pmksa is received from the userspace in
4968 * connected state and if the connected BSSID is not
4969 * same as the PMKSA entry bssid, then reject this
4970 * global cache updation.
4971 *
4972 * Also for FILS connection, the set_pmksa will not have
4973 * the BSSID. So avoid this check for FILS connection.
4974 */
4975 if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP &&
4976 !pmksa->ssid_len &&
4977 !qdf_is_macaddr_equal(&connected_bssid, &pmksa->bssid) &&
4978 !csr_pmk_match_mlo_address(vdev, pmksa)) {
4979 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4980 sme_debug("Set pmksa received for non-connected bss");
4981 return QDF_STATUS_E_INVAL;
4982 }
4983
4984 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4985
4986 wlan_cm_set_psk_pmk(mac->pdev, vdev_id, pmksa->pmk, pmksa->pmk_len);
4987 if (update_to_fw) {
4988 status = wlan_roam_update_cfg(mac->psoc, vdev_id,
4989 REASON_ROAM_PSK_PMK_CHANGED);
4990 if (status == QDF_STATUS_E_INVAL)
4991 wlan_mlme_defer_pmk_set_in_roaming(mac->psoc, vdev_id,
4992 true);
4993 }
4994
4995 return QDF_STATUS_SUCCESS;
4996 }
4997
csr_set_pmk_cache_ft(struct mac_context * mac,uint8_t vdev_id,struct wlan_crypto_pmksa * pmk_cache)4998 QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint8_t vdev_id,
4999 struct wlan_crypto_pmksa *pmk_cache)
5000 {
5001 struct wlan_objmgr_vdev *vdev;
5002 int32_t akm;
5003
5004 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) {
5005 sme_err("session %d not found", vdev_id);
5006 return QDF_STATUS_E_INVAL;
5007 }
5008
5009 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
5010 WLAN_LEGACY_SME_ID);
5011 if (!vdev) {
5012 sme_err("vdev is NULL");
5013 return QDF_STATUS_E_FAILURE;
5014 }
5015
5016 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
5017
5018 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5019
5020 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
5021 sme_debug("PMK update is not required for ESE");
5022 return QDF_STATUS_SUCCESS;
5023 }
5024
5025 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) ||
5026 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) ||
5027 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) ||
5028 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) {
5029 sme_debug("Auth type: %x update the MDID in cache", akm);
5030 cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache);
5031 } else {
5032 struct cm_roam_values_copy src_cfg = {};
5033 struct scan_filter *scan_filter;
5034 qdf_list_t *list = NULL;
5035 struct scan_cache_node *first_node = NULL;
5036 struct rsn_mdie *mdie = NULL;
5037 qdf_list_node_t *cur_node = NULL;
5038
5039 scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
5040 if (!scan_filter)
5041 return QDF_STATUS_E_NOMEM;
5042 scan_filter->num_of_bssid = 1;
5043 qdf_mem_copy(scan_filter->bssid_list[0].bytes,
5044 &pmk_cache->bssid, sizeof(struct qdf_mac_addr));
5045 list = wlan_scan_get_result(mac->pdev, scan_filter);
5046 qdf_mem_free(scan_filter);
5047 if (!list || (list && !qdf_list_size(list))) {
5048 sme_debug("Scan list is empty");
5049 goto err;
5050 }
5051 qdf_list_peek_front(list, &cur_node);
5052 first_node = qdf_container_of(cur_node,
5053 struct scan_cache_node,
5054 node);
5055 if (first_node && first_node->entry)
5056 mdie = (struct rsn_mdie *)
5057 util_scan_entry_mdie(first_node->entry);
5058 if (mdie) {
5059 sme_debug("Update MDID in cache from scan_res");
5060 src_cfg.bool_value = true;
5061 src_cfg.uint_value =
5062 (mdie->mobility_domain[0] |
5063 (mdie->mobility_domain[1] << 8));
5064 wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
5065 MOBILITY_DOMAIN, &src_cfg);
5066 cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache);
5067 }
5068 err:
5069 if (list)
5070 wlan_scan_purge_results(list);
5071 }
5072 return QDF_STATUS_SUCCESS;
5073 }
5074 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
5075
5076 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
csr_clear_sae_single_pmk(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct wlan_crypto_pmksa * pmk_cache)5077 void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc,
5078 uint8_t vdev_id,
5079 struct wlan_crypto_pmksa *pmk_cache)
5080 {
5081 struct wlan_objmgr_vdev *vdev;
5082 int32_t keymgmt;
5083 struct mlme_pmk_info pmk_info;
5084
5085 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
5086 WLAN_LEGACY_SME_ID);
5087 if (!vdev) {
5088 sme_err("vdev is NULL");
5089 return;
5090 }
5091
5092 keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
5093 if (keymgmt < 0) {
5094 sme_err("Invalid mgmt cipher");
5095 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5096 return;
5097 }
5098
5099 if (!(QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE) ||
5100 QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))) {
5101 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5102 return;
5103 }
5104 if (pmk_cache) {
5105 qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len);
5106 pmk_info.pmk_len = pmk_cache->pmk_len;
5107 wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info);
5108 } else {
5109 wlan_mlme_clear_sae_single_pmk_info(vdev, NULL);
5110 }
5111 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5112 }
5113 #endif
5114
5115 #ifdef FEATURE_WLAN_ESE
csr_update_prev_ap_info(struct csr_roam_session * session,struct wlan_objmgr_vdev * vdev)5116 void csr_update_prev_ap_info(struct csr_roam_session *session,
5117 struct wlan_objmgr_vdev *vdev)
5118 {
5119 struct wlan_ssid ssid;
5120 QDF_STATUS status;
5121 enum QDF_OPMODE opmode;
5122 struct rso_config *rso_cfg;
5123
5124 opmode = wlan_vdev_mlme_get_opmode(vdev);
5125 rso_cfg = wlan_cm_get_rso_config(vdev);
5126 if (!rso_cfg)
5127 return;
5128
5129 if (!rso_cfg->is_ese_assoc || opmode != QDF_STA_MODE)
5130 return;
5131 status = wlan_vdev_mlme_get_ssid(vdev, ssid.ssid, &ssid.length);
5132 if (QDF_IS_STATUS_ERROR(status)) {
5133 sme_err(" failed to find SSID for vdev %d", session->vdev_id);
5134 return;
5135 }
5136 session->isPrevApInfoValid = true;
5137 session->roamTS1 = qdf_mc_timer_get_system_time();
5138 }
5139 #endif
5140
5141 #ifdef WLAN_FEATURE_FILS_SK
csr_cm_update_fils_info(struct wlan_objmgr_vdev * vdev,struct bss_description * bss_desc,struct wlan_cm_vdev_connect_req * req)5142 static QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev,
5143 struct bss_description *bss_desc,
5144 struct wlan_cm_vdev_connect_req *req)
5145 {
5146 uint8_t cache_id[CACHE_ID_LEN] = {0};
5147 struct scan_cache_entry *entry;
5148 struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa;
5149
5150 if (!req->fils_info || !req->fils_info->is_fils_connection) {
5151 wlan_cm_update_mlme_fils_info(vdev, NULL);
5152 return QDF_STATUS_SUCCESS;
5153 }
5154
5155 if (bss_desc->fils_info_element.is_cache_id_present) {
5156 qdf_mem_copy(cache_id, bss_desc->fils_info_element.cache_id,
5157 CACHE_ID_LEN);
5158 sme_debug("FILS_PMKSA: cache_id[0]:%d, cache_id[1]:%d",
5159 cache_id[0], cache_id[1]);
5160 }
5161 entry = req->bss->entry;
5162 bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, &entry->bssid);
5163 fils_ssid_pmksa =
5164 wlan_crypto_get_fils_pmksa(vdev, cache_id,
5165 entry->ssid.ssid,
5166 entry->ssid.length);
5167
5168 if ((!req->fils_info->rrk_len ||
5169 !req->fils_info->username_len) &&
5170 !bss_desc->fils_info_element.is_cache_id_present &&
5171 !bssid_lookup_pmksa && !fils_ssid_pmksa)
5172 return QDF_STATUS_E_FAILURE;
5173
5174 return wlan_cm_update_mlme_fils_info(vdev, req->fils_info);
5175 }
5176 #else
5177 static inline
csr_cm_update_fils_info(struct wlan_objmgr_vdev * vdev,struct bss_description * bss_desc,struct wlan_cm_vdev_connect_req * req)5178 QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev,
5179 struct bss_description *bss_desc,
5180 struct wlan_cm_vdev_connect_req *req)
5181 {
5182 }
5183 #endif
5184
5185 #if defined(WLAN_FEATURE_HOST_ROAM) && defined(FEATURE_WLAN_ESE)
csr_update_tspec_info(struct mac_context * mac_ctx,struct wlan_objmgr_vdev * vdev,tDot11fBeaconIEs * ie_struct)5186 static void csr_update_tspec_info(struct mac_context *mac_ctx,
5187 struct wlan_objmgr_vdev *vdev,
5188 tDot11fBeaconIEs *ie_struct)
5189 {
5190 struct mlme_legacy_priv *mlme_priv;
5191 tESETspecInfo *ese_tspec;
5192
5193 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
5194 if (!mlme_priv)
5195 return;
5196 if (!cm_is_ese_connection(vdev, ie_struct->ESEVersion.present))
5197 return;
5198
5199 ese_tspec = &mlme_priv->connect_info.ese_tspec_info;
5200 qdf_mem_zero(ese_tspec, sizeof(tESETspecInfo));
5201 ese_tspec->numTspecs = sme_qos_ese_retrieve_tspec_info(mac_ctx,
5202 wlan_vdev_get_id(vdev),
5203 ese_tspec->tspec);
5204 }
5205 #else
csr_update_tspec_info(struct mac_context * mac_ctx,struct wlan_objmgr_vdev * vdev,tDot11fBeaconIEs * ie_struct)5206 static inline void csr_update_tspec_info(struct mac_context *mac_ctx,
5207 struct wlan_objmgr_vdev *vdev,
5208 tDot11fBeaconIEs *ie_struct) {}
5209 #endif
5210
cm_csr_send_set_ie(struct wlan_objmgr_vdev * vdev)5211 void cm_csr_send_set_ie(struct wlan_objmgr_vdev *vdev)
5212 {
5213 struct vdev_mlme_obj *vdev_mlme;
5214
5215 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
5216 if (!vdev_mlme) {
5217 sme_err("Failed to get vdev mlme obj!");
5218 QDF_BUG(0);
5219 return;
5220 }
5221
5222 csr_send_set_ie(vdev_mlme->mgmt.generic.type,
5223 vdev_mlme->mgmt.generic.subtype,
5224 wlan_vdev_get_id(vdev));
5225 }
5226
cm_csr_handle_join_req(struct wlan_objmgr_vdev * vdev,struct wlan_cm_vdev_connect_req * req,struct cm_vdev_join_req * join_req,bool reassoc)5227 QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev,
5228 struct wlan_cm_vdev_connect_req *req,
5229 struct cm_vdev_join_req *join_req,
5230 bool reassoc)
5231 {
5232 struct mac_context *mac_ctx;
5233 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5234 QDF_STATUS status;
5235 tDot11fBeaconIEs *ie_struct;
5236 struct bss_description *bss_desc;
5237 uint32_t ie_len, bss_len;
5238
5239 /*
5240 * This API is to update legacy struct and should be removed once
5241 * CSR is cleaned up fully. No new params should be added to CSR, use
5242 * vdev/pdev/psoc instead
5243 */
5244 mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5245 if (!mac_ctx)
5246 return QDF_STATUS_E_INVAL;
5247
5248 ie_len = util_scan_entry_ie_len(join_req->entry);
5249 bss_len = (uint16_t)(offsetof(struct bss_description,
5250 ieFields[0]) + ie_len);
5251
5252 bss_desc = qdf_mem_malloc(sizeof(*bss_desc) + bss_len);
5253 if (!bss_desc)
5254 return QDF_STATUS_E_NOMEM;
5255
5256 status = wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc,
5257 join_req->entry);
5258 if (QDF_IS_STATUS_ERROR(status)) {
5259 qdf_mem_free(bss_desc);
5260 return QDF_STATUS_E_FAILURE;
5261 }
5262
5263 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
5264 &ie_struct);
5265 if (QDF_IS_STATUS_ERROR(status)) {
5266 sme_err("IE parsing failed vdev id %d", vdev_id);
5267 qdf_mem_free(bss_desc);
5268 return QDF_STATUS_E_FAILURE;
5269 }
5270
5271 if (reassoc) {
5272 csr_update_tspec_info(mac_ctx, vdev, ie_struct);
5273 } else {
5274 status = csr_cm_update_fils_info(vdev, bss_desc, req);
5275 if (QDF_IS_STATUS_ERROR(status)) {
5276 sme_err("failed to update fils info vdev id %d",
5277 vdev_id);
5278 qdf_mem_free(ie_struct);
5279 qdf_mem_free(bss_desc);
5280 return QDF_STATUS_E_FAILURE;
5281 }
5282 sme_qos_csr_event_ind(mac_ctx, vdev_id,
5283 SME_QOS_CSR_JOIN_REQ, NULL);
5284 }
5285
5286 if ((wlan_reg_11d_enabled_on_host(mac_ctx->psoc)) &&
5287 !ie_struct->Country.present)
5288 csr_apply_channel_power_info_wrapper(mac_ctx);
5289
5290 qdf_mem_free(ie_struct);
5291 qdf_mem_free(bss_desc);
5292
5293 cm_csr_set_joining(vdev_id);
5294
5295 return QDF_STATUS_SUCCESS;
5296 }
5297
5298 #ifdef FEATURE_WLAN_ESE
csr_get_tspec_ie_len(struct cm_vdev_join_rsp * rsp)5299 static uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp)
5300 {
5301 return rsp->tspec_ie.len;
5302 }
csr_copy_tspec_ie_len(struct csr_roam_session * session,uint8_t * frame_ptr,struct cm_vdev_join_rsp * rsp)5303 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session,
5304 uint8_t *frame_ptr,
5305 struct cm_vdev_join_rsp *rsp)
5306 {
5307 session->connectedInfo.nTspecIeLength = rsp->tspec_ie.len;
5308 if (rsp->tspec_ie.len)
5309 qdf_mem_copy(frame_ptr, rsp->tspec_ie.ptr,
5310 rsp->tspec_ie.len);
5311 }
5312
5313 #else
csr_get_tspec_ie_len(struct cm_vdev_join_rsp * rsp)5314 static inline uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp)
5315 {
5316 return 0;
5317 }
csr_copy_tspec_ie_len(struct csr_roam_session * session,uint8_t * frame_ptr,struct cm_vdev_join_rsp * rsp)5318 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session,
5319 uint8_t *frame_ptr,
5320 struct cm_vdev_join_rsp *rsp)
5321 {}
5322 #endif
5323
csr_fill_connected_info(struct mac_context * mac_ctx,struct csr_roam_session * session,struct cm_vdev_join_rsp * rsp)5324 static void csr_fill_connected_info(struct mac_context *mac_ctx,
5325 struct csr_roam_session *session,
5326 struct cm_vdev_join_rsp *rsp)
5327 {
5328 uint32_t len;
5329 struct wlan_connect_rsp_ies *connect_ies;
5330 uint8_t *frame_ptr;
5331 uint32_t beacon_data_len = 0;
5332
5333 connect_ies = &rsp->connect_rsp.connect_ies;
5334 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
5335 if (connect_ies->bcn_probe_rsp.len > sizeof(struct wlan_frame_hdr))
5336 beacon_data_len = connect_ies->bcn_probe_rsp.len -
5337 sizeof(struct wlan_frame_hdr);
5338 len = beacon_data_len + connect_ies->assoc_req.len +
5339 connect_ies->assoc_rsp.len + rsp->ric_resp_ie.len +
5340 csr_get_tspec_ie_len(rsp);
5341 if (!len)
5342 return;
5343
5344 session->connectedInfo.pbFrames = qdf_mem_malloc(len);
5345 if (!session->connectedInfo.pbFrames)
5346 return;
5347
5348 frame_ptr = session->connectedInfo.pbFrames;
5349 session->connectedInfo.nBeaconLength = beacon_data_len;
5350 if (beacon_data_len)
5351 qdf_mem_copy(frame_ptr,
5352 connect_ies->bcn_probe_rsp.ptr +
5353 sizeof(struct wlan_frame_hdr),
5354 beacon_data_len);
5355 frame_ptr += beacon_data_len;
5356
5357 session->connectedInfo.nAssocReqLength = connect_ies->assoc_req.len;
5358 if (connect_ies->assoc_req.len)
5359 qdf_mem_copy(frame_ptr,
5360 connect_ies->assoc_req.ptr,
5361 connect_ies->assoc_req.len);
5362 frame_ptr += connect_ies->assoc_req.len;
5363
5364 session->connectedInfo.nAssocRspLength = connect_ies->assoc_rsp.len;
5365 if (connect_ies->assoc_rsp.len)
5366 qdf_mem_copy(frame_ptr,
5367 connect_ies->assoc_rsp.ptr,
5368 connect_ies->assoc_rsp.len);
5369 frame_ptr += connect_ies->assoc_rsp.len;
5370
5371 session->connectedInfo.nRICRspLength = rsp->ric_resp_ie.len;
5372 if (rsp->ric_resp_ie.len)
5373 qdf_mem_copy(frame_ptr, rsp->ric_resp_ie.ptr,
5374 rsp->ric_resp_ie.len);
5375 frame_ptr += rsp->ric_resp_ie.len;
5376
5377 csr_copy_tspec_ie_len(session, frame_ptr, rsp);
5378 }
5379
5380 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
csr_qos_send_disconnect_ind(struct mac_context * mac_ctx,uint8_t vdev_id)5381 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx,
5382 uint8_t vdev_id)
5383 {
5384 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_DISCONNECT_IND,
5385 NULL);
5386 }
5387
csr_qos_send_assoc_ind(struct mac_context * mac_ctx,uint8_t vdev_id,sme_QosAssocInfo * assoc_info)5388 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx,
5389 uint8_t vdev_id,
5390 sme_QosAssocInfo *assoc_info)
5391 {
5392 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_ASSOC_COMPLETE,
5393 assoc_info);
5394 }
5395
5396 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
5397 static void
csr_qso_disconnect_complete_ind(struct mac_context * mac_ctx,struct wlan_cm_connect_resp * connect_rsp)5398 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx,
5399 struct wlan_cm_connect_resp *connect_rsp)
5400 {
5401 if (IS_ROAM_REASON_DISCONNECTION(
5402 connect_rsp->roaming_info->roam_reason))
5403 sme_qos_csr_event_ind(mac_ctx, connect_rsp->vdev_id,
5404 SME_QOS_CSR_DISCONNECT_ROAM_COMPLETE,
5405 NULL);
5406 }
5407 #else
5408 static inline void
csr_qso_disconnect_complete_ind(struct mac_context * mac_ctx,struct wlan_cm_connect_resp * connect_rsp)5409 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx,
5410 struct wlan_cm_connect_resp *connect_rsp) {}
5411 #endif
5412
5413 static void
csr_qos_send_reassoc_ind(struct mac_context * mac_ctx,uint8_t vdev_id,sme_QosAssocInfo * assoc_info,struct wlan_cm_connect_resp * connect_rsp)5414 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx,
5415 uint8_t vdev_id,
5416 sme_QosAssocInfo *assoc_info,
5417 struct wlan_cm_connect_resp *connect_rsp)
5418 {
5419 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_ASSOC_REQ,
5420 NULL);
5421 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_REQ,
5422 NULL);
5423 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE,
5424 NULL);
5425 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_COMPLETE,
5426 assoc_info);
5427
5428 csr_qso_disconnect_complete_ind(mac_ctx, connect_rsp);
5429 }
5430 #else
csr_qos_send_disconnect_ind(struct mac_context * mac_ctx,uint8_t vdev_id)5431 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx,
5432 uint8_t vdev_id)
5433 {}
5434
csr_qos_send_assoc_ind(struct mac_context * mac_ctx,uint8_t vdev_id,sme_QosAssocInfo * assoc_info)5435 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx,
5436 uint8_t vdev_id,
5437 sme_QosAssocInfo *assoc_info)
5438 {}
5439 static inline void
csr_qos_send_reassoc_ind(struct mac_context * mac_ctx,uint8_t vdev_id,sme_QosAssocInfo * assoc_info,struct wlan_cm_connect_resp * connect_rsp)5440 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx,
5441 uint8_t vdev_id,
5442 sme_QosAssocInfo *assoc_info,
5443 struct wlan_cm_connect_resp *connect_rsp)
5444 {}
5445 #endif
5446
5447 static void
csr_update_beacon_in_connect_rsp(struct scan_cache_entry * entry,struct wlan_connect_rsp_ies * connect_ies)5448 csr_update_beacon_in_connect_rsp(struct scan_cache_entry *entry,
5449 struct wlan_connect_rsp_ies *connect_ies)
5450 {
5451 if (!entry)
5452 return;
5453
5454 /* no need to update if already present */
5455 if (connect_ies->bcn_probe_rsp.ptr)
5456 return;
5457
5458 /*
5459 * In case connection to MBSSID: Non Tx BSS OR host reassoc,
5460 * vdev/peer manager doesn't send unicast probe req so fill the
5461 * beacon in connect resp IEs here.
5462 */
5463 connect_ies->bcn_probe_rsp.len =
5464 util_scan_entry_frame_len(entry);
5465 connect_ies->bcn_probe_rsp.ptr =
5466 qdf_mem_malloc(connect_ies->bcn_probe_rsp.len);
5467 if (!connect_ies->bcn_probe_rsp.ptr)
5468 return;
5469
5470 qdf_mem_copy(connect_ies->bcn_probe_rsp.ptr,
5471 util_scan_entry_frame_ptr(entry),
5472 connect_ies->bcn_probe_rsp.len);
5473 }
5474
5475 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
csr_is_link_switch_in_progress(struct wlan_objmgr_vdev * vdev)5476 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev)
5477 {
5478 return mlo_mgr_is_link_switch_in_progress(vdev);
5479 }
5480 #else
csr_is_link_switch_in_progress(struct wlan_objmgr_vdev * vdev)5481 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev)
5482 {
5483 return false;
5484 }
5485 #endif
5486
csr_fill_connected_profile(struct mac_context * mac_ctx,struct csr_roam_session * session,struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_rsp * rsp)5487 static void csr_fill_connected_profile(struct mac_context *mac_ctx,
5488 struct csr_roam_session *session,
5489 struct wlan_objmgr_vdev *vdev,
5490 struct cm_vdev_join_rsp *rsp)
5491 {
5492 struct scan_filter *filter;
5493 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5494 QDF_STATUS status;
5495 qdf_list_t *list = NULL;
5496 qdf_list_node_t *cur_lst = NULL;
5497 struct scan_cache_node *cur_node = NULL;
5498 uint32_t bss_len, ie_len;
5499 struct bss_description *bss_desc = NULL;
5500 tDot11fBeaconIEs *bcn_ies;
5501 sme_QosAssocInfo assoc_info;
5502 struct cm_roam_values_copy src_cfg = {};
5503 bool is_ese = false;
5504 uint8_t country_code[REG_ALPHA2_LEN + 1];
5505
5506 session->modifyProfileFields.uapsd_mask = rsp->uapsd_mask;
5507 filter = qdf_mem_malloc(sizeof(*filter));
5508 if (!filter)
5509 return;
5510
5511 filter->num_of_bssid = 1;
5512 qdf_copy_macaddr(&filter->bssid_list[0], &rsp->connect_rsp.bssid);
5513 filter->ignore_auth_enc_type = true;
5514
5515 status = wlan_vdev_mlme_get_ssid(vdev, filter->ssid_list[0].ssid,
5516 &filter->ssid_list[0].length);
5517 if (QDF_IS_STATUS_SUCCESS(status))
5518 filter->num_of_ssid = 1;
5519
5520 list = wlan_scan_get_result(mac_ctx->pdev, filter);
5521 qdf_mem_free(filter);
5522 if (!list || (list && !qdf_list_size(list)))
5523 goto purge_list;
5524
5525
5526 qdf_list_peek_front(list, &cur_lst);
5527 if (!cur_lst)
5528 goto purge_list;
5529
5530 cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node);
5531 ie_len = util_scan_entry_ie_len(cur_node->entry);
5532 bss_len = (uint16_t)(offsetof(struct bss_description,
5533 ieFields[0]) + ie_len);
5534 bss_desc = qdf_mem_malloc(bss_len);
5535 if (!bss_desc)
5536 goto purge_list;
5537
5538 wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, cur_node->entry);
5539 src_cfg.uint_value = bss_desc->mbo_oce_enabled_ap;
5540 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, MBO_OCE_ENABLED_AP,
5541 &src_cfg);
5542 csr_fill_single_pmk(mac_ctx->psoc, vdev_id, bss_desc);
5543 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
5544 &bcn_ies);
5545 if (QDF_IS_STATUS_ERROR(status))
5546 goto purge_list;
5547
5548 if (!bss_desc->beaconInterval)
5549 sme_err("ERROR: Beacon interval is ZERO");
5550
5551 csr_update_beacon_in_connect_rsp(cur_node->entry,
5552 &rsp->connect_rsp.connect_ies);
5553
5554 assoc_info.bss_desc = bss_desc;
5555 if (rsp->connect_rsp.is_reassoc) {
5556 if (cm_is_ese_connection(vdev, bcn_ies->ESEVersion.present))
5557 is_ese = true;
5558 wlan_cm_set_ese_assoc(mac_ctx->pdev, vdev_id, is_ese);
5559 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, UAPSD_MASK,
5560 &src_cfg);
5561 assoc_info.uapsd_mask = src_cfg.uint_value;
5562 csr_qos_send_reassoc_ind(mac_ctx, vdev_id, &assoc_info,
5563 &rsp->connect_rsp);
5564 if (src_cfg.uint_value)
5565 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id);
5566 } else {
5567 assoc_info.uapsd_mask = rsp->uapsd_mask;
5568 csr_qos_send_assoc_ind(mac_ctx, vdev_id, &assoc_info);
5569 }
5570
5571 if (rsp->connect_rsp.is_reassoc ||
5572 csr_is_link_switch_in_progress(vdev))
5573 mlme_set_mbssid_info(vdev, &cur_node->entry->mbssid_info,
5574 bss_desc->chan_freq);
5575
5576 if (bcn_ies->Country.present)
5577 qdf_mem_copy(country_code, bcn_ies->Country.country,
5578 REG_ALPHA2_LEN + 1);
5579 else
5580 qdf_mem_zero(country_code, REG_ALPHA2_LEN + 1);
5581 wlan_cm_set_country_code(mac_ctx->pdev, vdev_id, country_code);
5582
5583 qdf_mem_free(bcn_ies);
5584
5585 purge_list:
5586 if (bss_desc)
5587 qdf_mem_free(bss_desc);
5588 if (list)
5589 wlan_scan_purge_results(list);
5590
5591 }
5592
cm_csr_connect_rsp(struct wlan_objmgr_vdev * vdev,struct cm_vdev_join_rsp * rsp)5593 QDF_STATUS cm_csr_connect_rsp(struct wlan_objmgr_vdev *vdev,
5594 struct cm_vdev_join_rsp *rsp)
5595 {
5596 struct mac_context *mac_ctx;
5597 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5598 struct csr_roam_session *session;
5599 struct cm_roam_values_copy src_config = {};
5600
5601 /*
5602 * This API is to update legacy struct and should be removed once
5603 * CSR is cleaned up fully. No new params should be added to CSR, use
5604 * vdev/pdev/psoc instead
5605 */
5606 if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status))
5607 return QDF_STATUS_SUCCESS;
5608
5609 /* handle below only in case of success */
5610 mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5611 if (!mac_ctx)
5612 return QDF_STATUS_E_INVAL;
5613
5614 session = CSR_GET_SESSION(mac_ctx, vdev_id);
5615 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
5616 sme_err("session not found for vdev_id %d", vdev_id);
5617 return QDF_STATUS_E_INVAL;
5618 }
5619
5620 if (!rsp->connect_rsp.is_reassoc) {
5621 if (rsp->uapsd_mask)
5622 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id);
5623 src_config.uint_value = rsp->uapsd_mask;
5624 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, UAPSD_MASK,
5625 &src_config);
5626 }
5627 session->nss = rsp->nss;
5628 csr_fill_connected_info(mac_ctx, session, rsp);
5629 csr_fill_connected_profile(mac_ctx, session, vdev, rsp);
5630
5631 return QDF_STATUS_SUCCESS;
5632 }
5633
5634 static void
cm_update_rsn_ocv_cap(int32_t * rsn_cap,struct wlan_cm_connect_resp * rsp)5635 cm_update_rsn_ocv_cap(int32_t *rsn_cap,
5636 struct wlan_cm_connect_resp *rsp)
5637 {
5638 struct wlan_crypto_params crypto_params;
5639 uint8_t *ie_ptr;
5640 uint32_t ie_len;
5641 QDF_STATUS status;
5642
5643 /* no need to do anything if OCV is not set */
5644 if (!(*rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED))
5645 return;
5646
5647 if (!rsp->connect_ies.bcn_probe_rsp.ptr ||
5648 !rsp->connect_ies.bcn_probe_rsp.len ||
5649 (rsp->connect_ies.bcn_probe_rsp.len <
5650 (sizeof(struct wlan_frame_hdr) +
5651 offsetof(struct wlan_bcn_frame, ie)))) {
5652 sme_err("invalid beacon probe rsp len %d",
5653 rsp->connect_ies.bcn_probe_rsp.len);
5654 return;
5655 }
5656
5657 ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
5658 sizeof(struct wlan_frame_hdr) -
5659 offsetof(struct wlan_bcn_frame, ie));
5660 ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
5661 sizeof(struct wlan_frame_hdr) +
5662 offsetof(struct wlan_bcn_frame, ie));
5663
5664 status = wlan_get_crypto_params_from_rsn_ie(&crypto_params, ie_ptr,
5665 ie_len);
5666 if (QDF_IS_STATUS_ERROR(status))
5667 return;
5668
5669 if (!(crypto_params.rsn_caps & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED))
5670 *rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED;
5671 }
5672
5673 QDF_STATUS
cm_csr_connect_done_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)5674 cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
5675 struct wlan_cm_connect_resp *rsp)
5676 {
5677 mac_handle_t mac_handle;
5678 struct mac_context *mac_ctx;
5679 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5680 int32_t count;
5681 struct set_context_rsp install_key_rsp;
5682 int32_t rsn_cap, set_value;
5683 struct wlan_mlme_psoc_ext_obj *mlme_obj;
5684 struct dual_sta_policy *dual_sta_policy;
5685 bool enable_mcc_adaptive_sch = false;
5686 struct qdf_mac_addr bc_mac = QDF_MAC_ADDR_BCAST_INIT;
5687
5688 /*
5689 * This API is to update legacy struct and should be removed once
5690 * CSR is cleaned up fully. No new params should be added to CSR, use
5691 * vdev/pdev/psoc instead
5692 */
5693 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5694
5695 mac_ctx = MAC_CONTEXT(mac_handle);
5696 if (!mac_ctx)
5697 return QDF_STATUS_E_INVAL;
5698
5699 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
5700 if (!mlme_obj)
5701 return QDF_STATUS_E_INVAL;
5702
5703 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) {
5704 cm_csr_set_idle(vdev_id);
5705 sme_qos_update_hand_off(vdev_id, false);
5706 sme_qos_csr_event_ind(mac_ctx, vdev_id,
5707 SME_QOS_CSR_DISCONNECT_IND, NULL);
5708 /* Fill legacy structures from resp for failure */
5709
5710 return QDF_STATUS_SUCCESS;
5711 }
5712
5713 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
5714 count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
5715 PM_STA_MODE, NULL);
5716 /*
5717 * send duty cycle percentage to FW only if STA + STA
5718 * concurrency is in MCC.
5719 */
5720 sme_debug("Current iface vdev_id:%d, Primary vdev_id:%d, Dual sta policy:%d, count:%d",
5721 vdev_id, dual_sta_policy->primary_vdev_id,
5722 dual_sta_policy->concurrent_sta_policy, count);
5723
5724 if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
5725 dual_sta_policy->concurrent_sta_policy ==
5726 QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 &&
5727 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
5728 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
5729 &enable_mcc_adaptive_sch);
5730 if (enable_mcc_adaptive_sch) {
5731 sme_debug("Disable mcc_adaptive_scheduler");
5732 policy_mgr_set_dynamic_mcc_adaptive_sch(
5733 mac_ctx->psoc, false);
5734 if (QDF_STATUS_SUCCESS != sme_set_mas(false)) {
5735 sme_err("Failed to disable mcc_adaptive_sched");
5736 return -EAGAIN;
5737 }
5738 }
5739 set_value =
5740 wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev);
5741 sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA,
5742 set_value, VDEV_CMD);
5743 } else if (dual_sta_policy->concurrent_sta_policy ==
5744 QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED && count == 2 &&
5745 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
5746 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
5747 &enable_mcc_adaptive_sch);
5748 if (enable_mcc_adaptive_sch) {
5749 sme_debug("Enable mcc_adaptive_scheduler");
5750 policy_mgr_set_dynamic_mcc_adaptive_sch(
5751 mac_ctx->psoc, true);
5752 if (QDF_STATUS_SUCCESS != sme_set_mas(true)) {
5753 sme_err("Failed to enable mcc_adaptive_sched");
5754 return -EAGAIN;
5755 }
5756 }
5757 } else {
5758 QDF_STATUS status = QDF_STATUS_SUCCESS;
5759 uint32_t quota_val;
5760
5761 quota_val =
5762 ucfg_mlme_get_user_mcc_quota_percentage(mac_ctx->psoc);
5763
5764 if (quota_val) {
5765 if (enable_mcc_adaptive_sch) {
5766 policy_mgr_set_dynamic_mcc_adaptive_sch(
5767 mac_ctx->psoc, false);
5768 status = sme_set_mas(false);
5769 }
5770 if (status == QDF_STATUS_SUCCESS)
5771 sme_cli_set_command(wlan_vdev_get_id(vdev),
5772 WMA_VDEV_MCC_SET_TIME_QUOTA,
5773 quota_val, VDEV_CMD);
5774 } else {
5775 sme_debug("no applicable user mcc/quota");
5776 }
5777 }
5778
5779 /*
5780 * For open mode authentication, send dummy install key response to
5781 * send OBSS scan and QOS event.
5782 */
5783 if (!rsp->is_wps_connection && cm_is_open_mode(vdev)) {
5784 install_key_rsp.length = sizeof(install_key_rsp);
5785 install_key_rsp.status_code = eSIR_SME_SUCCESS;
5786 install_key_rsp.sessionId = vdev_id;
5787 /* use BC mac to enable OBSS scan */
5788 qdf_copy_macaddr(&install_key_rsp.peer_macaddr, &bc_mac);
5789 csr_roam_chk_lnk_set_ctx_rsp(mac_ctx,
5790 (tSirSmeRsp *)&install_key_rsp);
5791 }
5792
5793 rsn_cap = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP);
5794 if (rsn_cap >= 0) {
5795 cm_update_rsn_ocv_cap(&rsn_cap, rsp);
5796 if (wma_cli_set2_command(vdev_id, wmi_vdev_param_rsn_capability,
5797 rsn_cap, 0, VDEV_CMD))
5798 sme_err("Failed to update wmi_vdev_param_rsn_capability for vdev id %d",
5799 vdev_id);
5800 }
5801
5802 /*
5803 * Update the IEs after connection to reconfigure
5804 * any capability that changed during connection.
5805 */
5806 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g)
5807 sme_set_vdev_ies_per_band(mac_handle, vdev_id,
5808 wlan_vdev_mlme_get_opmode(vdev));
5809
5810 return QDF_STATUS_SUCCESS;
5811 }
5812
cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev * vdev,struct wlan_cm_vdev_discon_req * req)5813 QDF_STATUS cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev *vdev,
5814 struct wlan_cm_vdev_discon_req *req)
5815 {
5816 struct mac_context *mac_ctx;
5817 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5818 struct csr_roam_session *session;
5819
5820 /*
5821 * This API is to update legacy struct and should be removed once
5822 * CSR is cleaned up fully. No new params should be added to CSR, use
5823 * vdev/pdev/psoc instead
5824 */
5825 mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5826 if (!mac_ctx)
5827 return QDF_STATUS_E_INVAL;
5828
5829 session = CSR_GET_SESSION(mac_ctx, vdev_id);
5830 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
5831 sme_err("session not found for vdev_id %d", vdev_id);
5832 return QDF_STATUS_E_INVAL;
5833 }
5834
5835 cm_csr_set_joining(vdev_id);
5836
5837 /* Update the disconnect stats */
5838 session->disconnect_stats.disconnection_cnt++;
5839 if (req->req.source == CM_PEER_DISCONNECT) {
5840 session->disconnect_stats.disassoc_by_peer++;
5841 } else if (req->req.source == CM_SB_DISCONNECT) {
5842 switch (req->req.reason_code) {
5843 case REASON_DISASSOC_DUE_TO_INACTIVITY:
5844 session->disconnect_stats.peer_kickout++;
5845 break;
5846 case REASON_BEACON_MISSED:
5847 session->disconnect_stats.bmiss++;
5848 break;
5849 default:
5850 /* Unknown reason code */
5851 break;
5852 }
5853 } else if (req->req.source == CM_MLO_LINK_SWITCH_DISCONNECT) {
5854 /* Do not update any stats as session is going to be deleted*/
5855 } else {
5856 session->disconnect_stats.disconnection_by_app++;
5857 }
5858
5859 csr_update_prev_ap_info(session, vdev);
5860 csr_qos_send_disconnect_ind(mac_ctx, vdev_id);
5861
5862 return QDF_STATUS_SUCCESS;
5863 }
5864
5865 QDF_STATUS
cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_discon_rsp * rsp)5866 cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev,
5867 struct wlan_cm_discon_rsp *rsp)
5868 {
5869 mac_handle_t mac_handle;
5870 struct mac_context *mac_ctx;
5871 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5872 struct wlan_mlme_psoc_ext_obj *mlme_obj;
5873
5874 /*
5875 * This API is to update legacy struct and should be removed once
5876 * CSR is cleaned up fully. No new params should be added to CSR, use
5877 * vdev/pdev/psoc instead
5878 */
5879 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5880
5881 mac_ctx = MAC_CONTEXT(mac_handle);
5882 if (!mac_ctx)
5883 return QDF_STATUS_E_INVAL;
5884
5885 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
5886 if (!mlme_obj)
5887 return QDF_STATUS_E_INVAL;
5888
5889 cm_csr_set_idle(vdev_id);
5890 if (cm_is_vdev_roaming(vdev))
5891 sme_qos_update_hand_off(vdev_id, false);
5892 csr_set_default_dot11_mode(mac_ctx);
5893
5894 /*
5895 * Update the IEs after disconnection to remove
5896 * any connection specific capability change and
5897 * to reset back to self cap
5898 */
5899 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) {
5900 wlan_cm_set_force_20mhz_in_24ghz(vdev, true);
5901 sme_set_vdev_ies_per_band(mac_handle, vdev_id,
5902 wlan_vdev_mlme_get_opmode(vdev));
5903 }
5904
5905 return QDF_STATUS_SUCCESS;
5906 }
5907
5908 #ifdef WLAN_FEATURE_HOST_ROAM
cm_csr_preauth_done(struct wlan_objmgr_vdev * vdev)5909 void cm_csr_preauth_done(struct wlan_objmgr_vdev *vdev)
5910 {
5911 struct mac_context *mac_ctx;
5912 uint8_t vdev_id = wlan_vdev_get_id(vdev);
5913 struct cm_roam_values_copy config;
5914 bool is_11r;
5915
5916 /*
5917 * This API is to update legacy struct and should be removed once
5918 * CSR is cleaned up fully. No new params should be added to CSR, use
5919 * vdev/pdev/psoc instead
5920 */
5921 mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5922 if (!mac_ctx) {
5923 sme_err("mac_ctx is NULL");
5924 return;
5925 }
5926
5927 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, IS_11R_CONNECTION,
5928 &config);
5929 is_11r = config.bool_value;
5930 if (is_11r || wlan_cm_get_ese_assoc(mac_ctx->pdev, vdev_id))
5931 sme_qos_csr_event_ind(mac_ctx, vdev_id,
5932 SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
5933 }
5934 #endif
5935
5936 /* */
csr_send_mb_disassoc_req_msg(struct mac_context * mac,uint32_t sessionId,tSirMacAddr bssId,uint16_t reasonCode)5937 QDF_STATUS csr_send_mb_disassoc_req_msg(struct mac_context *mac,
5938 uint32_t sessionId,
5939 tSirMacAddr bssId, uint16_t reasonCode)
5940 {
5941 struct disassoc_req *pMsg;
5942 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
5943
5944 if (!CSR_IS_SESSION_VALID(mac, sessionId))
5945 return QDF_STATUS_E_FAILURE;
5946
5947 pMsg = qdf_mem_malloc(sizeof(*pMsg));
5948 if (!pMsg)
5949 return QDF_STATUS_E_NOMEM;
5950
5951 pMsg->messageType = eWNI_SME_DISASSOC_REQ;
5952 pMsg->length = sizeof(*pMsg);
5953 pMsg->sessionId = sessionId;
5954
5955 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid);
5956 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE);
5957 pMsg->reasonCode = reasonCode;
5958
5959 /* Update the disconnect stats */
5960 pSession->disconnect_stats.disconnection_cnt++;
5961 pSession->disconnect_stats.disconnection_by_app++;
5962
5963 return umac_send_mb_message_to_mac(pMsg);
5964 }
5965
csr_send_chng_mcc_beacon_interval(struct mac_context * mac,uint32_t sessionId)5966 QDF_STATUS csr_send_chng_mcc_beacon_interval(struct mac_context *mac,
5967 uint32_t sessionId)
5968 {
5969 struct wlan_change_bi *pMsg;
5970 uint16_t len = 0;
5971 QDF_STATUS status = QDF_STATUS_SUCCESS;
5972 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
5973
5974 if (!pSession) {
5975 sme_err("session %d not found", sessionId);
5976 return QDF_STATUS_E_FAILURE;
5977 }
5978 /* NO need to update the Beacon Params if update beacon parameter flag
5979 * is not set
5980 */
5981 if (!mac->roam.roamSession[sessionId].update_bcn_int)
5982 return QDF_STATUS_SUCCESS;
5983
5984 mac->roam.roamSession[sessionId].update_bcn_int =
5985 false;
5986
5987 /* Create the message and send to lim */
5988 len = sizeof(*pMsg);
5989 pMsg = qdf_mem_malloc(len);
5990 if (!pMsg)
5991 status = QDF_STATUS_E_NOMEM;
5992 else
5993 status = QDF_STATUS_SUCCESS;
5994 if (QDF_IS_STATUS_SUCCESS(status)) {
5995 pMsg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
5996 pMsg->length = len;
5997
5998 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId,
5999 &pMsg->bssid);
6000 sme_debug("CSR Attempting to change BI for Bssid= "
6001 QDF_MAC_ADDR_FMT,
6002 QDF_MAC_ADDR_REF(pMsg->bssid.bytes));
6003 pMsg->session_id = sessionId;
6004 sme_debug("session %d BeaconInterval %d",
6005 sessionId,
6006 mac->roam.roamSession[sessionId].bcn_int);
6007 pMsg->beacon_interval =
6008 mac->roam.roamSession[sessionId].bcn_int;
6009 status = umac_send_mb_message_to_mac(pMsg);
6010 }
6011 return status;
6012 }
6013
6014 #ifdef QCA_HT_2040_COEX
csr_set_ht2040_mode(struct mac_context * mac,uint32_t sessionId,ePhyChanBondState cbMode,bool obssEnabled)6015 QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId,
6016 ePhyChanBondState cbMode, bool obssEnabled)
6017 {
6018 struct set_ht2040_mode *pMsg;
6019 uint16_t len = 0;
6020 QDF_STATUS status = QDF_STATUS_SUCCESS;
6021 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
6022
6023 if (!pSession) {
6024 sme_err("session %d not found", sessionId);
6025 return QDF_STATUS_E_FAILURE;
6026 }
6027
6028 /* Create the message and send to lim */
6029 len = sizeof(struct set_ht2040_mode);
6030 pMsg = qdf_mem_malloc(len);
6031 if (!pMsg)
6032 status = QDF_STATUS_E_NOMEM;
6033 else
6034 status = QDF_STATUS_SUCCESS;
6035 if (QDF_IS_STATUS_SUCCESS(status)) {
6036 qdf_mem_zero(pMsg, sizeof(struct set_ht2040_mode));
6037 pMsg->messageType = eWNI_SME_SET_HT_2040_MODE;
6038 pMsg->length = len;
6039
6040 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid);
6041 sme_debug(
6042 "CSR Attempting to set HT20/40 mode for Bssid= "
6043 QDF_MAC_ADDR_FMT,
6044 QDF_MAC_ADDR_REF(pMsg->bssid.bytes));
6045 pMsg->sessionId = sessionId;
6046 sme_debug(" session %d HT20/40 mode %d",
6047 sessionId, cbMode);
6048 pMsg->cbMode = cbMode;
6049 pMsg->obssEnabled = obssEnabled;
6050 status = umac_send_mb_message_to_mac(pMsg);
6051 }
6052 return status;
6053 }
6054 #endif
6055
csr_send_mb_deauth_req_msg(struct mac_context * mac,uint32_t vdev_id,tSirMacAddr bssId,uint16_t reasonCode)6056 QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac,
6057 uint32_t vdev_id,
6058 tSirMacAddr bssId, uint16_t reasonCode)
6059 {
6060 struct deauth_req *pMsg;
6061 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
6062
6063 if (!CSR_IS_SESSION_VALID(mac, vdev_id))
6064 return QDF_STATUS_E_FAILURE;
6065
6066 pMsg = qdf_mem_malloc(sizeof(*pMsg));
6067 if (!pMsg)
6068 return QDF_STATUS_E_NOMEM;
6069
6070 pMsg->messageType = eWNI_SME_DEAUTH_REQ;
6071 pMsg->length = sizeof(*pMsg);
6072 pMsg->vdev_id = vdev_id;
6073
6074 wlan_mlme_get_mac_vdev_id(mac->pdev, vdev_id, &pMsg->bssid);
6075 /* Set the peer MAC address before sending the message to LIM */
6076 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE);
6077 pMsg->reasonCode = reasonCode;
6078
6079 /* Update the disconnect stats */
6080 pSession->disconnect_stats.disconnection_cnt++;
6081 pSession->disconnect_stats.disconnection_by_app++;
6082
6083 return umac_send_mb_message_to_mac(pMsg);
6084 }
6085
csr_send_mb_disassoc_cnf_msg(struct mac_context * mac,struct disassoc_ind * pDisassocInd)6086 QDF_STATUS csr_send_mb_disassoc_cnf_msg(struct mac_context *mac,
6087 struct disassoc_ind *pDisassocInd)
6088 {
6089 QDF_STATUS status = QDF_STATUS_SUCCESS;
6090 struct disassoc_cnf *pMsg;
6091
6092 do {
6093 pMsg = qdf_mem_malloc(sizeof(*pMsg));
6094 if (!pMsg)
6095 status = QDF_STATUS_E_NOMEM;
6096 else
6097 status = QDF_STATUS_SUCCESS;
6098 if (!QDF_IS_STATUS_SUCCESS(status))
6099 break;
6100 pMsg->messageType = eWNI_SME_DISASSOC_CNF;
6101 pMsg->status_code = eSIR_SME_SUCCESS;
6102 pMsg->length = sizeof(*pMsg);
6103 pMsg->vdev_id = pDisassocInd->vdev_id;
6104 qdf_copy_macaddr(&pMsg->peer_macaddr,
6105 &pDisassocInd->peer_macaddr);
6106 status = QDF_STATUS_SUCCESS;
6107 if (!QDF_IS_STATUS_SUCCESS(status)) {
6108 qdf_mem_free(pMsg);
6109 break;
6110 }
6111
6112 qdf_copy_macaddr(&pMsg->bssid, &pDisassocInd->bssid);
6113 status = QDF_STATUS_SUCCESS;
6114 if (!QDF_IS_STATUS_SUCCESS(status)) {
6115 qdf_mem_free(pMsg);
6116 break;
6117 }
6118
6119 status = umac_send_mb_message_to_mac(pMsg);
6120 } while (0);
6121 return status;
6122 }
6123
csr_send_mb_deauth_cnf_msg(struct mac_context * mac,struct deauth_ind * pDeauthInd)6124 QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac,
6125 struct deauth_ind *pDeauthInd)
6126 {
6127 QDF_STATUS status = QDF_STATUS_SUCCESS;
6128 struct deauth_cnf *pMsg;
6129
6130 do {
6131 pMsg = qdf_mem_malloc(sizeof(*pMsg));
6132 if (!pMsg)
6133 status = QDF_STATUS_E_NOMEM;
6134 else
6135 status = QDF_STATUS_SUCCESS;
6136 if (!QDF_IS_STATUS_SUCCESS(status))
6137 break;
6138 pMsg->messageType = eWNI_SME_DEAUTH_CNF;
6139 pMsg->status_code = eSIR_SME_SUCCESS;
6140 pMsg->length = sizeof(*pMsg);
6141 pMsg->vdev_id = pDeauthInd->vdev_id;
6142 qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid);
6143 status = QDF_STATUS_SUCCESS;
6144 if (!QDF_IS_STATUS_SUCCESS(status)) {
6145 qdf_mem_free(pMsg);
6146 break;
6147 }
6148 qdf_copy_macaddr(&pMsg->peer_macaddr,
6149 &pDeauthInd->peer_macaddr);
6150 status = QDF_STATUS_SUCCESS;
6151 if (!QDF_IS_STATUS_SUCCESS(status)) {
6152 qdf_mem_free(pMsg);
6153 break;
6154 }
6155 status = umac_send_mb_message_to_mac(pMsg);
6156 } while (0);
6157 return status;
6158 }
6159
csr_send_assoc_cnf_msg(struct mac_context * mac,struct assoc_ind * pAssocInd,QDF_STATUS Halstatus,enum wlan_status_code mac_status_code)6160 QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
6161 struct assoc_ind *pAssocInd,
6162 QDF_STATUS Halstatus,
6163 enum wlan_status_code mac_status_code)
6164 {
6165 QDF_STATUS status = QDF_STATUS_SUCCESS;
6166 struct assoc_cnf *pMsg;
6167 struct scheduler_msg msg = { 0 };
6168
6169 sme_debug("HalStatus: %d, mac_status_code %d",
6170 Halstatus, mac_status_code);
6171 do {
6172 pMsg = qdf_mem_malloc(sizeof(*pMsg));
6173 if (!pMsg)
6174 return QDF_STATUS_E_NOMEM;
6175 pMsg->messageType = eWNI_SME_ASSOC_CNF;
6176 pMsg->length = sizeof(*pMsg);
6177 if (QDF_IS_STATUS_SUCCESS(Halstatus)) {
6178 pMsg->status_code = eSIR_SME_SUCCESS;
6179 } else {
6180 pMsg->status_code = eSIR_SME_ASSOC_REFUSED;
6181 pMsg->mac_status_code = mac_status_code;
6182 }
6183 /* bssId */
6184 qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId,
6185 QDF_MAC_ADDR_SIZE);
6186 /* peerMacAddr */
6187 qdf_mem_copy(pMsg->peer_macaddr.bytes, pAssocInd->peerMacAddr,
6188 QDF_MAC_ADDR_SIZE);
6189 /* aid */
6190 pMsg->aid = pAssocInd->aid;
6191 /* OWE IE */
6192 if (pAssocInd->owe_ie_len) {
6193 pMsg->owe_ie = qdf_mem_malloc(pAssocInd->owe_ie_len);
6194 if (!pMsg->owe_ie)
6195 return QDF_STATUS_E_NOMEM;
6196 qdf_mem_copy(pMsg->owe_ie, pAssocInd->owe_ie,
6197 pAssocInd->owe_ie_len);
6198 pMsg->owe_ie_len = pAssocInd->owe_ie_len;
6199 }
6200
6201 if (pAssocInd->ft_ie_len) {
6202 pMsg->ft_ie = qdf_mem_malloc(pAssocInd->ft_ie_len);
6203 if (!pMsg->ft_ie)
6204 return QDF_STATUS_E_NOMEM;
6205 qdf_mem_copy(pMsg->ft_ie, pAssocInd->ft_ie,
6206 pAssocInd->ft_ie_len);
6207 pMsg->ft_ie_len = pAssocInd->ft_ie_len;
6208 }
6209 pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb;
6210
6211 msg.type = pMsg->messageType;
6212 msg.bodyval = 0;
6213 msg.bodyptr = pMsg;
6214 /* pMsg is freed by umac_send_mb_message_to_mac in anycase*/
6215 status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE, &msg,
6216 true);
6217 } while (0);
6218 return status;
6219 }
6220
6221 /**
6222 * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini
6223 * @mac: mac_context.
6224 * @vdev: Pointer to pdev obj
6225 * @vdev_id: vdev_id
6226 *
6227 * This API will store the oce flags in vdev mlme priv object
6228 *
6229 * Return: none
6230 */
csr_store_oce_cfg_flags_in_vdev(struct mac_context * mac,struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)6231 static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac,
6232 struct wlan_objmgr_pdev *pdev,
6233 uint8_t vdev_id)
6234 {
6235 uint8_t *vdev_dynamic_oce;
6236 struct wlan_objmgr_vdev *vdev =
6237 wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_LEGACY_MAC_ID);
6238
6239 if (!vdev)
6240 return;
6241
6242 vdev_dynamic_oce = mlme_get_dynamic_oce_flags(vdev);
6243 if (vdev_dynamic_oce)
6244 *vdev_dynamic_oce = mac->mlme_cfg->oce.feature_bitmap;
6245 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
6246 }
6247
csr_send_set_ie(uint8_t type,uint8_t sub_type,uint8_t vdev_id)6248 void csr_send_set_ie(uint8_t type, uint8_t sub_type,
6249 uint8_t vdev_id)
6250 {
6251 struct send_extcap_ie *msg;
6252 QDF_STATUS status;
6253
6254 sme_debug("send SET IE msg to PE");
6255
6256 if (!(type == WLAN_VDEV_MLME_TYPE_STA ||
6257 (type == WLAN_VDEV_MLME_TYPE_AP &&
6258 sub_type == WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE))) {
6259 sme_debug("Failed to send set IE req for vdev_%d", vdev_id);
6260 return;
6261 }
6262
6263 msg = qdf_mem_malloc(sizeof(*msg));
6264 if (!msg)
6265 return;
6266
6267 msg->msg_type = eWNI_SME_SET_IE_REQ;
6268 msg->session_id = vdev_id;
6269 msg->length = sizeof(*msg);
6270 status = umac_send_mb_message_to_mac(msg);
6271 if (!QDF_IS_STATUS_SUCCESS(status))
6272 sme_debug("Failed to send set IE req for vdev_%d", vdev_id);
6273 }
6274
csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode,uint8_t * nss_2g,uint8_t * nss_5g)6275 void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g,
6276 uint8_t *nss_5g)
6277 {
6278 struct mac_context *mac_ctx = sme_get_mac_context();
6279
6280 if (!mac_ctx) {
6281 sme_err("Invalid MAC context");
6282 return;
6283 }
6284
6285 switch (dev_mode) {
6286 case QDF_STA_MODE:
6287 *nss_2g = mac_ctx->vdev_type_nss_2g.sta;
6288 *nss_5g = mac_ctx->vdev_type_nss_5g.sta;
6289 break;
6290 case QDF_SAP_MODE:
6291 *nss_2g = mac_ctx->vdev_type_nss_2g.sap;
6292 *nss_5g = mac_ctx->vdev_type_nss_5g.sap;
6293 break;
6294 case QDF_P2P_CLIENT_MODE:
6295 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli;
6296 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli;
6297 break;
6298 case QDF_P2P_GO_MODE:
6299 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go;
6300 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go;
6301 break;
6302 case QDF_P2P_DEVICE_MODE:
6303 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev;
6304 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev;
6305 break;
6306 case QDF_IBSS_MODE:
6307 *nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
6308 *nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
6309 break;
6310 case QDF_OCB_MODE:
6311 *nss_2g = mac_ctx->vdev_type_nss_2g.ocb;
6312 *nss_5g = mac_ctx->vdev_type_nss_5g.ocb;
6313 break;
6314 case QDF_NAN_DISC_MODE:
6315 *nss_2g = mac_ctx->vdev_type_nss_2g.nan;
6316 *nss_5g = mac_ctx->vdev_type_nss_5g.nan;
6317 break;
6318 case QDF_NDI_MODE:
6319 *nss_2g = mac_ctx->vdev_type_nss_2g.ndi;
6320 *nss_5g = mac_ctx->vdev_type_nss_5g.ndi;
6321 break;
6322 default:
6323 *nss_2g = 1;
6324 *nss_5g = 1;
6325 sme_err("Unknown device mode: %d", dev_mode);
6326 break;
6327 }
6328 sme_debug("mode - %d: nss_2g - %d, 5g - %d",
6329 dev_mode, *nss_2g, *nss_5g);
6330 }
6331
csr_setup_vdev_session(struct vdev_mlme_obj * vdev_mlme)6332 QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme)
6333 {
6334 QDF_STATUS status;
6335 uint32_t existing_session_id;
6336 struct csr_roam_session *session;
6337 struct mlme_vht_capabilities_info *vht_cap_info;
6338 u8 vdev_id;
6339 struct qdf_mac_addr *mac_addr;
6340 mac_handle_t mac_handle;
6341 struct mac_context *mac_ctx;
6342 struct wlan_objmgr_vdev *vdev;
6343 struct wlan_vht_config vht_config;
6344 struct wlan_ht_config ht_cap;
6345
6346 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
6347 mac_ctx = MAC_CONTEXT(mac_handle);
6348 if (!mac_ctx) {
6349 QDF_ASSERT(0);
6350 return QDF_STATUS_E_INVAL;
6351 }
6352
6353 if (!(mac_ctx->mlme_cfg)) {
6354 sme_err("invalid mlme cfg");
6355 return QDF_STATUS_E_FAILURE;
6356 }
6357 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
6358
6359 vdev = vdev_mlme->vdev;
6360
6361 vdev_id = wlan_vdev_get_id(vdev);
6362 mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev);
6363 /* check to see if the mac address already belongs to a session */
6364 status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr,
6365 &existing_session_id);
6366 if (QDF_IS_STATUS_SUCCESS(status)) {
6367 sme_err("Session %d exists with mac address "QDF_MAC_ADDR_FMT,
6368 existing_session_id,
6369 QDF_MAC_ADDR_REF(mac_addr->bytes));
6370 return QDF_STATUS_E_FAILURE;
6371 }
6372
6373 /* attempt to retrieve session for Id */
6374 session = CSR_GET_SESSION(mac_ctx, vdev_id);
6375 if (!session) {
6376 sme_err("Session does not exist for interface %d", vdev_id);
6377 return QDF_STATUS_E_FAILURE;
6378 }
6379
6380 /* check to see if the session is already active */
6381 if (session->sessionActive) {
6382 sme_err("Cannot re-open active session with Id %d", vdev_id);
6383 return QDF_STATUS_E_FAILURE;
6384 }
6385
6386 session->sessionActive = true;
6387 session->vdev_id = vdev_id;
6388
6389 ht_cap.caps = 0;
6390 vht_config.caps = 0;
6391 ht_cap.ht_caps = mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
6392 vdev_mlme->proto.ht_info.ht_caps = ht_cap.caps;
6393
6394 vht_config.max_mpdu_len = vht_cap_info->ampdu_len;
6395 vht_config.supported_channel_widthset =
6396 vht_cap_info->supp_chan_width;
6397 vht_config.ldpc_coding = vht_cap_info->ldpc_coding_cap;
6398 vht_config.shortgi80 = vht_cap_info->short_gi_80mhz;
6399 vht_config.shortgi160and80plus80 =
6400 vht_cap_info->short_gi_160mhz;
6401 vht_config.tx_stbc = vht_cap_info->tx_stbc;
6402 vht_config.rx_stbc = vht_cap_info->rx_stbc;
6403 vht_config.su_beam_former = vht_cap_info->su_bformer;
6404 vht_config.su_beam_formee = vht_cap_info->su_bformee;
6405 vht_config.csnof_beamformer_antSup =
6406 vht_cap_info->tx_bfee_ant_supp;
6407 vht_config.num_soundingdim = vht_cap_info->num_soundingdim;
6408 vht_config.mu_beam_former = vht_cap_info->mu_bformer;
6409 vht_config.mu_beam_formee = vht_cap_info->enable_mu_bformee;
6410 vht_config.vht_txops = vht_cap_info->txop_ps;
6411 vht_config.htc_vhtcap = vht_cap_info->htc_vhtc;
6412 vht_config.rx_antpattern = vht_cap_info->rx_antpattern;
6413 vht_config.tx_antpattern = vht_cap_info->tx_antpattern;
6414
6415 vht_config.max_ampdu_lenexp =
6416 vht_cap_info->ampdu_len_exponent;
6417 vdev_mlme->proto.vht_info.caps = vht_config.caps;
6418 csr_update_session_he_cap(mac_ctx, session);
6419 csr_update_session_eht_cap(mac_ctx, session);
6420
6421 csr_send_set_ie(vdev_mlme->mgmt.generic.type,
6422 vdev_mlme->mgmt.generic.subtype,
6423 wlan_vdev_get_id(vdev));
6424
6425 if (vdev_mlme->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_STA) {
6426 csr_store_oce_cfg_flags_in_vdev(mac_ctx, mac_ctx->pdev,
6427 wlan_vdev_get_id(vdev));
6428 wlan_mlme_update_oce_flags(mac_ctx->pdev);
6429 }
6430
6431 return QDF_STATUS_SUCCESS;
6432 }
6433
csr_cleanup_vdev_session(struct mac_context * mac,uint8_t vdev_id)6434 void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id)
6435 {
6436 if (CSR_IS_SESSION_VALID(mac, vdev_id)) {
6437 struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
6438 vdev_id);
6439
6440 csr_flush_roam_scan_chan_lists(mac, vdev_id);
6441 csr_roam_free_connected_info(mac, &pSession->connectedInfo);
6442 csr_init_session(mac, vdev_id);
6443 }
6444 }
6445
csr_prepare_vdev_delete(struct mac_context * mac_ctx,struct wlan_objmgr_vdev * vdev)6446 QDF_STATUS csr_prepare_vdev_delete(struct mac_context *mac_ctx,
6447 struct wlan_objmgr_vdev *vdev)
6448 {
6449 QDF_STATUS status = QDF_STATUS_SUCCESS;
6450 struct csr_roam_session *session;
6451 uint8_t vdev_id = wlan_vdev_get_id(vdev);
6452
6453 session = CSR_GET_SESSION(mac_ctx, vdev_id);
6454 if (!session)
6455 return QDF_STATUS_E_INVAL;
6456
6457 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id))
6458 return QDF_STATUS_E_INVAL;
6459
6460 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, vdev_id)) {
6461 sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE");
6462 cm_stop_wait_for_key_timer(mac_ctx->psoc, vdev_id);
6463 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
6464 vdev_id);
6465 }
6466
6467 wlan_ser_vdev_queue_disable(vdev);
6468 /* Flush all the commands for vdev */
6469 wlan_serialization_purge_all_cmd_by_vdev_id(mac_ctx->pdev, vdev_id);
6470 if (!mac_ctx->session_close_cb) {
6471 sme_err("no close session callback registered");
6472 return QDF_STATUS_E_FAILURE;
6473 }
6474
6475 return status;
6476 }
6477
csr_init_session(struct mac_context * mac,uint32_t sessionId)6478 static void csr_init_session(struct mac_context *mac, uint32_t sessionId)
6479 {
6480 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
6481
6482 if (!pSession)
6483 return;
6484
6485 pSession->sessionActive = false;
6486 pSession->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
6487 pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
6488 csr_roam_free_connected_info(mac, &pSession->connectedInfo);
6489 }
6490
csr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev * pdev,void * object,void * arg)6491 static void csr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
6492 void *object, void *arg)
6493 {
6494 struct bssid_search_arg *bssid_arg = arg;
6495 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
6496 struct wlan_objmgr_peer *peer;
6497
6498 if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS)
6499 return;
6500
6501 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_LEGACY_SME_ID);
6502 if (!peer)
6503 return;
6504
6505 if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes,
6506 wlan_peer_get_macaddr(peer)) == QDF_STATUS_SUCCESS)
6507 bssid_arg->vdev_id = wlan_vdev_get_id(vdev);
6508
6509 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
6510 }
6511
csr_roam_get_session_id_from_bssid(struct mac_context * mac,struct qdf_mac_addr * bssid,uint32_t * pSessionId)6512 QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac,
6513 struct qdf_mac_addr *bssid,
6514 uint32_t *pSessionId)
6515 {
6516 struct bssid_search_arg bssid_arg;
6517
6518 qdf_copy_macaddr(&bssid_arg.peer_addr, bssid);
6519 bssid_arg.vdev_id = WLAN_MAX_VDEVS;
6520 wlan_objmgr_pdev_iterate_obj_list(mac->pdev, WLAN_VDEV_OP,
6521 csr_get_vdev_id_from_bssid,
6522 &bssid_arg, 0,
6523 WLAN_LEGACY_SME_ID);
6524 if (bssid_arg.vdev_id >= WLAN_MAX_VDEVS) {
6525 *pSessionId = 0;
6526 return QDF_STATUS_E_FAILURE;
6527 }
6528
6529 *pSessionId = bssid_arg.vdev_id;
6530
6531 return QDF_STATUS_SUCCESS;
6532 }
6533
csr_get_snr(struct mac_context * mac,tCsrSnrCallback callback,struct qdf_mac_addr bssId,void * pContext)6534 QDF_STATUS csr_get_snr(struct mac_context *mac,
6535 tCsrSnrCallback callback,
6536 struct qdf_mac_addr bssId, void *pContext)
6537 {
6538 QDF_STATUS status = QDF_STATUS_SUCCESS;
6539 struct scheduler_msg msg = {0};
6540 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
6541 tAniGetSnrReq *pMsg;
6542
6543 pMsg = qdf_mem_malloc(sizeof(tAniGetSnrReq));
6544 if (!pMsg)
6545 return QDF_STATUS_E_NOMEM;
6546
6547 status = csr_roam_get_session_id_from_bssid(mac, &bssId, &sessionId);
6548 if (!QDF_IS_STATUS_SUCCESS(status)) {
6549 qdf_mem_free(pMsg);
6550 sme_err("Couldn't find session_id for given BSSID");
6551 return status;
6552 }
6553
6554 pMsg->msgType = eWNI_SME_GET_SNR_REQ;
6555 pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq);
6556 pMsg->sessionId = sessionId;
6557 pMsg->snrCallback = callback;
6558 pMsg->pDevContext = pContext;
6559 msg.type = eWNI_SME_GET_SNR_REQ;
6560 msg.bodyptr = pMsg;
6561 msg.reserved = 0;
6562
6563 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6564 QDF_MODULE_ID_SME,
6565 QDF_MODULE_ID_SME,
6566 &msg)) {
6567 qdf_mem_free((void *)pMsg);
6568 status = QDF_STATUS_E_FAILURE;
6569 }
6570
6571 return status;
6572 }
6573
6574 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
csr_invoke_neighbor_report_request(uint8_t session_id,struct sRrmNeighborReq * neighbor_report_req,bool send_resp_to_host)6575 QDF_STATUS csr_invoke_neighbor_report_request(
6576 uint8_t session_id,
6577 struct sRrmNeighborReq *neighbor_report_req,
6578 bool send_resp_to_host)
6579 {
6580 struct wmi_invoke_neighbor_report_params *invoke_params;
6581 struct scheduler_msg msg = {0};
6582
6583 if (!neighbor_report_req) {
6584 sme_err("Invalid params");
6585 return QDF_STATUS_E_INVAL;
6586 }
6587
6588 invoke_params = qdf_mem_malloc(sizeof(*invoke_params));
6589 if (!invoke_params)
6590 return QDF_STATUS_E_NOMEM;
6591
6592 invoke_params->vdev_id = session_id;
6593 invoke_params->send_resp_to_host = send_resp_to_host;
6594
6595 if (!neighbor_report_req->no_ssid) {
6596 invoke_params->ssid.length = neighbor_report_req->ssid.length;
6597 qdf_mem_copy(invoke_params->ssid.ssid,
6598 neighbor_report_req->ssid.ssId,
6599 neighbor_report_req->ssid.length);
6600 } else {
6601 invoke_params->ssid.length = 0;
6602 }
6603
6604 sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT");
6605
6606 msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT;
6607 msg.reserved = 0;
6608 msg.bodyptr = invoke_params;
6609
6610 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6611 QDF_MODULE_ID_WMA,
6612 QDF_MODULE_ID_WMA,
6613 &msg)) {
6614 sme_err("Not able to post message to WMA");
6615 qdf_mem_free(invoke_params);
6616 return QDF_STATUS_E_FAILURE;
6617 }
6618
6619 return QDF_STATUS_SUCCESS;
6620 }
6621
6622 #ifdef FEATURE_WLAN_ESE
wlan_cm_ese_populate_additional_ies(struct wlan_objmgr_pdev * pdev,struct wlan_mlme_psoc_ext_obj * mlme_obj,uint8_t vdev_id,struct wlan_roam_scan_offload_params * rso_mode_cfg)6623 void wlan_cm_ese_populate_additional_ies(struct wlan_objmgr_pdev *pdev,
6624 struct wlan_mlme_psoc_ext_obj *mlme_obj,
6625 uint8_t vdev_id,
6626 struct wlan_roam_scan_offload_params *rso_mode_cfg)
6627 {
6628 uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN]
6629 = { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 };
6630 uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j;
6631 ese_wmm_tspec_ie *tspec_ie;
6632 tESETspecInfo ese_tspec;
6633 struct mac_context *mac_ctx;
6634 struct csr_roam_session *session;
6635
6636 mac_ctx = sme_get_mac_context();
6637 if (!mac_ctx) {
6638 sme_err("mac_ctx is NULL");
6639 return;
6640 }
6641
6642 session = CSR_GET_SESSION(mac_ctx, vdev_id);
6643 if (!session) {
6644 sme_err("session is null %d", vdev_id);
6645 return;
6646 }
6647
6648 tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN);
6649 if (csr_is_wmm_supported(mac_ctx) &&
6650 mlme_obj->cfg.lfr.ese_enabled &&
6651 wlan_cm_get_ese_assoc(pdev, session->vdev_id)) {
6652 ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info(
6653 mac_ctx, session->vdev_id,
6654 (tTspecInfo *)&ese_tspec.tspec[0]);
6655 qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr,
6656 SIR_MAC_OUI_WME_HDR_MIN);
6657 for (j = 0; j < ese_tspec.numTspecs; j++) {
6658 /* Populate the tspec_ie */
6659 ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec,
6660 tspec_ie);
6661 wlan_cm_append_assoc_ies(rso_mode_cfg,
6662 WLAN_ELEMID_VENDOR,
6663 DOT11F_IE_WMMTSPEC_MAX_LEN,
6664 tspec_ie_buf);
6665 }
6666 }
6667 }
6668 #endif
6669
wlan_cm_get_rrm_cap_ie_data(void)6670 uint8_t *wlan_cm_get_rrm_cap_ie_data(void)
6671 {
6672 struct mac_context *mac_ctx;
6673
6674 mac_ctx = sme_get_mac_context();
6675 if (!mac_ctx) {
6676 sme_err("mac_ctx is NULL");
6677 return NULL;
6678 }
6679
6680 return (uint8_t *)&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps;
6681 }
6682 #endif
6683
csr_get_command_buffer(struct mac_context * mac)6684 tSmeCmd *csr_get_command_buffer(struct mac_context *mac)
6685 {
6686 tSmeCmd *pCmd = sme_get_command_buffer(mac);
6687
6688 if (pCmd)
6689 mac->roam.sPendingCommands++;
6690
6691 return pCmd;
6692 }
6693
csr_free_cmd_memory(struct mac_context * mac,tSmeCmd * pCommand)6694 static void csr_free_cmd_memory(struct mac_context *mac, tSmeCmd *pCommand)
6695 {
6696 if (!pCommand) {
6697 sme_err("pCommand is NULL");
6698 return;
6699 }
6700 switch (pCommand->command) {
6701 case eSmeCommandRoam:
6702 csr_release_command_roam(mac, pCommand);
6703 break;
6704 case eSmeCommandWmStatusChange:
6705 csr_release_command_wm_status_change(mac, pCommand);
6706 break;
6707 default:
6708 break;
6709 }
6710 }
6711
csr_release_command_buffer(struct mac_context * mac,tSmeCmd * pCommand)6712 void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand)
6713 {
6714 if (mac->roam.sPendingCommands > 0) {
6715 /*
6716 * All command allocated through csr_get_command_buffer
6717 * need to decrement the pending count when releasing
6718 */
6719 mac->roam.sPendingCommands--;
6720 csr_free_cmd_memory(mac, pCommand);
6721 sme_release_command(mac, pCommand);
6722 } else {
6723 sme_err("no pending commands");
6724 QDF_ASSERT(0);
6725 }
6726 }
6727
csr_release_command(struct mac_context * mac_ctx,tSmeCmd * sme_cmd)6728 void csr_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd)
6729 {
6730 struct wlan_serialization_queued_cmd_info cmd_info;
6731 struct wlan_serialization_command cmd;
6732 struct wlan_objmgr_vdev *vdev;
6733
6734 if (!sme_cmd) {
6735 sme_err("sme_cmd is NULL");
6736 return;
6737 }
6738 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
6739 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID);
6740 if (!vdev) {
6741 sme_err("Invalid vdev");
6742 return;
6743 }
6744 qdf_mem_zero(&cmd_info,
6745 sizeof(struct wlan_serialization_queued_cmd_info));
6746 cmd_info.cmd_id = sme_cmd->cmd_id;
6747 cmd_info.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
6748 cmd_info.cmd_type = csr_get_cmd_type(sme_cmd);
6749 cmd_info.vdev = vdev;
6750 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
6751 cmd.cmd_id = cmd_info.cmd_id;
6752 cmd.cmd_type = cmd_info.cmd_type;
6753 cmd.vdev = cmd_info.vdev;
6754 if (wlan_serialization_is_cmd_present_in_active_queue(
6755 mac_ctx->psoc, &cmd)) {
6756 cmd_info.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
6757 wlan_serialization_remove_cmd(&cmd_info);
6758 } else if (wlan_serialization_is_cmd_present_in_pending_queue(
6759 mac_ctx->psoc, &cmd)) {
6760 cmd_info.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE;
6761 wlan_serialization_cancel_request(&cmd_info);
6762 } else {
6763 sme_debug("can't find cmd_id %d cmd_type %d", cmd_info.cmd_id,
6764 cmd_info.cmd_type);
6765 }
6766 if (cmd_info.vdev)
6767 wlan_objmgr_vdev_release_ref(cmd_info.vdev, WLAN_LEGACY_SME_ID);
6768 }
6769
6770
csr_get_roam_cmd_type(tSmeCmd * sme_cmd)6771 static enum wlan_serialization_cmd_type csr_get_roam_cmd_type(
6772 tSmeCmd *sme_cmd)
6773 {
6774 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
6775
6776 switch (sme_cmd->u.roamCmd.roamReason) {
6777 case eCsrForcedDisassocSta:
6778 cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_STA;
6779 break;
6780 case eCsrForcedDeauthSta:
6781 cmd_type = WLAN_SER_CMD_FORCE_DEAUTH_STA;
6782 break;
6783 default:
6784 break;
6785 }
6786
6787 return cmd_type;
6788 }
6789
csr_get_cmd_type(tSmeCmd * sme_cmd)6790 enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd)
6791 {
6792 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
6793
6794 switch (sme_cmd->command) {
6795 case eSmeCommandRoam:
6796 cmd_type = csr_get_roam_cmd_type(sme_cmd);
6797 break;
6798 case eSmeCommandWmStatusChange:
6799 cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE;
6800 break;
6801 case eSmeCommandAddTs:
6802 cmd_type = WLAN_SER_CMD_ADDTS;
6803 break;
6804 case eSmeCommandDelTs:
6805 cmd_type = WLAN_SER_CMD_DELTS;
6806 break;
6807 case e_sme_command_set_hw_mode:
6808 cmd_type = WLAN_SER_CMD_SET_HW_MODE;
6809 break;
6810 case e_sme_command_nss_update:
6811 cmd_type = WLAN_SER_CMD_NSS_UPDATE;
6812 break;
6813 case e_sme_command_set_dual_mac_config:
6814 cmd_type = WLAN_SER_CMD_SET_DUAL_MAC_CONFIG;
6815 break;
6816 case e_sme_command_set_antenna_mode:
6817 cmd_type = WLAN_SER_CMD_SET_ANTENNA_MODE;
6818 break;
6819 case e_sme_command_sap_ch_width_update:
6820 cmd_type = WLAN_SER_CMD_SAP_BW_UPDATE;
6821 break;
6822 default:
6823 break;
6824 }
6825
6826 return cmd_type;
6827 }
6828
csr_get_monotonous_number(struct mac_context * mac_ctx)6829 static uint32_t csr_get_monotonous_number(struct mac_context *mac_ctx)
6830 {
6831 uint32_t cmd_id;
6832 uint32_t mask = 0x00FFFFFF, prefix = 0x0D000000;
6833
6834 cmd_id = qdf_atomic_inc_return(&mac_ctx->global_cmd_id);
6835 cmd_id = (cmd_id & mask);
6836 cmd_id = (cmd_id | prefix);
6837
6838 return cmd_id;
6839 }
6840
csr_fill_cmd_timeout(struct wlan_serialization_command * cmd)6841 static void csr_fill_cmd_timeout(struct wlan_serialization_command *cmd)
6842 {
6843 switch (cmd->cmd_type) {
6844 case WLAN_SER_CMD_WM_STATUS_CHANGE:
6845 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT;
6846 break;
6847 case WLAN_SER_CMD_VDEV_START_BSS:
6848 cmd->cmd_timeout_duration = SME_CMD_VDEV_START_BSS_TIMEOUT;
6849 break;
6850 case WLAN_SER_CMD_VDEV_STOP_BSS:
6851 cmd->cmd_timeout_duration = SME_CMD_STOP_BSS_CMD_TIMEOUT;
6852 break;
6853 case WLAN_SER_CMD_FORCE_DISASSOC_STA:
6854 case WLAN_SER_CMD_FORCE_DEAUTH_STA:
6855 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT;
6856 break;
6857
6858 case WLAN_SER_CMD_ADDTS:
6859 case WLAN_SER_CMD_DELTS:
6860 cmd->cmd_timeout_duration = SME_CMD_ADD_DEL_TS_TIMEOUT;
6861 break;
6862 case WLAN_SER_CMD_SET_HW_MODE:
6863 case WLAN_SER_CMD_NSS_UPDATE:
6864 case WLAN_SER_CMD_SET_DUAL_MAC_CONFIG:
6865 case WLAN_SER_CMD_SET_ANTENNA_MODE:
6866 case WLAN_SER_CMD_SAP_BW_UPDATE:
6867 cmd->cmd_timeout_duration = SME_CMD_POLICY_MGR_CMD_TIMEOUT;
6868 break;
6869 default:
6870 cmd->cmd_timeout_duration = SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
6871 break;
6872 }
6873 }
6874
csr_set_serialization_params_to_cmd(struct mac_context * mac_ctx,tSmeCmd * sme_cmd,struct wlan_serialization_command * cmd,uint8_t high_priority)6875 QDF_STATUS csr_set_serialization_params_to_cmd(struct mac_context *mac_ctx,
6876 tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd,
6877 uint8_t high_priority)
6878 {
6879 QDF_STATUS status = QDF_STATUS_E_FAILURE;
6880
6881 if (!sme_cmd) {
6882 sme_err("Invalid sme_cmd");
6883 return status;
6884 }
6885 if (!cmd) {
6886 sme_err("Invalid serialization_cmd");
6887 return status;
6888 }
6889
6890 /*
6891 * no need to fill command id for non-scan as they will be
6892 * zero always
6893 */
6894 sme_cmd->cmd_id = csr_get_monotonous_number(mac_ctx);
6895 cmd->cmd_id = sme_cmd->cmd_id;
6896
6897 cmd->cmd_type = csr_get_cmd_type(sme_cmd);
6898 if (cmd->cmd_type == WLAN_SER_CMD_MAX) {
6899 sme_err("serialization enum not found for sme_cmd type %d",
6900 sme_cmd->command);
6901 return status;
6902 }
6903 cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
6904 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID);
6905 if (!cmd->vdev) {
6906 sme_err("vdev is NULL for vdev_id:%d", sme_cmd->vdev_id);
6907 return status;
6908 }
6909 cmd->umac_cmd = sme_cmd;
6910
6911 csr_fill_cmd_timeout(cmd);
6912
6913 cmd->source = WLAN_UMAC_COMP_MLME;
6914 cmd->cmd_cb = sme_ser_cmd_callback;
6915 cmd->is_high_priority = high_priority;
6916 cmd->is_blocking = true;
6917
6918 return QDF_STATUS_SUCCESS;
6919 }
6920
csr_queue_sme_command(struct mac_context * mac_ctx,tSmeCmd * sme_cmd,bool high_priority)6921 QDF_STATUS csr_queue_sme_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd,
6922 bool high_priority)
6923 {
6924 struct wlan_serialization_command cmd;
6925 struct wlan_objmgr_vdev *vdev = NULL;
6926 enum wlan_serialization_status ser_cmd_status;
6927 QDF_STATUS status;
6928
6929 if (!SME_IS_START(mac_ctx)) {
6930 sme_err("Sme in stop state");
6931 QDF_ASSERT(0);
6932 goto error;
6933 }
6934
6935 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
6936 status = csr_set_serialization_params_to_cmd(mac_ctx, sme_cmd,
6937 &cmd, high_priority);
6938 if (QDF_IS_STATUS_ERROR(status)) {
6939 sme_err("failed to set ser params");
6940 goto error;
6941 }
6942
6943 vdev = cmd.vdev;
6944 ser_cmd_status = wlan_serialization_request(&cmd);
6945
6946 switch (ser_cmd_status) {
6947 case WLAN_SER_CMD_PENDING:
6948 case WLAN_SER_CMD_ACTIVE:
6949 /* Command posted to active/pending list */
6950 status = QDF_STATUS_SUCCESS;
6951 break;
6952 default:
6953 sme_err("Failed to queue command %d with status:%d",
6954 sme_cmd->command, ser_cmd_status);
6955 status = QDF_STATUS_E_FAILURE;
6956 goto error;
6957 }
6958
6959 return status;
6960
6961 error:
6962 if (vdev)
6963 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6964
6965 csr_release_command_buffer(mac_ctx, sme_cmd);
6966
6967 return QDF_STATUS_E_FAILURE;
6968 }
6969
csr_roam_update_config(struct mac_context * mac_ctx,uint8_t session_id,uint16_t capab,uint32_t value)6970 QDF_STATUS csr_roam_update_config(struct mac_context *mac_ctx, uint8_t session_id,
6971 uint16_t capab, uint32_t value)
6972 {
6973 struct update_config *msg;
6974 QDF_STATUS status = QDF_STATUS_SUCCESS;
6975 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
6976
6977 sme_debug("update HT config requested");
6978 if (!session) {
6979 sme_err("Session does not exist for session id %d", session_id);
6980 return QDF_STATUS_E_FAILURE;
6981 }
6982
6983 msg = qdf_mem_malloc(sizeof(*msg));
6984 if (!msg)
6985 return QDF_STATUS_E_NOMEM;
6986
6987 msg->messageType = eWNI_SME_UPDATE_CONFIG;
6988 msg->vdev_id = session_id;
6989 msg->capab = capab;
6990 msg->value = value;
6991 msg->length = sizeof(*msg);
6992 status = umac_send_mb_message_to_mac(msg);
6993
6994 return status;
6995 }
6996
csr_send_channel_change_req(struct mac_context * mac,struct channel_change_req * req)6997 QDF_STATUS csr_send_channel_change_req(struct mac_context *mac,
6998 struct channel_change_req *req)
6999 {
7000 struct scheduler_msg msg = {0};
7001 struct channel_change_req *ch_change_req;
7002 QDF_STATUS status;
7003
7004 ch_change_req = qdf_mem_malloc(sizeof(*ch_change_req));
7005 if (!ch_change_req)
7006 return QDF_STATUS_E_NOMEM;
7007
7008 qdf_mem_copy(ch_change_req, req, sizeof(*ch_change_req));
7009 msg.type = eWNI_SME_CHANNEL_CHANGE_REQ;
7010 msg.bodyptr = ch_change_req;
7011 msg.reserved = 0;
7012
7013 status = scheduler_post_message(QDF_MODULE_ID_SME,
7014 QDF_MODULE_ID_PE,
7015 QDF_MODULE_ID_PE,
7016 &msg);
7017 if (QDF_IS_STATUS_ERROR(status)) {
7018 sme_err("Failed to send channel change request with status : %d",
7019 status);
7020 qdf_mem_free(ch_change_req);
7021 }
7022
7023 return status;
7024 }
7025 /*
7026 * Post Beacon Tx Start request to LIM
7027 * immediately after SAP CAC WAIT is
7028 * completed without any RADAR indications.
7029 */
csr_roam_start_beacon_req(struct mac_context * mac,struct qdf_mac_addr bssid,uint8_t dfsCacWaitStatus)7030 QDF_STATUS csr_roam_start_beacon_req(struct mac_context *mac,
7031 struct qdf_mac_addr bssid,
7032 uint8_t dfsCacWaitStatus)
7033 {
7034 QDF_STATUS status = QDF_STATUS_SUCCESS;
7035 tSirStartBeaconIndication *pMsg;
7036
7037 pMsg = qdf_mem_malloc(sizeof(tSirStartBeaconIndication));
7038 if (!pMsg)
7039 return QDF_STATUS_E_NOMEM;
7040
7041 pMsg->messageType = eWNI_SME_START_BEACON_REQ;
7042 pMsg->messageLen = sizeof(tSirStartBeaconIndication);
7043 pMsg->beaconStartStatus = dfsCacWaitStatus;
7044 qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
7045
7046 status = umac_send_mb_message_to_mac(pMsg);
7047
7048 return status;
7049 }
7050
7051 /*
7052 * csr_roam_modify_add_ies -
7053 * This function sends msg to modify the additional IE buffers in PE
7054 *
7055 * @mac: mac global structure
7056 * @pModifyIE: pointer to tSirModifyIE structure
7057 * @updateType: Type of buffer
7058 *
7059 *
7060 * Return: QDF_STATUS - Success or failure
7061 */
7062 QDF_STATUS
csr_roam_modify_add_ies(struct mac_context * mac,tSirModifyIE * pModifyIE,eUpdateIEsType updateType)7063 csr_roam_modify_add_ies(struct mac_context *mac,
7064 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
7065 {
7066 tpSirModifyIEsInd pModifyAddIEInd = NULL;
7067 uint8_t *pLocalBuffer = NULL;
7068 QDF_STATUS status;
7069
7070 /* following buffer will be freed by consumer (PE) */
7071 pLocalBuffer = qdf_mem_malloc(pModifyIE->ieBufferlength);
7072 if (!pLocalBuffer)
7073 return QDF_STATUS_E_NOMEM;
7074
7075 pModifyAddIEInd = qdf_mem_malloc(sizeof(tSirModifyIEsInd));
7076 if (!pModifyAddIEInd) {
7077 qdf_mem_free(pLocalBuffer);
7078 return QDF_STATUS_E_NOMEM;
7079 }
7080
7081 /*copy the IE buffer */
7082 qdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer,
7083 pModifyIE->ieBufferlength);
7084 qdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd));
7085
7086 pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES;
7087 pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd);
7088
7089 qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid);
7090
7091 pModifyAddIEInd->modifyIE.vdev_id = pModifyIE->vdev_id;
7092 pModifyAddIEInd->modifyIE.notify = pModifyIE->notify;
7093 pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID;
7094 pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen;
7095 pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer;
7096 pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength;
7097 pModifyAddIEInd->modifyIE.oui_length = pModifyIE->oui_length;
7098
7099 pModifyAddIEInd->updateType = updateType;
7100
7101 status = umac_send_mb_message_to_mac(pModifyAddIEInd);
7102 if (!QDF_IS_STATUS_SUCCESS(status)) {
7103 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
7104 status);
7105 qdf_mem_free(pLocalBuffer);
7106 }
7107 return status;
7108 }
7109
7110 /*
7111 * csr_roam_update_add_ies -
7112 * This function sends msg to updates the additional IE buffers in PE
7113 *
7114 * @mac: mac global structure
7115 * @sessionId: SME session id
7116 * @bssid: BSSID
7117 * @additionIEBuffer: buffer containing addition IE from hostapd
7118 * @length: length of buffer
7119 * @updateType: Type of buffer
7120 * @append: append or replace completely
7121 *
7122 *
7123 * Return: QDF_STATUS - Success or failure
7124 */
7125 QDF_STATUS
csr_roam_update_add_ies(struct mac_context * mac,tSirUpdateIE * pUpdateIE,eUpdateIEsType updateType)7126 csr_roam_update_add_ies(struct mac_context *mac,
7127 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
7128 {
7129 tpSirUpdateIEsInd pUpdateAddIEs = NULL;
7130 uint8_t *pLocalBuffer = NULL;
7131 QDF_STATUS status;
7132
7133 if (pUpdateIE->ieBufferlength != 0) {
7134 /* Following buffer will be freed by consumer (PE) */
7135 pLocalBuffer = qdf_mem_malloc(pUpdateIE->ieBufferlength);
7136 if (!pLocalBuffer) {
7137 return QDF_STATUS_E_NOMEM;
7138 }
7139 qdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
7140 pUpdateIE->ieBufferlength);
7141 }
7142
7143 pUpdateAddIEs = qdf_mem_malloc(sizeof(tSirUpdateIEsInd));
7144 if (!pUpdateAddIEs) {
7145 qdf_mem_free(pLocalBuffer);
7146 return QDF_STATUS_E_NOMEM;
7147 }
7148
7149 pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES;
7150 pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd);
7151
7152 qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid);
7153
7154 pUpdateAddIEs->updateIE.vdev_id = pUpdateIE->vdev_id;
7155 pUpdateAddIEs->updateIE.append = pUpdateIE->append;
7156 pUpdateAddIEs->updateIE.notify = pUpdateIE->notify;
7157 pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength;
7158 pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer;
7159
7160 pUpdateAddIEs->updateType = updateType;
7161
7162 status = umac_send_mb_message_to_mac(pUpdateAddIEs);
7163 if (!QDF_IS_STATUS_SUCCESS(status)) {
7164 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
7165 status);
7166 qdf_mem_free(pLocalBuffer);
7167 }
7168 return status;
7169 }
7170
7171 /**
7172 * csr_send_ext_change_freq()- function to post send ECSA
7173 * action frame to lim.
7174 * @mac_ctx: pointer to global mac structure
7175 * @ch_freq: new channel freq to switch
7176 * @session_id: senssion it should be sent on.
7177 *
7178 * This function is called to post ECSA frame to lim.
7179 *
7180 * Return: success if msg posted to LIM else return failure
7181 */
csr_send_ext_change_freq(struct mac_context * mac_ctx,qdf_freq_t ch_freq,uint8_t session_id)7182 QDF_STATUS csr_send_ext_change_freq(struct mac_context *mac_ctx,
7183 qdf_freq_t ch_freq, uint8_t session_id)
7184 {
7185 QDF_STATUS status = QDF_STATUS_SUCCESS;
7186 struct sir_sme_ext_cng_chan_req *msg;
7187
7188 msg = qdf_mem_malloc(sizeof(*msg));
7189 if (!msg)
7190 return QDF_STATUS_E_NOMEM;
7191
7192 msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL;
7193 msg->length = sizeof(*msg);
7194 msg->new_ch_freq = ch_freq;
7195 msg->vdev_id = session_id;
7196 status = umac_send_mb_message_to_mac(msg);
7197 return status;
7198 }
7199
csr_csa_restart(struct mac_context * mac_ctx,uint8_t vdev_id)7200 QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t vdev_id)
7201 {
7202 QDF_STATUS status;
7203 struct wlan_objmgr_vdev *vdev;
7204 struct scheduler_msg message = {0};
7205
7206 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
7207 WLAN_LEGACY_MAC_ID);
7208 if (!vdev) {
7209 sme_err("VDEV not found for vdev id: %d", vdev_id);
7210 return QDF_STATUS_E_FAILURE;
7211 }
7212
7213 if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_AP_CSA_START, NULL);
7214 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
7215
7216 /* Serialize the req through MC thread */
7217 message.bodyval = vdev_id;
7218 message.type = eWNI_SME_CSA_RESTART_REQ;
7219 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
7220 QDF_MODULE_ID_PE, &message);
7221 if (!QDF_IS_STATUS_SUCCESS(status)) {
7222 sme_err("scheduler_post_msg failed!(err=%d)", status);
7223 status = QDF_STATUS_E_FAILURE;
7224 }
7225
7226 return status;
7227 }
7228
csr_roam_send_chan_sw_ie_request(struct mac_context * mac_ctx,struct qdf_mac_addr bssid,uint32_t target_chan_freq,uint8_t csa_ie_reqd,struct ch_params * ch_params,uint32_t new_cac_ms)7229 QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx,
7230 struct qdf_mac_addr bssid,
7231 uint32_t target_chan_freq,
7232 uint8_t csa_ie_reqd,
7233 struct ch_params *ch_params,
7234 uint32_t new_cac_ms)
7235 {
7236 QDF_STATUS status = QDF_STATUS_SUCCESS;
7237 tSirDfsCsaIeRequest *msg;
7238
7239 msg = qdf_mem_malloc(sizeof(tSirDfsCsaIeRequest));
7240 if (!msg)
7241 return QDF_STATUS_E_NOMEM;
7242
7243 msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ;
7244 msg->msgLen = sizeof(tSirDfsCsaIeRequest);
7245
7246 msg->target_chan_freq = target_chan_freq;
7247 msg->csaIeRequired = csa_ie_reqd;
7248 msg->ch_switch_beacon_cnt =
7249 mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt;
7250 if (mac_ctx->sap.one_time_csa_count) {
7251 msg->ch_switch_beacon_cnt = mac_ctx->sap.one_time_csa_count;
7252 mac_ctx->sap.one_time_csa_count = 0;
7253 }
7254 msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode;
7255 msg->dfs_ch_switch_disable =
7256 mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch;
7257 msg->new_chan_cac_ms = new_cac_ms;
7258 qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
7259 qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params));
7260
7261 status = umac_send_mb_message_to_mac(msg);
7262
7263 return status;
7264 }
7265
csr_sta_continue_csa(struct mac_context * mac_ctx,uint8_t vdev_id)7266 QDF_STATUS csr_sta_continue_csa(struct mac_context *mac_ctx, uint8_t vdev_id)
7267 {
7268 QDF_STATUS status;
7269 struct scheduler_msg message = {0};
7270
7271 /* Serialize the req through MC thread */
7272 message.bodyval = vdev_id;
7273 message.type = eWNI_SME_STA_CSA_CONTINUE_REQ;
7274 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
7275 QDF_MODULE_ID_PE, &message);
7276 if (!QDF_IS_STATUS_SUCCESS(status)) {
7277 sme_err("eWNI_SME_STA_CSA_CONTINUE_REQ failed!(err=%d)",
7278 status);
7279 status = QDF_STATUS_E_FAILURE;
7280 }
7281
7282 return status;
7283 }
7284
7285 /**
7286 * csr_update_op_class_array() - update op class for each band
7287 * @mac_ctx: mac global context
7288 * @op_classes: out param, operating class array to update
7289 * @channel_info: channel info
7290 * @ch_name: channel band name to display in debug messages
7291 * @i: out param, stores number of operating classes
7292 *
7293 * Return: void
7294 */
7295 static void
csr_update_op_class_array(struct mac_context * mac_ctx,uint8_t * op_classes,struct csr_channel * channel_info,char * ch_name,uint8_t * i)7296 csr_update_op_class_array(struct mac_context *mac_ctx,
7297 uint8_t *op_classes,
7298 struct csr_channel *channel_info,
7299 char *ch_name,
7300 uint8_t *i)
7301 {
7302 uint8_t j = 0, idx = 0, class = 0;
7303 bool found = false;
7304 uint8_t num_channels = channel_info->numChannels;
7305 uint8_t ch_num;
7306
7307 sme_debug("Num %s channels, %d", ch_name, num_channels);
7308
7309 for (idx = 0; idx < num_channels &&
7310 *i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) {
7311 wlan_reg_freq_to_chan_op_class(
7312 mac_ctx->pdev, channel_info->channel_freq_list[idx],
7313 true, BIT(BEHAV_NONE), &class, &ch_num);
7314
7315 found = false;
7316 for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; j++) {
7317 if (op_classes[j] == class) {
7318 found = true;
7319 break;
7320 }
7321 }
7322
7323 if (!found) {
7324 op_classes[*i] = class;
7325 *i = *i + 1;
7326 }
7327 }
7328 }
7329
7330 /**
7331 * csr_init_operating_classes() - update op class for all bands
7332 * @mac: pointer to mac context.
7333 *
7334 * Return: void
7335 */
csr_init_operating_classes(struct mac_context * mac)7336 static void csr_init_operating_classes(struct mac_context *mac)
7337 {
7338 uint8_t i = 0;
7339 uint8_t j = 0;
7340 uint8_t swap = 0;
7341 uint8_t numClasses = 0;
7342 uint8_t opClasses[REG_MAX_SUPP_OPER_CLASSES] = {0,};
7343 uint8_t reg_cc[REG_ALPHA2_LEN + 1];
7344
7345 wlan_reg_read_current_country(mac->psoc, reg_cc);
7346 sme_debug("Current Country = %s", reg_cc);
7347
7348 csr_update_op_class_array(mac, opClasses,
7349 &mac->scan.base_channels, "20MHz", &i);
7350 numClasses = i;
7351
7352 /* As per spec the operating classes should be in ascending order.
7353 * Bubble sort is fine since we don't have many classes
7354 */
7355 for (i = 0; i < (numClasses - 1); i++) {
7356 for (j = 0; j < (numClasses - i - 1); j++) {
7357 /* For decreasing order use < */
7358 if (opClasses[j] > opClasses[j + 1]) {
7359 swap = opClasses[j];
7360 opClasses[j] = opClasses[j + 1];
7361 opClasses[j + 1] = swap;
7362 }
7363 }
7364 }
7365
7366 /* Set the ordered list of op classes in regdomain
7367 * for use by other modules
7368 */
7369 wlan_reg_dmn_set_curr_opclasses(numClasses, &opClasses[0]);
7370 }
7371
7372 /**
7373 * csr_process_set_hw_mode() - Set HW mode command to PE
7374 * @mac: Globacl MAC pointer
7375 * @command: Command received from SME
7376 *
7377 * Posts the set HW mode command to PE. This message passing
7378 * through PE is required for PE's internal management
7379 *
7380 * Return: None
7381 */
csr_process_set_hw_mode(struct mac_context * mac,tSmeCmd * command)7382 void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command)
7383 {
7384 uint32_t len;
7385 struct s_sir_set_hw_mode *cmd = NULL;
7386 QDF_STATUS status;
7387 struct scheduler_msg msg = {0};
7388 struct sir_set_hw_mode_resp *param;
7389 enum policy_mgr_hw_mode_change hw_mode;
7390 enum policy_mgr_conc_next_action action;
7391 enum set_hw_mode_status hw_mode_change_status =
7392 SET_HW_MODE_STATUS_ECANCELED;
7393
7394 /* Setting HW mode is for the entire system.
7395 * So, no need to check session
7396 */
7397
7398 if (!command) {
7399 sme_err("Set HW mode param is NULL");
7400 goto fail;
7401 }
7402
7403 len = sizeof(*cmd);
7404 cmd = qdf_mem_malloc(len);
7405 if (!cmd)
7406 /* Probably the fail response will also fail during malloc.
7407 * Still proceeding to send response!
7408 */
7409 goto fail;
7410
7411 action = command->u.set_hw_mode_cmd.action;
7412
7413 status = policy_mgr_validate_dbs_switch(mac->psoc, action);
7414
7415 if (QDF_IS_STATUS_ERROR(status)) {
7416 sme_debug("Hw mode change not sent to FW status = %d", status);
7417 if (status == QDF_STATUS_E_ALREADY)
7418 hw_mode_change_status = SET_HW_MODE_STATUS_ALREADY;
7419 goto fail;
7420 }
7421
7422 hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index(
7423 mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index);
7424
7425 if (POLICY_MGR_HW_MODE_NOT_IN_PROGRESS == hw_mode) {
7426 sme_err("hw_mode %d, failing", hw_mode);
7427 goto fail;
7428 }
7429
7430 policy_mgr_set_hw_mode_change_in_progress(mac->psoc, hw_mode);
7431 policy_mgr_reset_connection_update(mac->psoc);
7432
7433 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
7434 command->u.set_hw_mode_cmd.reason) &&
7435 (true == mac->sme.get_connection_info_cb(NULL, NULL))) {
7436 sme_err("Set HW mode refused: conn in progress");
7437 policy_mgr_restart_opportunistic_timer(mac->psoc, false);
7438 goto reset_state;
7439 }
7440
7441 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
7442 command->u.set_hw_mode_cmd.reason) &&
7443 (!command->u.set_hw_mode_cmd.hw_mode_index &&
7444 !policy_mgr_need_opportunistic_upgrade(mac->psoc, NULL))) {
7445 sme_err("Set HW mode to SMM not needed anymore");
7446 goto reset_state;
7447 }
7448
7449 cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
7450 cmd->length = len;
7451 cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
7452 cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason;
7453 /*
7454 * Below callback and context info are not needed for PE as of now.
7455 * Storing the passed value in the same s_sir_set_hw_mode format.
7456 */
7457 cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb;
7458
7459 sme_debug(
7460 "Posting set hw mode req to PE session:%d reason:%d",
7461 command->u.set_hw_mode_cmd.session_id,
7462 command->u.set_hw_mode_cmd.reason);
7463
7464 status = umac_send_mb_message_to_mac(cmd);
7465 if (QDF_STATUS_SUCCESS != status) {
7466 sme_err("Posting to PE failed");
7467 cmd = NULL;
7468 goto reset_state;
7469 }
7470 return;
7471
7472 reset_state:
7473 policy_mgr_set_hw_mode_change_in_progress(mac->psoc,
7474 POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
7475 fail:
7476 if (cmd)
7477 qdf_mem_free(cmd);
7478 param = qdf_mem_malloc(sizeof(*param));
7479 if (!param)
7480 return;
7481
7482 sme_debug("Sending set HW fail response to SME");
7483 param->status = hw_mode_change_status;
7484 param->cfgd_hw_mode_index = 0;
7485 param->num_vdev_mac_entries = 0;
7486 msg.type = eWNI_SME_SET_HW_MODE_RESP;
7487 msg.bodyptr = param;
7488 msg.bodyval = 0;
7489 sys_process_mmh_msg(mac, &msg);
7490 }
7491
7492 /**
7493 * csr_process_set_dual_mac_config() - Set HW mode command to PE
7494 * @mac: Global MAC pointer
7495 * @command: Command received from SME
7496 *
7497 * Posts the set dual mac config command to PE.
7498 *
7499 * Return: None
7500 */
csr_process_set_dual_mac_config(struct mac_context * mac,tSmeCmd * command)7501 void csr_process_set_dual_mac_config(struct mac_context *mac, tSmeCmd *command)
7502 {
7503 uint32_t len;
7504 struct sir_set_dual_mac_cfg *cmd;
7505 QDF_STATUS status;
7506 struct scheduler_msg msg = {0};
7507 struct sir_dual_mac_config_resp *param;
7508
7509 /* Setting MAC configuration is for the entire system.
7510 * So, no need to check session
7511 */
7512
7513 if (!command) {
7514 sme_err("Set HW mode param is NULL");
7515 goto fail;
7516 }
7517
7518 len = sizeof(*cmd);
7519 cmd = qdf_mem_malloc(len);
7520 if (!cmd)
7521 /* Probably the fail response will also fail during malloc.
7522 * Still proceeding to send response!
7523 */
7524 goto fail;
7525
7526 cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ;
7527 cmd->length = len;
7528 cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config;
7529 cmd->set_dual_mac.fw_mode_config =
7530 command->u.set_dual_mac_cmd.fw_mode_config;
7531 /*
7532 * Below callback and context info are not needed for PE as of now.
7533 * Storing the passed value in the same sir_set_dual_mac_cfg format.
7534 */
7535 cmd->set_dual_mac.set_dual_mac_cb =
7536 command->u.set_dual_mac_cmd.set_dual_mac_cb;
7537
7538 sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x",
7539 cmd->set_dual_mac.scan_config,
7540 cmd->set_dual_mac.fw_mode_config);
7541
7542 status = umac_send_mb_message_to_mac(cmd);
7543 if (QDF_IS_STATUS_ERROR(status)) {
7544 sme_err("Posting to PE failed");
7545 goto fail;
7546 }
7547 return;
7548 fail:
7549 param = qdf_mem_malloc(sizeof(*param));
7550 if (!param)
7551 return;
7552
7553 sme_err("Sending set dual mac fail response to SME");
7554 param->status = SET_HW_MODE_STATUS_ECANCELED;
7555 msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
7556 msg.bodyptr = param;
7557 msg.bodyval = 0;
7558 sys_process_mmh_msg(mac, &msg);
7559 }
7560
7561 /**
7562 * csr_process_set_antenna_mode() - Set antenna mode command to
7563 * PE
7564 * @mac: Global MAC pointer
7565 * @command: Command received from SME
7566 *
7567 * Posts the set dual mac config command to PE.
7568 *
7569 * Return: None
7570 */
csr_process_set_antenna_mode(struct mac_context * mac,tSmeCmd * command)7571 void csr_process_set_antenna_mode(struct mac_context *mac, tSmeCmd *command)
7572 {
7573 uint32_t len;
7574 struct sir_set_antenna_mode *cmd;
7575 QDF_STATUS status;
7576 struct scheduler_msg msg = {0};
7577 struct sir_antenna_mode_resp *param;
7578
7579 /* Setting MAC configuration is for the entire system.
7580 * So, no need to check session
7581 */
7582
7583 if (!command) {
7584 sme_err("Set antenna mode param is NULL");
7585 goto fail;
7586 }
7587
7588 len = sizeof(*cmd);
7589 cmd = qdf_mem_malloc(len);
7590 if (!cmd)
7591 goto fail;
7592
7593 cmd->message_type = eWNI_SME_SET_ANTENNA_MODE_REQ;
7594 cmd->length = len;
7595 cmd->set_antenna_mode = command->u.set_antenna_mode_cmd;
7596
7597 sme_debug(
7598 "Posting eWNI_SME_SET_ANTENNA_MODE_REQ to PE: %d %d",
7599 cmd->set_antenna_mode.num_rx_chains,
7600 cmd->set_antenna_mode.num_tx_chains);
7601
7602 status = umac_send_mb_message_to_mac(cmd);
7603 if (QDF_STATUS_SUCCESS != status) {
7604 sme_err("Posting to PE failed");
7605 /*
7606 * umac_send_mb_message_to_mac would've released the mem
7607 * allocated by cmd.
7608 */
7609 goto fail;
7610 }
7611
7612 return;
7613 fail:
7614 param = qdf_mem_malloc(sizeof(*param));
7615 if (!param)
7616 return;
7617
7618 sme_err("Sending set dual mac fail response to SME");
7619 param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
7620 msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
7621 msg.bodyptr = param;
7622 msg.bodyval = 0;
7623 sys_process_mmh_msg(mac, &msg);
7624 }
7625
7626 /**
7627 * csr_process_nss_update_req() - Update nss command to PE
7628 * @mac: Globacl MAC pointer
7629 * @command: Command received from SME
7630 *
7631 * Posts the nss update command to PE. This message passing
7632 * through PE is required for PE's internal management
7633 *
7634 * Return: None
7635 */
csr_process_nss_update_req(struct mac_context * mac,tSmeCmd * command)7636 void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command)
7637 {
7638 uint32_t len;
7639 struct sir_nss_update_request *msg;
7640 QDF_STATUS status;
7641 struct scheduler_msg msg_return = {0};
7642 struct sir_bcn_update_rsp *param;
7643 struct csr_roam_session *session;
7644
7645
7646 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) {
7647 sme_err("Invalid session id %d", command->vdev_id);
7648 goto fail;
7649 }
7650 session = CSR_GET_SESSION(mac, command->vdev_id);
7651
7652 len = sizeof(*msg);
7653 msg = qdf_mem_malloc(len);
7654 if (!msg)
7655 /* Probably the fail response is also fail during malloc.
7656 * Still proceeding to send response!
7657 */
7658 goto fail;
7659
7660 msg->msgType = eWNI_SME_NSS_UPDATE_REQ;
7661 msg->msgLen = sizeof(*msg);
7662
7663 msg->new_nss = command->u.nss_update_cmd.new_nss;
7664 msg->ch_width = command->u.nss_update_cmd.ch_width;
7665 msg->vdev_id = command->u.nss_update_cmd.session_id;
7666
7667 sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE");
7668
7669 status = umac_send_mb_message_to_mac(msg);
7670 if (QDF_IS_STATUS_SUCCESS(status))
7671 return;
7672
7673 sme_err("Posting to PE failed");
7674 fail:
7675 param = qdf_mem_malloc(sizeof(*param));
7676 if (!param)
7677 return;
7678
7679 sme_err("Sending nss update fail response to SME");
7680 param->status = QDF_STATUS_E_FAILURE;
7681 param->vdev_id = command->u.nss_update_cmd.session_id;
7682 param->reason = REASON_NSS_UPDATE;
7683 msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
7684 msg_return.bodyptr = param;
7685 msg_return.bodyval = 0;
7686 sys_process_mmh_msg(mac, &msg_return);
7687 }
7688
7689 /**
7690 * csr_process_sap_ch_width_update() - Update ch_width command to PE
7691 * @mac: Globacl MAC pointer
7692 * @command: Command received from SME
7693 *
7694 * Posts the ch_width update command to PE. This message passing
7695 * through PE is required for PE's internal management
7696 *
7697 * Return: None
7698 */
csr_process_sap_ch_width_update(struct mac_context * mac,tSmeCmd * command)7699 void csr_process_sap_ch_width_update(struct mac_context *mac, tSmeCmd *command)
7700 {
7701 uint32_t len;
7702 struct sir_sap_ch_width_update *msg;
7703 QDF_STATUS status;
7704 struct scheduler_msg msg_return = {0};
7705 struct sir_bcn_update_rsp *param;
7706 enum policy_mgr_conn_update_reason reason =
7707 command->u.bw_update_cmd.reason;
7708
7709 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) {
7710 sme_err("Invalid session id %d", command->vdev_id);
7711 goto fail;
7712 }
7713
7714 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) &&
7715 (mac->sme.get_connection_info_cb(NULL, NULL))) {
7716 policy_mgr_restart_opportunistic_timer(mac->psoc, false);
7717 sme_info("Vdev %d : Avoid set BW as conn in progress",
7718 command->vdev_id);
7719 goto fail;
7720 }
7721
7722 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) &&
7723 (!policy_mgr_need_opportunistic_upgrade(mac->psoc, &reason))) {
7724 sme_info("Vdev %d: BW update not needed anymore",
7725 command->vdev_id);
7726 goto fail;
7727 }
7728
7729 len = sizeof(*msg);
7730 msg = qdf_mem_malloc(len);
7731 if (!msg)
7732 /* Probably the fail response is also fail during malloc.
7733 * Still proceeding to send response!
7734 */
7735 goto fail;
7736
7737 msg->msgType = eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ;
7738 msg->msgLen = sizeof(*msg);
7739
7740 msg->ch_width = command->u.bw_update_cmd.ch_width;
7741 msg->vdev_id = command->u.bw_update_cmd.vdev_id;
7742
7743 sme_debug("Posting eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ to PE");
7744
7745 status = umac_send_mb_message_to_mac(msg);
7746 if (QDF_IS_STATUS_SUCCESS(status))
7747 return;
7748
7749 sme_err("Posting to PE failed");
7750 fail:
7751 param = qdf_mem_malloc(sizeof(*param));
7752 if (param) {
7753 param->status = QDF_STATUS_E_FAILURE;
7754 param->vdev_id = command->u.bw_update_cmd.vdev_id;
7755 param->reason = REASON_CH_WIDTH_UPDATE;
7756 }
7757 msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP;
7758 msg_return.bodyptr = param;
7759 msg_return.bodyval = 0;
7760 sys_process_mmh_msg(mac, &msg_return);
7761 }
7762
7763 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
7764 #ifdef WLAN_FEATURE_SAE
7765 /**
7766 * csr_process_roam_auth_sae_callback() - API to trigger the
7767 * WPA3 pre-auth event for candidate AP received from firmware.
7768 * @mac_ctx: Global mac context pointer
7769 * @vdev_id: vdev id
7770 * @roam_bssid: Candidate BSSID to roam
7771 * @akm: Candidate AKM
7772 *
7773 * This function calls the hdd_sme_roam_callback with reason
7774 * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant.
7775 */
7776 static QDF_STATUS
csr_process_roam_auth_sae_callback(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr roam_bssid,uint32_t akm)7777 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
7778 uint8_t vdev_id,
7779 struct qdf_mac_addr roam_bssid,
7780 uint32_t akm)
7781 {
7782 struct csr_roam_info *roam_info;
7783 struct sir_sae_info sae_info;
7784 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
7785
7786 if (!session) {
7787 sme_err("WPA3 Preauth event with invalid session id:%d",
7788 vdev_id);
7789 return QDF_STATUS_E_FAILURE;
7790 }
7791
7792 roam_info = qdf_mem_malloc(sizeof(*roam_info));
7793 if (!roam_info)
7794 return QDF_STATUS_E_FAILURE;
7795
7796 sae_info.msg_len = sizeof(sae_info);
7797 sae_info.vdev_id = vdev_id;
7798 sae_info.akm = akm;
7799 wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id,
7800 sae_info.ssid.ssId,
7801 &sae_info.ssid.length);
7802 qdf_mem_copy(sae_info.peer_mac_addr.bytes,
7803 roam_bssid.bytes, QDF_MAC_ADDR_SIZE);
7804
7805 roam_info->sae_info = &sae_info;
7806
7807 csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
7808 eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE);
7809
7810 qdf_mem_free(roam_info);
7811
7812 return QDF_STATUS_SUCCESS;
7813 }
7814 #else
7815 static inline QDF_STATUS
csr_process_roam_auth_sae_callback(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr roam_bssid,uint32_t akm)7816 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
7817 uint8_t vdev_id,
7818 struct qdf_mac_addr roam_bssid,
7819 uint32_t akm)
7820 {
7821 return QDF_STATUS_E_NOSUPPORT;
7822 }
7823 #endif
7824
7825 QDF_STATUS
csr_roam_auth_offload_callback(struct mac_context * mac_ctx,uint8_t vdev_id,struct qdf_mac_addr bssid,uint32_t akm)7826 csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id,
7827 struct qdf_mac_addr bssid, uint32_t akm)
7828 {
7829 QDF_STATUS status;
7830
7831 status = sme_acquire_global_lock(&mac_ctx->sme);
7832 if (!QDF_IS_STATUS_SUCCESS(status))
7833 return status;
7834
7835 status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id,
7836 bssid, akm);
7837
7838 sme_release_global_lock(&mac_ctx->sme);
7839
7840 return status;
7841
7842 }
7843 #endif
7844
csr_update_owe_info(struct mac_context * mac,struct assoc_ind * assoc_ind)7845 QDF_STATUS csr_update_owe_info(struct mac_context *mac,
7846 struct assoc_ind *assoc_ind)
7847 {
7848 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
7849 QDF_STATUS status;
7850
7851 status = csr_roam_get_session_id_from_bssid(mac,
7852 (struct qdf_mac_addr *)assoc_ind->bssId,
7853 &session_id);
7854 if (!QDF_IS_STATUS_SUCCESS(status)) {
7855 sme_debug("Couldn't find session_id for given BSSID");
7856 return QDF_STATUS_E_FAILURE;
7857 }
7858
7859 /* Send Association completion message to PE */
7860 if (assoc_ind->owe_status)
7861 status = QDF_STATUS_E_INVAL;
7862 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status,
7863 assoc_ind->owe_status);
7864 /*
7865 * send a message to CSR itself just to avoid the EAPOL frames
7866 * going OTA before association response
7867 */
7868 if (assoc_ind->owe_status == 0)
7869 status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac,
7870 assoc_ind,
7871 status,
7872 session_id);
7873
7874 return status;
7875 }
7876
csr_update_ft_info(struct mac_context * mac,struct assoc_ind * assoc_ind)7877 QDF_STATUS csr_update_ft_info(struct mac_context *mac,
7878 struct assoc_ind *assoc_ind)
7879 {
7880 QDF_STATUS status;
7881
7882 /* Send Association completion message to PE */
7883 status = assoc_ind->ft_status ? QDF_STATUS_E_INVAL : QDF_STATUS_SUCCESS;
7884 assoc_ind->need_assoc_rsp_tx_cb = true;
7885 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status,
7886 assoc_ind->ft_status);
7887 return status;
7888 }
7889
7890 /**
7891 * csr_set_sap_ser_params() - API to fill serialization parameters for
7892 * SAP requests
7893 * @cmd : Serialization command
7894 * @cmd_type: Type of serialization command
7895 *
7896 * Return: Void
7897 */
csr_set_sap_ser_params(struct wlan_serialization_command * cmd,enum wlan_serialization_cmd_type cmd_type)7898 static void csr_set_sap_ser_params(struct wlan_serialization_command *cmd,
7899 enum wlan_serialization_cmd_type cmd_type)
7900 {
7901 cmd->cmd_type = cmd_type;
7902 cmd->source = WLAN_UMAC_COMP_MLME;
7903 cmd->cmd_cb = sme_sap_ser_callback;
7904 cmd->is_high_priority = false;
7905 cmd->is_blocking = true;
7906 return;
7907 }
7908
csr_bss_start(struct mac_context * mac,uint32_t vdev_id,struct start_bss_config * bss_config)7909 QDF_STATUS csr_bss_start(struct mac_context *mac, uint32_t vdev_id,
7910 struct start_bss_config *bss_config)
7911 {
7912 struct wlan_serialization_command cmd = {0};
7913 struct wlan_objmgr_vdev *vdev;
7914 struct start_bss_config *start_bss_cfg = NULL;
7915 enum QDF_OPMODE persona;
7916 enum wlan_serialization_status status;
7917 struct csr_roam_session *session;
7918 struct validate_bss_data candidate;
7919
7920 session = CSR_GET_SESSION(mac, vdev_id);
7921 if (!session)
7922 return QDF_STATUS_E_FAILURE;
7923
7924 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
7925 WLAN_LEGACY_MAC_ID);
7926 if (!vdev) {
7927 sme_err("VDEV not found for vdev id : %d", vdev_id);
7928 return QDF_STATUS_E_FAILURE;
7929 }
7930
7931 persona = wlan_vdev_mlme_get_opmode(vdev);
7932 if (persona != QDF_SAP_MODE && persona != QDF_NDI_MODE &&
7933 persona != QDF_P2P_GO_MODE) {
7934 sme_err("Start BSS request for invalid mode %d", persona);
7935 goto error;
7936 }
7937
7938 start_bss_cfg = qdf_mem_malloc(sizeof(struct start_bss_config));
7939 if (!start_bss_cfg) {
7940 sme_err("SAP BSS config allocation failed");
7941 goto error;
7942 }
7943
7944 qdf_mem_copy(start_bss_cfg, bss_config,
7945 sizeof(struct start_bss_config));
7946 start_bss_cfg->cmd_id = csr_get_monotonous_number(mac);
7947
7948 session->cb_mode = start_bss_cfg->sec_ch_offset;
7949 session->bcn_int = bss_config->beaconInterval;
7950 candidate.beacon_interval = session->bcn_int;
7951 candidate.chan_freq = bss_config->oper_ch_freq;
7952 if_mgr_is_beacon_interval_valid(mac->pdev, vdev_id,
7953 &candidate);
7954 bss_config->beaconInterval = candidate.beacon_interval;
7955 session->bcn_int = candidate.beacon_interval;
7956
7957 cmd.cmd_id = start_bss_cfg->cmd_id;
7958 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_START_BSS);
7959 cmd.umac_cmd = start_bss_cfg;
7960 cmd.vdev = vdev;
7961 csr_fill_cmd_timeout(&cmd);
7962
7963 status = wlan_vdev_mlme_ser_start_bss(&cmd);
7964 switch (status) {
7965 case WLAN_SER_CMD_PENDING:
7966 case WLAN_SER_CMD_ACTIVE:
7967 break;
7968 default:
7969 sme_err("ser cmd status %d", status);
7970 goto error;
7971 }
7972
7973 return QDF_STATUS_SUCCESS;
7974 error:
7975 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
7976 if (start_bss_cfg)
7977 qdf_mem_free(start_bss_cfg);
7978
7979 return QDF_STATUS_E_FAILURE;
7980 }
7981
csr_roam_issue_stop_bss_cmd(struct mac_context * mac,uint8_t vdev_id,eCsrRoamBssType bss_type)7982 QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac,
7983 uint8_t vdev_id,
7984 eCsrRoamBssType bss_type)
7985 {
7986 struct wlan_objmgr_vdev *vdev;
7987 struct wlan_serialization_command cmd = {0};
7988 enum wlan_serialization_status status;
7989 struct stop_bss_req *stop_bss_req;
7990
7991 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
7992 WLAN_LEGACY_MAC_ID);
7993 if (!vdev) {
7994 sme_err("VDEV not found for vdev id : %d", vdev_id);
7995 return QDF_STATUS_E_FAILURE;
7996 }
7997
7998 /* Change the substate in case it is wait-for-key */
7999 if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) {
8000 cm_stop_wait_for_key_timer(mac->psoc, vdev_id);
8001 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
8002 vdev_id);
8003 }
8004
8005 sme_debug("Stop BSS vdev_id: %d bss_type %d", vdev_id, bss_type);
8006 stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req));
8007 if (!stop_bss_req)
8008 goto error;
8009
8010 stop_bss_req->vdev_id = vdev_id;
8011 stop_bss_req->cmd_id = csr_get_monotonous_number(mac);
8012
8013 cmd.cmd_id = stop_bss_req->cmd_id;
8014 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_STOP_BSS);
8015 cmd.umac_cmd = stop_bss_req;
8016 cmd.vdev = vdev;
8017 csr_fill_cmd_timeout(&cmd);
8018
8019 status = wlan_vdev_mlme_ser_stop_bss(&cmd);
8020 switch (status) {
8021 case WLAN_SER_CMD_PENDING:
8022 case WLAN_SER_CMD_ACTIVE:
8023 break;
8024 default:
8025 sme_err("ser cmd status %d", status);
8026 goto error;
8027 }
8028 return QDF_STATUS_SUCCESS;
8029
8030 error:
8031 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
8032 qdf_mem_free(stop_bss_req);
8033 return QDF_STATUS_E_FAILURE;
8034 }
8035
csr_process_stop_bss_response(struct mac_context * mac_ctx,uint32_t vdev_id)8036 static void csr_process_stop_bss_response(struct mac_context *mac_ctx,
8037 uint32_t vdev_id)
8038 {
8039 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
8040
8041 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, vdev_id)) {
8042 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
8043 csr_set_default_dot11_mode(mac_ctx);
8044 }
8045
8046 csr_roam_call_callback(mac_ctx, vdev_id, NULL, eCSR_ROAM_INFRA_IND,
8047 eCSR_ROAM_RESULT_INFRA_STOPPED);
8048 return;
8049 }
8050
8051 /**
8052 * csr_process_sap_results() - API to process the LIM response for
8053 * the messages posted by SAP module
8054 * @mac_ctx: mac context
8055 * @req: Serialization command posted by SAP
8056 * @rsp: Response from LIM
8057 * @result: Result from LIM
8058 * @vdev_id : vdev id
8059 *
8060 * Return: void
8061 */
csr_process_sap_results(struct mac_context * mac_ctx,void * rsp,enum csr_sap_response_type result,uint8_t vdev_id)8062 static bool csr_process_sap_results(struct mac_context *mac_ctx,
8063 void *rsp,
8064 enum csr_sap_response_type result,
8065 uint8_t vdev_id)
8066 {
8067 struct csr_roam_info *roam_info;
8068 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
8069 eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND;
8070 eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED;
8071 enum QDF_OPMODE opmode;
8072
8073 if (!session) {
8074 sme_err("session %d not found ", vdev_id);
8075 return false;
8076 }
8077
8078 roam_info = qdf_mem_malloc(sizeof(*roam_info));
8079 if (!roam_info)
8080 return false;
8081
8082 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
8083 sme_debug("SAP result : %d", result);
8084
8085 switch (result) {
8086 case CSR_SAP_START_BSS_SUCCESS:
8087 csr_roam_process_start_bss_success(mac_ctx, roam_info,
8088 rsp, vdev_id);
8089 break;
8090 case CSR_SAP_START_BSS_FAILURE:
8091 if (opmode == QDF_NDI_MODE) {
8092 csr_roam_update_ndp_return_params(mac_ctx,
8093 CSR_SAP_START_BSS_FAILURE,
8094 &roam_status,
8095 &roam_result,
8096 roam_info);
8097 }
8098 csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
8099 roam_status, roam_result);
8100 csr_set_default_dot11_mode(mac_ctx);
8101 break;
8102 case CSR_SAP_STOP_BSS_SUCCESS:
8103 case CSR_SAP_STOP_BSS_FAILURE:
8104 if (opmode == QDF_NDI_MODE) {
8105 qdf_mem_zero(roam_info, sizeof(*roam_info));
8106 csr_roam_update_ndp_return_params(mac_ctx, result,
8107 &roam_status,
8108 &roam_result,
8109 roam_info);
8110 csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
8111 roam_status, roam_result);
8112 } else {
8113 csr_process_stop_bss_response(mac_ctx, vdev_id);
8114 }
8115 break;
8116 default:
8117 sme_err("Invalid response");
8118 break;
8119 }
8120 qdf_mem_free(roam_info);
8121 return true;
8122 }
8123
8124 static enum wlan_serialization_cmd_type
get_cmd_type_from_result(enum csr_sap_response_type result)8125 get_cmd_type_from_result(enum csr_sap_response_type result)
8126 {
8127 switch (result) {
8128 case CSR_SAP_START_BSS_SUCCESS:
8129 case CSR_SAP_START_BSS_FAILURE:
8130 return WLAN_SER_CMD_VDEV_START_BSS;
8131 case CSR_SAP_STOP_BSS_SUCCESS:
8132 case CSR_SAP_STOP_BSS_FAILURE:
8133 return WLAN_SER_CMD_VDEV_STOP_BSS;
8134 default:
8135 return WLAN_SER_CMD_MAX;
8136 }
8137 }
8138
8139 static inline
get_cmd_id_from_cmd_type(void * cmd,enum wlan_serialization_cmd_type cmd_type)8140 uint32_t get_cmd_id_from_cmd_type(void *cmd,
8141 enum wlan_serialization_cmd_type cmd_type)
8142 {
8143 switch (cmd_type) {
8144 case WLAN_SER_CMD_VDEV_START_BSS:
8145 return ((struct start_bss_config *)cmd)->cmd_id;
8146 case WLAN_SER_CMD_VDEV_STOP_BSS:
8147 return ((struct stop_bss_req *)cmd)->cmd_id;
8148 default:
8149 sme_err("Invalid cmd_type %d to be dequeued", cmd_type);
8150 return 0;
8151 }
8152 }
8153
csr_process_sap_response(struct mac_context * mac_ctx,enum csr_sap_response_type result,void * rsp,uint8_t vdev_id)8154 void csr_process_sap_response(struct mac_context *mac_ctx,
8155 enum csr_sap_response_type result,
8156 void *rsp, uint8_t vdev_id)
8157 {
8158 struct wlan_objmgr_vdev *vdev;
8159 void *req;
8160 uint32_t cmd_id;
8161 enum wlan_serialization_cmd_type cmd_type =
8162 get_cmd_type_from_result(result);
8163
8164 if (cmd_type >= WLAN_SER_CMD_MAX) {
8165 sme_err("Invalid command to be dequeued %d", cmd_type);
8166 return;
8167 }
8168
8169 req = wlan_serialization_get_active_cmd(mac_ctx->psoc,
8170 vdev_id, cmd_type);
8171 if (!req) {
8172 sme_err("No active command for response from LIM for cmd: %d vdev: %d",
8173 cmd_type, vdev_id);
8174 csr_process_sap_results(mac_ctx, rsp, result, vdev_id);
8175 return;
8176 }
8177
8178 csr_process_sap_results(mac_ctx, rsp, result, vdev_id);
8179
8180 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
8181 WLAN_LEGACY_MAC_ID);
8182 if (!vdev) {
8183 sme_err("vdev not found for vdev id: %d", vdev_id);
8184 return;
8185 }
8186
8187 cmd_id = get_cmd_id_from_cmd_type(req, cmd_type);
8188 sme_debug("Dequeue cmd id : %d type : %d", cmd_id, cmd_type);
8189
8190 wlan_vdev_mlme_ser_remove_request(vdev, cmd_id, cmd_type);
8191 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
8192 }
8193
csr_set_vdev_ies_per_band(mac_handle_t mac_handle,uint8_t vdev_id,enum QDF_OPMODE device_mode)8194 void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
8195 enum QDF_OPMODE device_mode)
8196 {
8197 struct sir_set_vdev_ies_per_band *p_msg;
8198 QDF_STATUS status = QDF_STATUS_E_FAILURE;
8199 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8200 enum csr_cfgdot11mode curr_dot11_mode =
8201 mac_ctx->roam.configParam.uCfgDot11Mode;
8202
8203 p_msg = qdf_mem_malloc(sizeof(*p_msg));
8204 if (!p_msg)
8205 return;
8206
8207 p_msg->vdev_id = vdev_id;
8208 p_msg->device_mode = device_mode;
8209 p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id,
8210 curr_dot11_mode);
8211 p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND;
8212 p_msg->len = sizeof(*p_msg);
8213 sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d",
8214 vdev_id, p_msg->dot11_mode, device_mode);
8215 status = umac_send_mb_message_to_mac(p_msg);
8216 if (QDF_STATUS_SUCCESS != status)
8217 sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail");
8218 }
8219