xref: /wlan-driver/qcacld-3.0/core/hdd/src/wlan_hdd_cm_connect.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
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 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: hdd_cm_connect.c
20  *
21  * WLAN Host Device Driver connect APIs implementation
22  *
23  */
24 
25 #include "wlan_hdd_main.h"
26 #include <wlan_hdd_mlo.h>
27 #include "wlan_hdd_cm_api.h"
28 #include "wlan_hdd_trace.h"
29 #include "wlan_hdd_object_manager.h"
30 #include "wlan_hdd_power.h"
31 #include "wlan_hdd_connectivity_logging.h"
32 #include <osif_cm_req.h>
33 #include <wlan_logging_sock_svc.h>
34 #include <wlan_hdd_green_ap.h>
35 #include <wlan_hdd_p2p.h>
36 #include <wlan_p2p_ucfg_api.h>
37 #include <wlan_pkt_capture_ucfg_api.h>
38 #include <wlan_hdd_ipa.h>
39 #include <wlan_ipa_ucfg_api.h>
40 #include <wlan_hdd_ftm_time_sync.h>
41 #include "wlan_crypto_global_api.h"
42 #include "wlan_vdev_mgr_ucfg_api.h"
43 #include "wlan_hdd_bootup_marker.h"
44 #include "sme_qos_internal.h"
45 #include "wlan_dlm_ucfg_api.h"
46 #include "wlan_hdd_scan.h"
47 #include "wlan_osif_priv.h"
48 #include <enet.h>
49 #include <wlan_mlme_twt_ucfg_api.h>
50 #include "wlan_roam_debug.h"
51 #include <wlan_hdd_regulatory.h>
52 #include "wlan_hdd_hostapd.h"
53 #include <wlan_twt_ucfg_ext_api.h>
54 #include <osif_twt_internal.h>
55 #include "wlan_osif_features.h"
56 #include "wlan_osif_request_manager.h"
57 #include <wlan_dp_ucfg_api.h>
58 #include "wlan_psoc_mlme_ucfg_api.h"
59 #include "wlan_action_oui_ucfg_api.h"
60 
hdd_cm_is_vdev_associated(struct wlan_hdd_link_info * link_info)61 bool hdd_cm_is_vdev_associated(struct wlan_hdd_link_info *link_info)
62 {
63 	struct wlan_objmgr_vdev *vdev;
64 	bool is_vdev_active;
65 	enum QDF_OPMODE opmode;
66 	struct hdd_station_ctx *sta_ctx;
67 
68 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
69 	if (link_info->adapter->device_mode == QDF_NDI_MODE)
70 		return (sta_ctx->conn_info.conn_state ==
71 			eConnectionState_NdiConnected);
72 
73 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
74 	if (!vdev)
75 		return false;
76 
77 	opmode = wlan_vdev_mlme_get_opmode(vdev);
78 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
79 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
80 		return false;
81 	}
82 	is_vdev_active = ucfg_cm_is_vdev_active(vdev);
83 
84 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
85 
86 	return is_vdev_active;
87 }
88 
hdd_cm_is_vdev_connected(struct wlan_hdd_link_info * link_info)89 bool hdd_cm_is_vdev_connected(struct wlan_hdd_link_info *link_info)
90 {
91 	struct wlan_objmgr_vdev *vdev;
92 	bool is_vdev_connected;
93 	struct hdd_station_ctx *sta_ctx;
94 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
95 
96 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
97 	if (opmode == QDF_NDI_MODE)
98 		return (sta_ctx->conn_info.conn_state ==
99 			eConnectionState_NdiConnected);
100 
101 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE)
102 		return false;
103 
104 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
105 	if (!vdev)
106 		return false;
107 
108 	is_vdev_connected = ucfg_cm_is_vdev_connected(vdev);
109 
110 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
111 
112 	return is_vdev_connected;
113 }
114 
hdd_cm_is_connecting(struct wlan_hdd_link_info * link_info)115 bool hdd_cm_is_connecting(struct wlan_hdd_link_info *link_info)
116 {
117 	struct wlan_objmgr_vdev *vdev;
118 	bool is_vdev_connecting;
119 	enum QDF_OPMODE opmode;
120 
121 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
122 	if (!vdev)
123 		return false;
124 
125 	opmode = wlan_vdev_mlme_get_opmode(vdev);
126 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
127 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
128 		return false;
129 	}
130 	is_vdev_connecting = ucfg_cm_is_vdev_connecting(vdev);
131 
132 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
133 
134 	return is_vdev_connecting;
135 }
136 
hdd_cm_is_disconnected(struct wlan_hdd_link_info * link_info)137 bool hdd_cm_is_disconnected(struct wlan_hdd_link_info *link_info)
138 {
139 	struct wlan_objmgr_vdev *vdev;
140 	bool is_vdev_disconnected;
141 	enum QDF_OPMODE opmode;
142 
143 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
144 	if (!vdev)
145 		return false;
146 
147 	opmode = wlan_vdev_mlme_get_opmode(vdev);
148 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
149 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
150 		return false;
151 	}
152 	is_vdev_disconnected = ucfg_cm_is_vdev_disconnected(vdev);
153 
154 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
155 
156 	return is_vdev_disconnected;
157 }
158 
hdd_cm_is_vdev_roaming(struct wlan_hdd_link_info * link_info)159 bool hdd_cm_is_vdev_roaming(struct wlan_hdd_link_info *link_info)
160 {
161 	struct wlan_objmgr_vdev *vdev;
162 	bool is_vdev_roaming;
163 	enum QDF_OPMODE opmode;
164 
165 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
166 	if (!vdev)
167 		return false;
168 
169 	opmode = wlan_vdev_mlme_get_opmode(vdev);
170 	if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
171 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
172 		return false;
173 	}
174 	is_vdev_roaming = ucfg_cm_is_vdev_roaming(vdev);
175 
176 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
177 
178 	return is_vdev_roaming;
179 }
180 
hdd_cm_set_peer_authenticate(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr * bssid,bool is_auth_required)181 void hdd_cm_set_peer_authenticate(struct wlan_hdd_link_info *link_info,
182 				  struct qdf_mac_addr *bssid,
183 				  bool is_auth_required)
184 {
185 	hdd_debug("sta: " QDF_MAC_ADDR_FMT "Changing TL state to %s",
186 		  QDF_MAC_ADDR_REF(bssid->bytes),
187 		  is_auth_required ? "CONNECTED" : "AUTHENTICATED");
188 
189 	hdd_change_peer_state(link_info, bssid->bytes,
190 			      is_auth_required ?
191 			      OL_TXRX_PEER_STATE_CONN :
192 			      OL_TXRX_PEER_STATE_AUTH);
193 	hdd_conn_set_authenticated(link_info, !is_auth_required);
194 	hdd_objmgr_set_peer_mlme_auth_state(link_info->vdev,
195 					    !is_auth_required);
196 }
197 
hdd_cm_update_rssi_snr_by_bssid(struct wlan_hdd_link_info * link_info)198 void hdd_cm_update_rssi_snr_by_bssid(struct wlan_hdd_link_info *link_info)
199 {
200 	struct hdd_station_ctx *sta_ctx;
201 	int8_t snr = 0;
202 	struct hdd_adapter *adapter = link_info->adapter;
203 	mac_handle_t mac_handle;
204 
205 	if (!adapter) {
206 		hdd_err_rl("null hdd_adapter pointer");
207 		return;
208 	}
209 
210 	mac_handle = hdd_adapter_get_mac_handle(adapter);
211 
212 	if (!mac_handle) {
213 		hdd_err_rl("null mac_handle pointer");
214 		return;
215 	}
216 
217 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
218 	hdd_get_rssi_snr_by_bssid(mac_handle,
219 				  sta_ctx->conn_info.bssid.bytes,
220 				  &link_info->rssi, &snr);
221 
222 	/* If RSSi is reported as positive then it is invalid */
223 	if (link_info->rssi > 0) {
224 		hdd_debug_rl("RSSI invalid %d", link_info->rssi);
225 		link_info->rssi = 0;
226 	}
227 
228 	hdd_debug("snr: %d, rssi: %d", snr, link_info->rssi);
229 
230 	sta_ctx->conn_info.signal = link_info->rssi;
231 	sta_ctx->conn_info.noise = sta_ctx->conn_info.signal - snr;
232 	sta_ctx->cache_conn_info.signal = sta_ctx->conn_info.signal;
233 	sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise;
234 }
235 
hdd_cm_handle_assoc_event(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac)236 void hdd_cm_handle_assoc_event(struct wlan_objmgr_vdev *vdev, uint8_t *peer_mac)
237 {
238 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
239 	struct wlan_hdd_link_info *link_info;
240 	struct hdd_station_ctx *sta_ctx;
241 	int ret;
242 
243 	if (!hdd_ctx) {
244 		hdd_err("hdd_ctx is NULL");
245 		return;
246 	}
247 
248 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
249 	if (!link_info) {
250 		hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
251 		return;
252 	}
253 
254 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
255 	ret = hdd_objmgr_set_peer_mlme_state(link_info->vdev,
256 					     WLAN_ASSOC_STATE);
257 	if (ret)
258 		hdd_err("Peer object " QDF_MAC_ADDR_FMT " fail to set associated state",
259 			QDF_MAC_ADDR_REF(peer_mac));
260 	ucfg_dp_add_latency_critical_client(vdev,
261 			hdd_convert_cfgdot11mode_to_80211mode(
262 				sta_ctx->conn_info.dot11mode));
263 
264 	ucfg_dp_bus_bw_compute_prev_txrx_stats(vdev);
265 	ucfg_dp_bus_bw_compute_timer_start(hdd_ctx->psoc);
266 
267 	if (ucfg_pkt_capture_get_pktcap_mode(hdd_ctx->psoc))
268 		ucfg_pkt_capture_record_channel(link_info->vdev);
269 }
270 
271 /**
272  * hdd_cm_netif_features_update_required() - Check if feature update
273  * is required
274  * @adapter: pointer to the adapter structure
275  * Returns: true if the connection is legacy and TSO and Checksum offload
276  * enabled or if the connection is not latency and TSO and Checksum
277  * offload are not enabled, false otherwise
278  */
hdd_cm_netif_features_update_required(struct hdd_adapter * adapter)279 static bool hdd_cm_netif_features_update_required(struct hdd_adapter *adapter)
280 {
281 	bool is_legacy_connection = hdd_is_legacy_connection(adapter->deflink);
282 
283 	hdd_debug("Legacy Connection: %d, TSO_CSUM Feature Enabled:%d",
284 		  is_legacy_connection, adapter->tso_csum_feature_enabled);
285 
286 	if (adapter->tso_csum_feature_enabled  && is_legacy_connection)
287 		return true;
288 
289 	if (!adapter->tso_csum_feature_enabled  && !is_legacy_connection)
290 		return true;
291 
292 	return false;
293 }
294 
hdd_cm_netif_queue_enable(struct hdd_adapter * adapter)295 void hdd_cm_netif_queue_enable(struct hdd_adapter *adapter)
296 {
297 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
298 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
299 
300 	if (cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload) &&
301 	    hdd_cm_netif_features_update_required(adapter)) {
302 		hdd_adapter_ops_record_event(hdd_ctx,
303 					     WLAN_HDD_ADAPTER_OPS_WORK_POST,
304 					     adapter->deflink->vdev_id);
305 		qdf_queue_work(0, hdd_ctx->adapter_ops_wq,
306 			       &adapter->netdev_features_update_work);
307 	}
308 
309 	wlan_hdd_netif_queue_control(adapter,
310 				     WLAN_WAKE_ALL_NETIF_QUEUE,
311 				     WLAN_CONTROL_PATH);
312 }
313 
hdd_cm_clear_pmf_stats(struct hdd_adapter * adapter)314 void hdd_cm_clear_pmf_stats(struct hdd_adapter *adapter)
315 {
316 	qdf_mem_zero(&adapter->deflink->hdd_stats.hdd_pmf_stats,
317 		     sizeof(adapter->deflink->hdd_stats.hdd_pmf_stats));
318 }
319 
hdd_cm_save_connect_status(struct wlan_hdd_link_info * link_info,uint32_t reason_code)320 void hdd_cm_save_connect_status(struct wlan_hdd_link_info *link_info,
321 				uint32_t reason_code)
322 {
323 	struct hdd_station_ctx *hdd_sta_ctx;
324 
325 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
326 	link_info->adapter->connect_req_status = reason_code;
327 	hdd_sta_ctx->conn_info.assoc_status_code = reason_code;
328 	hdd_sta_ctx->cache_conn_info.assoc_status_code = reason_code;
329 }
330 
331 #ifdef WLAN_FEATURE_11BE_MLO
hdd_cm_save_connected_links_info(struct qdf_mac_addr * self_mac,struct qdf_mac_addr * bssid,int32_t link_id)332 QDF_STATUS hdd_cm_save_connected_links_info(struct qdf_mac_addr *self_mac,
333 					    struct qdf_mac_addr *bssid,
334 					    int32_t link_id)
335 {
336 	struct hdd_context *hdd_ctx;
337 	struct wlan_hdd_link_info *link_info;
338 	struct hdd_station_ctx *sta_ctx;
339 
340 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
341 	if (!hdd_ctx) {
342 		hdd_err("HDD context NULL");
343 		return QDF_STATUS_E_INVAL;
344 	}
345 
346 	link_info = hdd_get_link_info_by_link_addr(hdd_ctx, self_mac);
347 	if (!link_info) {
348 		hdd_err("No link info with MAC: " QDF_MAC_ADDR_FMT,
349 			QDF_MAC_ADDR_REF(self_mac->bytes));
350 		return QDF_STATUS_E_INVAL;
351 	}
352 
353 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
354 	hdd_cm_set_ieee_link_id(link_info, link_id);
355 	qdf_copy_macaddr(&sta_ctx->conn_info.bssid, bssid);
356 	return QDF_STATUS_SUCCESS;
357 }
358 
359 void
hdd_cm_set_ieee_link_id(struct wlan_hdd_link_info * link_info,uint8_t link_id)360 hdd_cm_set_ieee_link_id(struct wlan_hdd_link_info *link_info, uint8_t link_id)
361 {
362 	struct hdd_station_ctx *sta_ctx =
363 				WLAN_HDD_GET_STATION_CTX_PTR(link_info);
364 
365 	hdd_debug("old_link_id:%d new_link_id:%d",
366 		  sta_ctx->conn_info.ieee_link_id, link_id);
367 	sta_ctx->conn_info.ieee_link_id = link_id;
368 }
369 
370 void
hdd_cm_clear_ieee_link_id(struct wlan_hdd_link_info * link_info)371 hdd_cm_clear_ieee_link_id(struct wlan_hdd_link_info *link_info)
372 {
373 	struct hdd_station_ctx *sta_ctx =
374 				WLAN_HDD_GET_STATION_CTX_PTR(link_info);
375 
376 	hdd_debug("clear link id:%d", sta_ctx->conn_info.ieee_link_id);
377 	sta_ctx->conn_info.ieee_link_id = WLAN_INVALID_LINK_ID;
378 }
379 #endif
380 
381 #ifdef FEATURE_WLAN_WAPI
hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)382 static bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)
383 {
384 	if (auth_type == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ||
385 	    auth_type == eCSR_AUTH_TYPE_WAPI_WAI_PSK)
386 		return true;
387 	else
388 		return false;
389 }
390 #else
hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)391 static inline bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)
392 {
393 	return false;
394 }
395 #endif
396 
hdd_update_scan_ie_for_connect(struct hdd_adapter * adapter,struct osif_connect_params * params)397 static void hdd_update_scan_ie_for_connect(struct hdd_adapter *adapter,
398 					   struct osif_connect_params *params)
399 {
400 	if (adapter->device_mode == QDF_P2P_CLIENT_MODE) {
401 		params->scan_ie.ptr =
402 			&adapter->scan_info.scan_add_ie.addIEdata[0];
403 		params->scan_ie.len = adapter->scan_info.scan_add_ie.length;
404 	} else if (adapter->scan_info.default_scan_ies) {
405 		params->scan_ie.ptr = adapter->scan_info.default_scan_ies;
406 		params->scan_ie.len = adapter->scan_info.default_scan_ies_len;
407 	} else if (adapter->scan_info.scan_add_ie.length) {
408 		params->scan_ie.ptr = adapter->scan_info.scan_add_ie.addIEdata;
409 		params->scan_ie.len = adapter->scan_info.scan_add_ie.length;
410 	}
411 }
412 
413 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) || \
414 	defined(CFG80211_11BE_BASIC)) && \
415 	defined(WLAN_FEATURE_11BE)
416 /**
417  * hdd_update_action_oui_for_connect() - Update Action OUI for 802.11be AP
418  * @hdd_ctx: hdd context
419  * @req: connect request parameter
420  *
421  * If user sets flag ASSOC_REQ_DISABLE_EHT in connect request, driver
422  * will send action oui "ffffff 00 01" to host mlme and also firmware
423  * for action id ACTION_OUI_11BE_OUI_ALLOW, so that all the AP will
424  * be not matched with this OUI and 802.11be mode will not be allowed,
425  * possibly downgrade to 11ax will happen.
426  * If user doesn't set ASSOC_REQ_DISABLE_EHT, driver/firmware will
427  * recover to default INI setting.
428  *
429  * Returns: void
430  */
431 static void
hdd_update_action_oui_for_connect(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)432 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx,
433 				  struct cfg80211_connect_params *req)
434 {
435 	QDF_STATUS status;
436 	uint8_t *str;
437 	bool usr_disable_eht;
438 
439 	if (!ucfg_action_oui_enabled(hdd_ctx->psoc))
440 		return;
441 
442 	usr_disable_eht = ucfg_mlme_get_usr_disable_sta_eht(hdd_ctx->psoc);
443 	if (req->flags & ASSOC_REQ_DISABLE_EHT ||
444 	    !(req->flags & CONNECT_REQ_MLO_SUPPORT)) {
445 		if (usr_disable_eht) {
446 			hdd_debug("user eht is disabled already");
447 			return;
448 		}
449 		status = ucfg_action_oui_cleanup(
450 				hdd_ctx->psoc, ACTION_OUI_11BE_OUI_ALLOW);
451 		if (!QDF_IS_STATUS_SUCCESS(status)) {
452 			hdd_err("Failed to cleanup oui id %d",
453 				ACTION_OUI_11BE_OUI_ALLOW);
454 			return;
455 		}
456 		status = ucfg_action_oui_parse(hdd_ctx->psoc,
457 					       ACTION_OUI_INVALID,
458 					       ACTION_OUI_11BE_OUI_ALLOW);
459 		if (!QDF_IS_STATUS_SUCCESS(status)) {
460 			hdd_err("Failed to parse action_oui str for id %d",
461 				ACTION_OUI_11BE_OUI_ALLOW);
462 			return;
463 		}
464 	} else {
465 		if (!usr_disable_eht) {
466 			hdd_debug("user eht is enabled already");
467 			return;
468 		}
469 		status = ucfg_action_oui_cleanup(hdd_ctx->psoc,
470 						 ACTION_OUI_11BE_OUI_ALLOW);
471 		if (!QDF_IS_STATUS_SUCCESS(status)) {
472 			hdd_err("Failed to cleanup oui id %d",
473 				ACTION_OUI_11BE_OUI_ALLOW);
474 			return;
475 		}
476 		str = ucfg_action_oui_get_config(hdd_ctx->psoc,
477 						 ACTION_OUI_11BE_OUI_ALLOW);
478 		if (!qdf_str_len(str))
479 			goto send_oui;
480 
481 		status = ucfg_action_oui_parse(hdd_ctx->psoc,
482 					       str, ACTION_OUI_11BE_OUI_ALLOW);
483 		if (!QDF_IS_STATUS_SUCCESS(status)) {
484 			hdd_err("Failed to parse action_oui str for id %d",
485 				ACTION_OUI_11BE_OUI_ALLOW);
486 			return;
487 		}
488 	}
489 
490 send_oui:
491 	status = ucfg_action_oui_send_by_id(hdd_ctx->psoc,
492 					    ACTION_OUI_11BE_OUI_ALLOW);
493 	if (!QDF_IS_STATUS_SUCCESS(status)) {
494 		hdd_err("Failed to send oui id %d", ACTION_OUI_11BE_OUI_ALLOW);
495 		return;
496 	}
497 	ucfg_mlme_set_usr_disable_sta_eht(hdd_ctx->psoc, !usr_disable_eht);
498 }
499 #else
500 static void
hdd_update_action_oui_for_connect(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)501 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx,
502 				  struct cfg80211_connect_params *req)
503 {
504 }
505 #endif
506 
507 #ifdef WLAN_FEATURE_11BE
508 static inline bool
hdd_config_is_dot11mode_11be_only(struct hdd_config * config)509 hdd_config_is_dot11mode_11be_only(struct hdd_config *config)
510 {
511 	if (config->dot11Mode == eHDD_DOT11_MODE_11be_ONLY)
512 		return true;
513 	else
514 		return false;
515 }
516 #else
517 static inline bool
hdd_config_is_dot11mode_11be_only(struct hdd_config * config)518 hdd_config_is_dot11mode_11be_only(struct hdd_config *config)
519 {
520 	return false;
521 }
522 #endif
523 
524 /**
525  * hdd_get_dot11mode_filter() - Get dot11 mode filter
526  * @hdd_ctx: HDD context
527  *
528  * This function is used to get the dot11 mode filter
529  *
530  * Context: Any Context.
531  * Return: dot11_mode_filter
532  */
533 static enum dot11_mode_filter
hdd_get_dot11mode_filter(struct hdd_context * hdd_ctx)534 hdd_get_dot11mode_filter(struct hdd_context *hdd_ctx)
535 {
536 	struct hdd_config *config = hdd_ctx->config;
537 
538 	if (config->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
539 		return ALLOW_11N_ONLY;
540 	else if (config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
541 		return ALLOW_11AC_ONLY;
542 	else if (config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
543 		return ALLOW_11AX_ONLY;
544 	else if (hdd_config_is_dot11mode_11be_only(config))
545 		return ALLOW_11BE_ONLY;
546 	else
547 		return ALLOW_ALL;
548 }
549 
550 /**
551  * hdd_get_sap_adapter_of_dfs - Get sap adapter on dfs channel
552  * @hdd_ctx: HDD context
553  *
554  * This function is used to get the sap adapter on dfs channel.
555  *
556  * Return: pointer to adapter or null
557  */
558 static struct hdd_adapter *
hdd_get_sap_adapter_of_dfs(struct hdd_context * hdd_ctx)559 hdd_get_sap_adapter_of_dfs(struct hdd_context *hdd_ctx)
560 {
561 	struct hdd_adapter *adapter, *next_adapter = NULL;
562 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
563 	struct wlan_channel *chan;
564 	struct ch_params ch_params = {0};
565 	struct wlan_hdd_link_info *link_info;
566 
567 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
568 					   dbgid) {
569 		if (adapter->device_mode != QDF_SAP_MODE)
570 			goto loop_next;
571 
572 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
573 			if (wlan_hdd_validate_vdev_id(link_info->vdev_id))
574 				continue;
575 
576 			/*
577 			 * sap is not in started state and also not under doing
578 			 * CAC, so it is fine to go ahead with sta.
579 			 */
580 			if (!test_bit(SOFTAP_BSS_STARTED,
581 				      &link_info->link_flags) &&
582 			    hdd_ctx->dev_dfs_cac_status != DFS_CAC_IN_PROGRESS)
583 				continue;
584 
585 			wlan_objmgr_vdev_get_ref(link_info->vdev,
586 						 WLAN_HDD_ID_OBJ_MGR);
587 			chan = wlan_vdev_get_active_channel(link_info->vdev);
588 			if (!chan) {
589 				hdd_debug("Can not get active channel");
590 				wlan_objmgr_vdev_release_ref(link_info->vdev,
591 							   WLAN_HDD_ID_OBJ_MGR);
592 				continue;
593 			}
594 
595 			wlan_objmgr_vdev_release_ref(link_info->vdev,
596 						     WLAN_HDD_ID_OBJ_MGR);
597 
598 			if (!wlan_reg_is_5ghz_ch_freq(chan->ch_freq))
599 				continue;
600 
601 			ch_params.ch_width = chan->ch_width;
602 			if (ch_params.ch_width == CH_WIDTH_160MHZ)
603 				wlan_reg_set_create_punc_bitmap(&ch_params,
604 								true);
605 
606 			if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
607 							hdd_ctx->pdev,
608 							chan->ch_freq,
609 							&ch_params,
610 							REG_CURRENT_PWR_MODE) ==
611 			    CHANNEL_STATE_DFS) {
612 				hdd_adapter_dev_put_debug(adapter, dbgid);
613 				if (next_adapter)
614 					hdd_adapter_dev_put_debug(next_adapter,
615 								  dbgid);
616 
617 				return adapter;
618 			}
619 		}
620 loop_next:
621 		hdd_adapter_dev_put_debug(adapter, dbgid);
622 	}
623 
624 	return NULL;
625 }
626 
627 /**
628  * wlan_hdd_cm_handle_sap_sta_dfs_conc() - to handle SAP STA DFS conc
629  * @hdd_ctx: hdd_ctx
630  * @req: connect req
631  *
632  * This routine will move SAP from dfs to non-dfs, if sta is coming up.
633  *
634  * Return: false if sta-sap conc is not allowed, else return true
635  */
636 static
wlan_hdd_cm_handle_sap_sta_dfs_conc(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)637 bool wlan_hdd_cm_handle_sap_sta_dfs_conc(struct hdd_context *hdd_ctx,
638 					 struct cfg80211_connect_params *req)
639 {
640 	struct hdd_adapter *ap_adapter;
641 	struct hdd_ap_ctx *hdd_ap_ctx;
642 	struct hdd_hostapd_state *hostapd_state;
643 	QDF_STATUS status;
644 	qdf_freq_t ch_freq = 0;
645 	enum phy_ch_width ch_bw;
646 	enum channel_state ch_state;
647 	struct scan_filter *scan_filter;
648 	qdf_list_t *list = NULL;
649 	qdf_list_node_t *cur_lst = NULL;
650 	struct scan_cache_node *cur_node = NULL;
651 	bool is_6ghz_cap = false;
652 
653 	ap_adapter = hdd_get_sap_adapter_of_dfs(hdd_ctx);
654 	/* probably no dfs sap running, no handling required */
655 	if (!ap_adapter)
656 		return true;
657 
658 	/* if sap is currently doing CAC then don't allow sta to go further */
659 	if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) {
660 		hdd_err("Concurrent SAP is in CAC state, STA is not allowed");
661 		return false;
662 	}
663 
664 	/*
665 	 * log and return error, if we allow STA to go through, we don't
666 	 * know what is going to happen better stop sta connection
667 	 */
668 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
669 	if (!hdd_ap_ctx) {
670 		hdd_err("AP context not found");
671 		return false;
672 	}
673 
674 	if (req->channel && req->channel->center_freq) {
675 		ch_freq = req->channel->center_freq;
676 		goto def_chan;
677 	}
678 	/*
679 	 * find out by looking in to scan cache where sta is going to
680 	 * connect by passing its ssid amd bssid.
681 	 */
682 	scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
683 	if (!scan_filter)
684 		goto def_chan;
685 
686 	if (req->bssid) {
687 		scan_filter->num_of_bssid = 1;
688 		qdf_mem_copy(scan_filter->bssid_list[0].bytes, req->bssid,
689 			     QDF_MAC_ADDR_SIZE);
690 	}
691 	if (req->ssid_len > WLAN_SSID_MAX_LEN) {
692 		scan_filter->num_of_ssid = 0;
693 		hdd_err("req ssid len invalid %zu", req->ssid_len);
694 	} else {
695 		scan_filter->num_of_ssid = 1;
696 		scan_filter->ssid_list[0].length = req->ssid_len;
697 		qdf_mem_copy(scan_filter->ssid_list[0].ssid, req->ssid,
698 			     scan_filter->ssid_list[0].length);
699 	}
700 	scan_filter->ignore_auth_enc_type = true;
701 	list = ucfg_scan_get_result(hdd_ctx->pdev, scan_filter);
702 	qdf_mem_free(scan_filter);
703 
704 	if (!list || (list && !qdf_list_size(list))) {
705 		hdd_debug("scan list empty");
706 		goto purge_list;
707 	}
708 	qdf_list_peek_front(list, &cur_lst);
709 	if (!cur_lst)
710 		goto purge_list;
711 
712 	cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node);
713 	ch_freq = cur_node->entry->channel.chan_freq;
714 purge_list:
715 	if (list)
716 		ucfg_scan_purge_results(list);
717 def_chan:
718 	/*
719 	 * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz
720 	 * channels for roaming case.
721 	 */
722 	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
723 		hdd_info("sap is on dfs, new sta conn on 2.4 is allowed");
724 		return true;
725 	}
726 
727 	if (policy_mgr_is_hw_sbs_capable(hdd_ctx->psoc) &&
728 	    ch_freq &&
729 	    policy_mgr_are_sbs_chan(hdd_ctx->psoc,
730 				    ch_freq,
731 				    hdd_ap_ctx->operating_chan_freq)) {
732 		hdd_debug("sta freq %d sap freq %d in sbs mode is allowed",
733 			  ch_freq, hdd_ap_ctx->operating_chan_freq);
734 		return true;
735 	}
736 
737 	/*
738 	 * If channel is 0 or DFS or LTE unsafe then better to call pcl and
739 	 * find out the best channel. If channel is non-dfs 5 GHz then
740 	 * better move SAP to STA's channel to make scc, so we have room
741 	 * for 3port MCC scenario.
742 	 */
743 	ch_bw = hdd_ap_ctx->sap_config.ch_width_orig;
744 	if (ch_freq)
745 		is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(hdd_ctx->psoc,
746 						ap_adapter->deflink->vdev_id,
747 							     NULL);
748 
749 	if (!ch_freq || wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, ch_freq) ||
750 	    !policy_mgr_is_safe_channel(hdd_ctx->psoc, ch_freq) ||
751 	    wlan_reg_is_passive_for_freq(hdd_ctx->pdev, ch_freq) ||
752 	    (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && !is_6ghz_cap))
753 		ch_freq = policy_mgr_get_nondfs_preferred_channel(
754 				hdd_ctx->psoc, PM_SAP_MODE,
755 				true, ap_adapter->deflink->vdev_id);
756 
757 	if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
758 	    ch_bw > CH_WIDTH_20MHZ) {
759 		struct ch_params ch_params;
760 
761 		qdf_mem_zero(&ch_params, sizeof(ch_params));
762 		ch_params.ch_width = ch_bw;
763 		ch_state =
764 		wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
765 				hdd_ctx->pdev, ch_freq, &ch_params,
766 				REG_CURRENT_PWR_MODE);
767 		while (ch_bw > CH_WIDTH_20MHZ &&
768 		       ch_state != CHANNEL_STATE_ENABLE) {
769 			ch_bw =
770 			wlan_reg_get_next_lower_bandwidth(ch_bw);
771 			ch_params.ch_width = ch_bw;
772 			ch_state =
773 			wlan_reg_get_5g_bonded_channel_state_for_pwrmode
774 				(hdd_ctx->pdev, ch_freq, &ch_params,
775 				REG_CURRENT_PWR_MODE);
776 		}
777 		hdd_debug("bw change from %d to %d",
778 			  hdd_ap_ctx->sap_config.ch_width_orig,
779 			  ch_bw);
780 	}
781 
782 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
783 	qdf_event_reset(&hostapd_state->qdf_event);
784 	wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->deflink->vdev_id,
785 				    CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS);
786 
787 	status = wlansap_set_channel_change_with_csa(
788 			WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter->deflink), ch_freq,
789 			ch_bw, false);
790 
791 	if (QDF_STATUS_SUCCESS != status) {
792 		hdd_err("Set channel with CSA IE failed, can't allow STA");
793 		return false;
794 	}
795 
796 	/*
797 	 * wait here for SAP to finish the channel switch. When channel
798 	 * switch happens, SAP sends few beacons with CSA_IE. After
799 	 * successfully Transmission of those beacons, it will move its
800 	 * state from started to disconnected and move to new channel.
801 	 * once it moves to new channel, sap again moves its state
802 	 * machine from disconnected to started and set this event.
803 	 * wait for 10 secs to finish this.
804 	 */
805 	status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
806 					       10000);
807 	if (!QDF_IS_STATUS_SUCCESS(status)) {
808 		hdd_err("wait for qdf_event failed, STA not allowed!!");
809 		return false;
810 	}
811 
812 	return true;
813 }
814 
wlan_hdd_cm_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * req)815 int wlan_hdd_cm_connect(struct wiphy *wiphy,
816 			struct net_device *ndev,
817 			struct cfg80211_connect_params *req)
818 {
819 	int status;
820 	struct wlan_objmgr_vdev *vdev;
821 	struct osif_connect_params params;
822 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
823 	struct hdd_context *hdd_ctx;
824 	struct hdd_station_ctx *hdd_sta_ctx;
825 	qdf_freq_t ch_freq = 0;
826 
827 	hdd_enter();
828 
829 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
830 		hdd_err("Command not allowed in FTM mode");
831 		return -EINVAL;
832 	}
833 
834 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
835 		return -EINVAL;
836 
837 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
838 		   TRACE_CODE_HDD_CFG80211_CONNECT,
839 		   adapter->deflink->vdev_id, adapter->device_mode);
840 
841 	if (adapter->device_mode != QDF_STA_MODE &&
842 	    adapter->device_mode != QDF_P2P_CLIENT_MODE) {
843 		hdd_err("Device_mode %s(%d) is not supported",
844 			qdf_opmode_str(adapter->device_mode),
845 			adapter->device_mode);
846 		return -EINVAL;
847 	}
848 
849 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
850 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
851 
852 	status = wlan_hdd_validate_context(hdd_ctx);
853 	if (status)
854 		return status;
855 
856 	hdd_reg_wait_for_country_change(hdd_ctx);
857 
858 	if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
859 	    !wlan_hdd_cm_handle_sap_sta_dfs_conc(hdd_ctx, req)) {
860 		hdd_err("sap-sta conc will fail, can't allow sta");
861 		return -EINVAL;
862 	}
863 
864 	if (req->channel && req->channel->center_freq)
865 		ch_freq = req->channel->center_freq;
866 
867 	if (ch_freq && wlan_reg_is_6ghz_chan_freq(ch_freq) &&
868 	    !wlan_reg_is_6ghz_band_set(hdd_ctx->pdev)) {
869 		hdd_err("6 GHz band disabled");
870 		return -EINVAL;
871 	}
872 
873 	qdf_mem_zero(&params, sizeof(params));
874 	ucfg_dlm_dump_deny_list_ap(hdd_ctx->pdev);
875 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_CM_ID);
876 	if (!vdev)
877 		return -EINVAL;
878 
879 	ucfg_pmo_flush_gtk_offload_req(vdev);
880 	qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag,
881 		     sizeof(hdd_sta_ctx->conn_info.conn_flag));
882 
883 	/*
884 	 * Reset the ptk, gtk status flags to avoid using old/previous
885 	 * connection status.
886 	 */
887 	hdd_sta_ctx->conn_info.gtk_installed = false;
888 	hdd_sta_ctx->conn_info.ptk_installed = false;
889 	adapter->last_disconnect_reason = 0;
890 
891 	qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.connect);
892 	hdd_prevent_suspend_timeout(HDD_WAKELOCK_CONNECT_COMPLETE,
893 				    WIFI_POWER_EVENT_WAKELOCK_CONNECT);
894 
895 	params.force_rsne_override = hdd_ctx->force_rsne_override;
896 	params.dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx);
897 
898 	hdd_update_scan_ie_for_connect(adapter, &params);
899 	hdd_update_action_oui_for_connect(hdd_ctx, req);
900 
901 	if (!hdd_cm_is_vdev_associated(adapter->deflink)) {
902 		/*
903 		 * Clear user/wpa_supplicant disabled_roaming flag for new
904 		 * connection
905 		 */
906 		ucfg_clear_user_disabled_roaming(hdd_ctx->psoc,
907 						 adapter->deflink->vdev_id);
908 	}
909 	status = osif_cm_connect(ndev, vdev, req, &params);
910 
911 	if (status || ucfg_cm_is_vdev_roaming(vdev)) {
912 		/* Release suspend and wake lock for failure or roam invoke */
913 		if (status)
914 			hdd_err("Vdev %d connect failed status %d",
915 				adapter->deflink->vdev_id, status);
916 		else
917 			hdd_debug("Vdev %d: connect lead to roam invoke",
918 				  adapter->deflink->vdev_id);
919 		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
920 		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
921 	}
922 
923 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
924 	return status;
925 }
926 
hdd_cm_rec_connect_info(struct wlan_cm_connect_resp * rsp)927 static void hdd_cm_rec_connect_info(struct wlan_cm_connect_resp *rsp)
928 {
929 	if (rsp->is_reassoc)
930 		wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_ROAMED_IND,
931 				   rsp->bssid.bytes, rsp->cm_id, 0);
932 	else
933 		wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_CONNECT_RESULT,
934 				   rsp->bssid.bytes, rsp->cm_id << 16 |
935 				   rsp->reason,
936 				   rsp->status_code);
937 }
938 
939 static void
hdd_cm_connect_failure_pre_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)940 hdd_cm_connect_failure_pre_user_update(struct wlan_objmgr_vdev *vdev,
941 				       struct wlan_cm_connect_resp *rsp)
942 {
943 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
944 	struct hdd_adapter *adapter;
945 	struct hdd_station_ctx *hdd_sta_ctx;
946 	uint32_t time_buffer_size;
947 	struct wlan_hdd_link_info *link_info;
948 	bool is_link_switch =
949 			wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev);
950 
951 	if (!hdd_ctx) {
952 		hdd_err("hdd_ctx is NULL");
953 		return;
954 	}
955 
956 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
957 	if (!link_info) {
958 		hdd_err("adapter is NULL vdev %d", rsp->vdev_id);
959 		return;
960 	}
961 
962 	adapter = link_info->adapter;
963 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
964 	time_buffer_size = sizeof(hdd_sta_ctx->conn_info.connect_time);
965 	qdf_mem_zero(hdd_sta_ctx->conn_info.connect_time, time_buffer_size);
966 	hdd_init_scan_reject_params(hdd_ctx);
967 	hdd_cm_save_connect_status(link_info, rsp->status_code);
968 	if (!is_link_switch) {
969 		/* For link switch connection failure, do not clear existing
970 		 * connection info in OSIF.
971 		 */
972 		hdd_conn_remove_connect_info(hdd_sta_ctx);
973 		hdd_adapter_reset_station_ctx(adapter);
974 	}
975 
976 	ucfg_dp_remove_conn_info(vdev);
977 	hdd_cm_update_rssi_snr_by_bssid(link_info);
978 	hdd_cm_rec_connect_info(rsp);
979 	hdd_debug("Invoking packetdump deregistration API");
980 	wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID);
981 }
982 
983 static void
hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)984 hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev *vdev,
985 					struct wlan_cm_connect_resp *rsp)
986 {
987 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
988 	struct hdd_adapter *adapter;
989 	struct wlan_hdd_link_info *link_info;
990 	bool is_roam = rsp->is_reassoc;
991 
992 	if (!hdd_ctx) {
993 		hdd_err("hdd_ctx is NULL");
994 		return;
995 	}
996 
997 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
998 	if (!link_info) {
999 		hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
1000 		return;
1001 	}
1002 	if (!is_roam) {
1003 		/* call only for connect */
1004 		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
1005 		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
1006 	}
1007 
1008 	adapter = link_info->adapter;
1009 	wlan_hdd_connectivity_fail_event(vdev, rsp);
1010 	hdd_clear_roam_profile_ie(adapter);
1011 	ucfg_cm_reset_key(hdd_ctx->pdev, link_info->vdev_id);
1012 	hdd_wmm_dscp_initial_state(adapter);
1013 
1014 	/*
1015 	 * If connect failure is due to link switch, do not disable the
1016 	 * netdev queues as it will lead to data stall/NUD failure.
1017 	 */
1018 	if (!(rsp->cm_id & CM_ID_LSWITCH_BIT)) {
1019 		hdd_debug("Disabling queues");
1020 		wlan_hdd_netif_queue_control(adapter,
1021 					     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
1022 					     WLAN_CONTROL_PATH);
1023 	}
1024 
1025 	ucfg_dp_periodic_sta_stats_start(vdev);
1026 	wlan_twt_concurrency_update(hdd_ctx);
1027 }
1028 
hdd_cm_connect_failure(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1029 static void hdd_cm_connect_failure(struct wlan_objmgr_vdev *vdev,
1030 				   struct wlan_cm_connect_resp *rsp,
1031 				   enum osif_cb_type type)
1032 {
1033 	switch (type) {
1034 	case OSIF_PRE_USERSPACE_UPDATE:
1035 		hdd_cm_connect_failure_pre_user_update(vdev, rsp);
1036 		break;
1037 	case OSIF_POST_USERSPACE_UPDATE:
1038 		hdd_cm_connect_failure_post_user_update(vdev, rsp);
1039 		break;
1040 	default:
1041 		hdd_cm_connect_failure_pre_user_update(vdev, rsp);
1042 		hdd_cm_connect_failure_post_user_update(vdev, rsp);
1043 	}
1044 }
1045 
1046 /**
1047  * hdd_cm_update_prev_ap_ie() - Update the connected AP IEs
1048  * @hdd_sta_ctx: Station context.
1049  * @rsp: Connect response
1050  *
1051  * This API updates the connected ap beacon IEs to station context connection
1052  * info.
1053  *
1054  * Return: None
1055  */
hdd_cm_update_prev_ap_ie(struct hdd_station_ctx * hdd_sta_ctx,struct wlan_cm_connect_resp * rsp)1056 static void hdd_cm_update_prev_ap_ie(struct hdd_station_ctx *hdd_sta_ctx,
1057 				     struct wlan_cm_connect_resp *rsp)
1058 {
1059 	struct element_info *bcn_probe_rsp = &rsp->connect_ies.bcn_probe_rsp;
1060 	struct element_info *bcn_ie;
1061 	uint32_t len;
1062 
1063 	bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
1064 	if (bcn_ie->ptr) {
1065 		qdf_mem_free(bcn_ie->ptr);
1066 		bcn_ie->ptr = NULL;
1067 		bcn_ie->len = 0;
1068 	}
1069 
1070 	if (bcn_probe_rsp->ptr &&
1071 	    bcn_probe_rsp->len > sizeof(struct wlan_frame_hdr)) {
1072 		len = bcn_probe_rsp->len - sizeof(struct wlan_frame_hdr);
1073 		bcn_ie->ptr = qdf_mem_malloc(len);
1074 		if (!bcn_ie->ptr) {
1075 			bcn_ie->len = 0;
1076 			return;
1077 		}
1078 		qdf_mem_copy(bcn_ie->ptr, bcn_probe_rsp->ptr +
1079 			     sizeof(struct wlan_frame_hdr), len);
1080 		bcn_ie->len = len;
1081 	}
1082 }
1083 
hdd_cm_save_bss_info(struct wlan_hdd_link_info * link_info,struct wlan_cm_connect_resp * rsp)1084 static void hdd_cm_save_bss_info(struct wlan_hdd_link_info *link_info,
1085 				 struct wlan_cm_connect_resp *rsp)
1086 {
1087 	struct hdd_context *hdd_ctx;
1088 	struct hdd_station_ctx *hdd_sta_ctx;
1089 	QDF_STATUS status;
1090 	struct hdd_adapter *adapter = link_info->adapter;
1091 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1092 	struct sDot11fAssocResponse *assoc_resp;
1093 
1094 	if (!mac_handle) {
1095 		hdd_err("mac handle is null");
1096 		return;
1097 	}
1098 
1099 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1100 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1101 
1102 	assoc_resp = qdf_mem_malloc(sizeof(struct sDot11fAssocResponse));
1103 	if (!assoc_resp)
1104 		return;
1105 
1106 	qdf_mem_zero(&hdd_sta_ctx->conn_info.hs20vendor_ie,
1107 		     sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie));
1108 	if (rsp->connect_ies.bcn_probe_rsp.ptr)
1109 		sme_get_hs20vendor_ie(mac_handle,
1110 				      rsp->connect_ies.bcn_probe_rsp.ptr,
1111 				      rsp->connect_ies.bcn_probe_rsp.len,
1112 				      &hdd_sta_ctx->conn_info.hs20vendor_ie);
1113 
1114 	status = sme_unpack_assoc_rsp(mac_handle, rsp, assoc_resp);
1115 	if (QDF_IS_STATUS_ERROR(status)) {
1116 		hdd_err("could not parse assoc response");
1117 		qdf_mem_free(assoc_resp);
1118 		return;
1119 	}
1120 
1121 	if (assoc_resp->VHTCaps.present) {
1122 		hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
1123 		hdd_copy_vht_caps(&hdd_sta_ctx->conn_info.vht_caps,
1124 				  &assoc_resp->VHTCaps);
1125 	} else {
1126 		hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
1127 	}
1128 	if (assoc_resp->HTCaps.present) {
1129 		hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
1130 		hdd_copy_ht_caps(&hdd_sta_ctx->conn_info.ht_caps,
1131 				 &assoc_resp->HTCaps);
1132 	} else {
1133 		hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
1134 	}
1135 	if (rsp->is_reassoc)
1136 		hdd_sta_ctx->conn_info.roam_count++;
1137 
1138 	if (assoc_resp->HTInfo.present) {
1139 		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
1140 		hdd_copy_ht_operation(hdd_sta_ctx, &assoc_resp->HTInfo);
1141 	} else {
1142 		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
1143 	}
1144 	if (assoc_resp->VHTOperation.present) {
1145 		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
1146 		hdd_copy_vht_operation(hdd_sta_ctx, &assoc_resp->VHTOperation);
1147 	} else {
1148 		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
1149 	}
1150 
1151 	if (assoc_resp->he_cap.present)
1152 		hdd_sta_ctx->conn_info.conn_flag.he_present = true;
1153 	else
1154 		hdd_sta_ctx->conn_info.conn_flag.he_present = false;
1155 
1156 	if (assoc_resp->eht_cap.present)
1157 		hdd_sta_ctx->conn_info.conn_flag.eht_present = true;
1158 	else
1159 		hdd_sta_ctx->conn_info.conn_flag.eht_present = false;
1160 
1161 	if (assoc_resp->eht_op.present)
1162 		hdd_sta_ctx->conn_info.conn_flag.eht_op_present = true;
1163 	else
1164 		hdd_sta_ctx->conn_info.conn_flag.eht_op_present = false;
1165 
1166 	/*
1167 	 * Cache connection info only in case of station
1168 	 */
1169 	if (adapter->device_mode == QDF_STA_MODE) {
1170 		/* Cleanup already existing he info */
1171 		hdd_cleanup_conn_info(link_info);
1172 
1173 		hdd_copy_eht_operation(hdd_sta_ctx, &assoc_resp->eht_op);
1174 		/* Cache last connection info */
1175 		qdf_mem_copy(&hdd_sta_ctx->cache_conn_info,
1176 			     &hdd_sta_ctx->conn_info,
1177 			     sizeof(hdd_sta_ctx->cache_conn_info));
1178 
1179 		hdd_copy_he_operation(hdd_sta_ctx, &assoc_resp->he_op);
1180 		hdd_cm_update_prev_ap_ie(hdd_sta_ctx, rsp);
1181 	}
1182 
1183 	qdf_mem_free(assoc_resp);
1184 }
1185 
1186 #ifdef FEATURE_WLAN_ESE
hdd_is_ese_assoc(enum csr_akm_type auth_type,tDot11fBeaconIEs * bcn_ie,struct mac_context * mac_ctx)1187 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type,
1188 			     tDot11fBeaconIEs *bcn_ie,
1189 			     struct mac_context *mac_ctx)
1190 {
1191 	if ((csr_is_auth_type_ese(auth_type) ||
1192 	     (bcn_ie->ESEVersion.present &&
1193 	     auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) &&
1194 	    mac_ctx->mlme_cfg->lfr.ese_enabled) {
1195 		return true;
1196 	}
1197 
1198 	return false;
1199 }
1200 #else
hdd_is_ese_assoc(enum csr_akm_type auth_type,tDot11fBeaconIEs * bcn_ie,struct mac_context * mac_ctx)1201 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type,
1202 			     tDot11fBeaconIEs *bcn_ie,
1203 			     struct mac_context *mac_ctx)
1204 {
1205 	return false;
1206 }
1207 #endif
1208 
1209 static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
1210 	0x4,                    /* SME_AC_BK */
1211 	0x8,                    /* SME_AC_BE */
1212 	0x2,                    /* SME_AC_VI */
1213 	0x1                     /* SME_AC_VO */
1214 };
1215 
hdd_wmm_cm_connect(struct wlan_objmgr_vdev * vdev,struct hdd_adapter * adapter,tDot11fBeaconIEs * bcn_ie,enum csr_akm_type auth_type)1216 static void hdd_wmm_cm_connect(struct wlan_objmgr_vdev *vdev,
1217 			       struct hdd_adapter *adapter,
1218 			       tDot11fBeaconIEs *bcn_ie,
1219 			       enum csr_akm_type auth_type)
1220 {
1221 	int ac;
1222 	bool qap;
1223 	bool qos_connection;
1224 	uint8_t acm_mask = 0;
1225 	struct vdev_mlme_obj *vdev_mlme;
1226 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1227 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1228 
1229 	if (!mac_handle) {
1230 		hdd_err("mac handle is null");
1231 		return;
1232 	}
1233 
1234 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
1235 	if (!vdev_mlme) {
1236 		hdd_err("vdev component object is NULL");
1237 		return;
1238 	}
1239 	if (CSR_IS_QOS_BSS(bcn_ie) || bcn_ie->HTCaps.present)
1240 		/* Some HT AP's dont send WMM IE so in that case we
1241 		 * assume all HT Ap's are Qos Enabled AP's
1242 		 */
1243 		qap = true;
1244 	else
1245 		qap = false;
1246 
1247 	qos_connection = vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled;
1248 
1249 	acm_mask = sme_qos_get_acm_mask(mac_ctx, NULL, bcn_ie);
1250 
1251 	hdd_debug("qap is %d, qos_connection is %d, acm_mask is 0x%x",
1252 		  qap, qos_connection, acm_mask);
1253 
1254 	adapter->hdd_wmm_status.qap = qap;
1255 	adapter->hdd_wmm_status.qos_connection = qos_connection;
1256 
1257 	if (acm_mask)
1258 		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1259 				   (uint8_t *)acm_mask_bit,  WLAN_MAX_AC);
1260 
1261 	for (ac = 0; ac < WLAN_MAX_AC; ac++) {
1262 		if (qap && qos_connection && (acm_mask & acm_mask_bit[ac])) {
1263 
1264 			/* admission is required */
1265 			adapter->hdd_wmm_status.ac_status[ac].
1266 			is_access_required = true;
1267 			adapter->hdd_wmm_status.ac_status[ac].
1268 			is_access_allowed = false;
1269 			adapter->hdd_wmm_status.ac_status[ac].
1270 			was_access_granted = false;
1271 			/* after reassoc if we have valid tspec, allow access */
1272 			if (adapter->hdd_wmm_status.ac_status[ac].
1273 			    is_tspec_valid &&
1274 			    (adapter->hdd_wmm_status.ac_status[ac].
1275 				tspec.ts_info.direction !=
1276 				SME_QOS_WMM_TS_DIR_DOWNLINK)) {
1277 				adapter->hdd_wmm_status.ac_status[ac].
1278 				is_access_allowed = true;
1279 			}
1280 			if (!sme_neighbor_roam_is11r_assoc(
1281 						mac_handle,
1282 						adapter->deflink->vdev_id) &&
1283 			    !hdd_is_ese_assoc(auth_type, bcn_ie, mac_ctx)) {
1284 				adapter->hdd_wmm_status.ac_status[ac].
1285 					is_tspec_valid = false;
1286 				adapter->hdd_wmm_status.ac_status[ac].
1287 					is_access_allowed = false;
1288 			}
1289 		} else {
1290 			/* admission is not required so access is allowed */
1291 			adapter->hdd_wmm_status.ac_status[ac].
1292 			is_access_required = false;
1293 			adapter->hdd_wmm_status.ac_status[ac].
1294 			is_access_allowed = true;
1295 		}
1296 	}
1297 }
1298 
hdd_cm_save_connect_info(struct wlan_hdd_link_info * link_info,struct wlan_cm_connect_resp * rsp)1299 static void hdd_cm_save_connect_info(struct wlan_hdd_link_info *link_info,
1300 				     struct wlan_cm_connect_resp *rsp)
1301 {
1302 	struct hdd_station_ctx *sta_ctx;
1303 	struct wlan_crypto_params *crypto_params;
1304 	struct wlan_channel *des_chan;
1305 	struct wlan_objmgr_vdev *vdev;
1306 	uint8_t *ie_field;
1307 	uint32_t ie_len, status;
1308 	tDot11fBeaconIEs *bcn_ie;
1309 	struct s_ext_cap *p_ext_cap = NULL;
1310 	struct hdd_adapter *adapter = link_info->adapter;
1311 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1312 	uint32_t phymode;
1313 
1314 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1315 	bcn_ie = qdf_mem_malloc(sizeof(*bcn_ie));
1316 	if (!bcn_ie)
1317 		return;
1318 
1319 	qdf_copy_macaddr(&sta_ctx->conn_info.bssid, &rsp->bssid);
1320 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
1321 	if (vdev) {
1322 		ucfg_dp_conn_info_set_bssid(vdev, &rsp->bssid);
1323 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
1324 	}
1325 
1326 	phymode = wlan_reg_get_max_phymode(adapter->hdd_ctx->pdev,
1327 					   REG_PHYMODE_MAX,
1328 					   rsp->freq);
1329 
1330 	sta_ctx->reg_phymode = csr_convert_from_reg_phy_mode(phymode);
1331 
1332 	sta_ctx->conn_info.assoc_status_code = rsp->status_code;
1333 
1334 	crypto_params =
1335 		wlan_crypto_vdev_get_crypto_params(link_info->vdev);
1336 
1337 	if (crypto_params) {
1338 		sme_fill_enc_type(&sta_ctx->conn_info.uc_encrypt_type,
1339 				  crypto_params->ucastcipherset);
1340 
1341 		sme_fill_auth_type(&sta_ctx->conn_info.auth_type,
1342 				   crypto_params->authmodeset,
1343 				   crypto_params->key_mgmt,
1344 				   crypto_params->ucastcipherset);
1345 		sta_ctx->conn_info.last_auth_type =
1346 					sta_ctx->conn_info.auth_type;
1347 	}
1348 	des_chan = wlan_vdev_mlme_get_des_chan(link_info->vdev);
1349 
1350 	sta_ctx->conn_info.chan_freq = rsp->freq;
1351 
1352 	/* Save the ssid for the connection */
1353 	qdf_mem_copy(&sta_ctx->conn_info.ssid.SSID.ssId,
1354 		     &rsp->ssid.ssid,
1355 		     rsp->ssid.length);
1356 	qdf_mem_copy(&sta_ctx->conn_info.last_ssid.SSID.ssId,
1357 		     &rsp->ssid.ssid,
1358 		     rsp->ssid.length);
1359 	sta_ctx->conn_info.ssid.SSID.length = rsp->ssid.length;
1360 	sta_ctx->conn_info.last_ssid.SSID.length = rsp->ssid.length;
1361 
1362 	sta_ctx->conn_info.dot11mode =
1363 				sme_phy_mode_to_dot11mode(des_chan->ch_phymode);
1364 
1365 	sta_ctx->conn_info.ch_width = des_chan->ch_width;
1366 	if (!rsp->connect_ies.bcn_probe_rsp.ptr ||
1367 	    (rsp->connect_ies.bcn_probe_rsp.len <
1368 	     (sizeof(struct wlan_frame_hdr) +
1369 	      offsetof(struct wlan_bcn_frame, ie)))) {
1370 		hdd_err("beacon len is invalid %d",
1371 			rsp->connect_ies.bcn_probe_rsp.len);
1372 		qdf_mem_free(bcn_ie);
1373 		return;
1374 	}
1375 
1376 	ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
1377 			sizeof(struct wlan_frame_hdr) -
1378 			offsetof(struct wlan_bcn_frame, ie));
1379 	ie_field = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
1380 				sizeof(struct wlan_frame_hdr) +
1381 				offsetof(struct wlan_bcn_frame, ie));
1382 
1383 	status = dot11f_unpack_beacon_i_es(MAC_CONTEXT(mac_handle), ie_field,
1384 					   ie_len, bcn_ie, false);
1385 
1386 	if (DOT11F_FAILED(status)) {
1387 		hdd_err("Failed to parse beacon ie");
1388 		qdf_mem_free(bcn_ie);
1389 		return;
1390 	}
1391 	if (bcn_ie->ExtCap.present) {
1392 		p_ext_cap = (struct s_ext_cap *)bcn_ie->ExtCap.bytes;
1393 		sta_ctx->conn_info.proxy_arp_service =
1394 						p_ext_cap->proxy_arp_service;
1395 
1396 	}
1397 
1398 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
1399 	if (vdev) {
1400 		sta_ctx->conn_info.nss = wlan_vdev_mlme_get_nss(vdev);
1401 		ucfg_wlan_vdev_mgr_get_param(vdev, WLAN_MLME_CFG_RATE_FLAGS,
1402 					     &sta_ctx->conn_info.rate_flags);
1403 		hdd_wmm_cm_connect(vdev, adapter, bcn_ie,
1404 				   sta_ctx->conn_info.auth_type);
1405 
1406 		if (p_ext_cap)
1407 			ucfg_dp_conn_info_set_arp_service(vdev,
1408 					p_ext_cap->proxy_arp_service);
1409 
1410 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
1411 	}
1412 	qdf_mem_free(bcn_ie);
1413 
1414 	hdd_cm_save_bss_info(link_info, rsp);
1415 }
1416 
1417 #ifdef WLAN_FEATURE_FILS_SK
hdd_cm_is_fils_connection(struct wlan_cm_connect_resp * rsp)1418 static bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp)
1419 {
1420 	return rsp->is_fils_connection;
1421 }
1422 #else
1423 static inline
hdd_cm_is_fils_connection(struct wlan_cm_connect_resp * rsp)1424 bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp)
1425 {
1426 	return false;
1427 }
1428 #endif
1429 
1430 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
hdd_cm_is_roam_auth_required(struct hdd_station_ctx * sta_ctx,struct wlan_cm_connect_resp * rsp)1431 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
1432 					 struct wlan_cm_connect_resp *rsp)
1433 {
1434 	if (!rsp->roaming_info)
1435 		return false;
1436 
1437 	if (rsp->roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED)
1438 		return false;
1439 
1440 	return true;
1441 }
1442 #else
hdd_cm_is_roam_auth_required(struct hdd_station_ctx * sta_ctx,struct wlan_cm_connect_resp * rsp)1443 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
1444 					 struct wlan_cm_connect_resp *rsp)
1445 {
1446 	return true;
1447 }
1448 #endif
1449 
1450 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
1451 #ifndef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
hdd_get_assoc_link_adapter(struct hdd_adapter * ml_adapter)1452 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter)
1453 {
1454 	int i;
1455 	bool eht_capab;
1456 	struct hdd_adapter *link_adapter;
1457 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ml_adapter);
1458 
1459 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
1460 	if (!eht_capab || hdd_adapter_is_sl_ml_adapter(ml_adapter))
1461 		return ml_adapter;
1462 
1463 	for (i = 0; i < WLAN_MAX_MLD; i++) {
1464 		link_adapter = ml_adapter->mlo_adapter_info.link_adapter[i];
1465 		if (link_adapter) {
1466 			if (hdd_adapter_is_associated_with_ml_adapter(
1467 								link_adapter))
1468 				return link_adapter;
1469 		}
1470 	}
1471 
1472 	return NULL;
1473 }
1474 #endif
1475 
1476 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1477 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1478 					 bool is_immediate_powersave)
1479 {
1480 	struct hdd_station_ctx *sta_ctx;
1481 	struct wlan_hdd_link_info *link_info;
1482 
1483 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
1484 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1485 		sta_ctx->ap_supports_immediate_power_save =
1486 						is_immediate_powersave;
1487 	}
1488 }
1489 #else
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1490 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1491 					 bool is_immediate_powersave)
1492 {
1493 	struct hdd_adapter *link_adapter;
1494 	struct hdd_mlo_adapter_info *mlo_adapter_info;
1495 	struct hdd_station_ctx *sta_ctx;
1496 	int i;
1497 
1498 	if (!hdd_adapter_is_ml_adapter(adapter))
1499 		goto update_non_ml;
1500 
1501 	mlo_adapter_info = &adapter->mlo_adapter_info;
1502 	for (i = 0; i < WLAN_MAX_MLD; i++) {
1503 		link_adapter = mlo_adapter_info->link_adapter[i];
1504 		if (!link_adapter)
1505 			continue;
1506 
1507 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_adapter->deflink);
1508 		sta_ctx->ap_supports_immediate_power_save =
1509 						is_immediate_powersave;
1510 	}
1511 
1512 update_non_ml:
1513 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
1514 	sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave;
1515 }
1516 #endif
1517 #else
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1518 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1519 					 bool is_immediate_powersave)
1520 {
1521 	struct hdd_station_ctx *sta_ctx;
1522 
1523 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
1524 	sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave;
1525 }
1526 #endif
1527 
1528 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
1529 static QDF_STATUS
hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter * adapter,struct wlan_objmgr_vdev * vdev)1530 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter,
1531 					struct wlan_objmgr_vdev *vdev)
1532 {
1533 	struct wlan_objmgr_psoc *psoc;
1534 	struct wlan_hdd_link_info *link_info;
1535 	struct hdd_station_ctx *sta_ctx;
1536 	uint8_t link_id = wlan_vdev_get_link_id(vdev);
1537 	uint8_t ch_width;
1538 	enum phy_ch_width connection_ch_width = CH_WIDTH_INVALID;
1539 
1540 	psoc = wlan_vdev_get_psoc(vdev);
1541 	if (!psoc) {
1542 		hdd_err("Failed to get PSOC Object");
1543 		return QDF_STATUS_E_INVAL;
1544 	}
1545 
1546 	link_info = hdd_get_link_info_by_ieee_link_id(adapter, link_id);
1547 	if (!link_info) {
1548 		hdd_err("Link info not found by linkid:%u", link_id);
1549 		return QDF_STATUS_E_INVAL;
1550 	}
1551 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1552 	ch_width = sta_ctx->user_cfg_chn_width;
1553 
1554 	wlan_mlme_get_sta_ch_width(vdev, &connection_ch_width);
1555 
1556 	if (ch_width == CH_WIDTH_INVALID) {
1557 		hdd_debug("no cached bandwidth for the link %u", link_id);
1558 		return QDF_STATUS_SUCCESS;
1559 	}
1560 
1561 	if (ch_width == connection_ch_width) {
1562 		hdd_debug("user config max bd same as connection ch bw:%u",
1563 			  ch_width);
1564 		return QDF_STATUS_SUCCESS;
1565 	}
1566 
1567 	hdd_debug("send vdev id:%u, chwidth:%u", link_info->vdev_id,
1568 		  ch_width);
1569 
1570 	wlan_mlme_send_ch_width_update_with_notify(psoc, vdev,
1571 						   link_info->vdev_id,
1572 						   ch_width);
1573 	return QDF_STATUS_SUCCESS;
1574 }
1575 #else
1576 static QDF_STATUS
hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter * adapter,struct wlan_objmgr_vdev * vdev)1577 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter,
1578 					struct wlan_objmgr_vdev *vdev)
1579 {
1580 	return QDF_STATUS_SUCCESS;
1581 }
1582 #endif
1583 
1584 static void
hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1585 hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev,
1586 				       struct wlan_cm_connect_resp *rsp)
1587 {
1588 	struct hdd_context *hdd_ctx;
1589 	struct hdd_adapter *adapter;
1590 	struct hdd_station_ctx *sta_ctx;
1591 	struct vdev_mlme_obj *vdev_mlme;
1592 	unsigned long rc;
1593 	uint32_t ie_len;
1594 	uint8_t *ie_field;
1595 	mac_handle_t mac_handle;
1596 	bool is_auth_required = true;
1597 	bool is_roam_offload = false;
1598 	bool is_roam = rsp->is_reassoc;
1599 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
1600 	uint8_t uapsd_mask = 0;
1601 	uint32_t time_buffer_size;
1602 	struct hdd_adapter *assoc_link_adapter;
1603 	bool is_immediate_power_save;
1604 	struct wlan_hdd_link_info *link_info;
1605 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1606 	bool alt_pipe;
1607 
1608 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1609 	if (!hdd_ctx) {
1610 		hdd_err("hdd_ctx is NULL");
1611 		return;
1612 	}
1613 
1614 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
1615 	if (!link_info) {
1616 		hdd_err("Invalid vdev");
1617 		return;
1618 	}
1619 
1620 	adapter = link_info->adapter;
1621 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1622 	mac_handle = hdd_adapter_get_mac_handle(adapter);
1623 
1624 	wlan_hdd_ft_set_key_delay(vdev);
1625 	hdd_cm_update_rssi_snr_by_bssid(link_info);
1626 	hdd_cm_save_connect_status(link_info, rsp->status_code);
1627 
1628 	hdd_init_scan_reject_params(hdd_ctx);
1629 	time_buffer_size = sizeof(sta_ctx->conn_info.connect_time);
1630 	qdf_mem_zero(sta_ctx->conn_info.connect_time, time_buffer_size);
1631 	qdf_get_time_of_the_day_in_hr_min_sec_usec(sta_ctx->conn_info.connect_time,
1632 						   time_buffer_size);
1633 	hdd_start_tsf_sync(adapter);
1634 	hdd_cm_rec_connect_info(rsp);
1635 
1636 	hdd_cm_save_connect_info(link_info, rsp);
1637 	if (adapter->device_mode == QDF_STA_MODE &&
1638 	    hdd_adapter_is_ml_adapter(adapter)) {
1639 		/* Save connection info in assoc link adapter as well */
1640 		assoc_link_adapter = hdd_get_assoc_link_adapter(adapter);
1641 		if (assoc_link_adapter)
1642 			hdd_cm_save_connect_info(assoc_link_adapter->deflink,
1643 						 rsp);
1644 	}
1645 	if (hdd_add_beacon_filter(adapter) != 0)
1646 		hdd_err("add beacon filter failed");
1647 
1648 	adapter->wapi_info.is_wapi_sta = hdd_cm_is_wapi_sta(
1649 						sta_ctx->conn_info.auth_type);
1650 	if (adapter->device_mode == QDF_STA_MODE &&
1651 	    rsp->connect_ies.bcn_probe_rsp.ptr &&
1652 	    (rsp->connect_ies.bcn_probe_rsp.len >
1653 	     (sizeof(struct wlan_frame_hdr) +
1654 	      offsetof(struct wlan_bcn_frame, ie)))) {
1655 		ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
1656 				sizeof(struct wlan_frame_hdr) -
1657 				offsetof(struct wlan_bcn_frame, ie));
1658 
1659 		ie_field  = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
1660 				sizeof(struct wlan_frame_hdr) +
1661 				offsetof(struct wlan_bcn_frame, ie));
1662 		is_immediate_power_save =
1663 				wlan_hdd_is_ap_supports_immediate_power_save(
1664 					ie_field, ie_len);
1665 		hdd_set_immediate_power_save(adapter, is_immediate_power_save);
1666 		hdd_debug("ap_supports_immediate_power_save flag [%d]",
1667 			  sta_ctx->ap_supports_immediate_power_save);
1668 	}
1669 	hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, true);
1670 
1671 	hdd_cm_handle_assoc_event(vdev, rsp->bssid.bytes);
1672 
1673 	if (ucfg_cm_is_link_switch_connect_resp(rsp)) {
1674 		if (hdd_cm_mlme_send_standby_link_chn_width(adapter, vdev))
1675 			hdd_debug("send standby link chn width fail");
1676 	}
1677 
1678 	/*
1679 	 * check update hdd_send_update_beacon_ies_event,
1680 	 * hdd_send_ft_assoc_response,
1681 	 */
1682 
1683 	wlan_hdd_set_tx_flow_info();
1684 	hdd_place_marker(adapter, "ASSOCIATION COMPLETE", NULL);
1685 
1686 	if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) {
1687 		if (hdd_ctx->miracast_value)
1688 			wlan_hdd_set_mas(adapter, hdd_ctx->miracast_value);
1689 	}
1690 
1691 	if (!is_roam) {
1692 		/* Initialize the Linkup event completion variable */
1693 		INIT_COMPLETION(adapter->linkup_event_var);
1694 
1695 		/*
1696 		 * Enable Linkup Event Servicing which allows the net
1697 		 * device notifier to set the linkup event variable.
1698 		 */
1699 		adapter->is_link_up_service_needed = true;
1700 
1701 		/* Switch on the Carrier to activate the device */
1702 		wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_ON,
1703 					     WLAN_CONTROL_PATH);
1704 
1705 		/*
1706 		 * Wait for the Link to up to ensure all the queues
1707 		 * are set properly by the kernel.
1708 		 */
1709 		rc = wait_for_completion_timeout(
1710 					&adapter->linkup_event_var,
1711 					 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
1712 		/*
1713 		 * Disable Linkup Event Servicing - no more service
1714 		 * required from the net device notifier call.
1715 		 */
1716 		adapter->is_link_up_service_needed = false;
1717 	}
1718 
1719 	vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev,
1720 							  WLAN_UMAC_COMP_MLME);
1721 	if (vdev_mlme)
1722 		uapsd_mask =
1723 			vdev_mlme->ext_vdev_ptr->connect_info.uapsd_per_ac_bitmask;
1724 
1725 	cdp_hl_fc_set_td_limit(soc, link_info->vdev_id,
1726 			       sta_ctx->conn_info.chan_freq);
1727 	hdd_wmm_assoc(adapter, false, uapsd_mask);
1728 
1729 	if (!rsp->is_wps_connection &&
1730 	    !rsp->is_osen_connection &&
1731 	    (sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_NONE ||
1732 	     sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM ||
1733 	     sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_SHARED_KEY ||
1734 	     hdd_cm_is_fils_connection(rsp)))
1735 		is_auth_required = false;
1736 
1737 	if (is_roam)
1738 		/* If roaming is set check if FW roaming/LFR3  */
1739 		ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &is_roam_offload);
1740 
1741 	if (is_roam_offload || !is_roam) {
1742 		/* For FW_ROAM/LFR3 OR connect */
1743 		/* for LFR 3 get authenticated info from resp */
1744 		if (is_roam) {
1745 			is_auth_required =
1746 				hdd_cm_is_roam_auth_required(sta_ctx, rsp);
1747 			if (is_auth_required)
1748 				wlan_acquire_peer_key_wakelock(hdd_ctx->pdev,
1749 							      rsp->bssid.bytes);
1750 		}
1751 		hdd_debug("is_roam_offload %d, is_roam %d, is_auth_required %d",
1752 			  is_roam_offload, is_roam, is_auth_required);
1753 		hdd_roam_register_sta(link_info, &rsp->bssid, is_auth_required);
1754 	} else {
1755 		/* for host roam/LFR2 */
1756 		hdd_cm_set_peer_authenticate(link_info,
1757 					     &rsp->bssid, is_auth_required);
1758 	}
1759 
1760 	hdd_debug("Enabling queues");
1761 	hdd_cm_netif_queue_enable(adapter);
1762 
1763 	/* send peer status indication to oem app */
1764 	if (vdev_mlme) {
1765 		hdd_send_peer_status_ind_to_app(
1766 			&rsp->bssid,
1767 			ePeerConnected,
1768 			vdev_mlme->ext_vdev_ptr->connect_info.timing_meas_cap,
1769 			link_info->vdev_id,
1770 			&vdev_mlme->ext_vdev_ptr->connect_info.chan_info,
1771 			adapter->device_mode);
1772 	}
1773 
1774 	if (ucfg_ipa_is_enabled() && !is_auth_required) {
1775 		status = hdd_ipa_get_tx_pipe(hdd_ctx, link_info, &alt_pipe);
1776 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1777 			hdd_debug("Failed to get alternate pipe for vdev %d",
1778 				  link_info->vdev_id);
1779 			alt_pipe = false;
1780 		}
1781 
1782 		ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
1783 				  adapter->device_mode,
1784 				  link_info->vdev_id,
1785 				  WLAN_IPA_STA_CONNECT,
1786 				  rsp->bssid.bytes,
1787 				  alt_pipe);
1788 	}
1789 
1790 	if (adapter->device_mode == QDF_STA_MODE)
1791 		cdp_reset_rx_hw_ext_stats(soc);
1792 
1793 	wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
1794 
1795 	DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1796 		link_info->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
1797 		QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
1798 
1799 	if (is_roam)
1800 		ucfg_dp_nud_indicate_roam(vdev);
1801 	 /* hdd_objmgr_set_peer_mlme_auth_state */
1802 
1803 	if (adapter->keep_alive_interval)
1804 		hdd_vdev_send_sta_keep_alive_interval(link_info, hdd_ctx,
1805 						adapter->keep_alive_interval);
1806 }
1807 
1808 static void
hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1809 hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev,
1810 					struct wlan_cm_connect_resp *rsp)
1811 {
1812 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1813 	struct hdd_adapter *adapter;
1814 	struct wlan_hdd_link_info *link_info;
1815 	bool is_roam = rsp->is_reassoc;
1816 
1817 	if (!hdd_ctx) {
1818 		hdd_err("hdd_ctx is NULL");
1819 		return;
1820 	}
1821 
1822 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
1823 	if (!link_info) {
1824 		hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
1825 		return;
1826 	}
1827 
1828 	if (!is_roam) {
1829 		/* call only for connect */
1830 		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
1831 		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
1832 	}
1833 
1834 	adapter = link_info->adapter;
1835 	hdd_cm_clear_pmf_stats(adapter);
1836 
1837 	if (adapter->device_mode == QDF_STA_MODE) {
1838 		/* Inform FTM TIME SYNC about the connection with AP */
1839 		hdd_ftm_time_sync_sta_state_notify(adapter,
1840 						   FTM_TIME_SYNC_STA_CONNECTED);
1841 		ucfg_mlme_init_twt_context(hdd_ctx->psoc,
1842 					   &rsp->bssid,
1843 					   TWT_ALL_SESSIONS_DIALOG_ID);
1844 		ucfg_twt_init_context(hdd_ctx->psoc,
1845 				      &rsp->bssid,
1846 				      TWT_ALL_SESSIONS_DIALOG_ID);
1847 	}
1848 	ucfg_dp_periodic_sta_stats_start(vdev);
1849 	wlan_twt_concurrency_update(hdd_ctx);
1850 
1851 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev))
1852 		hdd_send_ps_config_to_fw(adapter);
1853 }
1854 
hdd_cm_connect_success(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1855 static void hdd_cm_connect_success(struct wlan_objmgr_vdev *vdev,
1856 				   struct wlan_cm_connect_resp *rsp,
1857 				   enum osif_cb_type type)
1858 {
1859 	switch (type) {
1860 	case OSIF_PRE_USERSPACE_UPDATE:
1861 		hdd_cm_connect_success_pre_user_update(vdev, rsp);
1862 		break;
1863 	case OSIF_POST_USERSPACE_UPDATE:
1864 		hdd_cm_connect_success_post_user_update(vdev, rsp);
1865 		break;
1866 	default:
1867 		hdd_cm_connect_success_pre_user_update(vdev, rsp);
1868 		hdd_cm_connect_success_post_user_update(vdev, rsp);
1869 	}
1870 }
1871 
1872 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
hdd_cm_connect_active_notify(uint8_t vdev_id)1873 void hdd_cm_connect_active_notify(uint8_t vdev_id)
1874 {
1875 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1876 	struct wlan_hdd_link_info *link_info;
1877 
1878 	if (!hdd_ctx) {
1879 		hdd_err("HDD context is NULL");
1880 		return;
1881 	}
1882 
1883 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
1884 	if (!link_info) {
1885 		hdd_err("Link info not found for vdev %d", vdev_id);
1886 		return;
1887 	}
1888 
1889 	if (hdd_adapter_restore_link_vdev_map(link_info->adapter, true))
1890 		hdd_adapter_update_mlo_mgr_mac_addr(link_info->adapter);
1891 }
1892 #endif
1893 
hdd_cm_connect_complete(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1894 QDF_STATUS hdd_cm_connect_complete(struct wlan_objmgr_vdev *vdev,
1895 				   struct wlan_cm_connect_resp *rsp,
1896 				   enum osif_cb_type type)
1897 {
1898 	if (QDF_IS_STATUS_ERROR(rsp->connect_status))
1899 		hdd_cm_connect_failure(vdev, rsp, type);
1900 	else
1901 		hdd_cm_connect_success(vdev, rsp, type);
1902 
1903 	return QDF_STATUS_SUCCESS;
1904 }
1905 
hdd_cm_send_vdev_keys(struct wlan_objmgr_vdev * vdev,u8 key_index,bool pairwise,enum wlan_crypto_cipher_type cipher_type)1906 QDF_STATUS hdd_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
1907 				 u8 key_index, bool pairwise,
1908 				 enum wlan_crypto_cipher_type cipher_type)
1909 {
1910 	return wlan_hdd_send_key_vdev(vdev, key_index, pairwise, cipher_type);
1911 }
1912 
1913 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
1914 #define WLAN_WAIT_TIME_HANDOFF_PARAMS 1000
hdd_cm_get_handoff_param(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum vendor_control_roam_param param_id)1915 QDF_STATUS hdd_cm_get_handoff_param(struct wlan_objmgr_psoc *psoc,
1916 				    uint8_t vdev_id,
1917 				    enum vendor_control_roam_param param_id)
1918 {
1919 	QDF_STATUS status;
1920 	int retval;
1921 	void *vendor_handoff_context;
1922 	struct osif_request *request;
1923 	static const struct osif_request_params params = {
1924 		.priv_size = 0,
1925 		.timeout_ms = WLAN_WAIT_TIME_HANDOFF_PARAMS,
1926 	};
1927 
1928 	request = osif_request_alloc(&params);
1929 	if (!request) {
1930 		hdd_err("Request allocation failure");
1931 		status = QDF_STATUS_E_NOMEM;
1932 		goto error;
1933 	}
1934 
1935 	vendor_handoff_context = osif_request_cookie(request);
1936 
1937 	hdd_debug("sending vendor handoff param request for :0x%x", param_id);
1938 	status = ucfg_cm_roam_send_vendor_handoff_param_req(psoc, vdev_id,
1939 							param_id,
1940 							vendor_handoff_context);
1941 	if (QDF_IS_STATUS_ERROR(status)) {
1942 		hdd_err("Unable to get vendor handoff param");
1943 		goto error;
1944 	}
1945 
1946 	retval = osif_request_wait_for_response(request);
1947 	if (retval) {
1948 		hdd_err("Target response timed out");
1949 		status = qdf_status_from_os_return(retval);
1950 	}
1951 error:
1952 	if (request)
1953 		osif_request_put(request);
1954 
1955 	return status;
1956 }
1957 
1958 QDF_STATUS
hdd_cm_get_vendor_handoff_params(struct wlan_objmgr_psoc * psoc,void * vendor_handoff_context)1959 hdd_cm_get_vendor_handoff_params(struct wlan_objmgr_psoc *psoc,
1960 				 void *vendor_handoff_context)
1961 {
1962 	struct osif_request *request;
1963 
1964 	hdd_debug("Received vendor handoff event from FW");
1965 
1966 	request = osif_request_get(vendor_handoff_context);
1967 	if (!request) {
1968 		hdd_err("Invalid request");
1969 		return QDF_STATUS_E_FAILURE;
1970 	}
1971 
1972 	osif_request_complete(request);
1973 	osif_request_put(request);
1974 
1975 	hdd_exit();
1976 
1977 	return QDF_STATUS_SUCCESS;
1978 }
1979 #endif
1980 
1981 QDF_STATUS
hdd_cm_get_scan_ie_params(struct wlan_objmgr_vdev * vdev,struct element_info * scan_ie,enum dot11_mode_filter * dot11mode_filter)1982 hdd_cm_get_scan_ie_params(struct wlan_objmgr_vdev *vdev,
1983 			  struct element_info *scan_ie,
1984 			  enum dot11_mode_filter *dot11mode_filter)
1985 {
1986 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1987 	struct wlan_hdd_link_info *link_info;
1988 	struct hdd_scan_info *scan_info;
1989 
1990 	if (!hdd_ctx) {
1991 		hdd_err("hdd_ctx is NULL");
1992 		return QDF_STATUS_E_INVAL;
1993 	}
1994 
1995 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
1996 	if (!link_info) {
1997 		hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
1998 		return QDF_STATUS_E_INVAL;
1999 	}
2000 
2001 	scan_info = &link_info->adapter->scan_info;
2002 	if (link_info->adapter->device_mode == QDF_P2P_CLIENT_MODE) {
2003 		scan_ie->ptr = &scan_info->scan_add_ie.addIEdata[0];
2004 		scan_ie->len = scan_info->scan_add_ie.length;
2005 	} else if (scan_info->default_scan_ies) {
2006 		scan_ie->ptr = scan_info->default_scan_ies;
2007 		scan_ie->len = scan_info->default_scan_ies_len;
2008 	} else if (scan_info->scan_add_ie.length) {
2009 		scan_ie->ptr = scan_info->scan_add_ie.addIEdata;
2010 		scan_ie->len = scan_info->scan_add_ie.length;
2011 	}
2012 
2013 	*dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx);
2014 
2015 	return QDF_STATUS_SUCCESS;
2016 }
2017 
2018 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
2019 #ifdef WLAN_FEATURE_FILS_SK
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2020 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2021 			   struct wlan_cm_connect_resp *rsp)
2022 {
2023 	uint8_t *kek;
2024 	uint32_t kek_len;
2025 	uint8_t *kck = NULL;
2026 	uint8_t kck_len = 0;
2027 	uint8_t replay_ctr_def[REPLAY_CTR_LEN] = {0};
2028 	uint8_t *replay_ctr;
2029 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2030 	struct wlan_hdd_link_info *link_info;
2031 
2032 	if (!hdd_ctx) {
2033 		hdd_err("hdd_ctx is NULL");
2034 		return QDF_STATUS_E_INVAL;
2035 	}
2036 
2037 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
2038 	if (!link_info) {
2039 		hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
2040 		return QDF_STATUS_E_INVAL;
2041 	}
2042 
2043 	if (rsp->is_reassoc && rsp->roaming_info) {
2044 		kek = rsp->roaming_info->kek;
2045 		kek_len = rsp->roaming_info->kek_len;
2046 		kck = rsp->roaming_info->kck;
2047 		kck_len = rsp->roaming_info->kck_len;
2048 		replay_ctr = rsp->roaming_info->replay_ctr;
2049 	} else if (rsp->connect_ies.fils_ie) {
2050 		kek = rsp->connect_ies.fils_ie->kek;
2051 		kek_len = rsp->connect_ies.fils_ie->kek_len;
2052 		replay_ctr = replay_ctr_def;
2053 	} else {
2054 		return QDF_STATUS_SUCCESS;
2055 	}
2056 	wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len,
2057 					 kek, kek_len, replay_ctr, true);
2058 
2059 	return QDF_STATUS_SUCCESS;
2060 }
2061 #else
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2062 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2063 			   struct wlan_cm_connect_resp *rsp)
2064 {
2065 	uint8_t *kek;
2066 	uint32_t kek_len;
2067 	uint8_t *kck = NULL;
2068 	uint8_t kck_len = 0;
2069 	uint8_t *replay_ctr;
2070 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2071 	struct wlan_hdd_link_info *link_info;
2072 
2073 	if (!hdd_ctx) {
2074 		hdd_err("hdd_ctx is NULL");
2075 		return QDF_STATUS_E_INVAL;
2076 	}
2077 
2078 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
2079 	if (!link_info) {
2080 		hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
2081 		return QDF_STATUS_E_INVAL;
2082 	}
2083 
2084 	if (rsp->is_reassoc && rsp->roaming_info) {
2085 		kek = rsp->roaming_info.kek;
2086 		kek_len = rsp->roaming_info.kek_len;
2087 		kck = rsp->roaming_info.kck;
2088 		kck_len = rsp->roaming_info.kck_len;
2089 		replay_ctr = rsp->roaming_info.replay_ctr;
2090 	} else {
2091 		return QDF_STATUS_SUCCESS;
2092 	}
2093 	wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len,
2094 					 kek, kek_len, replay_ctr, true);
2095 
2096 	return QDF_STATUS_SUCCESS;
2097 }
2098 #endif /* WLAN_FEATURE_FILS_SK*/
2099 #else
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2100 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2101 			   struct wlan_cm_connect_resp *rsp)
2102 {
2103 	return QDF_STATUS_SUCCESS;
2104 }
2105 #endif
2106 
2107 #ifdef WLAN_FEATURE_FILS_SK
hdd_update_hlp_info(struct net_device * dev,struct wlan_cm_connect_resp * rsp)2108 static void hdd_update_hlp_info(struct net_device *dev,
2109 				struct wlan_cm_connect_resp *rsp)
2110 {
2111 	struct sk_buff *skb;
2112 	uint16_t skb_len;
2113 	struct llc_snap_hdr_t *llc_hdr;
2114 	QDF_STATUS status;
2115 	uint8_t *hlp_data;
2116 	uint16_t hlp_data_len;
2117 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2118 
2119 	if (!rsp || !rsp->connect_ies.fils_ie) {
2120 		return;
2121 	}
2122 
2123 	if (!rsp->connect_ies.fils_ie->hlp_data_len) {
2124 		return;
2125 	}
2126 
2127 	hlp_data = rsp->connect_ies.fils_ie->hlp_data;
2128 	hlp_data_len = rsp->connect_ies.fils_ie->hlp_data_len;
2129 
2130 	/* Calculate skb length */
2131 	skb_len = (2 * ETH_ALEN) + hlp_data_len;
2132 	skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
2133 	if (!skb) {
2134 		hdd_err("HLP packet nbuf alloc fails");
2135 		return;
2136 	}
2137 
2138 	qdf_mem_copy(skb_put(skb, ETH_ALEN),
2139 		     rsp->connect_ies.fils_ie->dst_mac.bytes,
2140 		     QDF_MAC_ADDR_SIZE);
2141 	qdf_mem_copy(skb_put(skb, ETH_ALEN),
2142 		     rsp->connect_ies.fils_ie->src_mac.bytes,
2143 		     QDF_MAC_ADDR_SIZE);
2144 
2145 	llc_hdr = (struct llc_snap_hdr_t *)hlp_data;
2146 	if (IS_SNAP(llc_hdr)) {
2147 		hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
2148 		hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
2149 	}
2150 
2151 	qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
2152 
2153 	/*
2154 	 * This HLP packet is formed from HLP info encapsulated
2155 	 * in assoc response frame which is AEAD encrypted.
2156 	 * Hence, this checksum validation can be set unnecessary.
2157 	 * i.e. network layer need not worry about checksum.
2158 	 */
2159 	skb->ip_summed = CHECKSUM_UNNECESSARY;
2160 
2161 	/*
2162 	 * adapter->deflink->vdev is directly dereferenced because in per packet
2163 	 * path usage of hdd_get_vdev_by_user is costly operation as it
2164 	 * involves lock access. And it is guaranteed during TX/RX operations
2165 	 * vdev will be active will not deleted.
2166 	 */
2167 	status = ucfg_dp_rx_packet_cbk(adapter->deflink->vdev, (qdf_nbuf_t)skb);
2168 	if (QDF_IS_STATUS_ERROR(status)) {
2169 		hdd_err("Sending HLP packet fails");
2170 		return;
2171 	}
2172 	hdd_debug("send HLP packet to netif successfully");
2173 }
2174 
hdd_cm_set_hlp_data(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2175 QDF_STATUS hdd_cm_set_hlp_data(struct net_device *dev,
2176 			       struct wlan_objmgr_vdev *vdev,
2177 			       struct wlan_cm_connect_resp *rsp)
2178 {
2179 	hdd_update_hlp_info(dev, rsp);
2180 	return QDF_STATUS_SUCCESS;
2181 }
2182 #endif
2183 
2184 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
2185 /**
2186  * hdd_cm_get_ft_preauth_response() - get ft preauth response
2187  * related information
2188  * @vdev: vdev pointer
2189  * @rsp: preauth response
2190  * @ft_ie: ft ie
2191  * @ft_ie_ip_len: ft ie ip length
2192  * @ft_ie_length: ft ies length
2193  *
2194  * This function is used to get ft ie related information
2195  *
2196  * Return: none
2197  */
2198 static void
hdd_cm_get_ft_preauth_response(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp,uint8_t * ft_ie,uint32_t ft_ie_ip_len,uint16_t * ft_ie_length)2199 hdd_cm_get_ft_preauth_response(struct wlan_objmgr_vdev *vdev,
2200 			       struct wlan_preauth_rsp *rsp, uint8_t *ft_ie,
2201 			       uint32_t ft_ie_ip_len, uint16_t *ft_ie_length)
2202 {
2203 	struct mlme_legacy_priv *mlme_priv;
2204 
2205 	*ft_ie_length = 0;
2206 
2207 	if (!vdev)
2208 		return;
2209 
2210 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
2211 	if (!mlme_priv)
2212 		return;
2213 
2214 	/* All or nothing - proceed only if both BSSID and FT IE fit */
2215 	if ((QDF_MAC_ADDR_SIZE + rsp->ft_ie_length) > ft_ie_ip_len)
2216 		return;
2217 	/*
2218 	 * hdd needs to pack the bssid also along with the
2219 	 * auth response to supplicant
2220 	 */
2221 	qdf_mem_copy(ft_ie, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE);
2222 
2223 	/* Copy the auth resp FTIEs */
2224 	qdf_mem_copy(&ft_ie[QDF_MAC_ADDR_SIZE],
2225 		     rsp->ft_ie, rsp->ft_ie_length);
2226 
2227 	*ft_ie_length = QDF_MAC_ADDR_SIZE + rsp->ft_ie_length;
2228 
2229 	hdd_debug("Filled auth resp: %d", *ft_ie_length);
2230 }
2231 
2232 #if defined(KERNEL_SUPPORT_11R_CFG80211)
hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2233 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev,
2234 				      struct wlan_preauth_rsp *rsp)
2235 {
2236 	mac_handle_t mac_handle;
2237 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2238 	struct wireless_dev *wdev;
2239 	uint16_t auth_resp_len = 0;
2240 	uint32_t ric_ies_length = 0;
2241 	struct cfg80211_ft_event_params ft_event = {0};
2242 	uint8_t ft_ie[DOT11F_IE_FTINFO_MAX_LEN] = {0};
2243 	uint8_t ric_ies[DOT11F_IE_RICDESCRIPTOR_MAX_LEN] = {0};
2244 
2245 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2246 	if (!mac_handle) {
2247 		hdd_err("mac_handle is null");
2248 		return QDF_STATUS_E_INVAL;
2249 	}
2250 
2251 	if (!osif_priv) {
2252 		hdd_err("Invalid vdev osif priv");
2253 		return QDF_STATUS_E_INVAL;
2254 	}
2255 
2256 	wdev = osif_priv->wdev;
2257 	if (!wdev) {
2258 		hdd_err("wdev is null");
2259 		return QDF_STATUS_E_INVAL;
2260 	}
2261 
2262 	if (rsp->ric_ies_length &&
2263 	    rsp->ric_ies_length <= DOT11F_IE_RICDESCRIPTOR_MAX_LEN) {
2264 		qdf_mem_copy(ric_ies, rsp->ric_ies, rsp->ric_ies_length);
2265 		ric_ies_length = rsp->ric_ies_length;
2266 	} else {
2267 		hdd_warn("Do not send RIC IEs as length is 0");
2268 	}
2269 
2270 	if (ric_ies_length) {
2271 		ft_event.ric_ies = ric_ies;
2272 		ft_event.ric_ies_len = ric_ies_length;
2273 	}
2274 	hdd_debug("RIC IEs is of length %d", ric_ies_length);
2275 
2276 	hdd_cm_get_ft_preauth_response(vdev, rsp, ft_ie,
2277 				       DOT11F_IE_FTINFO_MAX_LEN,
2278 				       &auth_resp_len);
2279 	if (!auth_resp_len) {
2280 		hdd_debug("AuthRsp FTIES is of length 0");
2281 		return QDF_STATUS_E_FAILURE;
2282 	}
2283 
2284 	ucfg_cm_set_ft_pre_auth_state(vdev, true);
2285 
2286 	ft_event.target_ap = ft_ie;
2287 	ft_event.ies = (u8 *)(ft_ie + QDF_MAC_ADDR_SIZE);
2288 	ft_event.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
2289 
2290 	hdd_debug("ftEvent.ies_len %zu", ft_event.ies_len);
2291 	hdd_debug("ftEvent.ric_ies_len %zu", ft_event.ric_ies_len);
2292 	hdd_debug("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x",
2293 		  ft_event.target_ap[0], ft_event.target_ap[1],
2294 		  ft_event.target_ap[2], ft_event.target_ap[3],
2295 		  ft_event.target_ap[4], ft_event.target_ap[5]);
2296 
2297 	(void)cfg80211_ft_event(wdev->netdev, &ft_event);
2298 
2299 	return QDF_STATUS_SUCCESS;
2300 }
2301 #else
hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2302 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev,
2303 				      struct wlan_preauth_rsp *rsp)
2304 {
2305 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2306 	struct wireless_dev *wdev;
2307 	uint16_t auth_resp_len = 0;
2308 	uint32_t ric_ies_length = 0;
2309 	char *buff;
2310 	union iwreq_data wrqu;
2311 	uint16_t str_len;
2312 
2313 	if (!osif_priv) {
2314 		hdd_err("Invalid vdev osif priv");
2315 		return QDF_STATUS_E_INVAL;
2316 	}
2317 
2318 	wdev = osif_priv->wdev;
2319 	if (!wdev) {
2320 		hdd_err("wdev is null");
2321 		return QDF_STATUS_E_INVAL;
2322 	}
2323 
2324 	/* need to send the IEs to the supplicant */
2325 	buff = qdf_mem_malloc(IW_CUSTOM_MAX);
2326 	if (!buff)
2327 		return QDF_STATUS_E_NOMEM;
2328 
2329 	/* need to send the RIC IEs first */
2330 	str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
2331 	if (rsp->ric_ies_length &&
2332 	    (rsp->ric_ies_length <= (IW_CUSTOM_MAX - str_len))) {
2333 		qdf_mem_copy(&buff[str_len], rsp->ric_ies,
2334 			     rsp->ric_ies_length);
2335 		ric_ies_length = rsp->ric_ies_length;
2336 		wrqu.data.length = str_len + ric_ies_length;
2337 		hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff);
2338 	} else {
2339 		hdd_warn("Do not send RIC IEs as length is 0");
2340 	}
2341 
2342 	/* need to provide the Auth Resp */
2343 	qdf_mem_zero(buff, IW_CUSTOM_MAX);
2344 	str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
2345 	hdd_cm_get_ft_preauth_response(vdev, rsp, &buff[str_len],
2346 				       (IW_CUSTOM_MAX - str_len),
2347 				       &auth_resp_len);
2348 	if (!auth_resp_len) {
2349 		qdf_mem_free(buff);
2350 		hdd_debug("AuthRsp FTIES is of length 0");
2351 		return QDF_STATUS_E_FAILURE;
2352 	}
2353 
2354 	wrqu.data.length = str_len + auth_resp_len;
2355 	hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff);
2356 
2357 	qdf_mem_free(buff);
2358 	return QDF_STATUS_SUCCESS;
2359 }
2360 #endif
2361 
2362 #ifdef FEATURE_WLAN_ESE
hdd_cm_cckm_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2363 QDF_STATUS hdd_cm_cckm_preauth_complete(struct wlan_objmgr_vdev *vdev,
2364 					struct wlan_preauth_rsp *rsp)
2365 {
2366 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2367 	struct wireless_dev *wdev;
2368 	union iwreq_data wrqu;
2369 	char buf[IW_CUSTOM_MAX + 1];
2370 	char *pos = buf;
2371 	int nbytes = 0, freebytes = IW_CUSTOM_MAX;
2372 
2373 	if (!osif_priv) {
2374 		hdd_err("Invalid vdev osif priv");
2375 		return QDF_STATUS_E_INVAL;
2376 	}
2377 
2378 	wdev = osif_priv->wdev;
2379 	if (!wdev) {
2380 		hdd_err("wdev is null");
2381 		return QDF_STATUS_E_INVAL;
2382 	}
2383 
2384 	/* create the event */
2385 	memset(&wrqu, '\0', sizeof(wrqu));
2386 	memset(buf, '\0', sizeof(buf));
2387 
2388 	/* timestamp0 is lower 32 bits and timestamp1 is upper 32 bits */
2389 	hdd_debug("CCXPREAUTHNOTIFY=" QDF_MAC_ADDR_FMT " %d:%d",
2390 		  QDF_MAC_ADDR_REF(rsp->pre_auth_bssid.bytes),
2391 		  rsp->timestamp[0], rsp->timestamp[1]);
2392 
2393 	nbytes = snprintf(pos, freebytes, "CCXPREAUTHNOTIFY=");
2394 	pos += nbytes;
2395 	freebytes -= nbytes;
2396 
2397 	qdf_mem_copy(pos, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE);
2398 	pos += QDF_MAC_ADDR_SIZE;
2399 	freebytes -= QDF_MAC_ADDR_SIZE;
2400 
2401 	nbytes = snprintf(pos, freebytes, " %u:%u",
2402 			  rsp->timestamp[0], rsp->timestamp[1]);
2403 	freebytes -= nbytes;
2404 
2405 	wrqu.data.pointer = buf;
2406 	wrqu.data.length = (IW_CUSTOM_MAX - freebytes);
2407 
2408 	/* send the event */
2409 	hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buf);
2410 
2411 	return QDF_STATUS_SUCCESS;
2412 }
2413 #endif /* FEATURE_WLAN_ESE */
2414 #endif /* WLAN_FEATURE_PREAUTH_ENABLE */
2415