xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c (revision b80337cee1b59d5fa6f823a38d377ce0bc0a3ab3)
1 /*
2  * Copyright (c) 2012-2015, 2020-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: wlan_cm_api.c
20  *
21  * This file maintains definitaions public apis.
22  */
23 
24 #include <wlan_cm_api.h>
25 #include "connection_mgr/core/src/wlan_cm_main_api.h"
26 #include "connection_mgr/core/src/wlan_cm_roam.h"
27 #include <wlan_vdev_mgr_utils_api.h>
28 #ifdef WLAN_FEATURE_11BE_MLO
29 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
30 #include "wlan_mlo_mgr_roam.h"
31 #endif
32 #endif
33 
34 QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev,
35 				 struct wlan_cm_connect_req *req)
36 {
37 	return cm_connect_start_req(vdev, req);
38 }
39 
40 QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev,
41 			      enum wlan_cm_source source,
42 			      enum wlan_reason_code reason_code,
43 			      struct qdf_mac_addr *bssid)
44 {
45 	struct wlan_cm_disconnect_req req = {0};
46 
47 	req.vdev_id = wlan_vdev_get_id(vdev);
48 	req.source = source;
49 	req.reason_code = reason_code;
50 	if (bssid)
51 		qdf_copy_macaddr(&req.bssid, bssid);
52 
53 	return cm_disconnect_start_req(vdev, &req);
54 }
55 
56 QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev,
57 				   enum wlan_cm_source source,
58 				   enum wlan_reason_code reason_code)
59 {
60 	struct wlan_cm_disconnect_req req = {0};
61 
62 	req.vdev_id = wlan_vdev_get_id(vdev);
63 	req.source = source;
64 	req.reason_code = reason_code;
65 
66 	return cm_disconnect_start_req_sync(vdev, &req);
67 }
68 
69 QDF_STATUS wlan_cm_bss_select_ind_rsp(struct wlan_objmgr_vdev *vdev,
70 				      QDF_STATUS status)
71 {
72 	return cm_bss_select_ind_rsp(vdev, status);
73 }
74 
75 QDF_STATUS wlan_cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev,
76 				       QDF_STATUS status,
77 				       struct qdf_mac_addr *peer_mac)
78 {
79 	uint32_t prefix;
80 	struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev);
81 
82 	if (!cm_ctx)
83 		return QDF_STATUS_E_INVAL;
84 
85 	prefix = CM_ID_GET_PREFIX(cm_ctx->active_cm_id);
86 	if (prefix == ROAM_REQ_PREFIX)
87 		return cm_roam_bss_peer_create_rsp(vdev, status, peer_mac);
88 	else
89 		return cm_bss_peer_create_rsp(vdev, status, peer_mac);
90 }
91 
92 QDF_STATUS wlan_cm_connect_rsp(struct wlan_objmgr_vdev *vdev,
93 			       struct wlan_cm_connect_resp *resp)
94 {
95 	return cm_connect_rsp(vdev, resp);
96 }
97 
98 QDF_STATUS wlan_cm_bss_peer_delete_ind(struct wlan_objmgr_vdev *vdev,
99 				       struct qdf_mac_addr *peer_mac)
100 {
101 	return cm_bss_peer_delete_req(vdev, peer_mac);
102 }
103 
104 QDF_STATUS wlan_cm_bss_peer_delete_rsp(struct wlan_objmgr_vdev *vdev,
105 				       uint32_t status)
106 {
107 	return cm_vdev_down_req(vdev, status);
108 }
109 
110 QDF_STATUS wlan_cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev,
111 				  struct wlan_cm_discon_rsp *resp)
112 {
113 	uint32_t prefix;
114 	struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev);
115 
116 	if (!cm_ctx)
117 		return QDF_STATUS_E_INVAL;
118 
119 	prefix = CM_ID_GET_PREFIX(cm_ctx->active_cm_id);
120 	if (prefix == ROAM_REQ_PREFIX)
121 		return cm_roam_disconnect_rsp(vdev, resp);
122 	else
123 		return cm_disconnect_rsp(vdev, resp);
124 }
125 
126 #ifdef WLAN_FEATURE_HOST_ROAM
127 QDF_STATUS wlan_cm_reassoc_rsp(struct wlan_objmgr_vdev *vdev,
128 			       struct wlan_cm_connect_resp *resp)
129 {
130 	return cm_reassoc_rsp(vdev, resp);
131 }
132 #endif
133 
134 void wlan_cm_free_connect_req(struct wlan_cm_connect_req *connect_req)
135 {
136 	if (!connect_req)
137 		return;
138 
139 	cm_free_connect_req(connect_req);
140 }
141 
142 void wlan_cm_free_connect_resp(struct wlan_cm_connect_resp *connect_rsp)
143 {
144 	if (!connect_rsp)
145 		return;
146 
147 	cm_free_connect_rsp(connect_rsp);
148 }
149 
150 void wlan_cm_free_connect_req_param(struct wlan_cm_connect_req *req)
151 {
152 	if (!req)
153 		return;
154 
155 	cm_free_connect_req_param(req);
156 }
157 
158 void wlan_cm_set_max_connect_attempts(struct wlan_objmgr_vdev *vdev,
159 				      uint8_t max_connect_attempts)
160 {
161 	cm_set_max_connect_attempts(vdev, max_connect_attempts);
162 }
163 
164 void wlan_cm_set_max_connect_timeout(struct wlan_objmgr_vdev *vdev,
165 				     uint32_t max_connect_timeout)
166 {
167 	cm_set_max_connect_timeout(vdev, max_connect_timeout);
168 }
169 
170 bool wlan_cm_is_vdev_connecting(struct wlan_objmgr_vdev *vdev)
171 {
172 	return cm_is_vdev_connecting(vdev);
173 }
174 
175 bool wlan_cm_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
176 {
177 	return cm_is_vdev_connected(vdev);
178 }
179 
180 bool wlan_cm_is_vdev_active(struct wlan_objmgr_vdev *vdev)
181 {
182 	return cm_is_vdev_active(vdev);
183 }
184 
185 bool wlan_cm_is_vdev_disconnecting(struct wlan_objmgr_vdev *vdev)
186 {
187 	return cm_is_vdev_disconnecting(vdev);
188 }
189 
190 bool wlan_cm_is_vdev_disconnected(struct wlan_objmgr_vdev *vdev)
191 {
192 	return cm_is_vdev_disconnected(vdev);
193 }
194 
195 bool wlan_cm_is_vdev_idle_due_to_link_switch(struct wlan_objmgr_vdev *vdev)
196 {
197 	return cm_is_vdev_idle_due_to_link_switch(vdev);
198 }
199 
200 bool wlan_cm_is_vdev_roaming(struct wlan_objmgr_vdev *vdev)
201 {
202 	return cm_is_vdev_roaming(vdev);
203 }
204 
205 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
206 bool wlan_cm_is_vdev_roam_started(struct wlan_objmgr_vdev *vdev)
207 {
208 	return cm_is_vdev_roam_started(vdev);
209 }
210 
211 bool wlan_cm_is_vdev_roam_sync_inprogress(struct wlan_objmgr_vdev *vdev)
212 {
213 	return cm_is_vdev_roam_sync_inprogress(vdev);
214 }
215 #endif
216 
217 #ifdef WLAN_FEATURE_HOST_ROAM
218 bool wlan_cm_is_vdev_roam_preauth_state(struct wlan_objmgr_vdev *vdev)
219 {
220 	return cm_is_vdev_roam_preauth_state(vdev);
221 }
222 
223 bool wlan_cm_is_vdev_roam_reassoc_state(struct wlan_objmgr_vdev *vdev)
224 {
225 	return cm_is_vdev_roam_reassoc_state(vdev);
226 }
227 #endif
228 
229 enum wlan_cm_active_request_type
230 wlan_cm_get_active_req_type(struct wlan_objmgr_vdev *vdev)
231 {
232 	return cm_get_active_req_type(vdev);
233 }
234 
235 bool wlan_cm_get_active_connect_req(struct wlan_objmgr_vdev *vdev,
236 				    struct wlan_cm_vdev_connect_req *req)
237 {
238 	return cm_get_active_connect_req(vdev, req);
239 }
240 
241 QDF_STATUS
242 wlan_cm_get_active_connect_req_param(struct wlan_objmgr_vdev *vdev,
243 				     struct wlan_cm_connect_req *req)
244 {
245 	return cm_get_active_connect_req_param(vdev, req);
246 }
247 
248 cm_ext_t *wlan_cm_get_ext_hdl(struct wlan_objmgr_vdev *vdev)
249 {
250 	return cm_get_ext_hdl(vdev);
251 }
252 
253 bool wlan_cm_is_first_candidate_connect_attempt(struct wlan_objmgr_vdev *vdev)
254 {
255 	return cm_is_first_candidate_connect_attempt(vdev);
256 }
257 
258 bool wlan_cm_is_link_switch_disconnect_resp(struct wlan_cm_discon_rsp *resp)
259 {
260 	return cm_is_link_switch_disconnect_resp(resp);
261 }
262 
263 bool wlan_cm_is_link_switch_connect_resp(struct wlan_cm_connect_resp *resp)
264 {
265 	return cm_is_link_switch_connect_resp(resp);
266 }
267 
268 void wlan_cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev,
269 					  enum qdf_hang_reason reason)
270 {
271 	cm_trigger_panic_on_cmd_timeout(vdev, reason);
272 }
273 
274 #ifdef WLAN_FEATURE_HOST_ROAM
275 bool wlan_cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev,
276 				    struct wlan_cm_vdev_reassoc_req *req)
277 {
278 	return cm_get_active_reassoc_req(vdev, req);
279 }
280 #endif
281 
282 bool wlan_cm_get_active_disconnect_req(struct wlan_objmgr_vdev *vdev,
283 				       struct wlan_cm_vdev_discon_req *req)
284 {
285 	return cm_get_active_disconnect_req(vdev, req);
286 }
287 
288 const char *wlan_cm_reason_code_to_str(enum wlan_reason_code reason)
289 {
290 	if (reason > REASON_PROP_START)
291 		return "";
292 
293 	switch (reason) {
294 	CASE_RETURN_STRING(REASON_UNSPEC_FAILURE);
295 	CASE_RETURN_STRING(REASON_PREV_AUTH_NOT_VALID);
296 	CASE_RETURN_STRING(REASON_DEAUTH_NETWORK_LEAVING);
297 	CASE_RETURN_STRING(REASON_DISASSOC_DUE_TO_INACTIVITY);
298 	CASE_RETURN_STRING(REASON_DISASSOC_AP_BUSY);
299 	CASE_RETURN_STRING(REASON_CLASS2_FRAME_FROM_NON_AUTH_STA);
300 	CASE_RETURN_STRING(REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA);
301 	CASE_RETURN_STRING(REASON_DISASSOC_NETWORK_LEAVING);
302 	CASE_RETURN_STRING(REASON_STA_NOT_AUTHENTICATED);
303 	CASE_RETURN_STRING(REASON_BAD_PWR_CAPABILITY);
304 	CASE_RETURN_STRING(REASON_BAD_SUPPORTED_CHANNELS);
305 	CASE_RETURN_STRING(REASON_DISASSOC_BSS_TRANSITION);
306 	CASE_RETURN_STRING(REASON_INVALID_IE);
307 	CASE_RETURN_STRING(REASON_MIC_FAILURE);
308 	CASE_RETURN_STRING(REASON_4WAY_HANDSHAKE_TIMEOUT);
309 	CASE_RETURN_STRING(REASON_GROUP_KEY_UPDATE_TIMEOUT);
310 	CASE_RETURN_STRING(REASON_IN_4WAY_DIFFERS);
311 	CASE_RETURN_STRING(REASON_INVALID_GROUP_CIPHER);
312 	CASE_RETURN_STRING(REASON_INVALID_PAIRWISE_CIPHER);
313 	CASE_RETURN_STRING(REASON_INVALID_AKMP);
314 	CASE_RETURN_STRING(REASON_UNSUPPORTED_RSNE_VER);
315 	CASE_RETURN_STRING(REASON_INVALID_RSNE_CAPABILITIES);
316 	CASE_RETURN_STRING(REASON_1X_AUTH_FAILURE);
317 	CASE_RETURN_STRING(REASON_CIPHER_SUITE_REJECTED);
318 	CASE_RETURN_STRING(REASON_TDLS_PEER_UNREACHABLE);
319 	CASE_RETURN_STRING(REASON_TDLS_UNSPEC);
320 	CASE_RETURN_STRING(REASON_DISASSOC_SSP_REQUESTED);
321 	CASE_RETURN_STRING(REASON_NO_SSP_ROAMING_AGREEMENT);
322 	CASE_RETURN_STRING(REASON_BAD_CIPHER_OR_AKM);
323 	CASE_RETURN_STRING(REASON_LOCATION_NOT_AUTHORIZED);
324 	CASE_RETURN_STRING(REASON_SERVICE_CHANGE_PRECLUDES_TS);
325 	CASE_RETURN_STRING(REASON_QOS_UNSPECIFIED);
326 	CASE_RETURN_STRING(REASON_NO_BANDWIDTH);
327 	CASE_RETURN_STRING(REASON_XS_UNACKED_FRAMES);
328 	CASE_RETURN_STRING(REASON_EXCEEDED_TXOP);
329 	CASE_RETURN_STRING(REASON_STA_LEAVING);
330 	CASE_RETURN_STRING(REASON_END_TS_BA_DLS);
331 	CASE_RETURN_STRING(REASON_UNKNOWN_TS_BA);
332 	CASE_RETURN_STRING(REASON_TIMEDOUT);
333 	CASE_RETURN_STRING(REASON_PEERKEY_MISMATCH);
334 	CASE_RETURN_STRING(REASON_AUTHORIZED_ACCESS_LIMIT_REACHED);
335 	CASE_RETURN_STRING(REASON_EXTERNAL_SERVICE_REQUIREMENTS);
336 	CASE_RETURN_STRING(REASON_INVALID_FT_ACTION_FRAME_COUNT);
337 	CASE_RETURN_STRING(REASON_INVALID_PMKID);
338 	CASE_RETURN_STRING(REASON_INVALID_MDE);
339 	CASE_RETURN_STRING(REASON_INVALID_FTE);
340 	CASE_RETURN_STRING(REASON_MESH_PEERING_CANCELLED);
341 	CASE_RETURN_STRING(REASON_MESH_MAX_PEERS);
342 	CASE_RETURN_STRING(REASON_MESH_CONFIG_POLICY_VIOLATION);
343 	CASE_RETURN_STRING(REASON_MESH_CLOSE_RCVD);
344 	CASE_RETURN_STRING(REASON_MESH_MAX_RETRIES);
345 	CASE_RETURN_STRING(REASON_MESH_CONFIRM_TIMEOUT);
346 	CASE_RETURN_STRING(REASON_MESH_INVALID_GTK);
347 	CASE_RETURN_STRING(REASON_MESH_INCONSISTENT_PARAMS);
348 	CASE_RETURN_STRING(REASON_MESH_INVALID_SECURITY_CAP);
349 	CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_PROXY_INFO);
350 	CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_FORWARDING_INFO);
351 	CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_DEST_UNREACHABLE);
352 	CASE_RETURN_STRING(REASON_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS);
353 	CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_REGULATORY_REQ);
354 	CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_UNSPECIFIED);
355 	CASE_RETURN_STRING(REASON_POOR_RSSI_CONDITIONS);
356 	default:
357 		return "Unknown";
358 	}
359 }
360 
361 #ifdef WLAN_POLICY_MGR_ENABLE
362 void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
363 				 wlan_cm_id cm_id, QDF_STATUS status)
364 {
365 	uint32_t prefix;
366 
367 	prefix = CM_ID_GET_PREFIX(cm_id);
368 	if (prefix == ROAM_REQ_PREFIX)
369 		cm_reassoc_hw_mode_change_resp(pdev, vdev_id, cm_id, status);
370 	else
371 		cm_hw_mode_change_resp(pdev, vdev_id, cm_id, status);
372 }
373 #endif /* ifdef POLICY_MGR_ENABLE */
374 
375 #ifdef WLAN_FEATURE_LL_LT_SAP
376 void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
377 				wlan_cm_id cm_id, QDF_STATUS status)
378 {
379 	cm_bearer_switch_resp(psoc, vdev_id, cm_id, status);
380 }
381 #endif
382 
383 #ifdef SM_ENG_HIST_ENABLE
384 void wlan_cm_sm_history_print(struct wlan_objmgr_vdev *vdev)
385 {
386 	return cm_sm_history_print(vdev);
387 }
388 
389 void wlan_cm_req_history_print(struct wlan_objmgr_vdev *vdev)
390 {
391 	struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev);
392 
393 	if (!cm_ctx)
394 		return;
395 
396 	cm_req_history_print(cm_ctx);
397 }
398 #endif /* SM_ENG_HIST_ENABLE */
399 
400 #ifndef CONN_MGR_ADV_FEATURE
401 void wlan_cm_set_candidate_advance_filter_cb(
402 		struct wlan_objmgr_vdev *vdev,
403 		void (*filter_fun)(struct wlan_objmgr_vdev *vdev,
404 				   struct scan_filter *filter))
405 {
406 	cm_set_candidate_advance_filter_cb(vdev, filter_fun);
407 }
408 
409 void wlan_cm_set_candidate_custom_sort_cb(
410 		struct wlan_objmgr_vdev *vdev,
411 		void (*sort_fun)(struct wlan_objmgr_vdev *vdev,
412 				 qdf_list_t *list))
413 {
414 	cm_set_candidate_custom_sort_cb(vdev, sort_fun);
415 }
416 
417 #endif
418 
419 QDF_STATUS wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id,
420 			   struct reduced_neighbor_report *rnr)
421 {
422 	enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev);
423 
424 	if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) {
425 		mlme_err("vdev %d Invalid mode %d",
426 			 wlan_vdev_get_id(vdev), op_mode);
427 		return QDF_STATUS_E_NOSUPPORT;
428 	}
429 
430 	return cm_get_rnr(vdev, cm_id, rnr);
431 }
432 
433 void
434 wlan_cm_connect_resp_fill_mld_addr_from_cm_id(struct wlan_objmgr_vdev *vdev,
435 					     wlan_cm_id cm_id,
436 					     struct wlan_cm_connect_resp *rsp)
437 {
438 	return cm_connect_resp_fill_mld_addr_from_cm_id(vdev, cm_id, rsp);
439 }
440 
441 #ifdef WLAN_FEATURE_11BE_MLO
442 void
443 wlan_cm_connect_resp_fill_mld_addr_from_vdev_id(struct wlan_objmgr_psoc *psoc,
444 						uint8_t vdev_id,
445 						struct scan_cache_entry *entry,
446 						struct wlan_cm_connect_resp *rsp)
447 {
448 	struct wlan_objmgr_vdev *vdev;
449 
450 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
451 						    WLAN_MLME_CM_ID);
452 	if (!vdev)
453 		return;
454 
455 	cm_connect_resp_fill_mld_addr_from_candidate(vdev, entry, rsp);
456 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
457 }
458 #endif
459 
460 QDF_STATUS
461 wlan_cm_disc_cont_after_rso_stop(struct wlan_objmgr_vdev *vdev,
462 				 struct wlan_cm_vdev_discon_req *req)
463 {
464 	return cm_handle_rso_stop_rsp(vdev, req);
465 }
466 
467 #ifdef WLAN_FEATURE_11BE
468 QDF_STATUS wlan_cm_sta_set_chan_param(struct wlan_objmgr_vdev *vdev,
469 				      qdf_freq_t ch_freq,
470 				      enum phy_ch_width ori_bw,
471 				      uint16_t ori_punc,
472 				      uint8_t ccfs0, uint8_t ccfs1,
473 				      struct ch_params *chan_param)
474 {
475 	uint16_t primary_puncture_bitmap = 0;
476 	struct wlan_objmgr_pdev *pdev;
477 	struct reg_channel_list chan_list;
478 	qdf_freq_t sec_ch_2g_freq = 0;
479 	qdf_freq_t center_freq_320 = 0;
480 	qdf_freq_t center_freq_40 = 0;
481 	uint8_t band_mask;
482 	uint16_t new_punc = 0;
483 
484 	if (!vdev || !chan_param) {
485 		mlme_err("invalid input parameters");
486 		return QDF_STATUS_E_INVAL;
487 	}
488 	pdev = wlan_vdev_get_pdev(vdev);
489 	if (!pdev) {
490 		mlme_err("invalid pdev");
491 		return QDF_STATUS_E_INVAL;
492 	}
493 	if (ori_bw == CH_WIDTH_320MHZ) {
494 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq))
495 			band_mask = BIT(REG_BAND_6G);
496 		else
497 			band_mask = BIT(REG_BAND_5G);
498 		center_freq_320 = wlan_reg_chan_band_to_freq(pdev, ccfs1,
499 							     band_mask);
500 	} else if (ori_bw == CH_WIDTH_40MHZ) {
501 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
502 			band_mask = BIT(REG_BAND_2G);
503 			center_freq_40 = wlan_reg_chan_band_to_freq(pdev,
504 								    ccfs0,
505 								    band_mask);
506 			if (center_freq_40 == ch_freq + BW_10_MHZ)
507 				sec_ch_2g_freq = ch_freq + BW_20_MHZ;
508 			if (center_freq_40 == ch_freq - BW_10_MHZ)
509 				sec_ch_2g_freq = ch_freq - BW_20_MHZ;
510 		}
511 	}
512 	wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc,
513 					ch_freq,
514 					center_freq_320,
515 					CH_WIDTH_20MHZ,
516 					&primary_puncture_bitmap);
517 	if (primary_puncture_bitmap) {
518 		mlme_err("sta vdev %d freq %d RX bw %d puncture 0x%x primary chan is punctured",
519 			 wlan_vdev_get_id(vdev), ch_freq,
520 			 ori_bw, ori_punc);
521 		return QDF_STATUS_E_FAULT;
522 	}
523 	if (chan_param->ch_width != CH_WIDTH_320MHZ)
524 		center_freq_320 = 0;
525 	qdf_mem_zero(&chan_list, sizeof(chan_list));
526 	wlan_reg_fill_channel_list_for_pwrmode(pdev, ch_freq,
527 					       sec_ch_2g_freq,
528 					       chan_param->ch_width,
529 					       center_freq_320, &chan_list,
530 					       REG_CURRENT_PWR_MODE, true);
531 	*chan_param = chan_list.chan_param[0];
532 	if (chan_param->ch_width == ori_bw)
533 		new_punc = ori_punc;
534 	else
535 		wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc,
536 						ch_freq,
537 						chan_param->mhz_freq_seg1,
538 						chan_param->ch_width,
539 						&new_punc);
540 
541 	chan_param->reg_punc_bitmap = new_punc;
542 
543 	return QDF_STATUS_SUCCESS;
544 }
545 
546 QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev,
547 					  uint8_t *peer_mac,
548 					  uint16_t ori_punc,
549 					  enum phy_ch_width ori_bw,
550 					  uint8_t ccfs0, uint8_t ccfs1,
551 					  enum phy_ch_width new_bw)
552 {
553 	struct wlan_channel *des_chan;
554 	struct ch_params ch_param;
555 	uint32_t bw_puncture = 0;
556 	QDF_STATUS status = QDF_STATUS_E_INVAL;
557 
558 	if (!vdev || !peer_mac) {
559 		mlme_err("invalid input parameters");
560 		return status;
561 	}
562 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
563 	if (!des_chan) {
564 		mlme_err("invalid des chan");
565 		return status;
566 	}
567 	qdf_mem_zero(&ch_param, sizeof(ch_param));
568 	ch_param.ch_width = new_bw;
569 	status = wlan_cm_sta_set_chan_param(vdev, des_chan->ch_freq,
570 					    ori_bw, ori_punc, ccfs0,
571 					    ccfs1, &ch_param);
572 	if (QDF_IS_STATUS_ERROR(status))
573 		return status;
574 
575 	if (des_chan->puncture_bitmap == ch_param.reg_punc_bitmap &&
576 	    des_chan->ch_width == ch_param.ch_width)
577 		return status;
578 
579 	des_chan->ch_freq_seg1 = ch_param.center_freq_seg0;
580 	des_chan->ch_freq_seg2 = ch_param.center_freq_seg1;
581 	des_chan->ch_cfreq1 = ch_param.mhz_freq_seg0;
582 	des_chan->ch_cfreq2 = ch_param.mhz_freq_seg1;
583 	des_chan->puncture_bitmap = ch_param.reg_punc_bitmap;
584 	des_chan->ch_width = ch_param.ch_width;
585 	mlme_debug("sta vdev %d freq %d bw %d puncture 0x%x ch_cfreq1 %d ch_cfreq2 %d",
586 		   wlan_vdev_get_id(vdev), des_chan->ch_freq,
587 		   des_chan->ch_width, des_chan->puncture_bitmap,
588 		   des_chan->ch_cfreq1, des_chan->ch_cfreq2);
589 	QDF_SET_BITS(bw_puncture, 0, 8, des_chan->ch_width);
590 	QDF_SET_BITS(bw_puncture, 8, 16, des_chan->puncture_bitmap);
591 	return wlan_util_vdev_peer_set_param_send(vdev, peer_mac,
592 						  WLAN_MLME_PEER_BW_PUNCTURE,
593 						  bw_puncture);
594 }
595 #endif /* WLAN_FEATURE_11BE */
596 
597 #ifdef WLAN_FEATURE_11BE_MLO
598 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
599 bool
600 wlan_cm_check_mlo_roam_auth_status(struct wlan_objmgr_vdev *vdev)
601 {
602 	return mlo_roam_is_auth_status_connected(wlan_vdev_get_psoc(vdev),
603 					  wlan_vdev_get_id(vdev));
604 }
605 #endif
606 #endif
607 enum MLO_TYPE
608 wlan_cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc,
609 		     struct scan_cache_entry *entry,
610 		     qdf_list_t *scan_list)
611 {
612 	return cm_bss_mlo_type(psoc, entry, scan_list);
613 }
614