xref: /wlan-dirver/qca-wifi-host-cmn/os_if/linux/mlme/src/osif_cm_roam_rsp.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
1 /*
2  * Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 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: osif_cm_roam_rsp.c
20  *
21  * This file maintains definitaions of roam response apis.
22  */
23 
24 #include <linux/version.h>
25 #include <linux/nl80211.h>
26 #include <net/cfg80211.h>
27 #include <wlan_osif_priv.h>
28 #include "osif_cm_rsp.h"
29 #include <osif_cm_util.h>
30 #include <wlan_cfg80211.h>
31 #include <wlan_cfg80211_scan.h>
32 #include "wlan_mlo_mgr_sta.h"
33 #ifdef CONN_MGR_ADV_FEATURE
34 #include "wlan_mlme_ucfg_api.h"
35 #endif
36 #include "wlan_crypto_global_api.h"
37 
38 #ifdef CONN_MGR_ADV_FEATURE
39 #ifdef WLAN_FEATURE_FILS_SK
40 static inline void osif_update_fils_hlp_data(struct net_device *dev,
41 					     struct wlan_objmgr_vdev *vdev,
42 					     struct wlan_cm_connect_resp *rsp)
43 {
44 	if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len)
45 		osif_cm_set_hlp_data(dev, vdev, rsp);
46 }
47 #else
48 static inline void osif_update_fils_hlp_data(struct net_device *dev,
49 					     struct wlan_objmgr_vdev *vdev,
50 					     struct wlan_cm_connect_resp *rsp)
51 {
52 }
53 #endif
54 
55 /**
56  * osif_roamed_ind() - send roamed indication to cfg80211
57  * @dev: network device
58  * @bss: cfg80211 roamed bss pointer
59  * @req_ie: IEs used in reassociation request
60  * @req_ie_len: Length of the @req_ie
61  * @resp_ie: IEs received in successful reassociation response
62  * @resp_ie_len: Length of @resp_ie
63  *
64  * Return: none
65  */
66 #if defined CFG80211_ROAMED_API_UNIFIED || \
67 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
68 #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
69 static
70 void osif_copy_roamed_info(struct cfg80211_roam_info *info,
71 			   struct cfg80211_bss *bss)
72 {
73 	info->links[0].bss = bss;
74 }
75 #else
76 static
77 void osif_copy_roamed_info(struct cfg80211_roam_info *info,
78 			   struct cfg80211_bss *bss)
79 {
80 	info->bss = bss;
81 }
82 #endif
83 
84 #if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
85 static
86 void osif_populate_mlo_info_for_link(struct wlan_objmgr_vdev *vdev,
87 				     struct cfg80211_roam_info *roam_info_params,
88 				     uint8_t link_id,
89 				     struct cfg80211_bss *bss)
90 {
91 	osif_debug("Link_id :%d", link_id);
92 	roam_info_params->valid_links |=  BIT(link_id);
93 	roam_info_params->links[link_id].bssid = bss->bssid;
94 	roam_info_params->links[link_id].bss = bss;
95 	roam_info_params->links[link_id].addr =
96 					 wlan_vdev_mlme_get_macaddr(vdev);
97 }
98 
99 static void
100 osif_populate_partner_links_roam_mlo_params(struct wlan_objmgr_pdev *pdev,
101 					    struct wlan_cm_connect_resp *rsp,
102 					    struct cfg80211_roam_info *roam_info_params)
103 {
104 	struct wlan_objmgr_vdev *partner_vdev;
105 	struct mlo_link_info *rsp_partner_info;
106 	struct mlo_partner_info assoc_partner_info = {0};
107 	struct cfg80211_bss *bss = NULL;
108 	QDF_STATUS qdf_status;
109 	uint8_t link_id = 0, num_links;
110 	int i;
111 
112 	qdf_status = osif_get_partner_info_from_mlie(rsp, &assoc_partner_info);
113 	if (QDF_IS_STATUS_ERROR(qdf_status))
114 		return;
115 
116 	num_links = rsp->ml_parnter_info.num_partner_links;
117 	for (i = 0 ; i < num_links; i++) {
118 		rsp_partner_info = &rsp->ml_parnter_info.partner_link_info[i];
119 
120 		qdf_status = osif_get_link_id_from_assoc_ml_ie(rsp_partner_info,
121 							       &assoc_partner_info,
122 							       &link_id);
123 		if (QDF_IS_STATUS_ERROR(qdf_status))
124 			continue;
125 
126 		partner_vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev,
127 						      rsp_partner_info->vdev_id,
128 						      WLAN_MLO_MGR_ID);
129 		if (!partner_vdev)
130 			continue;
131 
132 		bss = osif_get_chan_bss_from_kernel(partner_vdev,
133 						    rsp_partner_info, rsp);
134 		if (!bss) {
135 			wlan_objmgr_vdev_release_ref(partner_vdev,
136 						     WLAN_MLO_MGR_ID);
137 			continue;
138 		}
139 
140 		osif_populate_mlo_info_for_link(partner_vdev,
141 						roam_info_params,
142 						link_id, bss);
143 		wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_MLO_MGR_ID);
144 	}
145 }
146 
147 static QDF_STATUS
148 osif_fill_peer_mld_mac_roam_info(struct wlan_objmgr_vdev *vdev,
149 				 struct wlan_cm_connect_resp *rsp,
150 				 struct cfg80211_roam_info *roam_info_params)
151 {
152 	struct wlan_objmgr_peer *peer_obj;
153 
154 	peer_obj = wlan_objmgr_get_peer_by_mac(wlan_vdev_get_psoc(vdev),
155 					       rsp->bssid.bytes, WLAN_OSIF_ID);
156 	if (!peer_obj)
157 		return QDF_STATUS_E_INVAL;
158 
159 	roam_info_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
160 
161 	wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
162 
163 	return QDF_STATUS_SUCCESS;
164 }
165 
166 static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
167 				      struct wlan_cm_connect_resp *rsp,
168 				      struct cfg80211_bss *bss,
169 				      struct cfg80211_roam_info *info)
170 {
171 	QDF_STATUS qdf_status;
172 	uint8_t assoc_link_id;
173 
174 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
175 		return;
176 
177 	qdf_status = osif_fill_peer_mld_mac_roam_info(vdev, rsp,
178 						      info);
179 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
180 		osif_err("Unable to fill peer mld address: %d", qdf_status);
181 		return;
182 	}
183 
184 	assoc_link_id = wlan_vdev_get_link_id(vdev);
185 	osif_populate_mlo_info_for_link(vdev, info,
186 					assoc_link_id, bss);
187 
188 	osif_populate_partner_links_roam_mlo_params(wlan_vdev_get_pdev(vdev),
189 						    rsp,
190 						    info);
191 }
192 #else
193 static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
194 				      struct wlan_cm_connect_resp *rsp,
195 				      struct cfg80211_bss *bss,
196 				      struct cfg80211_roam_info *info)
197 {}
198 #endif
199 static void osif_roamed_ind(struct net_device *dev,
200 			    struct wlan_objmgr_vdev *vdev,
201 			    struct wlan_cm_connect_resp *rsp,
202 			    struct cfg80211_bss *bss,
203 			    const uint8_t *req_ie,
204 			    size_t req_ie_len, const uint8_t *resp_ie,
205 			    size_t resp_ie_len)
206 {
207 	struct cfg80211_roam_info info = {0};
208 
209 	osif_copy_roamed_info(&info, bss);
210 	info.req_ie = req_ie;
211 	info.req_ie_len = req_ie_len;
212 	info.resp_ie = resp_ie;
213 	info.resp_ie_len = resp_ie_len;
214 	osif_fill_mlo_roam_params(vdev, rsp, bss, &info);
215 	cfg80211_roamed(dev, &info, qdf_mem_malloc_flags());
216 }
217 #else
218 static inline void osif_roamed_ind(struct net_device *dev,
219 			    struct wlan_objmgr_vdev *vdev,
220 			    struct wlan_cm_connect_resp *rsp,
221 			    struct cfg80211_bss *bss,
222 			    const uint8_t *req_ie,
223 			    size_t req_ie_len, const uint8_t *resp_ie,
224 			    size_t resp_ie_len)
225 
226 {
227 	cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
228 			    qdf_mem_malloc_flags());
229 }
230 #endif
231 
232 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
233 #ifdef WLAN_FEATURE_FILS_SK
234 /**
235  * wlan_hdd_add_fils_params_roam_auth_event() - Adds FILS params in roam auth
236  * @skb: SK buffer
237  * @roam_info: Roam info
238  *
239  * API adds fils params[pmk, pmkid, next sequence number] to roam auth event
240  *
241  * Return: zero on success, error code on failure
242  */
243 static int
244 osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
245 				     struct wlan_roam_sync_info *roam_info)
246 {
247 	if (roam_info->pmk_len &&
248 	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK,
249 		    roam_info->pmk_len, roam_info->pmk)) {
250 		osif_err("pmk send fail");
251 		return -EINVAL;
252 	}
253 
254 	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID,
255 		    PMKID_LEN, roam_info->pmkid)) {
256 		osif_err("pmkid send fail");
257 		return -EINVAL;
258 	}
259 
260 	osif_debug("Update ERP Seq Num %d, Next ERP Seq Num %d",
261 		   roam_info->update_erp_next_seq_num,
262 		   roam_info->next_erp_seq_num);
263 	if (roam_info->update_erp_next_seq_num &&
264 	    nla_put_u16(skb,
265 			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM,
266 			roam_info->next_erp_seq_num)) {
267 		osif_err("ERP seq num send fail");
268 		return -EINVAL;
269 	}
270 
271 	return 0;
272 }
273 #else
274 static inline int
275 osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
276 				     struct wlan_roam_sync_info *roam_info)
277 {
278 	return 0;
279 }
280 #endif
281 
282 /**
283  * osif_get_roam_reason() - convert wmi roam reason to
284  * enum qca_roam_reason
285  * @roam_scan_trigger: wmi roam scan trigger ID
286  *
287  * Return: Meaningful qca_roam_reason from enum WMI_ROAM_TRIGGER_REASON_ID
288  */
289 static enum qca_roam_reason osif_get_roam_reason(uint16_t roam_scan_trigger)
290 {
291 	switch (roam_scan_trigger) {
292 	case ROAM_TRIGGER_REASON_PER:
293 		return QCA_ROAM_REASON_PER;
294 	case ROAM_TRIGGER_REASON_BMISS:
295 		return QCA_ROAM_REASON_BEACON_MISS;
296 	case ROAM_TRIGGER_REASON_LOW_RSSI:
297 	case ROAM_TRIGGER_REASON_BACKGROUND:
298 		return QCA_ROAM_REASON_POOR_RSSI;
299 	case ROAM_TRIGGER_REASON_HIGH_RSSI:
300 		return QCA_ROAM_REASON_BETTER_RSSI;
301 	case ROAM_TRIGGER_REASON_DENSE:
302 		return QCA_ROAM_REASON_CONGESTION;
303 	case ROAM_TRIGGER_REASON_FORCED:
304 		return QCA_ROAM_REASON_USER_TRIGGER;
305 	case ROAM_TRIGGER_REASON_BTM:
306 		return QCA_ROAM_REASON_BTM;
307 	case ROAM_TRIGGER_REASON_BSS_LOAD:
308 		return QCA_ROAM_REASON_BSS_LOAD;
309 	default:
310 		return QCA_ROAM_REASON_UNKNOWN;
311 	}
312 
313 	return QCA_ROAM_REASON_UNKNOWN;
314 }
315 
316 #ifdef WLAN_FEATURE_11BE_MLO
317 
318 static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
319 {
320 	struct wlan_objmgr_peer *peer;
321 
322 	peer = wlan_vdev_get_bsspeer(vdev);
323 	if (peer)
324 		if (wlan_vdev_mlme_is_mlo_vdev(vdev))
325 			return wlan_peer_mlme_get_mldaddr(peer);
326 		else
327 			return wlan_peer_get_macaddr(peer);
328 	else
329 		return NULL;
330 }
331 
332 /**
333  * osif_send_roam_auth_mlo_links_event() - API to send roam auth mlo
334  * links event response to kernel
335  * @skb : sk buffer pointer
336  * @vdev: vdev pointer
337  * @rsp: Connection manager response
338  *
339  * This is called when wlan driver needs to send the mlo links roaming
340  * information after roaming.
341  *
342  * Context: Any context.
343  * Return: int
344  */
345 static int
346 osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
347 				    struct wlan_objmgr_vdev *vdev,
348 				    struct vdev_osif_priv *osif_priv,
349 				    struct wlan_cm_connect_resp *rsp)
350 {
351 	struct wlan_objmgr_psoc *psoc;
352 	bool roam_offload_enable;
353 	uint8_t i;
354 	struct nlattr *mlo_links;
355 	struct nlattr *mlo_links_info;
356 	struct wlan_objmgr_vdev *link_vdev;
357 	uint8_t link_vdev_id;
358 
359 	if (!vdev)
360 		return -EINVAL;
361 
362 	psoc = wlan_vdev_get_psoc(vdev);
363 	ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
364 
365 	if (!roam_offload_enable)
366 		return -EINVAL;
367 
368 	mlo_links  = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS);
369 	if (!mlo_links) {
370 		osif_err("nla_nest_start error");
371 		return -EINVAL;
372 	}
373 
374 	for (i = 0; i < rsp->ml_parnter_info.num_partner_links; i++) {
375 		mlo_links_info = nla_nest_start(skb, i);
376 		if (!mlo_links_info) {
377 			osif_err("nla nest start fail");
378 			return -EINVAL;
379 		}
380 
381 		if (nla_put_u8(skb,
382 			       QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID,
383 			       rsp->ml_parnter_info.partner_link_info[i].link_id)) {
384 			osif_err("nla put fail");
385 			return -EINVAL;
386 		}
387 
388 		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID,
389 			    ETH_ALEN,
390 			    (void *)&rsp->ml_parnter_info.partner_link_info[i].link_addr)) {
391 			osif_err("nla put fail");
392 			return -EINVAL;
393 		}
394 
395 		link_vdev_id = rsp->ml_parnter_info.partner_link_info[i].vdev_id;
396 		link_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
397 								 link_vdev_id,
398 								 WLAN_OSIF_CM_ID);
399 		if (!link_vdev) {
400 			osif_err("link vdev is null");
401 			return -EINVAL;
402 		}
403 
404 		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR,
405 			    ETH_ALEN, wlan_vdev_mlme_get_macaddr(link_vdev))) {
406 			osif_err("nla put fail");
407 			wlan_objmgr_vdev_release_ref(link_vdev,
408 						     WLAN_OSIF_CM_ID);
409 			return -EINVAL;
410 		}
411 		wlan_objmgr_vdev_release_ref(link_vdev, WLAN_OSIF_CM_ID);
412 		nla_nest_end(skb, mlo_links_info);
413 	}
414 
415 	nla_nest_end(skb, mlo_links);
416 
417 	return 0;
418 }
419 #else
420 static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
421 {
422 	struct wlan_objmgr_peer *peer;
423 
424 	peer = wlan_vdev_get_bsspeer(vdev);
425 	if (peer)
426 		return wlan_peer_get_macaddr(peer);
427 	else
428 		return NULL;
429 }
430 
431 static inline int
432 osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
433 				    struct wlan_objmgr_vdev *vdev,
434 				    struct vdev_osif_priv *osif_priv,
435 				    struct wlan_cm_connect_resp *rsp)
436 {
437 	return 0;
438 }
439 #endif
440 
441 /**
442  * osif_send_roam_auth_event() - API to send roam auth event response to kernel
443  * @vdev: vdev pointer
444  * @osif_priv: OS private structure of vdev
445  * @rsp: Connection manager response
446  *
447  * This is called when wlan driver needs to send the roaming and
448  * authorization information after roaming.
449  *
450  * The information that would be sent is the request RSN IE, response
451  * RSN IE and BSSID of the newly roamed AP.
452  *
453  * If the Authorized status is authenticated, then additional parameters
454  * like PTK's KCK and KEK and Replay Counter would also be passed to the
455  * supplicant.
456  *
457  * The supplicant upon receiving this event would ignore the legacy
458  * cfg80211_roamed call and use the entire information from this event.
459  * The cfg80211_roamed should still co-exist since the kernel will
460  * make use of the parameters even if the supplicant ignores it.
461  *
462  *
463  * Context: Any context.
464  * Return: int
465  */
466 static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
467 				     struct vdev_osif_priv *osif_priv,
468 				     struct wlan_cm_connect_resp *rsp,
469 				     const uint8_t *req_ie,
470 				     size_t req_ie_len, const uint8_t *resp_ie,
471 				     size_t resp_ie_len)
472 {
473 	struct wlan_objmgr_psoc *psoc;
474 	uint32_t fils_params_len;
475 	struct sk_buff *skb = NULL;
476 	struct wlan_roam_sync_info *roaming_info;
477 	int status;
478 	int32_t akm;
479 	bool roam_offload_enable;
480 	uint8_t *bss_mac_addr;
481 	uint8_t num_of_links = 0;
482 
483 	psoc = wlan_vdev_get_psoc(vdev);
484 	ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
485 
486 	if (!roam_offload_enable)
487 		return 0;
488 
489 	roaming_info = rsp->roaming_info;
490 
491 	/*
492 	 * PMK is sent from FW in Roam Synch Event for FILS Roaming.
493 	 * In that case, add three more NL attributes.ie. PMK, PMKID
494 	 * and ERP next sequence number. Add corresponding lengths
495 	 * with 3 extra NL message headers for each of the
496 	 * aforementioned params.
497 	 */
498 	fils_params_len = roaming_info->pmk_len + PMKID_LEN +
499 			  sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
500 
501 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
502 #ifdef WLAN_FEATURE_11BE_MLO
503 		num_of_links = rsp->ml_parnter_info.num_partner_links;
504 #endif
505 		skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
506 				osif_priv->wdev,
507 				(ETH_ALEN * num_of_links) +
508 				(sizeof(uint8_t) * num_of_links) +
509 				(ETH_ALEN * num_of_links) +
510 				req_ie_len + resp_ie_len +
511 				sizeof(uint8_t) + REPLAY_CTR_LEN +
512 				roaming_info->kck_len + roaming_info->kek_len +
513 				sizeof(uint16_t) + sizeof(uint8_t) +
514 				(9 * NLMSG_HDRLEN) + fils_params_len,
515 				QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
516 				qdf_mem_malloc_flags());
517 	} else {
518 		skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
519 				osif_priv->wdev,
520 				ETH_ALEN + req_ie_len +
521 				resp_ie_len +
522 				sizeof(uint8_t) + REPLAY_CTR_LEN +
523 				roaming_info->kck_len + roaming_info->kek_len +
524 				sizeof(uint16_t) + sizeof(uint8_t) +
525 				(9 * NLMSG_HDRLEN) + fils_params_len,
526 				QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
527 				qdf_mem_malloc_flags());
528 	}
529 	if (!skb) {
530 		osif_err("cfg80211_vendor_event_alloc failed");
531 		return -1;
532 	}
533 
534 	bss_mac_addr = osif_get_bss_mac_addr(vdev);
535 	if (!bss_mac_addr) {
536 		osif_err("Invalid bss mac addr");
537 		goto nla_put_failure;
538 	}
539 	if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
540 		    ETH_ALEN, bss_mac_addr) ||
541 	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
542 		    req_ie_len, req_ie) ||
543 	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
544 		    resp_ie_len, resp_ie)) {
545 		osif_err("nla put fail");
546 		goto nla_put_failure;
547 	}
548 
549 	if (roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED) {
550 		osif_debug("Include Auth Params TLV's");
551 		if (nla_put_u8(skb,
552 			       QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
553 			       true)) {
554 			osif_err("nla put fail");
555 			goto nla_put_failure;
556 		}
557 		akm = wlan_crypto_get_param(vdev,
558 					    WLAN_CRYPTO_PARAM_KEY_MGMT);
559 		/* if FT or CCKM connection: dont send replay counter */
560 		if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) &&
561 		    !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK) &&
562 		    !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) &&
563 		    !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) &&
564 		    !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM) &&
565 		    nla_put(skb,
566 			    QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
567 			    REPLAY_CTR_LEN,
568 			    roaming_info->replay_ctr)) {
569 			osif_err("non FT/non CCKM connection");
570 			osif_err("failed to send replay counter");
571 			goto nla_put_failure;
572 		}
573 		if (roaming_info->kek_len > MAX_KEK_LENGTH ||
574 		    roaming_info->kck_len > MAX_KCK_LEN ||
575 		    nla_put(skb,
576 			    QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
577 			    roaming_info->kck_len, roaming_info->kck) ||
578 		    nla_put(skb,
579 			    QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
580 			    roaming_info->kek_len, roaming_info->kek)) {
581 			osif_err("nla put fail, kek_len %d",
582 				 roaming_info->kek_len);
583 			goto nla_put_failure;
584 		}
585 
586 		if (nla_put_u16(skb,
587 				QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON,
588 				osif_get_roam_reason(roaming_info->roam_reason))) {
589 			osif_err("roam reason send failure");
590 			goto nla_put_failure;
591 		}
592 
593 		status = osif_add_fils_params_roam_auth_event(skb,
594 							      roaming_info);
595 		if (status)
596 			goto nla_put_failure;
597 		/*
598 		 * Save the gtk rekey parameters in HDD STA context. They will
599 		 * be used next time when host enables GTK offload and goes
600 		 * into power save state.
601 		 */
602 		osif_cm_save_gtk(vdev, rsp);
603 		osif_debug("replay_ctr 0x%llx kck %d kek %d",
604 			   *((uint64_t *)roaming_info->replay_ctr),
605 			   roaming_info->kck_len,
606 			   roaming_info->kek_len);
607 
608 	} else {
609 		osif_debug("No Auth Params TLV's");
610 		if (nla_put_u8(skb,
611 			       QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
612 			       false)) {
613 			osif_err("nla put fail");
614 			goto nla_put_failure;
615 		}
616 	}
617 
618 	osif_debug("Auth Status = %d Subnet Change Status = %d",
619 		   roaming_info->auth_status,
620 		   roaming_info->subnet_change_status);
621 	/*
622 	 * Add subnet change status if subnet has changed
623 	 * 0 = unchanged
624 	 * 1 = changed
625 	 * 2 = unknown
626 	 */
627 	if (roaming_info->subnet_change_status) {
628 		if (nla_put_u8(skb,
629 			       QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
630 			       roaming_info->subnet_change_status)) {
631 			osif_err("nla put fail");
632 			goto nla_put_failure;
633 		}
634 	}
635 
636 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
637 		status = osif_send_roam_auth_mlo_links_event(skb, vdev,
638 							     osif_priv,
639 							     rsp);
640 		if (status) {
641 			osif_err("Send mlo link fail");
642 			goto nla_put_failure;
643 		}
644 	}
645 	cfg80211_vendor_event(skb, qdf_mem_malloc_flags());
646 	return 0;
647 
648 nla_put_failure:
649 	kfree_skb(skb);
650 	return -1;
651 }
652 #else
653 static inline int
654 osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
655 			  struct vdev_osif_priv *osif_priv,
656 			  struct wlan_cm_connect_resp *rsp,
657 			  const uint8_t *req_ie,
658 			  size_t req_ie_len, const uint8_t *resp_ie,
659 			  size_t resp_ie_len)
660 {
661 	return 0;
662 }
663 #endif
664 
665 static void osif_cm_get_reassoc_req_ie_data(struct element_info *assoc_req,
666 					    size_t *ie_data_len,
667 					    const uint8_t **ie_data_ptr)
668 {
669 	/* Validate IE and length */
670 	if (!assoc_req->len || !assoc_req->ptr ||
671 	    assoc_req->len <= WLAN_REASSOC_REQ_IES_OFFSET)
672 		return;
673 
674 	*ie_data_len = assoc_req->len - WLAN_REASSOC_REQ_IES_OFFSET;
675 	*ie_data_ptr = assoc_req->ptr + WLAN_REASSOC_REQ_IES_OFFSET;
676 }
677 
678 void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
679 				   struct vdev_osif_priv *osif_priv,
680 				   struct wlan_cm_connect_resp *rsp)
681 {
682 	struct net_device *dev = osif_priv->wdev->netdev;
683 	size_t req_len = 0;
684 	const uint8_t *req_ie = NULL;
685 	size_t rsp_len = 0;
686 	const uint8_t *rsp_ie = NULL;
687 	struct cfg80211_bss *bss;
688 	struct ieee80211_channel *chan;
689 	struct wlan_objmgr_psoc *psoc;
690 
691 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
692 	    wlan_vdev_mlme_is_mlo_link_vdev(vdev))
693 		return;
694 
695 	if (QDF_IS_STATUS_ERROR(rsp->connect_status))
696 		return;
697 
698 	psoc = wlan_vdev_get_psoc(vdev);
699 	if (!psoc)
700 		return;
701 
702 	chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
703 				     rsp->freq);
704 	bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
705 				    rsp->bssid.bytes, rsp->ssid.ssid,
706 				    rsp->ssid.length);
707 	if (!bss)
708 		osif_warn("not able to find bss");
709 	if (rsp->is_assoc)
710 		osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
711 					      &req_len, &req_ie);
712 	else
713 		osif_cm_get_reassoc_req_ie_data(&rsp->connect_ies.assoc_req,
714 						&req_len, &req_ie);
715 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
716 				      &rsp_len, &rsp_ie);
717 	osif_roamed_ind(dev, vdev, rsp, bss, req_ie, req_len, rsp_ie, rsp_len);
718 	osif_send_roam_auth_event(vdev, osif_priv, rsp, req_ie, req_len, rsp_ie,
719 				  rsp_len);
720 
721 	osif_update_fils_hlp_data(dev, vdev, rsp);
722 }
723 
724 QDF_STATUS
725 osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev,
726 			    struct qdf_mac_addr *bssid,
727 			    int index, bool preauth)
728 {
729 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
730 	struct wireless_dev *wdev;
731 
732 	if (!osif_priv) {
733 		osif_err("Invalid vdev osif priv");
734 		return QDF_STATUS_E_INVAL;
735 	}
736 
737 	wdev = osif_priv->wdev;
738 	if (!wdev) {
739 		osif_err("wdev is null");
740 		return QDF_STATUS_E_INVAL;
741 	}
742 
743 	osif_debug("is going to notify supplicant of:");
744 	osif_info(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(bssid->bytes));
745 
746 	cfg80211_pmksa_candidate_notify(wdev->netdev, index,
747 					bssid->bytes,
748 					preauth, qdf_mem_malloc_flags());
749 	return QDF_STATUS_SUCCESS;
750 }
751 #endif /* CONN_MGR_ADV_FEATURE */
752