xref: /wlan-driver/qca-wifi-host-cmn/os_if/linux/mlme/src/osif_cm_connect_rsp.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: osif_cm_connect_rsp.c
20*5113495bSYour Name  *
21*5113495bSYour Name  * This file maintains definitaions of connect response apis.
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #include <linux/version.h>
25*5113495bSYour Name #include <linux/nl80211.h>
26*5113495bSYour Name #include <net/cfg80211.h>
27*5113495bSYour Name #include "wlan_osif_priv.h"
28*5113495bSYour Name #include "osif_cm_rsp.h"
29*5113495bSYour Name #include "osif_cm_util.h"
30*5113495bSYour Name #include "wlan_cfg80211.h"
31*5113495bSYour Name #include "wlan_cfg80211_scan.h"
32*5113495bSYour Name #include "wlan_mlo_mgr_sta.h"
33*5113495bSYour Name #include "wlan_mlo_mgr_cmn.h"
34*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
35*5113495bSYour Name #include "wlan_objmgr_peer_obj.h"
36*5113495bSYour Name #include "utils_mlo.h"
37*5113495bSYour Name #include <wlan_mlo_mgr_link_switch.h>
38*5113495bSYour Name #include "wlan_crypto_global_api.h"
39*5113495bSYour Name 
40*5113495bSYour Name #ifdef CONN_MGR_ADV_FEATURE
osif_cm_get_assoc_req_ie_data(struct element_info * assoc_req,size_t * ie_data_len,const uint8_t ** ie_data_ptr)41*5113495bSYour Name void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req,
42*5113495bSYour Name 				   size_t *ie_data_len,
43*5113495bSYour Name 				   const uint8_t **ie_data_ptr)
44*5113495bSYour Name {
45*5113495bSYour Name 	/* Validate IE and length */
46*5113495bSYour Name 	if (!assoc_req->len || !assoc_req->ptr ||
47*5113495bSYour Name 	    assoc_req->len <= WLAN_ASSOC_REQ_IES_OFFSET)
48*5113495bSYour Name 		return;
49*5113495bSYour Name 
50*5113495bSYour Name 	*ie_data_len = assoc_req->len - WLAN_ASSOC_REQ_IES_OFFSET;
51*5113495bSYour Name 	*ie_data_ptr = assoc_req->ptr + WLAN_ASSOC_REQ_IES_OFFSET;
52*5113495bSYour Name }
53*5113495bSYour Name #else
osif_cm_get_assoc_req_ie_data(struct element_info * assoc_req,size_t * ie_data_len,const uint8_t ** ie_data_ptr)54*5113495bSYour Name void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req,
55*5113495bSYour Name 				   size_t *ie_data_len,
56*5113495bSYour Name 				   const uint8_t **ie_data_ptr)
57*5113495bSYour Name {
58*5113495bSYour Name 	/* Validate IE and length */
59*5113495bSYour Name 	if (!assoc_req->len || !assoc_req->ptr)
60*5113495bSYour Name 		return;
61*5113495bSYour Name 
62*5113495bSYour Name 	*ie_data_len = assoc_req->len;
63*5113495bSYour Name 	*ie_data_ptr = assoc_req->ptr;
64*5113495bSYour Name }
65*5113495bSYour Name #endif
66*5113495bSYour Name 
osif_cm_get_assoc_rsp_ie_data(struct element_info * assoc_rsp,size_t * ie_data_len,const uint8_t ** ie_data_ptr)67*5113495bSYour Name void osif_cm_get_assoc_rsp_ie_data(struct element_info *assoc_rsp,
68*5113495bSYour Name 				   size_t *ie_data_len,
69*5113495bSYour Name 				   const uint8_t **ie_data_ptr)
70*5113495bSYour Name {
71*5113495bSYour Name 	/* Validate IE and length */
72*5113495bSYour Name 	if (!assoc_rsp->len || !assoc_rsp->ptr ||
73*5113495bSYour Name 	    assoc_rsp->len <= WLAN_ASSOC_RSP_IES_OFFSET)
74*5113495bSYour Name 		return;
75*5113495bSYour Name 
76*5113495bSYour Name 	*ie_data_len = assoc_rsp->len - WLAN_ASSOC_RSP_IES_OFFSET;
77*5113495bSYour Name 	*ie_data_ptr = assoc_rsp->ptr + WLAN_ASSOC_RSP_IES_OFFSET;
78*5113495bSYour Name }
79*5113495bSYour Name 
80*5113495bSYour Name /**
81*5113495bSYour Name  * osif_validate_connect_and_reset_src_id() - Validate connect response and
82*5113495bSYour Name  * resets source and id
83*5113495bSYour Name  * @osif_priv: Pointer to vdev osif priv
84*5113495bSYour Name  * @rsp: Connection manager connect response
85*5113495bSYour Name  *
86*5113495bSYour Name  * This function validates connect response and if the connect
87*5113495bSYour Name  * response is valid, resets the source and id of the command
88*5113495bSYour Name  *
89*5113495bSYour Name  * Context: Any context. Takes and releases cmd id spinlock.
90*5113495bSYour Name  * Return: QDF_STATUS
91*5113495bSYour Name  */
92*5113495bSYour Name static QDF_STATUS
osif_validate_connect_and_reset_src_id(struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)93*5113495bSYour Name osif_validate_connect_and_reset_src_id(struct vdev_osif_priv *osif_priv,
94*5113495bSYour Name 				       struct wlan_cm_connect_resp *rsp)
95*5113495bSYour Name {
96*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
97*5113495bSYour Name 
98*5113495bSYour Name 	/*
99*5113495bSYour Name 	 * Do not send to kernel if last osif cookie doesn't match or
100*5113495bSYour Name 	 * or source is CM_OSIF_CFG_CONNECT with success status.
101*5113495bSYour Name 	 * If cookie matches reset the cookie and source.
102*5113495bSYour Name 	 */
103*5113495bSYour Name 	qdf_spinlock_acquire(&osif_priv->cm_info.cmd_id_lock);
104*5113495bSYour Name 	if (rsp->cm_id != osif_priv->cm_info.last_id ||
105*5113495bSYour Name 	    (osif_priv->cm_info.last_source == CM_OSIF_CFG_CONNECT &&
106*5113495bSYour Name 	     QDF_IS_STATUS_SUCCESS(rsp->connect_status))) {
107*5113495bSYour Name 		osif_debug("Ignore as cm_id(0x%x)/src(%d) != cm_id(0x%x)/src(%d) OR source is CFG connect with status %d",
108*5113495bSYour Name 			   rsp->cm_id, CM_OSIF_CONNECT,
109*5113495bSYour Name 			   osif_priv->cm_info.last_id,
110*5113495bSYour Name 			   osif_priv->cm_info.last_source,
111*5113495bSYour Name 			   rsp->connect_status);
112*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
113*5113495bSYour Name 		goto rel_lock;
114*5113495bSYour Name 	}
115*5113495bSYour Name 
116*5113495bSYour Name 	osif_cm_reset_id_and_src_no_lock(osif_priv);
117*5113495bSYour Name rel_lock:
118*5113495bSYour Name 	qdf_spinlock_release(&osif_priv->cm_info.cmd_id_lock);
119*5113495bSYour Name 
120*5113495bSYour Name 	return status;
121*5113495bSYour Name }
122*5113495bSYour Name 
123*5113495bSYour Name static enum ieee80211_statuscode
osif_get_statuscode(enum wlan_status_code status)124*5113495bSYour Name osif_get_statuscode(enum wlan_status_code status)
125*5113495bSYour Name {
126*5113495bSYour Name 	return (enum ieee80211_statuscode)status;
127*5113495bSYour Name }
128*5113495bSYour Name 
129*5113495bSYour Name static enum ieee80211_statuscode
osif_get_connect_status_code(struct wlan_cm_connect_resp * rsp)130*5113495bSYour Name osif_get_connect_status_code(struct wlan_cm_connect_resp *rsp)
131*5113495bSYour Name {
132*5113495bSYour Name 	enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS;
133*5113495bSYour Name 
134*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(rsp->connect_status)) {
135*5113495bSYour Name 		if (rsp->status_code)
136*5113495bSYour Name 			status = osif_get_statuscode(rsp->status_code);
137*5113495bSYour Name 		else
138*5113495bSYour Name 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
139*5113495bSYour Name 	}
140*5113495bSYour Name 
141*5113495bSYour Name 	return status;
142*5113495bSYour Name }
143*5113495bSYour Name 
144*5113495bSYour Name /**
145*5113495bSYour Name  * osif_convert_timeout_reason() - Convert to kernel specific enum
146*5113495bSYour Name  * @reason: reason for connect timeout
147*5113495bSYour Name  *
148*5113495bSYour Name  * This function is used to convert host timeout
149*5113495bSYour Name  * reason enum to kernel specific enum.
150*5113495bSYour Name  *
151*5113495bSYour Name  * Context: Any context.
152*5113495bSYour Name  * Return: nl timeout enum
153*5113495bSYour Name  */
154*5113495bSYour Name 
155*5113495bSYour Name static enum nl80211_timeout_reason
osif_convert_timeout_reason(enum wlan_cm_connect_fail_reason reason)156*5113495bSYour Name osif_convert_timeout_reason(enum wlan_cm_connect_fail_reason reason)
157*5113495bSYour Name {
158*5113495bSYour Name 	switch (reason) {
159*5113495bSYour Name 	case CM_JOIN_TIMEOUT:
160*5113495bSYour Name 		return NL80211_TIMEOUT_SCAN;
161*5113495bSYour Name 	case CM_AUTH_TIMEOUT:
162*5113495bSYour Name 		return NL80211_TIMEOUT_AUTH;
163*5113495bSYour Name 	case CM_ASSOC_TIMEOUT:
164*5113495bSYour Name 		return NL80211_TIMEOUT_ASSOC;
165*5113495bSYour Name 	default:
166*5113495bSYour Name 		return NL80211_TIMEOUT_UNSPECIFIED;
167*5113495bSYour Name 	}
168*5113495bSYour Name }
169*5113495bSYour Name 
170*5113495bSYour Name #if defined CFG80211_CONNECT_BSS || \
171*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
172*5113495bSYour Name 
173*5113495bSYour Name #if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
174*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
175*5113495bSYour Name /**
176*5113495bSYour Name  * osif_connect_timeout() - API to send connection timeout reason
177*5113495bSYour Name  * @dev: network device
178*5113495bSYour Name  * @bssid: bssid to which we want to associate
179*5113495bSYour Name  * @reason: reason for connect timeout
180*5113495bSYour Name  *
181*5113495bSYour Name  * This API is used to send connection timeout reason to supplicant
182*5113495bSYour Name  *
183*5113495bSYour Name  * Context: Any context.
184*5113495bSYour Name  * Return: Void
185*5113495bSYour Name  */
186*5113495bSYour Name static void
osif_connect_timeout(struct net_device * dev,const u8 * bssid,enum wlan_cm_connect_fail_reason reason)187*5113495bSYour Name osif_connect_timeout(struct net_device *dev, const u8 *bssid,
188*5113495bSYour Name 		     enum wlan_cm_connect_fail_reason reason)
189*5113495bSYour Name {
190*5113495bSYour Name 	enum nl80211_timeout_reason nl_timeout_reason;
191*5113495bSYour Name 
192*5113495bSYour Name 	nl_timeout_reason = osif_convert_timeout_reason(reason);
193*5113495bSYour Name 
194*5113495bSYour Name 	osif_debug("nl_timeout_reason %d", nl_timeout_reason);
195*5113495bSYour Name 
196*5113495bSYour Name 	cfg80211_connect_timeout(dev, bssid, NULL, 0, qdf_mem_malloc_flags(),
197*5113495bSYour Name 				 nl_timeout_reason);
198*5113495bSYour Name }
199*5113495bSYour Name 
200*5113495bSYour Name /**
201*5113495bSYour Name  * __osif_connect_bss() - API to send connection status to supplicant
202*5113495bSYour Name  * @dev: network device
203*5113495bSYour Name  * @bss: bss info
204*5113495bSYour Name  * @rsp: Connection manager connect response
205*5113495bSYour Name  * @status: 802.11 status code
206*5113495bSYour Name  *
207*5113495bSYour Name  * Context: Any context.
208*5113495bSYour Name  * Return: void
209*5113495bSYour Name  */
__osif_connect_bss(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,enum ieee80211_statuscode status)210*5113495bSYour Name static void __osif_connect_bss(struct net_device *dev,
211*5113495bSYour Name 			       struct cfg80211_bss *bss,
212*5113495bSYour Name 			       struct wlan_cm_connect_resp *rsp,
213*5113495bSYour Name 			       enum ieee80211_statuscode status)
214*5113495bSYour Name {
215*5113495bSYour Name 	enum nl80211_timeout_reason nl_timeout_reason;
216*5113495bSYour Name 	size_t req_len = 0;
217*5113495bSYour Name 	const uint8_t *req_ptr = NULL;
218*5113495bSYour Name 	size_t rsp_len = 0;
219*5113495bSYour Name 	const uint8_t *rsp_ptr = NULL;
220*5113495bSYour Name 
221*5113495bSYour Name 	nl_timeout_reason = osif_convert_timeout_reason(rsp->reason);
222*5113495bSYour Name 
223*5113495bSYour Name 	osif_debug("nl_timeout_reason %d", nl_timeout_reason);
224*5113495bSYour Name 
225*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
226*5113495bSYour Name 				      &req_len, &req_ptr);
227*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
228*5113495bSYour Name 				      &rsp_len, &rsp_ptr);
229*5113495bSYour Name 
230*5113495bSYour Name 	cfg80211_connect_bss(dev, rsp->bssid.bytes, bss,
231*5113495bSYour Name 			     req_ptr, req_len, rsp_ptr, rsp_len, status,
232*5113495bSYour Name 			     qdf_mem_malloc_flags(), nl_timeout_reason);
233*5113495bSYour Name }
234*5113495bSYour Name #else /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */
235*5113495bSYour Name 
236*5113495bSYour Name #if defined CFG80211_CONNECT_TIMEOUT || \
237*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
osif_connect_timeout(struct net_device * dev,const u8 * bssid,enum wlan_cm_connect_fail_reason reason)238*5113495bSYour Name static void osif_connect_timeout(
239*5113495bSYour Name 			struct net_device *dev,
240*5113495bSYour Name 			const u8 *bssid,
241*5113495bSYour Name 			enum wlan_cm_connect_fail_reason reason)
242*5113495bSYour Name {
243*5113495bSYour Name 	cfg80211_connect_timeout(dev, bssid, NULL, 0, qdf_mem_malloc_flags());
244*5113495bSYour Name }
245*5113495bSYour Name #endif
246*5113495bSYour Name 
__osif_connect_bss(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,ieee80211_statuscode status)247*5113495bSYour Name static void __osif_connect_bss(struct net_device *dev,
248*5113495bSYour Name 			       struct cfg80211_bss *bss,
249*5113495bSYour Name 			       struct wlan_cm_connect_resp *rsp,
250*5113495bSYour Name 			       ieee80211_statuscode status)
251*5113495bSYour Name {
252*5113495bSYour Name 	size_t req_len = 0;
253*5113495bSYour Name 	const uint8_t *req_ptr = NULL;
254*5113495bSYour Name 	size_t rsp_len = 0;
255*5113495bSYour Name 	const uint8_t *rsp_ptr = NULL;
256*5113495bSYour Name 
257*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
258*5113495bSYour Name 				      &req_len, &req_ptr);
259*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
260*5113495bSYour Name 				      &rsp_len, &rsp_ptr);
261*5113495bSYour Name 
262*5113495bSYour Name 	cfg80211_connect_bss(dev, rsp->bssid.bytes, bss,
263*5113495bSYour Name 			     req_ptr, req_len, rsp_ptr, rsp_len,
264*5113495bSYour Name 			     status, qdf_mem_malloc_flags());
265*5113495bSYour Name }
266*5113495bSYour Name #endif /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */
267*5113495bSYour Name 
268*5113495bSYour Name /**
269*5113495bSYour Name  * osif_connect_bss() - API to send connection status to supplicant
270*5113495bSYour Name  * @dev: network device
271*5113495bSYour Name  * @bss: bss info
272*5113495bSYour Name  * @rsp: Connection manager connect response
273*5113495bSYour Name  *
274*5113495bSYour Name  * The API is a wrapper to send connection status to supplicant
275*5113495bSYour Name  *
276*5113495bSYour Name  * Context: Any context.
277*5113495bSYour Name  * Return: Void
278*5113495bSYour Name  */
279*5113495bSYour Name #if defined CFG80211_CONNECT_TIMEOUT || \
280*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
osif_connect_bss(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp)281*5113495bSYour Name static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss,
282*5113495bSYour Name 			     struct wlan_cm_connect_resp *rsp)
283*5113495bSYour Name {
284*5113495bSYour Name 	enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS;
285*5113495bSYour Name 
286*5113495bSYour Name 	osif_enter_dev(dev);
287*5113495bSYour Name 
288*5113495bSYour Name 	if (rsp->reason == CM_JOIN_TIMEOUT ||
289*5113495bSYour Name 	    rsp->reason == CM_AUTH_TIMEOUT ||
290*5113495bSYour Name 	    rsp->reason == CM_ASSOC_TIMEOUT) {
291*5113495bSYour Name 		osif_connect_timeout(dev, rsp->bssid.bytes,
292*5113495bSYour Name 				     rsp->reason);
293*5113495bSYour Name 	} else {
294*5113495bSYour Name 		status = osif_get_connect_status_code(rsp);
295*5113495bSYour Name 
296*5113495bSYour Name 		__osif_connect_bss(dev, bss, rsp, status);
297*5113495bSYour Name 	}
298*5113495bSYour Name }
299*5113495bSYour Name #else /* CFG80211_CONNECT_TIMEOUT */
osif_connect_bss(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp)300*5113495bSYour Name static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss,
301*5113495bSYour Name 			     struct wlan_cm_connect_resp *rsp)
302*5113495bSYour Name {
303*5113495bSYour Name 	enum ieee80211_statuscode status;
304*5113495bSYour Name 
305*5113495bSYour Name 	osif_enter_dev(dev);
306*5113495bSYour Name 
307*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
308*5113495bSYour Name 	__osif_connect_bss(dev, bss, rsp, status);
309*5113495bSYour Name }
310*5113495bSYour Name #endif /* CFG80211_CONNECT_TIMEOUT */
311*5113495bSYour Name 
312*5113495bSYour Name #if defined(CFG80211_CONNECT_DONE) || \
313*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
314*5113495bSYour Name 
315*5113495bSYour Name #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
316*5113495bSYour Name 
317*5113495bSYour Name #if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
318*5113495bSYour Name /**
319*5113495bSYour Name  * osif_populate_fils_params() - Populate FILS keys to connect response
320*5113495bSYour Name  * @rsp_params: connect response to supplicant
321*5113495bSYour Name  * @connect_ies: Connect response IEs
322*5113495bSYour Name  *
323*5113495bSYour Name  * Context: Any context.
324*5113495bSYour Name  * Return: None
325*5113495bSYour Name  */
326*5113495bSYour Name static void
osif_populate_fils_params(struct cfg80211_connect_resp_params * rsp_params,struct wlan_connect_rsp_ies * connect_ies)327*5113495bSYour Name osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
328*5113495bSYour Name 			  struct wlan_connect_rsp_ies *connect_ies)
329*5113495bSYour Name {
330*5113495bSYour Name 	if (!connect_ies->fils_ie)
331*5113495bSYour Name 		return;
332*5113495bSYour Name 
333*5113495bSYour Name 	/*  Increment seq number to be used for next FILS */
334*5113495bSYour Name 	rsp_params->fils_erp_next_seq_num =
335*5113495bSYour Name 				connect_ies->fils_ie->fils_seq_num + 1;
336*5113495bSYour Name 	rsp_params->update_erp_next_seq_num = true;
337*5113495bSYour Name 	rsp_params->fils_kek = connect_ies->fils_ie->kek;
338*5113495bSYour Name 	rsp_params->fils_kek_len = connect_ies->fils_ie->kek_len;
339*5113495bSYour Name 	rsp_params->pmk = connect_ies->fils_ie->fils_pmk;
340*5113495bSYour Name 	rsp_params->pmk_len = connect_ies->fils_ie->fils_pmk_len;
341*5113495bSYour Name 	rsp_params->pmkid = connect_ies->fils_ie->fils_pmkid;
342*5113495bSYour Name 	osif_debug("erp_next_seq_num:%d", rsp_params->fils_erp_next_seq_num);
343*5113495bSYour Name }
344*5113495bSYour Name #else /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */
345*5113495bSYour Name static inline void
osif_populate_fils_params(struct cfg80211_connect_resp_params * rsp_params,struct wlan_connect_rsp_ies * connect_ies)346*5113495bSYour Name osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
347*5113495bSYour Name 			  struct wlan_connect_rsp_ies *connect_ies)
348*5113495bSYour Name { }
349*5113495bSYour Name #endif /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */
350*5113495bSYour Name 
351*5113495bSYour Name #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
352*5113495bSYour Name #if defined(WLAN_FEATURE_FILS_SK)
353*5113495bSYour Name /**
354*5113495bSYour Name  * osif_populate_fils_params() - Populate FILS keys to connect response
355*5113495bSYour Name  * @rsp_params: connect response to supplicant
356*5113495bSYour Name  * @connect_ies: Connect response IEs
357*5113495bSYour Name  *
358*5113495bSYour Name  * Context: Any context.
359*5113495bSYour Name  * Return: None
360*5113495bSYour Name  */
361*5113495bSYour Name static void
osif_populate_fils_params(struct cfg80211_connect_resp_params * rsp_params,struct wlan_connect_rsp_ies * connect_ies)362*5113495bSYour Name osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
363*5113495bSYour Name 			  struct wlan_connect_rsp_ies *connect_ies)
364*5113495bSYour Name 
365*5113495bSYour Name {
366*5113495bSYour Name 	if (!connect_ies->fils_ie)
367*5113495bSYour Name 		return;
368*5113495bSYour Name 
369*5113495bSYour Name 	/* Increment seq number to be used for next FILS */
370*5113495bSYour Name 	rsp_params->fils.erp_next_seq_num =
371*5113495bSYour Name 					connect_ies->fils_ie->fils_seq_num + 1;
372*5113495bSYour Name 	rsp_params->fils.update_erp_next_seq_num = true;
373*5113495bSYour Name 	rsp_params->fils.kek = connect_ies->fils_ie->kek;
374*5113495bSYour Name 	rsp_params->fils.kek_len = connect_ies->fils_ie->kek_len;
375*5113495bSYour Name 	rsp_params->fils.pmk = connect_ies->fils_ie->fils_pmk;
376*5113495bSYour Name 	rsp_params->fils.pmk_len = connect_ies->fils_ie->fils_pmk_len;
377*5113495bSYour Name 	rsp_params->fils.pmkid = connect_ies->fils_ie->fils_pmkid;
378*5113495bSYour Name 	osif_debug("erp_next_seq_num:%d", rsp_params->fils.erp_next_seq_num);
379*5113495bSYour Name }
380*5113495bSYour Name #else /* WLAN_FEATURE_FILS_SK */
381*5113495bSYour Name static inline void
osif_populate_fils_params(struct cfg80211_connect_resp_params * rsp_params,struct wlan_connect_rsp_ies * connect_ies)382*5113495bSYour Name osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
383*5113495bSYour Name 			  struct wlan_connect_rsp_ies *connect_ies)
384*5113495bSYour Name { }
385*5113495bSYour Name #endif /* WLAN_FEATURE_FILS_SK */
386*5113495bSYour Name #endif
387*5113495bSYour Name 
388*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
389*5113495bSYour Name QDF_STATUS
osif_get_partner_info_from_mlie(struct wlan_cm_connect_resp * connect_rsp,struct mlo_partner_info * partner_info)390*5113495bSYour Name osif_get_partner_info_from_mlie(struct wlan_cm_connect_resp *connect_rsp,
391*5113495bSYour Name 				struct mlo_partner_info *partner_info)
392*5113495bSYour Name {
393*5113495bSYour Name 	qdf_size_t connect_resp_len = 0, ml_ie_len = 0;
394*5113495bSYour Name 	const uint8_t *connect_resp_ptr = NULL;
395*5113495bSYour Name 	QDF_STATUS qdf_status;
396*5113495bSYour Name 	uint8_t *ml_ie = NULL;
397*5113495bSYour Name 
398*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&connect_rsp->connect_ies.assoc_rsp,
399*5113495bSYour Name 				      &connect_resp_len, &connect_resp_ptr);
400*5113495bSYour Name 
401*5113495bSYour Name 	if (!connect_resp_len) {
402*5113495bSYour Name 		osif_err("Connect response is null return error");
403*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
404*5113495bSYour Name 	}
405*5113495bSYour Name 
406*5113495bSYour Name 	qdf_status = util_find_mlie((uint8_t *)connect_resp_ptr,
407*5113495bSYour Name 				    connect_resp_len, &ml_ie, &ml_ie_len);
408*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status) || !ml_ie) {
409*5113495bSYour Name 		osif_debug("ML IE not found %d", qdf_status);
410*5113495bSYour Name 		return qdf_status;
411*5113495bSYour Name 	}
412*5113495bSYour Name 
413*5113495bSYour Name 	osif_debug("ML IE found length %d", (int)ml_ie_len);
414*5113495bSYour Name 
415*5113495bSYour Name 	qdf_status = util_get_bvmlie_persta_partner_info(ml_ie, ml_ie_len,
416*5113495bSYour Name 							 partner_info);
417*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
418*5113495bSYour Name 		osif_err("Unable to find per-sta profile in ML IE");
419*5113495bSYour Name 		return qdf_status;
420*5113495bSYour Name 	}
421*5113495bSYour Name 
422*5113495bSYour Name 	return qdf_status;
423*5113495bSYour Name }
424*5113495bSYour Name 
425*5113495bSYour Name QDF_STATUS
osif_get_link_id_from_assoc_ml_ie(struct mlo_link_info * rsp_link_info,struct mlo_partner_info * assoc_partner_info,uint8_t * link_id)426*5113495bSYour Name osif_get_link_id_from_assoc_ml_ie(struct mlo_link_info *rsp_link_info,
427*5113495bSYour Name 				  struct mlo_partner_info *assoc_partner_info,
428*5113495bSYour Name 				  uint8_t *link_id)
429*5113495bSYour Name {
430*5113495bSYour Name 	int j;
431*5113495bSYour Name 
432*5113495bSYour Name 	for (j = 0; j < assoc_partner_info->num_partner_links; j++) {
433*5113495bSYour Name 		if (!qdf_mem_cmp(rsp_link_info->link_addr.bytes,
434*5113495bSYour Name 				 assoc_partner_info->partner_link_info[j].link_addr.bytes,
435*5113495bSYour Name 				 QDF_MAC_ADDR_SIZE)) {
436*5113495bSYour Name 			*link_id = assoc_partner_info->partner_link_info[j].link_id;
437*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
438*5113495bSYour Name 		}
439*5113495bSYour Name 	}
440*5113495bSYour Name 
441*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
442*5113495bSYour Name }
443*5113495bSYour Name 
444*5113495bSYour Name struct cfg80211_bss *
osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev * vdev,struct mlo_link_info * rsp_link_info,struct wlan_cm_connect_resp * rsp)445*5113495bSYour Name osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
446*5113495bSYour Name 			      struct mlo_link_info *rsp_link_info,
447*5113495bSYour Name 			      struct wlan_cm_connect_resp *rsp)
448*5113495bSYour Name {
449*5113495bSYour Name 	struct vdev_osif_priv *osif_priv;
450*5113495bSYour Name 	struct cfg80211_bss *partner_bss;
451*5113495bSYour Name 	struct ieee80211_channel *chan;
452*5113495bSYour Name 
453*5113495bSYour Name 	osif_priv = wlan_vdev_get_ospriv(vdev);
454*5113495bSYour Name 	chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
455*5113495bSYour Name 				     rsp_link_info->chan_freq);
456*5113495bSYour Name 	if (!chan) {
457*5113495bSYour Name 		osif_err("Invalid partner channel");
458*5113495bSYour Name 		return NULL;
459*5113495bSYour Name 	}
460*5113495bSYour Name 
461*5113495bSYour Name 	partner_bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
462*5113495bSYour Name 					    rsp_link_info->link_addr.bytes,
463*5113495bSYour Name 					    rsp->ssid.ssid, rsp->ssid.length);
464*5113495bSYour Name 	if (!partner_bss) {
465*5113495bSYour Name 		osif_err("could not fetch partner bss from kernel vdev id %d freq %d ssid:" QDF_SSID_FMT " and BSSID " QDF_MAC_ADDR_FMT,
466*5113495bSYour Name 			 wlan_vdev_get_id(vdev), rsp_link_info->chan_freq,
467*5113495bSYour Name 			 QDF_SSID_REF(rsp->ssid.length, rsp->ssid.ssid),
468*5113495bSYour Name 			 QDF_MAC_ADDR_REF(rsp->bssid.bytes));
469*5113495bSYour Name 		return NULL;
470*5113495bSYour Name 	}
471*5113495bSYour Name 
472*5113495bSYour Name 	return partner_bss;
473*5113495bSYour Name }
474*5113495bSYour Name #endif
475*5113495bSYour Name 
476*5113495bSYour Name #if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
477*5113495bSYour Name #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
osif_get_partner_vdev(struct wlan_objmgr_vdev * vdev,struct mlo_link_info rsp_partner_info,wlan_objmgr_ref_dbgid id)478*5113495bSYour Name static struct wlan_objmgr_vdev *osif_get_partner_vdev(
479*5113495bSYour Name 					struct wlan_objmgr_vdev *vdev,
480*5113495bSYour Name 					struct mlo_link_info rsp_partner_info,
481*5113495bSYour Name 					wlan_objmgr_ref_dbgid id)
482*5113495bSYour Name {
483*5113495bSYour Name 	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id, id);
484*5113495bSYour Name }
485*5113495bSYour Name #endif
486*5113495bSYour Name 
487*5113495bSYour Name static
osif_populate_connect_response_for_link(struct wlan_objmgr_vdev * vdev,struct cfg80211_connect_resp_params * conn_rsp_params,uint8_t link_id,uint8_t * link_addr,struct cfg80211_bss * bss)488*5113495bSYour Name void osif_populate_connect_response_for_link(struct wlan_objmgr_vdev *vdev,
489*5113495bSYour Name 					     struct cfg80211_connect_resp_params *conn_rsp_params,
490*5113495bSYour Name 					     uint8_t link_id,
491*5113495bSYour Name 					     uint8_t *link_addr,
492*5113495bSYour Name 					     struct cfg80211_bss *bss)
493*5113495bSYour Name {
494*5113495bSYour Name 	if (bss) {
495*5113495bSYour Name 		osif_debug("Link_id :%d", link_id);
496*5113495bSYour Name 		conn_rsp_params->valid_links |=  BIT(link_id);
497*5113495bSYour Name 		conn_rsp_params->links[link_id].bssid = bss->bssid;
498*5113495bSYour Name 		conn_rsp_params->links[link_id].bss = bss;
499*5113495bSYour Name 		conn_rsp_params->links[link_id].addr = link_addr;
500*5113495bSYour Name 	}
501*5113495bSYour Name 
502*5113495bSYour Name 	mlo_mgr_osif_update_connect_info(vdev, link_id);
503*5113495bSYour Name }
504*5113495bSYour Name 
505*5113495bSYour Name static QDF_STATUS
osif_fill_peer_mld_mac_connect_resp(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_connect_resp_params * conn_rsp_params)506*5113495bSYour Name osif_fill_peer_mld_mac_connect_resp(struct wlan_objmgr_vdev *vdev,
507*5113495bSYour Name 				    struct wlan_cm_connect_resp *rsp,
508*5113495bSYour Name 				    struct cfg80211_connect_resp_params *conn_rsp_params)
509*5113495bSYour Name {
510*5113495bSYour Name 	struct wlan_objmgr_peer *peer_obj;
511*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
512*5113495bSYour Name 
513*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
514*5113495bSYour Name 	if (!psoc)
515*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
516*5113495bSYour Name 
517*5113495bSYour Name 	peer_obj = wlan_objmgr_get_peer_by_mac(psoc, rsp->bssid.bytes,
518*5113495bSYour Name 					       WLAN_OSIF_ID);
519*5113495bSYour Name 	if (!peer_obj)
520*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
521*5113495bSYour Name 
522*5113495bSYour Name 	conn_rsp_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
523*5113495bSYour Name 
524*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
525*5113495bSYour Name 
526*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
527*5113495bSYour Name }
528*5113495bSYour Name 
529*5113495bSYour Name static void
osif_populate_partner_links_mlo_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_connect_resp_params * conn_rsp_params)530*5113495bSYour Name osif_populate_partner_links_mlo_params(struct wlan_objmgr_vdev *vdev,
531*5113495bSYour Name 				       struct wlan_cm_connect_resp *rsp,
532*5113495bSYour Name 				       struct cfg80211_connect_resp_params *conn_rsp_params)
533*5113495bSYour Name {
534*5113495bSYour Name 	struct mlo_link_info *rsp_partner_info;
535*5113495bSYour Name 	struct cfg80211_bss *bss = NULL;
536*5113495bSYour Name 	uint8_t link_id = 0, num_links;
537*5113495bSYour Name 	int i;
538*5113495bSYour Name 	struct mlo_link_info *link_info;
539*5113495bSYour Name 
540*5113495bSYour Name 	num_links = rsp->ml_parnter_info.num_partner_links;
541*5113495bSYour Name 	for (i = 0 ; i < num_links; i++) {
542*5113495bSYour Name 		rsp_partner_info = &rsp->ml_parnter_info.partner_link_info[i];
543*5113495bSYour Name 		link_id = rsp_partner_info->link_id;
544*5113495bSYour Name 
545*5113495bSYour Name 		link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx,
546*5113495bSYour Name 							   link_id);
547*5113495bSYour Name 		if (!link_info)
548*5113495bSYour Name 			continue;
549*5113495bSYour Name 
550*5113495bSYour Name 		bss = osif_get_chan_bss_from_kernel(vdev, rsp_partner_info,
551*5113495bSYour Name 						    rsp);
552*5113495bSYour Name 
553*5113495bSYour Name 		osif_populate_connect_response_for_link(vdev, conn_rsp_params,
554*5113495bSYour Name 							link_id,
555*5113495bSYour Name 							link_info->link_addr.bytes,
556*5113495bSYour Name 							bss);
557*5113495bSYour Name 	}
558*5113495bSYour Name }
559*5113495bSYour Name 
osif_fill_connect_resp_mlo_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct cfg80211_connect_resp_params * conn_rsp_params)560*5113495bSYour Name static void osif_fill_connect_resp_mlo_params(struct wlan_objmgr_vdev *vdev,
561*5113495bSYour Name 					      struct wlan_cm_connect_resp *rsp,
562*5113495bSYour Name 					      struct cfg80211_bss *bss,
563*5113495bSYour Name 					      struct cfg80211_connect_resp_params *conn_rsp_params)
564*5113495bSYour Name {
565*5113495bSYour Name 	uint8_t assoc_link_id;
566*5113495bSYour Name 	QDF_STATUS qdf_status;
567*5113495bSYour Name 	struct mlo_link_info *link_info = NULL;
568*5113495bSYour Name 
569*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
570*5113495bSYour Name 		return;
571*5113495bSYour Name 
572*5113495bSYour Name 	qdf_status = osif_fill_peer_mld_mac_connect_resp(vdev, rsp,
573*5113495bSYour Name 							 conn_rsp_params);
574*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
575*5113495bSYour Name 		osif_err("Unable to fill peer mld address: %d", qdf_status);
576*5113495bSYour Name 		return;
577*5113495bSYour Name 	}
578*5113495bSYour Name 
579*5113495bSYour Name 	assoc_link_id = wlan_vdev_get_link_id(vdev);
580*5113495bSYour Name 	link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx,
581*5113495bSYour Name 						   assoc_link_id);
582*5113495bSYour Name 	if (!link_info) {
583*5113495bSYour Name 		osif_err("Unable to find link_info for link_id: %d",
584*5113495bSYour Name 			 assoc_link_id);
585*5113495bSYour Name 		return;
586*5113495bSYour Name 	}
587*5113495bSYour Name 
588*5113495bSYour Name 	osif_populate_connect_response_for_link(vdev, conn_rsp_params,
589*5113495bSYour Name 						assoc_link_id,
590*5113495bSYour Name 						link_info->link_addr.bytes,
591*5113495bSYour Name 						bss);
592*5113495bSYour Name 	osif_populate_partner_links_mlo_params(vdev, rsp, conn_rsp_params);
593*5113495bSYour Name }
594*5113495bSYour Name 
595*5113495bSYour Name static void
osif_free_ml_link_params(struct cfg80211_connect_resp_params * conn_rsp_params)596*5113495bSYour Name osif_free_ml_link_params(struct cfg80211_connect_resp_params *conn_rsp_params)
597*5113495bSYour Name {
598*5113495bSYour Name }
599*5113495bSYour Name #elif defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
600*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
osif_get_partner_vdev(struct wlan_objmgr_vdev * vdev,struct mlo_link_info rsp_partner_info,wlan_objmgr_ref_dbgid id)601*5113495bSYour Name static struct wlan_objmgr_vdev *osif_get_partner_vdev(
602*5113495bSYour Name 					struct wlan_objmgr_vdev *vdev,
603*5113495bSYour Name 					struct mlo_link_info rsp_partner_info,
604*5113495bSYour Name 					wlan_objmgr_ref_dbgid id)
605*5113495bSYour Name {
606*5113495bSYour Name 	return wlan_objmgr_get_vdev_by_id_from_pdev(
607*5113495bSYour Name 						vdev->vdev_objmgr.wlan_pdev,
608*5113495bSYour Name 						rsp_partner_info.vdev_id, id);
609*5113495bSYour Name }
610*5113495bSYour Name #else
osif_get_partner_vdev(struct wlan_objmgr_vdev * vdev,struct mlo_link_info rsp_partner_info,wlan_objmgr_ref_dbgid id)611*5113495bSYour Name static struct wlan_objmgr_vdev *osif_get_partner_vdev(
612*5113495bSYour Name 					struct wlan_objmgr_vdev *vdev,
613*5113495bSYour Name 					struct mlo_link_info rsp_partner_info,
614*5113495bSYour Name 					wlan_objmgr_ref_dbgid id)
615*5113495bSYour Name {
616*5113495bSYour Name 	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id, id);
617*5113495bSYour Name }
618*5113495bSYour Name #endif
osif_fill_connect_resp_mlo_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct cfg80211_connect_resp_params * conn_rsp_params)619*5113495bSYour Name static void osif_fill_connect_resp_mlo_params(
620*5113495bSYour Name 			struct wlan_objmgr_vdev *vdev,
621*5113495bSYour Name 			struct wlan_cm_connect_resp *rsp,
622*5113495bSYour Name 			struct cfg80211_bss *bss,
623*5113495bSYour Name 			struct cfg80211_connect_resp_params *conn_rsp_params)
624*5113495bSYour Name {
625*5113495bSYour Name 	uint8_t i, num_mlo_links = rsp->ml_parnter_info.num_partner_links + 1;
626*5113495bSYour Name 	struct wlan_objmgr_vdev *ml_vdev = vdev;
627*5113495bSYour Name 	struct vdev_osif_priv *osif_priv;
628*5113495bSYour Name 	struct ieee80211_channel *chan;
629*5113495bSYour Name 	struct cfg80211_mlo_link_params *ml_link_params;
630*5113495bSYour Name 	struct mlo_link_info *rsp_partner_info;
631*5113495bSYour Name 
632*5113495bSYour Name 	if (num_mlo_links == 1)
633*5113495bSYour Name 		return;
634*5113495bSYour Name 
635*5113495bSYour Name 	ml_link_params = qdf_mem_malloc(
636*5113495bSYour Name 				num_mlo_links * sizeof(*ml_link_params));
637*5113495bSYour Name 	if (!ml_link_params)
638*5113495bSYour Name 		return;
639*5113495bSYour Name 
640*5113495bSYour Name 	rsp_partner_info = rsp->ml_parnter_info.partner_link_info;
641*5113495bSYour Name 	if (rsp->ml_parnter_info.num_partner_links) {
642*5113495bSYour Name 		conn_rsp_params->n_mlo_links = num_mlo_links;
643*5113495bSYour Name 		osif_priv = wlan_vdev_get_ospriv(ml_vdev);
644*5113495bSYour Name 		for (i = 0; i < conn_rsp_params->n_mlo_links; i++) {
645*5113495bSYour Name 			ml_link_params[i].wdev = osif_priv->wdev;
646*5113495bSYour Name 
647*5113495bSYour Name 			if (i != 0) {
648*5113495bSYour Name 				chan = ieee80211_get_channel(
649*5113495bSYour Name 					   osif_priv->wdev->wiphy,
650*5113495bSYour Name 					   rsp_partner_info[i - 1].chan_freq);
651*5113495bSYour Name 				if (!chan) {
652*5113495bSYour Name 					osif_err("Invalid partner channel");
653*5113495bSYour Name 					goto end;
654*5113495bSYour Name 				}
655*5113495bSYour Name 
656*5113495bSYour Name 				bss = wlan_cfg80211_get_bss(
657*5113495bSYour Name 					osif_priv->wdev->wiphy, chan,
658*5113495bSYour Name 					rsp_partner_info[i - 1].link_addr.bytes,
659*5113495bSYour Name 					rsp->ssid.ssid, rsp->ssid.length);
660*5113495bSYour Name 				if (!bss) {
661*5113495bSYour Name 					osif_err("Partner bss is null");
662*5113495bSYour Name 					goto end;
663*5113495bSYour Name 				}
664*5113495bSYour Name 			}
665*5113495bSYour Name 			qdf_mem_copy(ml_link_params[i].bssid, bss->bssid,
666*5113495bSYour Name 				     QDF_MAC_ADDR_SIZE);
667*5113495bSYour Name 
668*5113495bSYour Name 			if (i == rsp->ml_parnter_info.num_partner_links)
669*5113495bSYour Name 				break;
670*5113495bSYour Name 
671*5113495bSYour Name 			ml_vdev = osif_get_partner_vdev(vdev,
672*5113495bSYour Name 							rsp_partner_info[i],
673*5113495bSYour Name 							WLAN_OSIF_CM_ID);
674*5113495bSYour Name 
675*5113495bSYour Name 			if (ml_vdev) {
676*5113495bSYour Name 				osif_priv = wlan_vdev_get_ospriv(ml_vdev);
677*5113495bSYour Name 				wlan_objmgr_vdev_release_ref(ml_vdev,
678*5113495bSYour Name 							     WLAN_OSIF_CM_ID);
679*5113495bSYour Name 			} else {
680*5113495bSYour Name 				osif_err("Partner vdev not found with vdev_id:%d",
681*5113495bSYour Name 					 rsp_partner_info[i].vdev_id);
682*5113495bSYour Name 				goto end;
683*5113495bSYour Name 			}
684*5113495bSYour Name 		}
685*5113495bSYour Name 	}
686*5113495bSYour Name end:
687*5113495bSYour Name 	conn_rsp_params->mlo_links = ml_link_params;
688*5113495bSYour Name }
689*5113495bSYour Name 
690*5113495bSYour Name static void
osif_free_ml_link_params(struct cfg80211_connect_resp_params * conn_rsp_params)691*5113495bSYour Name osif_free_ml_link_params(struct cfg80211_connect_resp_params *conn_rsp_params)
692*5113495bSYour Name {
693*5113495bSYour Name 	struct cfg80211_mlo_link_params *ml_links;
694*5113495bSYour Name 
695*5113495bSYour Name 	ml_links =
696*5113495bSYour Name 		(struct cfg80211_mlo_link_params *)conn_rsp_params->mlo_links;
697*5113495bSYour Name 	if (ml_links)
698*5113495bSYour Name 		qdf_mem_free(ml_links);
699*5113495bSYour Name }
700*5113495bSYour Name 
701*5113495bSYour Name #else
osif_fill_connect_resp_mlo_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct cfg80211_connect_resp_params * conn_rsp_params)702*5113495bSYour Name static void osif_fill_connect_resp_mlo_params(
703*5113495bSYour Name 			struct wlan_objmgr_vdev *vdev,
704*5113495bSYour Name 			struct wlan_cm_connect_resp *rsp,
705*5113495bSYour Name 			struct cfg80211_bss *bss,
706*5113495bSYour Name 			struct cfg80211_connect_resp_params *conn_rsp_params)
707*5113495bSYour Name {
708*5113495bSYour Name }
709*5113495bSYour Name 
710*5113495bSYour Name static void
osif_free_ml_link_params(struct cfg80211_connect_resp_params * conn_rsp_params)711*5113495bSYour Name osif_free_ml_link_params(struct cfg80211_connect_resp_params *conn_rsp_params)
712*5113495bSYour Name {
713*5113495bSYour Name }
714*5113495bSYour Name #endif
715*5113495bSYour Name 
716*5113495bSYour Name #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
717*5113495bSYour Name static
osif_copy_connected_info(struct cfg80211_connect_resp_params * conn_rsp,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct wlan_objmgr_vdev * vdev)718*5113495bSYour Name void osif_copy_connected_info(struct cfg80211_connect_resp_params *conn_rsp,
719*5113495bSYour Name 			      struct wlan_cm_connect_resp *rsp,
720*5113495bSYour Name 			      struct cfg80211_bss *bss,
721*5113495bSYour Name 			      struct wlan_objmgr_vdev *vdev)
722*5113495bSYour Name {
723*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
724*5113495bSYour Name 		qdf_debug("MLO vdev fill everything in mlo fill params");
725*5113495bSYour Name 		return;
726*5113495bSYour Name 	}
727*5113495bSYour Name 
728*5113495bSYour Name 	conn_rsp->links[0].bssid = rsp->bssid.bytes;
729*5113495bSYour Name 	conn_rsp->links[0].bss = bss;
730*5113495bSYour Name }
731*5113495bSYour Name #else
732*5113495bSYour Name static
osif_copy_connected_info(struct cfg80211_connect_resp_params * conn_rsp,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct wlan_objmgr_vdev * vdev)733*5113495bSYour Name void osif_copy_connected_info(struct cfg80211_connect_resp_params *conn_rsp,
734*5113495bSYour Name 			      struct wlan_cm_connect_resp *rsp,
735*5113495bSYour Name 			      struct cfg80211_bss *bss,
736*5113495bSYour Name 			      struct wlan_objmgr_vdev *vdev)
737*5113495bSYour Name {
738*5113495bSYour Name 	conn_rsp->bssid = rsp->bssid.bytes;
739*5113495bSYour Name 	conn_rsp->bss = bss;
740*5113495bSYour Name }
741*5113495bSYour Name #endif
742*5113495bSYour Name 
743*5113495bSYour Name /**
744*5113495bSYour Name  * osif_connect_done() - Wrapper API to call cfg80211_connect_done
745*5113495bSYour Name  * @dev: network device
746*5113495bSYour Name  * @bss: bss info
747*5113495bSYour Name  * @rsp: Connection manager connect response
748*5113495bSYour Name  * @vdev: pointer to vdev
749*5113495bSYour Name  *
750*5113495bSYour Name  * This API is used as wrapper to send connect status and params to
751*5113495bSYour Name  * supplicant.
752*5113495bSYour Name  *
753*5113495bSYour Name  * Context: Any context.
754*5113495bSYour Name  * Return: 0 if success. Error code for failure
755*5113495bSYour Name  */
osif_connect_done(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,struct wlan_objmgr_vdev * vdev)756*5113495bSYour Name static int osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss,
757*5113495bSYour Name 			     struct wlan_cm_connect_resp *rsp,
758*5113495bSYour Name 			     struct wlan_objmgr_vdev *vdev)
759*5113495bSYour Name {
760*5113495bSYour Name 	struct cfg80211_connect_resp_params conn_rsp_params;
761*5113495bSYour Name 	enum ieee80211_statuscode status;
762*5113495bSYour Name 
763*5113495bSYour Name 	osif_enter_dev(dev);
764*5113495bSYour Name 
765*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
766*5113495bSYour Name 	qdf_mem_zero(&conn_rsp_params, sizeof(conn_rsp_params));
767*5113495bSYour Name 
768*5113495bSYour Name 	conn_rsp_params.status = status;
769*5113495bSYour Name 	osif_copy_connected_info(&conn_rsp_params, rsp, bss, vdev);
770*5113495bSYour Name 	conn_rsp_params.timeout_reason =
771*5113495bSYour Name 			osif_convert_timeout_reason(rsp->reason);
772*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
773*5113495bSYour Name 				      &conn_rsp_params.req_ie_len,
774*5113495bSYour Name 				      &conn_rsp_params.req_ie);
775*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
776*5113495bSYour Name 				      &conn_rsp_params.resp_ie_len,
777*5113495bSYour Name 				      &conn_rsp_params.resp_ie);
778*5113495bSYour Name 	osif_populate_fils_params(&conn_rsp_params, &rsp->connect_ies);
779*5113495bSYour Name 	osif_cm_save_gtk(vdev, rsp);
780*5113495bSYour Name 
781*5113495bSYour Name 	if (status == WLAN_STATUS_SUCCESS)
782*5113495bSYour Name 		osif_fill_connect_resp_mlo_params(vdev, rsp, bss,
783*5113495bSYour Name 						  &conn_rsp_params);
784*5113495bSYour Name 
785*5113495bSYour Name 	osif_debug("Connect resp status  %d", conn_rsp_params.status);
786*5113495bSYour Name 
787*5113495bSYour Name 	cfg80211_connect_done(dev, &conn_rsp_params, qdf_mem_malloc_flags());
788*5113495bSYour Name 	osif_cm_set_hlp_data(dev, vdev, rsp);
789*5113495bSYour Name 
790*5113495bSYour Name 	osif_free_ml_link_params(&conn_rsp_params);
791*5113495bSYour Name 
792*5113495bSYour Name 	return 0;
793*5113495bSYour Name }
794*5113495bSYour Name #else /* CFG80211_CONNECT_DONE */
795*5113495bSYour Name static inline int
osif_connect_done(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,struct wlan_objmgr_vdev * vdev)796*5113495bSYour Name osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss,
797*5113495bSYour Name 		  struct wlan_cm_connect_resp *rsp,
798*5113495bSYour Name 		  struct wlan_objmgr_vdev *vdev)
799*5113495bSYour Name {
800*5113495bSYour Name 	return -EINVAL;
801*5113495bSYour Name }
802*5113495bSYour Name #endif
803*5113495bSYour Name 
804*5113495bSYour Name #if (defined(CFG80211_CONNECT_DONE) || \
805*5113495bSYour Name 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
806*5113495bSYour Name /**
807*5113495bSYour Name  * osif_update_connect_results() - API to send connection status to
808*5113495bSYour Name  * supplicant.
809*5113495bSYour Name  * @dev: network device
810*5113495bSYour Name  * @bss: bss info
811*5113495bSYour Name  * @rsp: Connection manager connect response
812*5113495bSYour Name  * @vdev: pointer to vdev
813*5113495bSYour Name  *
814*5113495bSYour Name  * The API is a wrapper to send connection status to supplicant
815*5113495bSYour Name  *
816*5113495bSYour Name  * Context: Any context.
817*5113495bSYour Name  * Return: 0 if success else failure
818*5113495bSYour Name  */
osif_update_connect_results(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,struct wlan_objmgr_vdev * vdev)819*5113495bSYour Name static int osif_update_connect_results(struct net_device *dev,
820*5113495bSYour Name 				       struct cfg80211_bss *bss,
821*5113495bSYour Name 				       struct wlan_cm_connect_resp *rsp,
822*5113495bSYour Name 				       struct wlan_objmgr_vdev *vdev)
823*5113495bSYour Name {
824*5113495bSYour Name 	return osif_connect_done(dev, bss, rsp, vdev);
825*5113495bSYour Name }
826*5113495bSYour Name #else /* CFG80211_CONNECT_DONE */
827*5113495bSYour Name 
osif_update_connect_results(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,struct wlan_objmgr_vdev * vdev)828*5113495bSYour Name static inline int osif_update_connect_results(struct net_device *dev,
829*5113495bSYour Name 					      struct cfg80211_bss *bss,
830*5113495bSYour Name 					      struct wlan_cm_connect_resp *rsp,
831*5113495bSYour Name 					      struct wlan_objmgr_vdev *vdev)
832*5113495bSYour Name {
833*5113495bSYour Name 	return -EINVAL;
834*5113495bSYour Name }
835*5113495bSYour Name #endif /* CFG80211_CONNECT_DONE */
836*5113495bSYour Name 
837*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
838*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)839*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
840*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
841*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
842*5113495bSYour Name {
843*5113495bSYour Name 	struct cfg80211_bss *bss = NULL;
844*5113495bSYour Name 	struct ieee80211_channel *chan;
845*5113495bSYour Name 	int32_t akm;
846*5113495bSYour Name 
847*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
848*5113495bSYour Name 		chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
849*5113495bSYour Name 					     rsp->freq);
850*5113495bSYour Name 		bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
851*5113495bSYour Name 					    rsp->bssid.bytes,
852*5113495bSYour Name 					    rsp->ssid.ssid,
853*5113495bSYour Name 					    rsp->ssid.length);
854*5113495bSYour Name 	}
855*5113495bSYour Name 
856*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
857*5113495bSYour Name 		if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
858*5113495bSYour Name 						rsp, vdev))
859*5113495bSYour Name 			osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
860*5113495bSYour Name 		return;
861*5113495bSYour Name 	}
862*5113495bSYour Name 
863*5113495bSYour Name 	akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
864*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
865*5113495bSYour Name 		if (osif_update_connect_results(
866*5113495bSYour Name 				osif_priv->wdev->netdev, bss,
867*5113495bSYour Name 				rsp, vdev))
868*5113495bSYour Name 			osif_connect_bss(osif_priv->wdev->netdev,
869*5113495bSYour Name 					 bss, rsp);
870*5113495bSYour Name 	} else if (osif_get_connect_status_code(rsp) == WLAN_STATUS_SUCCESS &&
871*5113495bSYour Name 		   QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE)) {
872*5113495bSYour Name 		/*
873*5113495bSYour Name 		 * For OWE roaming, link vdev is disconnected on receiving
874*5113495bSYour Name 		 * roam synch indication. As part of the disconnect osif link
875*5113495bSYour Name 		 * info will be cleared and connect request is prepared from
876*5113495bSYour Name 		 * mlo roam module.
877*5113495bSYour Name 		 * So update OSIF Link info for that case here.
878*5113495bSYour Name 		 */
879*5113495bSYour Name 		mlo_mgr_osif_update_connect_info(vdev,
880*5113495bSYour Name 						 wlan_vdev_get_link_id(vdev));
881*5113495bSYour Name 	}
882*5113495bSYour Name 
883*5113495bSYour Name }
884*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
885*5113495bSYour Name 
886*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 213)) && \
887*5113495bSYour Name 	(LINUX_VERSION_CODE < KERNEL_VERSION(6, 0, 0))
888*5113495bSYour Name /**
889*5113495bSYour Name  * osif_update_current_bss() - Wrapper API to call cfg80211_update_current_bss
890*5113495bSYour Name  * @dev: network device
891*5113495bSYour Name  * @bss: bss info
892*5113495bSYour Name  * @rsp: Connection manager connect response
893*5113495bSYour Name  * @vdev: pointer to vdev
894*5113495bSYour Name  *
895*5113495bSYour Name  * This API is used as wrapper to update the current bss param of non-assoc link
896*5113495bSYour Name  * sta vdev.
897*5113495bSYour Name  *
898*5113495bSYour Name  * Context: Any context.
899*5113495bSYour Name  * Return: QDF_STATUS.
900*5113495bSYour Name  */
osif_update_current_bss(struct net_device * dev,struct cfg80211_bss * bss,struct wlan_cm_connect_resp * rsp,struct wlan_objmgr_vdev * vdev)901*5113495bSYour Name static QDF_STATUS osif_update_current_bss(struct net_device *dev,
902*5113495bSYour Name 					  struct cfg80211_bss *bss,
903*5113495bSYour Name 					  struct wlan_cm_connect_resp *rsp,
904*5113495bSYour Name 					  struct wlan_objmgr_vdev *vdev)
905*5113495bSYour Name {
906*5113495bSYour Name 	struct cfg80211_connect_resp_params conn_rsp_params;
907*5113495bSYour Name 	enum ieee80211_statuscode status;
908*5113495bSYour Name 	int ret;
909*5113495bSYour Name 
910*5113495bSYour Name 	osif_enter_dev(dev);
911*5113495bSYour Name 
912*5113495bSYour Name 	qdf_mem_zero(&conn_rsp_params, sizeof(conn_rsp_params));
913*5113495bSYour Name 
914*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
915*5113495bSYour Name 	conn_rsp_params.status = status;
916*5113495bSYour Name 	osif_copy_connected_info(&conn_rsp_params, rsp, bss, vdev);
917*5113495bSYour Name 
918*5113495bSYour Name 	osif_debug("Connect resp status %d", conn_rsp_params.status);
919*5113495bSYour Name 	ret = cfg80211_update_current_bss(dev, &conn_rsp_params, rsp->ssid.ssid,
920*5113495bSYour Name 					  rsp->ssid.length);
921*5113495bSYour Name 	if (ret)
922*5113495bSYour Name 		osif_err("cfg80211_update_current_bss failed for psoc:%d pdev:%d vdev:%d",
923*5113495bSYour Name 			 wlan_vdev_get_psoc_id(vdev),
924*5113495bSYour Name 			 wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)),
925*5113495bSYour Name 			 wlan_vdev_get_id(vdev));
926*5113495bSYour Name 
927*5113495bSYour Name 	return qdf_status_from_os_return(ret);
928*5113495bSYour Name }
929*5113495bSYour Name 
930*5113495bSYour Name /**
931*5113495bSYour Name  * osif_update_current_bss_for_non_assoc_link_vdevs() - API to update the
932*5113495bSYour Name  * current_bss param of non-assoc link STA vdev.
933*5113495bSYour Name  * @vdev: Pointer to vdev
934*5113495bSYour Name  * @arg: Connection manager connect response
935*5113495bSYour Name  *
936*5113495bSYour Name  * Return: None.
937*5113495bSYour Name  */
osif_update_current_bss_for_non_assoc_link_vdevs(struct wlan_objmgr_vdev * vdev,void * arg)938*5113495bSYour Name static void osif_update_current_bss_for_non_assoc_link_vdevs(
939*5113495bSYour Name 		struct wlan_objmgr_vdev *vdev, void *arg)
940*5113495bSYour Name {
941*5113495bSYour Name 	struct wlan_objmgr_vdev *assoc_vdev;
942*5113495bSYour Name 	struct wlan_cm_connect_resp resp = {0};
943*5113495bSYour Name 	struct qdf_mac_addr macaddr = {0};
944*5113495bSYour Name 	struct vdev_osif_priv *osif_priv = NULL;
945*5113495bSYour Name 	struct wlan_cm_connect_resp *assoc_link_rsp;
946*5113495bSYour Name 
947*5113495bSYour Name 	assoc_link_rsp = (struct wlan_cm_connect_resp *)arg;
948*5113495bSYour Name 	if (!assoc_link_rsp) {
949*5113495bSYour Name 		osif_err("assoc_link_rsp is null");
950*5113495bSYour Name 		return;
951*5113495bSYour Name 	}
952*5113495bSYour Name 
953*5113495bSYour Name 	assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
954*5113495bSYour Name 
955*5113495bSYour Name 	/* For assoc vdev cfg80211_connect_done() is called to update the
956*5113495bSYour Name 	 * current bss param. Hence, skip the assoc vdev here.
957*5113495bSYour Name 	 */
958*5113495bSYour Name 	if (vdev == assoc_vdev)
959*5113495bSYour Name 		return;
960*5113495bSYour Name 
961*5113495bSYour Name 	wlan_vdev_mlme_get_ssid(vdev, resp.ssid.ssid, &resp.ssid.length);
962*5113495bSYour Name 
963*5113495bSYour Name 	wlan_vdev_get_bss_peer_mac(vdev, &macaddr);
964*5113495bSYour Name 	qdf_mem_copy(resp.bssid.bytes, macaddr.bytes, QDF_MAC_ADDR_SIZE);
965*5113495bSYour Name 
966*5113495bSYour Name 	resp.connect_status = assoc_link_rsp->connect_status;
967*5113495bSYour Name 
968*5113495bSYour Name 	osif_debug("vdev:%p bssid:" QDF_MAC_ADDR_FMT " ssid.length:%d ssid: " QDF_SSID_FMT,
969*5113495bSYour Name 		   vdev, QDF_MAC_ADDR_REF(macaddr.bytes), resp.ssid.length,
970*5113495bSYour Name 		   QDF_SSID_REF(resp.ssid.length, resp.ssid.ssid));
971*5113495bSYour Name 
972*5113495bSYour Name 	osif_priv = wlan_vdev_get_ospriv(vdev);
973*5113495bSYour Name 	osif_update_current_bss(osif_priv->wdev->netdev, NULL, &resp, vdev);
974*5113495bSYour Name }
975*5113495bSYour Name 
976*5113495bSYour Name /**
977*5113495bSYour Name  * osif_update_current_bss_for_non_assoc_links() - API to update the
978*5113495bSYour Name  * current_bss param of non-assoc link STA vdev.
979*5113495bSYour Name  * @assoc_vdev: Pointer to assoc vdev
980*5113495bSYour Name  * @rsp: Connection manager connect response
981*5113495bSYour Name  *
982*5113495bSYour Name  * Return: None.
983*5113495bSYour Name  */
osif_update_current_bss_for_non_assoc_links(struct wlan_objmgr_vdev * assoc_vdev,struct wlan_cm_connect_resp * rsp)984*5113495bSYour Name static void osif_update_current_bss_for_non_assoc_links(
985*5113495bSYour Name 		struct wlan_objmgr_vdev *assoc_vdev,
986*5113495bSYour Name 		struct wlan_cm_connect_resp *rsp)
987*5113495bSYour Name {
988*5113495bSYour Name 	mlo_iterate_connected_vdev_list(
989*5113495bSYour Name 			assoc_vdev,
990*5113495bSYour Name 			osif_update_current_bss_for_non_assoc_link_vdevs,
991*5113495bSYour Name 			rsp);
992*5113495bSYour Name }
993*5113495bSYour Name #else
osif_update_current_bss_for_non_assoc_links(struct wlan_objmgr_vdev * assoc_vdev,struct wlan_cm_connect_resp * rsp)994*5113495bSYour Name static void osif_update_current_bss_for_non_assoc_links(
995*5113495bSYour Name 		struct wlan_objmgr_vdev *assoc_vdev,
996*5113495bSYour Name 		struct wlan_cm_connect_resp *rsp)
997*5113495bSYour Name {
998*5113495bSYour Name }
999*5113495bSYour Name #endif
1000*5113495bSYour Name 
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1001*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
1002*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
1003*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1004*5113495bSYour Name {
1005*5113495bSYour Name 	struct cfg80211_bss *bss = NULL;
1006*5113495bSYour Name 	struct ieee80211_channel *chan;
1007*5113495bSYour Name 	struct wlan_objmgr_vdev *assoc_vdev = NULL;
1008*5113495bSYour Name 	struct vdev_osif_priv *tmp_osif_priv = NULL;
1009*5113495bSYour Name 	qdf_freq_t freq;
1010*5113495bSYour Name 	struct qdf_mac_addr macaddr = {0};
1011*5113495bSYour Name 	struct wlan_cm_connect_resp resp = {0};
1012*5113495bSYour Name 
1013*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
1014*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
1015*5113495bSYour Name 			chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
1016*5113495bSYour Name 						     rsp->freq);
1017*5113495bSYour Name 			bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy,
1018*5113495bSYour Name 						    chan,
1019*5113495bSYour Name 						    rsp->bssid.bytes,
1020*5113495bSYour Name 						    rsp->ssid.ssid,
1021*5113495bSYour Name 						    rsp->ssid.length);
1022*5113495bSYour Name 		}
1023*5113495bSYour Name 		if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
1024*5113495bSYour Name 						rsp, vdev))
1025*5113495bSYour Name 			osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
1026*5113495bSYour Name 		return;
1027*5113495bSYour Name 	}
1028*5113495bSYour Name 
1029*5113495bSYour Name 	if ((QDF_IS_STATUS_SUCCESS(rsp->connect_status) &&
1030*5113495bSYour Name 	    ucfg_mlo_is_mld_connected(vdev)) ||
1031*5113495bSYour Name 	    (QDF_IS_STATUS_ERROR(rsp->connect_status) &&
1032*5113495bSYour Name 	    ucfg_mlo_is_mld_disconnected(vdev))) {
1033*5113495bSYour Name 		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
1034*5113495bSYour Name 		if (!assoc_vdev)
1035*5113495bSYour Name 			return;
1036*5113495bSYour Name 		qdf_mem_copy(&resp, rsp, sizeof(struct wlan_cm_connect_resp));
1037*5113495bSYour Name 		tmp_osif_priv  = wlan_vdev_get_ospriv(assoc_vdev);
1038*5113495bSYour Name 		freq = assoc_vdev->vdev_mlme.bss_chan->ch_freq;
1039*5113495bSYour Name 		qdf_mem_copy(macaddr.bytes, rsp->bssid.bytes,
1040*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
1041*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
1042*5113495bSYour Name 			wlan_vdev_get_bss_peer_mac(assoc_vdev, &macaddr);
1043*5113495bSYour Name 			chan = ieee80211_get_channel(tmp_osif_priv->wdev->wiphy,
1044*5113495bSYour Name 						     freq);
1045*5113495bSYour Name 			bss = wlan_cfg80211_get_bss(tmp_osif_priv->wdev->wiphy,
1046*5113495bSYour Name 						    chan,
1047*5113495bSYour Name 						    macaddr.bytes,
1048*5113495bSYour Name 						    rsp->ssid.ssid,
1049*5113495bSYour Name 						    rsp->ssid.length);
1050*5113495bSYour Name 		}
1051*5113495bSYour Name 		qdf_mem_copy(resp.bssid.bytes, macaddr.bytes,
1052*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
1053*5113495bSYour Name 		resp.freq = freq;
1054*5113495bSYour Name 		resp.connect_ies.assoc_req.ptr = rsp->connect_ies.assoc_req.ptr;
1055*5113495bSYour Name 		resp.connect_ies.assoc_req.len = rsp->connect_ies.assoc_req.len;
1056*5113495bSYour Name 		resp.connect_ies.assoc_rsp.ptr = rsp->connect_ies.assoc_rsp.ptr;
1057*5113495bSYour Name 		resp.connect_ies.assoc_rsp.len = rsp->connect_ies.assoc_rsp.len;
1058*5113495bSYour Name 		if (osif_update_connect_results(tmp_osif_priv->wdev->netdev, bss,
1059*5113495bSYour Name 						&resp, assoc_vdev))
1060*5113495bSYour Name 			osif_connect_bss(tmp_osif_priv->wdev->netdev, bss, &resp);
1061*5113495bSYour Name 
1062*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(rsp->connect_status))
1063*5113495bSYour Name 			osif_update_current_bss_for_non_assoc_links(assoc_vdev,
1064*5113495bSYour Name 								    rsp);
1065*5113495bSYour Name 	}
1066*5113495bSYour Name }
1067*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
1068*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO */
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1069*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
1070*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
1071*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1072*5113495bSYour Name {
1073*5113495bSYour Name 	struct cfg80211_bss *bss = NULL;
1074*5113495bSYour Name 	struct ieee80211_channel *chan;
1075*5113495bSYour Name 
1076*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
1077*5113495bSYour Name 		chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
1078*5113495bSYour Name 					     rsp->freq);
1079*5113495bSYour Name 		bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
1080*5113495bSYour Name 					    rsp->bssid.bytes,
1081*5113495bSYour Name 					    rsp->ssid.ssid,
1082*5113495bSYour Name 					    rsp->ssid.length);
1083*5113495bSYour Name 	}
1084*5113495bSYour Name 
1085*5113495bSYour Name 	if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
1086*5113495bSYour Name 					rsp, vdev))
1087*5113495bSYour Name 		osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
1088*5113495bSYour Name }
1089*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
1090*5113495bSYour Name #else  /* CFG80211_CONNECT_BSS */
1091*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
1092*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1093*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
1094*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
1095*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1096*5113495bSYour Name {
1097*5113495bSYour Name 	enum ieee80211_statuscode status;
1098*5113495bSYour Name 	size_t req_len = 0;
1099*5113495bSYour Name 	const uint8_t *req_ptr = NULL;
1100*5113495bSYour Name 	size_t rsp_len = 0;
1101*5113495bSYour Name 	const uint8_t *rsp_ptr = NULL;
1102*5113495bSYour Name 	struct wlan_objmgr_vdev *assoc_vdev = NULL;
1103*5113495bSYour Name 	struct vdev_osif_priv *tmp_osif_priv = NULL;
1104*5113495bSYour Name 
1105*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
1106*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
1107*5113495bSYour Name 				      &req_len, &req_ptr);
1108*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
1109*5113495bSYour Name 				      &rsp_len, &rsp_ptr);
1110*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
1111*5113495bSYour Name 		if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev))
1112*5113495bSYour Name 			cfg80211_connect_result(
1113*5113495bSYour Name 				osif_priv->wdev->netdev,
1114*5113495bSYour Name 				rsp->bssid.bytes, req_ptr, req_len,
1115*5113495bSYour Name 				rsp_ptr, rsp_len, status,
1116*5113495bSYour Name 				qdf_mem_malloc_flags());
1117*5113495bSYour Name 	} else {
1118*5113495bSYour Name 		cfg80211_connect_result(osif_priv->wdev->netdev,
1119*5113495bSYour Name 					rsp->bssid.bytes, req_ptr, req_len,
1120*5113495bSYour Name 					rsp_ptr, rsp_len, status,
1121*5113495bSYour Name 					qdf_mem_malloc_flags());
1122*5113495bSYour Name 	}
1123*5113495bSYour Name }
1124*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1125*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
1126*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
1127*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1128*5113495bSYour Name {
1129*5113495bSYour Name 	enum ieee80211_statuscode status;
1130*5113495bSYour Name 	size_t req_len = 0;
1131*5113495bSYour Name 	const uint8_t *req_ptr = NULL;
1132*5113495bSYour Name 	size_t rsp_len = 0;
1133*5113495bSYour Name 	const uint8_t *rsp_ptr = NULL;
1134*5113495bSYour Name 	struct wlan_objmgr_vdev *assoc_vdev = NULL;
1135*5113495bSYour Name 	struct vdev_osif_priv *tmp_osif_priv = NULL;
1136*5113495bSYour Name 	struct qdf_mac_addr macaddr = {0};
1137*5113495bSYour Name 
1138*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
1139*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
1140*5113495bSYour Name 				      &req_len, &req_ptr);
1141*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
1142*5113495bSYour Name 				      &rsp_len, &rsp_ptr);
1143*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
1144*5113495bSYour Name 		if ((QDF_IS_STATUS_SUCCESS(rsp->connect_status) &&
1145*5113495bSYour Name 		    ucfg_mlo_is_mld_connected(vdev)) ||
1146*5113495bSYour Name 		    (QDF_IS_STATUS_ERROR(rsp->connect_status) &&
1147*5113495bSYour Name 		    ucfg_mlo_is_mld_disconnected(vdev))) {
1148*5113495bSYour Name 			assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
1149*5113495bSYour Name 			if (!assoc_vdev)
1150*5113495bSYour Name 				return;
1151*5113495bSYour Name 			tmp_osif_priv  = wlan_vdev_get_ospriv(assoc_vdev);
1152*5113495bSYour Name 			wlan_vdev_get_bss_peer_mac(assoc_vdev, &macaddr);
1153*5113495bSYour Name 			cfg80211_connect_result(tmp_osif_priv->wdev->netdev,
1154*5113495bSYour Name 						macaddr.bytes, req_ptr,
1155*5113495bSYour Name 						req_len, rsp_ptr, rsp_len,
1156*5113495bSYour Name 						status, qdf_mem_malloc_flags());
1157*5113495bSYour Name 		}
1158*5113495bSYour Name 	} else {
1159*5113495bSYour Name 		cfg80211_connect_result(osif_priv->wdev->netdev,
1160*5113495bSYour Name 					rsp->bssid.bytes, req_ptr, req_len,
1161*5113495bSYour Name 					rsp_ptr, rsp_len, status,
1162*5113495bSYour Name 					qdf_mem_malloc_flags());
1163*5113495bSYour Name 	}
1164*5113495bSYour Name }
1165*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
1166*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO */
osif_indcate_connect_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1167*5113495bSYour Name static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
1168*5113495bSYour Name 					 struct vdev_osif_priv *osif_priv,
1169*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1170*5113495bSYour Name {
1171*5113495bSYour Name 	enum ieee80211_statuscode status;
1172*5113495bSYour Name 	size_t req_len = 0;
1173*5113495bSYour Name 	const uint8_t *req_ptr = NULL;
1174*5113495bSYour Name 	size_t rsp_len = 0;
1175*5113495bSYour Name 	const uint8_t *rsp_ptr = NULL;
1176*5113495bSYour Name 
1177*5113495bSYour Name 	status = osif_get_connect_status_code(rsp);
1178*5113495bSYour Name 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
1179*5113495bSYour Name 				      &req_len, &req_ptr);
1180*5113495bSYour Name 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
1181*5113495bSYour Name 				      &rsp_len, &rsp_ptr);
1182*5113495bSYour Name 	cfg80211_connect_result(osif_priv->wdev->netdev,
1183*5113495bSYour Name 				rsp->bssid.bytes, req_ptr, req_len,
1184*5113495bSYour Name 				rsp_ptr, rsp_len, status,
1185*5113495bSYour Name 				qdf_mem_malloc_flags());
1186*5113495bSYour Name }
1187*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
1188*5113495bSYour Name #endif /* CFG80211_CONNECT_BSS */
1189*5113495bSYour Name 
1190*5113495bSYour Name #ifdef CONN_MGR_ADV_FEATURE
1191*5113495bSYour Name static inline
osif_cm_is_unlink_bss_required(struct wlan_cm_connect_resp * rsp)1192*5113495bSYour Name bool osif_cm_is_unlink_bss_required(struct wlan_cm_connect_resp *rsp)
1193*5113495bSYour Name {
1194*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status) ||
1195*5113495bSYour Name 	    ucfg_cm_is_link_switch_connect_resp(rsp))
1196*5113495bSYour Name 		return false;
1197*5113495bSYour Name 
1198*5113495bSYour Name 	if (rsp->reason == CM_NO_CANDIDATE_FOUND ||
1199*5113495bSYour Name 	    rsp->reason == CM_JOIN_TIMEOUT ||
1200*5113495bSYour Name 	    rsp->reason == CM_AUTH_TIMEOUT ||
1201*5113495bSYour Name 	    rsp->reason == CM_ASSOC_TIMEOUT)
1202*5113495bSYour Name 		return true;
1203*5113495bSYour Name 
1204*5113495bSYour Name 	return false;
1205*5113495bSYour Name }
osif_check_and_unlink_bss(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1206*5113495bSYour Name static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev,
1207*5113495bSYour Name 					     struct wlan_cm_connect_resp *rsp)
1208*5113495bSYour Name {
1209*5113495bSYour Name 	if (osif_cm_is_unlink_bss_required(rsp))
1210*5113495bSYour Name 		osif_cm_unlink_bss(vdev, &rsp->bssid);
1211*5113495bSYour Name }
1212*5113495bSYour Name #else
osif_check_and_unlink_bss(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1213*5113495bSYour Name static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev,
1214*5113495bSYour Name 					     struct wlan_cm_connect_resp *rsp)
1215*5113495bSYour Name {}
1216*5113495bSYour Name #endif
1217*5113495bSYour Name 
1218*5113495bSYour Name #define OSIF_CM_FAIL_INFO_STRING_SIZE 50
1219*5113495bSYour Name 
1220*5113495bSYour Name static inline void
osif_dump_connect_rsp(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)1221*5113495bSYour Name osif_dump_connect_rsp(struct wlan_objmgr_vdev *vdev,
1222*5113495bSYour Name 		      struct vdev_osif_priv *osif_priv,
1223*5113495bSYour Name 		      struct wlan_cm_connect_resp *rsp)
1224*5113495bSYour Name {
1225*5113495bSYour Name 	char fail_info[OSIF_CM_FAIL_INFO_STRING_SIZE] = {0};
1226*5113495bSYour Name 
1227*5113495bSYour Name 	/* Fill status code and reason only on failure */
1228*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(rsp->connect_status))
1229*5113495bSYour Name 		qdf_scnprintf(fail_info, sizeof(fail_info),
1230*5113495bSYour Name 			      "reason %d status %d %s",
1231*5113495bSYour Name 			      rsp->reason, rsp->status_code,
1232*5113495bSYour Name 			      rsp->send_disconnect ?
1233*5113495bSYour Name 			      ", Send disconnect" : "");
1234*5113495bSYour Name 
1235*5113495bSYour Name 	osif_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " %s with " QDF_MAC_ADDR_FMT " \"" QDF_SSID_FMT "\" is %s, cmid 0x%x %s",
1236*5113495bSYour Name 		       osif_priv->wdev->netdev->name, rsp->vdev_id,
1237*5113495bSYour Name 		       QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)),
1238*5113495bSYour Name 		       rsp->is_reassoc ? "Roam" : "Connect",
1239*5113495bSYour Name 		       QDF_MAC_ADDR_REF(rsp->bssid.bytes),
1240*5113495bSYour Name 		       QDF_SSID_REF(rsp->ssid.length, rsp->ssid.ssid),
1241*5113495bSYour Name 		       rsp->connect_status ? "FAILURE" : "SUCCESS", rsp->cm_id,
1242*5113495bSYour Name 		       fail_info);
1243*5113495bSYour Name }
1244*5113495bSYour Name 
osif_connect_handler(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1245*5113495bSYour Name QDF_STATUS osif_connect_handler(struct wlan_objmgr_vdev *vdev,
1246*5113495bSYour Name 				struct wlan_cm_connect_resp *rsp)
1247*5113495bSYour Name {
1248*5113495bSYour Name 	struct vdev_osif_priv *osif_priv  = wlan_vdev_get_ospriv(vdev);
1249*5113495bSYour Name 	QDF_STATUS status;
1250*5113495bSYour Name 
1251*5113495bSYour Name 	osif_dump_connect_rsp(vdev, osif_priv, rsp);
1252*5113495bSYour Name 	osif_check_and_unlink_bss(vdev, rsp);
1253*5113495bSYour Name 
1254*5113495bSYour Name 	status = osif_validate_connect_and_reset_src_id(osif_priv, rsp);
1255*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status) ||
1256*5113495bSYour Name 	    ucfg_cm_is_link_switch_connect_resp(rsp)) {
1257*5113495bSYour Name 		osif_cm_connect_comp_ind(vdev, rsp, OSIF_NOT_HANDLED);
1258*5113495bSYour Name 		return status;
1259*5113495bSYour Name 	}
1260*5113495bSYour Name 
1261*5113495bSYour Name 	osif_cm_connect_comp_ind(vdev, rsp, OSIF_PRE_USERSPACE_UPDATE);
1262*5113495bSYour Name 
1263*5113495bSYour Name 	/*
1264*5113495bSYour Name 	 * To fix issue that scan with random address failed since wdev keeps
1265*5113495bSYour Name 	 * connected, rsp->send_disconnect is added.
1266*5113495bSYour Name 	 * Reproduce steps:
1267*5113495bSYour Name 	 *  1.  Connect from OSIF success, wdev->connected = true;
1268*5113495bSYour Name 	 *  2.  Disconnect from target if and reassoc from OSIF happens back to
1269*5113495bSYour Name 	 *	back.
1270*5113495bSYour Name 	 *  3.  Disconnect event is not sent to kernel, wdev->connected keeps
1271*5113495bSYour Name 	 *	true, isn't cleared.
1272*5113495bSYour Name 	 *  4.  Connect from OSIF failed too, wdev->connected keeps true,  isn't
1273*5113495bSYour Name 	 *	cleared.
1274*5113495bSYour Name 	 *  5.  Scan with random address failed since wdev->connected is true.
1275*5113495bSYour Name 	 *
1276*5113495bSYour Name 	 * To fix it, if connect req was a reassoc req and received in not
1277*5113495bSYour Name 	 * connected state for race between disconnect from target if and
1278*5113495bSYour Name 	 * reassoc connect from OSIF, set reassoc_in_non_connected to send
1279*5113495bSYour Name 	 * disconnect instead of connect rsp to kernel to cleanup kernel flags
1280*5113495bSYour Name 	 * like: wdev->connected.
1281*5113495bSYour Name 	 */
1282*5113495bSYour Name 	if (rsp->is_reassoc)
1283*5113495bSYour Name 		osif_indicate_reassoc_results(vdev, osif_priv, rsp);
1284*5113495bSYour Name 	else if (rsp->send_disconnect &&
1285*5113495bSYour Name 		 QDF_IS_STATUS_ERROR(rsp->connect_status))
1286*5113495bSYour Name 		osif_cm_indicate_disconnect(vdev, osif_priv->wdev->netdev,
1287*5113495bSYour Name 					    WLAN_REASON_UNSPECIFIED,
1288*5113495bSYour Name 					    false, NULL, 0, -1,
1289*5113495bSYour Name 					    qdf_mem_malloc_flags());
1290*5113495bSYour Name 	else
1291*5113495bSYour Name 		osif_indcate_connect_results(vdev, osif_priv, rsp);
1292*5113495bSYour Name 	osif_cm_connect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE);
1293*5113495bSYour Name 
1294*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1295*5113495bSYour Name }
1296*5113495bSYour Name 
osif_failed_candidate_handler(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1297*5113495bSYour Name QDF_STATUS osif_failed_candidate_handler(struct wlan_objmgr_vdev *vdev,
1298*5113495bSYour Name 					 struct wlan_cm_connect_resp *rsp)
1299*5113495bSYour Name {
1300*5113495bSYour Name 	struct vdev_osif_priv *osif_priv  = wlan_vdev_get_ospriv(vdev);
1301*5113495bSYour Name 
1302*5113495bSYour Name 	osif_dump_connect_rsp(vdev, osif_priv, rsp);
1303*5113495bSYour Name 
1304*5113495bSYour Name 	/**
1305*5113495bSYour Name 	 * Do not unlink the BSS if it is an ML candidate. In case of ML,
1306*5113495bSYour Name 	 * failed candidate may be used as partner link while trying the
1307*5113495bSYour Name 	 * connection on other links.
1308*5113495bSYour Name 	 */
1309*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
1310*5113495bSYour Name 		osif_check_and_unlink_bss(vdev, rsp);
1311*5113495bSYour Name 
1312*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1313*5113495bSYour Name }
1314