xref: /wlan-dirver/qca-wifi-host-cmn/os_if/linux/mlme/src/osif_cm_connect_rsp.c (revision 878d42c770e8f4f39f616b20412de44faeced7b9)
1 /*
2  * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: osif_cm_connect_rsp.c
19  *
20  * This file maintains definitaions of connect response apis.
21  */
22 
23 #include <linux/version.h>
24 #include <linux/nl80211.h>
25 #include <net/cfg80211.h>
26 #include "wlan_osif_priv.h"
27 #include "osif_cm_rsp.h"
28 #include "osif_cm_util.h"
29 #include "wlan_cfg80211.h"
30 #include "wlan_cfg80211_scan.h"
31 
32 #ifdef CONN_MGR_ADV_FEATURE
33 void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req,
34 				   size_t *ie_data_len,
35 				   const uint8_t **ie_data_ptr)
36 {
37 	/* Validate IE and length */
38 	if (!assoc_req->len || !assoc_req->ptr ||
39 	    assoc_req->len <= WLAN_ASSOC_REQ_IES_OFFSET)
40 		return;
41 
42 	*ie_data_len = assoc_req->len - WLAN_ASSOC_REQ_IES_OFFSET;
43 	*ie_data_ptr = assoc_req->ptr + WLAN_ASSOC_REQ_IES_OFFSET;
44 }
45 
46 void osif_cm_get_assoc_rsp_ie_data(struct element_info *assoc_rsp,
47 				   size_t *ie_data_len,
48 				   const uint8_t **ie_data_ptr)
49 {
50 	/* Validate IE and length */
51 	if (!assoc_rsp->len || !assoc_rsp->ptr ||
52 	    assoc_rsp->len <= WLAN_ASSOC_RSP_IES_OFFSET)
53 		return;
54 
55 	*ie_data_len = assoc_rsp->len - WLAN_ASSOC_RSP_IES_OFFSET;
56 	*ie_data_ptr = assoc_rsp->ptr + WLAN_ASSOC_RSP_IES_OFFSET;
57 }
58 
59 #else
60 
61 void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req,
62 				   size_t *ie_data_len,
63 				   const uint8_t **ie_data_ptr)
64 {
65 	*ie_data_len = assoc_req->len;
66 	*ie_data_ptr = assoc_req->ptr;
67 }
68 
69 void osif_cm_get_assoc_rsp_ie_data(struct element_info *assoc_rsp,
70 				   size_t *ie_data_len,
71 				   const uint8_t **ie_data_ptr)
72 {
73 	*ie_data_len = assoc_rsp->len;
74 	*ie_data_ptr = assoc_rsp->ptr;
75 }
76 
77 #endif
78 
79 /**
80  * osif_validate_connect_and_reset_src_id() - Validate connect response and
81  * resets source and id
82  * @osif_priv: Pointer to vdev osif priv
83  * @rsp: Connection manager connect response
84  *
85  * This function validates connect response and if the connect
86  * response is valid, resets the source and id of the command
87  *
88  * Context: Any context. Takes and releases cmd id spinlock.
89  * Return: QDF_STATUS
90  */
91 static QDF_STATUS
92 osif_validate_connect_and_reset_src_id(struct vdev_osif_priv *osif_priv,
93 				       struct wlan_cm_connect_resp *rsp)
94 {
95 	QDF_STATUS status = QDF_STATUS_SUCCESS;
96 
97 	/*
98 	 * Do not send to kernel if last osif cookie doesnt match or
99 	 * or source is CM_OSIF_CFG_CONNECT with success status.
100 	 * If cookie matches reset the cookie and source.
101 	 */
102 	qdf_spinlock_acquire(&osif_priv->cm_info.cmd_id_lock);
103 	if (rsp->cm_id != osif_priv->cm_info.last_id ||
104 	    (osif_priv->cm_info.last_source == CM_OSIF_CFG_CONNECT &&
105 	     QDF_IS_STATUS_SUCCESS(rsp->connect_status))) {
106 		osif_debug("Ignore as cm_id(0x%x)/src(%d) != cm_id(0x%x)/src(%d) OR source is CFG connect with status %d",
107 			   rsp->cm_id, CM_OSIF_CONNECT,
108 			   osif_priv->cm_info.last_id,
109 			   osif_priv->cm_info.last_source,
110 			   rsp->connect_status);
111 		status = QDF_STATUS_E_INVAL;
112 		goto rel_lock;
113 	}
114 
115 	osif_cm_reset_id_and_src_no_lock(osif_priv);
116 rel_lock:
117 	qdf_spinlock_release(&osif_priv->cm_info.cmd_id_lock);
118 
119 	return status;
120 }
121 
122 static enum ieee80211_statuscode
123 osif_get_statuscode(enum wlan_status_code status)
124 {
125 	return (enum ieee80211_statuscode)status;
126 }
127 
128 static enum ieee80211_statuscode
129 osif_get_connect_status_code(struct wlan_cm_connect_resp *rsp)
130 {
131 	enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS;
132 
133 	if (QDF_IS_STATUS_ERROR(rsp->connect_status)) {
134 		if (rsp->status_code)
135 			status = osif_get_statuscode(rsp->status_code);
136 		else
137 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
138 	}
139 
140 	return status;
141 }
142 
143 /**
144  * osif_convert_timeout_reason() - Convert to kernel specific enum
145  * @timeout_reason: reason for connect timeout
146  *
147  * This function is used to convert host timeout
148  * reason enum to kernel specific enum.
149  *
150  * Context: Any context.
151  * Return: nl timeout enum
152  */
153 
154 static enum nl80211_timeout_reason
155 osif_convert_timeout_reason(enum wlan_cm_connect_fail_reason reason)
156 {
157 	switch (reason) {
158 	case CM_JOIN_TIMEOUT:
159 		return NL80211_TIMEOUT_SCAN;
160 	case CM_AUTH_TIMEOUT:
161 		return NL80211_TIMEOUT_AUTH;
162 	case CM_ASSOC_TIMEOUT:
163 		return NL80211_TIMEOUT_ASSOC;
164 	default:
165 		return NL80211_TIMEOUT_UNSPECIFIED;
166 	}
167 }
168 
169 #if defined CFG80211_CONNECT_BSS || \
170 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
171 
172 #if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
173 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
174 /**
175  * osif_connect_timeout() - API to send connection timeout reason
176  * @dev: network device
177  * @bssid: bssid to which we want to associate
178  * @reason: reason for connect timeout
179  *
180  * This API is used to send connection timeout reason to supplicant
181  *
182  * Context: Any context.
183  * Return: Void
184  */
185 static void
186 osif_connect_timeout(struct net_device *dev, const u8 *bssid,
187 		     enum wlan_cm_connect_fail_reason reason)
188 {
189 	enum nl80211_timeout_reason nl_timeout_reason;
190 
191 	nl_timeout_reason = osif_convert_timeout_reason(reason);
192 
193 	osif_debug("nl_timeout_reason %d", nl_timeout_reason);
194 
195 	cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
196 				 nl_timeout_reason);
197 }
198 
199 /**
200  * __osif_connect_bss() - API to send connection status to supplicant
201  * @dev: network device
202  * @bss: bss info
203  * @connect_rsp: Connection manager connect response
204  *
205  * Context: Any context.
206  * Return: void
207  */
208 static void __osif_connect_bss(struct net_device *dev,
209 			       struct cfg80211_bss *bss,
210 			       struct wlan_cm_connect_resp *rsp,
211 			       enum ieee80211_statuscode status)
212 {
213 	enum nl80211_timeout_reason nl_timeout_reason;
214 	size_t req_len = 0;
215 	const uint8_t *req_ptr = NULL;
216 	size_t rsp_len = 0;
217 	const uint8_t *rsp_ptr = NULL;
218 
219 	nl_timeout_reason = osif_convert_timeout_reason(rsp->reason);
220 
221 	osif_debug("nl_timeout_reason %d", nl_timeout_reason);
222 
223 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
224 				      &req_len, &req_ptr);
225 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
226 				      &rsp_len, &rsp_ptr);
227 
228 	cfg80211_connect_bss(dev, rsp->bssid.bytes, bss,
229 			     req_ptr, req_len, rsp_ptr, rsp_len, status,
230 			     GFP_KERNEL, nl_timeout_reason);
231 }
232 #else /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */
233 
234 #if defined CFG80211_CONNECT_TIMEOUT || \
235 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
236 static void osif_connect_timeout(
237 			struct net_device *dev,
238 			const u8 *bssid,
239 			enum wlan_cm_connect_fail_reason reason)
240 {
241 	cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
242 }
243 #endif
244 
245 static void __osif_connect_bss(struct net_device *dev,
246 			       struct cfg80211_bss *bss,
247 			       struct wlan_cm_connect_resp *rsp,
248 			       ieee80211_statuscode status)
249 {
250 	size_t req_len = 0;
251 	const uint8_t *req_ptr = NULL;
252 	size_t rsp_len = 0;
253 	const uint8_t *rsp_ptr = NULL;
254 
255 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
256 				      &req_len, &req_ptr);
257 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
258 				      &rsp_len, &rsp_ptr);
259 
260 	cfg80211_connect_bss(dev, rsp->bssid.bytes, bss,
261 			     req_ptr, req_len, rsp_ptr, rsp_len,
262 			     status, GFP_KERNEL);
263 }
264 #endif /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */
265 
266 /**
267  * osif_connect_bss() - API to send connection status to supplicant
268  * @dev: network device
269  * @bss: bss info
270  * @connect_rsp: Connection manager connect response
271  *
272  * The API is a wrapper to send connection status to supplicant
273  *
274  * Context: Any context.
275  * Return: Void
276  */
277 #if defined CFG80211_CONNECT_TIMEOUT || \
278 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
279 static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss,
280 			     struct wlan_cm_connect_resp *rsp)
281 {
282 	enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS;
283 
284 	osif_enter_dev(dev);
285 
286 	if (rsp->reason == CM_JOIN_TIMEOUT ||
287 	    rsp->reason == CM_AUTH_TIMEOUT ||
288 	    rsp->reason == CM_ASSOC_TIMEOUT) {
289 		osif_connect_timeout(dev, rsp->bssid.bytes,
290 				     rsp->reason);
291 	} else {
292 		status = osif_get_connect_status_code(rsp);
293 
294 		__osif_connect_bss(dev, bss, rsp, status);
295 	}
296 }
297 #else /* CFG80211_CONNECT_TIMEOUT */
298 static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss,
299 			     struct wlan_cm_connect_resp *rsp)
300 {
301 	enum ieee80211_statuscode status;
302 
303 	osif_enter_dev(dev);
304 
305 	status = osif_get_connect_status_code(rsp);
306 	__osif_connect_bss(dev, bss, rsp, status);
307 }
308 #endif /* CFG80211_CONNECT_TIMEOUT */
309 
310 #if defined(WLAN_FEATURE_FILS_SK)
311 
312 #if (defined(CFG80211_CONNECT_DONE) || \
313 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) && \
314 	(LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
315 
316 #if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
317 		 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
318 /**
319  * osif_populate_fils_params() - Populate FILS keys to connect response
320  * @conn_rsp_params: connect response to supplicant
321  * @fils_ie: Fils ie information from connection manager
322  *
323  * Context: Any context.
324  * Return: None
325  */
326 static void
327 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
328 			  struct fils_connect_rsp_params *fils_ie)
329 {
330 	/*  Increment seq number to be used for next FILS */
331 	rsp_params->fils_erp_next_seq_num = fils_ie->fils_seq_num + 1;
332 	rsp_params->update_erp_next_seq_num = true;
333 	rsp_params->fils_kek = fils_ie->kek;
334 	rsp_params->fils_kek_len = fils_ie->kek_len;
335 	rsp_params->pmk = fils_ie->fils_pmk;
336 	rsp_params->pmk_len = fils_ie->fils_pmk_len;
337 	rsp_params->pmkid = fils_ie->fils_pmkid;
338 	osif_debug("erp_next_seq_num:%d", rsp_params->fils_erp_next_seq_num);
339 }
340 #else /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */
341 static inline void
342 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
343 			  struct fils_connect_rsp_params *fils_ie)
344 
345 { }
346 #endif /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */
347 
348 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
349 /**
350  * osif_populate_fils_params() - Populate FILS keys to connect response
351  * @conn_rsp_params: connect response to supplicant
352  * @fils_ie: Fils ie information from connection manager
353  *
354  * Context: Any context.
355  * Return: None
356  */
357 static void
358 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
359 			  struct fils_connect_rsp_params *fils_ie)
360 
361 {
362 	/* Increament seq number to be used for next FILS */
363 	rsp_params->fils.erp_next_seq_num = fils_ie->fils_seq_num + 1;
364 	rsp_params->fils.update_erp_next_seq_num = true;
365 	rsp_params->fils.kek = fils_ie->kek;
366 	rsp_params->fils.kek_len = fils_ie->kek_len;
367 	rsp_params->fils.pmk = fils_ie->fils_pmk;
368 	rsp_params->fils.pmk_len = fils_ie->fils_pmk_len;
369 	rsp_params->fils.pmkid = fils_ie->fils_pmkid;
370 	osif_debug("erp_next_seq_num:%d", rsp_params->fils.erp_next_seq_num);
371 }
372 #endif /* CFG80211_CONNECT_DONE */
373 
374 #if defined(CFG80211_CONNECT_DONE) || \
375 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
376 
377 /**
378  * osif_connect_done() - Wrapper API to call cfg80211_connect_done
379  * @dev: network device
380  * @bss: bss info
381  * @connect_rsp: Connection manager connect response
382  * @vdev: pointer to vdev
383  *
384  * This API is used as wrapper to send FILS key/sequence number
385  * params etc. to supplicant in case of FILS connection
386  *
387  * Context: Any context.
388  * Return: None
389  */
390 static void osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss,
391 			      struct wlan_cm_connect_resp *rsp,
392 			      struct wlan_objmgr_vdev *vdev)
393 {
394 	struct cfg80211_connect_resp_params conn_rsp_params;
395 	enum ieee80211_statuscode status;
396 
397 	osif_enter_dev(dev);
398 
399 	status = osif_get_connect_status_code(rsp);
400 	qdf_mem_zero(&conn_rsp_params, sizeof(conn_rsp_params));
401 
402 	if (!rsp->connect_ies.fils_ie) {
403 		conn_rsp_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
404 	} else {
405 		conn_rsp_params.status = status;
406 		conn_rsp_params.bssid = rsp->bssid.bytes;
407 		conn_rsp_params.timeout_reason =
408 			osif_convert_timeout_reason(rsp->reason);
409 		osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
410 					      &conn_rsp_params.req_ie_len,
411 					      &conn_rsp_params.req_ie);
412 		osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
413 					      &conn_rsp_params.resp_ie_len,
414 					      &conn_rsp_params.resp_ie);
415 		conn_rsp_params.bss = bss;
416 		osif_populate_fils_params(&conn_rsp_params,
417 					  rsp->connect_ies.fils_ie);
418 		osif_cm_save_gtk(vdev, rsp);
419 	}
420 
421 	osif_debug("Connect resp status  %d", conn_rsp_params.status);
422 	cfg80211_connect_done(dev, &conn_rsp_params, GFP_KERNEL);
423 	if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len)
424 		osif_cm_set_hlp_data(dev, vdev, rsp);
425 }
426 #else /* CFG80211_CONNECT_DONE */
427 static inline void
428 osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss,
429 		  struct wlan_cm_connect_resp *rsp,
430 		  struct wlan_objmgr_vdev *vdev)
431 { }
432 #endif /* CFG80211_CONNECT_DONE */
433 #endif /* WLAN_FEATURE_FILS_SK */
434 
435 #if defined(WLAN_FEATURE_FILS_SK) && \
436 	(defined(CFG80211_CONNECT_DONE) || \
437 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
438 /**
439  * osif_fils_update_connect_results() - API to send fils connection status to
440  * supplicant.
441  * @dev: network device
442  * @bss: bss info
443  * @connect_rsp: Connection manager connect response
444  * @vdev: pointer to vdev
445  *
446  * The API is a wrapper to send connection status to supplicant
447  *
448  * Context: Any context.
449  * Return: 0 if success else failure
450  */
451 static int osif_update_connect_results(struct net_device *dev,
452 				       struct cfg80211_bss *bss,
453 				       struct wlan_cm_connect_resp *rsp,
454 				       struct wlan_objmgr_vdev *vdev)
455 {
456 	if (!rsp->is_fils_connection) {
457 		osif_debug("fils IE is NULL");
458 		return -EINVAL;
459 	}
460 	osif_connect_done(dev, bss, rsp, vdev);
461 
462 	return 0;
463 }
464 #else /* WLAN_FEATURE_FILS_SK && CFG80211_CONNECT_DONE */
465 
466 static inline int osif_update_connect_results(struct net_device *dev,
467 					      struct cfg80211_bss *bss,
468 					      struct wlan_cm_connect_resp *rsp,
469 					      struct wlan_objmgr_vdev *vdev)
470 {
471 	return -EINVAL;
472 }
473 #endif /* WLAN_FEATURE_FILS_SK && CFG80211_CONNECT_DONE */
474 
475 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
476 					 struct vdev_osif_priv *osif_priv,
477 					 struct wlan_cm_connect_resp *rsp)
478 {
479 	struct cfg80211_bss *bss = NULL;
480 	struct ieee80211_channel *chan;
481 
482 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
483 		chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
484 					     rsp->freq);
485 		bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
486 					    rsp->bssid.bytes,
487 					    rsp->ssid.ssid,
488 					    rsp->ssid.length);
489 	}
490 
491 	if (osif_update_connect_results(osif_priv->wdev->netdev, bss,
492 					rsp, vdev))
493 		osif_connect_bss(osif_priv->wdev->netdev, bss, rsp);
494 }
495 #else  /* CFG80211_CONNECT_BSS */
496 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
497 					 struct vdev_osif_priv *osif_priv,
498 					 struct wlan_cm_connect_resp *rsp)
499 {
500 	enum ieee80211_statuscode status;
501 	size_t req_len = 0;
502 	const uint8_t *req_ptr = NULL;
503 	size_t rsp_len = 0;
504 	const uint8_t *rsp_ptr = NULL;
505 
506 	status = osif_get_connect_status_code(rsp);
507 	osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
508 				      &req_len, &req_ptr);
509 	osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
510 				      &rsp_len, &rsp_ptr);
511 	cfg80211_connect_result(osif_priv->wdev->netdev,
512 				rsp->bssid.bytes, req_ptr, req_len,
513 				rsp_ptr, rsp_len, status, GFP_KERNEL);
514 }
515 #endif /* CFG80211_CONNECT_BSS */
516 
517 #ifdef CONN_MGR_ADV_FEATURE
518 static inline
519 bool osif_cm_is_unlink_bss_required(struct wlan_cm_connect_resp *rsp)
520 {
521 	if (QDF_IS_STATUS_SUCCESS(rsp->connect_status))
522 		return false;
523 
524 	if (rsp->reason == CM_NO_CANDIDATE_FOUND ||
525 	    rsp->reason == CM_JOIN_TIMEOUT ||
526 	    rsp->reason == CM_AUTH_TIMEOUT ||
527 	    rsp->reason == CM_ASSOC_TIMEOUT)
528 		return true;
529 
530 	return false;
531 }
532 static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev,
533 					     struct vdev_osif_priv *osif_priv,
534 					     struct wlan_cm_connect_resp *rsp)
535 {
536 	if (osif_cm_is_unlink_bss_required(rsp))
537 		osif_cm_unlink_bss(vdev, osif_priv, &rsp->bssid, rsp->ssid.ssid,
538 				   rsp->ssid.length);
539 }
540 #else
541 static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev,
542 					     struct vdev_osif_priv *osif_priv,
543 					     struct wlan_cm_connect_resp *rsp)
544 {}
545 #endif
546 
547 QDF_STATUS osif_connect_handler(struct wlan_objmgr_vdev *vdev,
548 				struct wlan_cm_connect_resp *rsp)
549 {
550 	struct vdev_osif_priv *osif_priv  = wlan_vdev_get_ospriv(vdev);
551 	QDF_STATUS status;
552 
553 	osif_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " Connect with " QDF_MAC_ADDR_FMT " SSID \"%.*s\" is %s cm_id 0x%x cm_reason %d status_code %d is_reassoc %d",
554 		       osif_priv->wdev->netdev->name, rsp->vdev_id,
555 		       QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)),
556 		       QDF_MAC_ADDR_REF(rsp->bssid.bytes),
557 		       rsp->ssid.length, rsp->ssid.ssid,
558 		       rsp->connect_status ? "FAILURE" : "SUCCESS", rsp->cm_id,
559 		       rsp->reason, rsp->status_code, rsp->is_reassoc);
560 
561 	osif_check_and_unlink_bss(vdev, osif_priv, rsp);
562 
563 	status = osif_validate_connect_and_reset_src_id(osif_priv, rsp);
564 	if (QDF_IS_STATUS_ERROR(status)) {
565 		osif_cm_connect_comp_ind(vdev, rsp, OSIF_NOT_HANDLED);
566 		return status;
567 	}
568 
569 	osif_cm_connect_comp_ind(vdev, rsp, OSIF_PRE_USERSPACE_UPDATE);
570 	if (rsp->is_reassoc)
571 		osif_indicate_reassoc_results(vdev, osif_priv, rsp);
572 	else
573 		osif_indcate_connect_results(vdev, osif_priv, rsp);
574 	osif_cm_connect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE);
575 
576 	return QDF_STATUS_SUCCESS;
577 }
578 
579 QDF_STATUS osif_failed_candidate_handler(struct wlan_objmgr_vdev *vdev,
580 					 struct wlan_cm_connect_resp *rsp)
581 {
582 	struct vdev_osif_priv *osif_priv  = wlan_vdev_get_ospriv(vdev);
583 
584 	osif_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " Connect with " QDF_MAC_ADDR_FMT " SSID \"%.*s\" FAILED cm_id 0x%x cm_reason %d reason_code %d",
585 		       osif_priv->wdev->netdev->name, rsp->vdev_id,
586 		       QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)),
587 		       QDF_MAC_ADDR_REF(rsp->bssid.bytes),
588 		       rsp->ssid.length, rsp->ssid.ssid, rsp->cm_id,
589 		       rsp->reason, rsp->status_code);
590 
591 	osif_check_and_unlink_bss(vdev, osif_priv, rsp);
592 
593 	return QDF_STATUS_SUCCESS;
594 }
595