xref: /wlan-dirver/qca-wifi-host-cmn/os_if/linux/mlme/src/osif_cm_util.c (revision 689990d5df106ae79275687b40b8144dd8fee6ff)
1 /*
2  * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: osif_cm_util.c
20  *
21  * This file maintains definitaions of connect, disconnect, roam
22  * common apis.
23  */
24 #include <include/wlan_mlme_cmn.h>
25 #include "osif_cm_util.h"
26 #include "wlan_osif_priv.h"
27 #include "wlan_cfg80211.h"
28 #include "osif_cm_rsp.h"
29 #include "wlan_cfg80211_scan.h"
30 #include "wlan_mlo_mgr_sta.h"
31 
32 enum qca_sta_connect_fail_reason_codes
33 osif_cm_mac_to_qca_connect_fail_reason(enum wlan_status_code internal_reason)
34 {
35 	enum qca_sta_connect_fail_reason_codes reason = 0;
36 
37 	if (internal_reason < STATUS_PROP_START)
38 		return reason;
39 
40 	switch (internal_reason) {
41 	case STATUS_NO_NETWORK_FOUND:
42 		reason = QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND;
43 		break;
44 	case STATUS_AUTH_TX_FAIL:
45 		reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL;
46 		break;
47 	case STATUS_AUTH_NO_ACK_RECEIVED:
48 		reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED;
49 		break;
50 	case STATUS_AUTH_NO_RESP_RECEIVED:
51 		reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED;
52 		break;
53 	case STATUS_ASSOC_TX_FAIL:
54 		reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL;
55 		break;
56 	case STATUS_ASSOC_NO_ACK_RECEIVED:
57 		reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED;
58 		break;
59 	case STATUS_ASSOC_NO_RESP_RECEIVED:
60 		reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED;
61 		break;
62 	default:
63 		osif_debug("QCA code not present for internal status code %d",
64 			   internal_reason);
65 	}
66 
67 	return reason;
68 }
69 
70 const char *
71 osif_cm_qca_reason_to_str(enum qca_disconnect_reason_codes reason)
72 {
73 	switch (reason) {
74 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE);
75 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE);
76 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE);
77 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA);
78 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR);
79 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED);
80 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_DEVICE_RECOVERY);
81 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_KEY_TIMEOUT);
82 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE);
83 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_IFACE_DOWN);
84 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL);
85 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_INACTIVITY);
86 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT);
87 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE);
88 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE);
89 	CASE_RETURN_STRING(QCA_DISCONNECT_REASON_USER_TRIGGERED);
90 	case QCA_DISCONNECT_REASON_UNSPECIFIED:
91 		return "";
92 	default:
93 		return "Unknown";
94 	}
95 }
96 
97 enum qca_disconnect_reason_codes
98 osif_cm_mac_to_qca_reason(enum wlan_reason_code internal_reason)
99 {
100 	enum qca_disconnect_reason_codes reason =
101 					QCA_DISCONNECT_REASON_UNSPECIFIED;
102 
103 	if (internal_reason < REASON_PROP_START)
104 		return reason;
105 
106 	switch (internal_reason) {
107 	case REASON_HOST_TRIGGERED_ROAM_FAILURE:
108 	case REASON_FW_TRIGGERED_ROAM_FAILURE:
109 		reason = QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE;
110 		break;
111 	case REASON_USER_TRIGGERED_ROAM_FAILURE:
112 		reason = QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE;
113 		break;
114 	case REASON_GATEWAY_REACHABILITY_FAILURE:
115 		reason =
116 		QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE;
117 		break;
118 	case REASON_UNSUPPORTED_CHANNEL_CSA:
119 		reason = QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA;
120 		break;
121 	case REASON_OPER_CHANNEL_DISABLED_INDOOR:
122 		reason =
123 		QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR;
124 		break;
125 	case REASON_OPER_CHANNEL_USER_DISABLED:
126 		reason =
127 		QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED;
128 		break;
129 	case REASON_DEVICE_RECOVERY:
130 		reason = QCA_DISCONNECT_REASON_DEVICE_RECOVERY;
131 		break;
132 	case REASON_KEY_TIMEOUT:
133 		reason = QCA_DISCONNECT_REASON_KEY_TIMEOUT;
134 		break;
135 	case REASON_OPER_CHANNEL_BAND_CHANGE:
136 		reason = QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE;
137 		break;
138 	case REASON_IFACE_DOWN:
139 		reason = QCA_DISCONNECT_REASON_IFACE_DOWN;
140 		break;
141 	case REASON_PEER_XRETRY_FAIL:
142 		reason = QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL;
143 		break;
144 	case REASON_PEER_INACTIVITY:
145 		reason = QCA_DISCONNECT_REASON_PEER_INACTIVITY;
146 		break;
147 	case REASON_SA_QUERY_TIMEOUT:
148 		reason = QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT;
149 		break;
150 	case REASON_CHANNEL_SWITCH_FAILED:
151 		reason = QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE;
152 		break;
153 	case REASON_BEACON_MISSED:
154 		reason = QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE;
155 		break;
156 	default:
157 		osif_debug("No QCA reason code for mac reason: %u",
158 			   internal_reason);
159 		/* Unspecified reason by default */
160 	}
161 
162 	return reason;
163 }
164 
165 static struct osif_cm_ops *osif_cm_legacy_ops;
166 
167 void osif_cm_reset_id_and_src_no_lock(struct vdev_osif_priv *osif_priv)
168 {
169 	osif_priv->cm_info.last_id = CM_ID_INVALID;
170 	osif_priv->cm_info.last_source = CM_SOURCE_INVALID;
171 }
172 
173 QDF_STATUS osif_cm_reset_id_and_src(struct wlan_objmgr_vdev *vdev)
174 {
175 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
176 
177 	if (!osif_priv) {
178 		osif_err("Invalid vdev osif priv");
179 		return QDF_STATUS_E_INVAL;
180 	}
181 	qdf_spinlock_acquire(&osif_priv->cm_info.cmd_id_lock);
182 	osif_cm_reset_id_and_src_no_lock(osif_priv);
183 	qdf_spinlock_release(&osif_priv->cm_info.cmd_id_lock);
184 
185 	return QDF_STATUS_SUCCESS;
186 }
187 
188 /**
189  * osif_cm_connect_complete_cb() - Connect complete callback
190  * @vdev: vdev pointer
191  * @rsp: connect response
192  *
193  * Return: QDF_STATUS
194  */
195 static QDF_STATUS
196 osif_cm_connect_complete_cb(struct wlan_objmgr_vdev *vdev,
197 			    struct wlan_cm_connect_resp *rsp)
198 {
199 	return osif_connect_handler(vdev, rsp);
200 }
201 
202 /**
203  * osif_cm_failed_candidate_cb() - Callback to indicate failed candidate
204  * @vdev: vdev pointer
205  * @rsp: connect response
206  *
207  * Return: QDF_STATUS
208  */
209 static QDF_STATUS
210 osif_cm_failed_candidate_cb(struct wlan_objmgr_vdev *vdev,
211 			    struct wlan_cm_connect_resp *rsp)
212 {
213 	return osif_failed_candidate_handler(vdev, rsp);
214 }
215 
216 /**
217  * osif_cm_update_id_and_src_cb() - Callback to update id and
218  * source of the connect/disconnect request
219  * @vdev: vdev pointer
220  * @source: Source of the connect req
221  * @cm_id: Connect/disconnect id
222  *
223  * Context: Any context. Takes and releases cmd id spinlock
224  * Return: QDF_STATUS
225  */
226 static QDF_STATUS
227 osif_cm_update_id_and_src_cb(struct wlan_objmgr_vdev *vdev,
228 			     enum wlan_cm_source source, wlan_cm_id cm_id)
229 {
230 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
231 
232 	if (!osif_priv) {
233 		osif_err("Invalid vdev osif priv");
234 		return QDF_STATUS_E_INVAL;
235 	}
236 
237 	qdf_spinlock_acquire(&osif_priv->cm_info.cmd_id_lock);
238 	osif_priv->cm_info.last_id = cm_id;
239 	osif_priv->cm_info.last_source = source;
240 	qdf_spinlock_release(&osif_priv->cm_info.cmd_id_lock);
241 
242 	return QDF_STATUS_SUCCESS;
243 }
244 
245 /**
246  * osif_cm_disconnect_complete_cb() - Disconnect done callback
247  * @vdev: vdev pointer
248  * @rsp: Disconnect response
249  *
250  * Context: Any context
251  * Return: QDF_STATUS
252  */
253 
254 static QDF_STATUS
255 osif_cm_disconnect_complete_cb(struct wlan_objmgr_vdev *vdev,
256 			       struct wlan_cm_discon_rsp *rsp)
257 {
258 	return osif_disconnect_handler(vdev, rsp);
259 }
260 
261 #ifdef CONN_MGR_ADV_FEATURE
262 void osif_cm_unlink_bss(struct wlan_objmgr_vdev *vdev,
263 			struct qdf_mac_addr *bssid)
264 {
265 	struct scan_filter *filter;
266 
267 	filter = qdf_mem_malloc(sizeof(*filter));
268 	if (!filter)
269 		return;
270 
271 	filter->num_of_bssid = 1;
272 	qdf_copy_macaddr(&filter->bssid_list[0], bssid);
273 	ucfg_scan_flush_results(wlan_vdev_get_pdev(vdev), filter);
274 	qdf_mem_free(filter);
275 }
276 
277 static QDF_STATUS
278 osif_cm_disable_netif_queue(struct wlan_objmgr_vdev *vdev)
279 {
280 	return osif_cm_netif_queue_ind(vdev,
281 				       WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
282 				       WLAN_CONTROL_PATH);
283 }
284 
285 /**
286  * osif_cm_roam_sync_cb() - Roam sync callback
287  * @vdev: vdev pointer
288  *
289  * This callback indicates os_if that roam sync ind received
290  * so that os_if can stop all the activity on this connection
291  *
292  * Return: QDF_STATUS
293  */
294 static QDF_STATUS
295 osif_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev)
296 {
297 	osif_cm_napi_serialize(true);
298 	return osif_cm_netif_queue_ind(vdev,
299 				       WLAN_STOP_ALL_NETIF_QUEUE,
300 				       WLAN_CONTROL_PATH);
301 }
302 
303 /**
304  * osif_pmksa_candidate_notify_cb() - Roam pmksa candidate notify callback
305  * @vdev: vdev pointer
306  * @bssid: bssid
307  * @index: index
308  * @preauth: preauth flag
309  *
310  * Return: QDF_STATUS
311  */
312 static QDF_STATUS
313 osif_pmksa_candidate_notify_cb(struct wlan_objmgr_vdev *vdev,
314 			       struct qdf_mac_addr *bssid,
315 			       int index, bool preauth)
316 {
317 	return osif_pmksa_candidate_notify(vdev, bssid, index, preauth);
318 }
319 
320 /**
321  * osif_cm_send_keys_cb() - Send keys callback
322  * @vdev: vdev pointer
323  * @key_index: key index
324  * @pairwise: true if pairwise
325  * @cipher_type: cipher type
326  *
327  * This callback indicates os_if that
328  * so that os_if can stop all the activity on this connection
329  *
330  * Return: QDF_STATUS
331  */
332 static QDF_STATUS
333 osif_cm_send_keys_cb(struct wlan_objmgr_vdev *vdev, uint8_t key_index,
334 		     bool pairwise, enum wlan_crypto_cipher_type cipher_type)
335 {
336 	return osif_cm_send_vdev_keys(vdev,
337 				       key_index,
338 				       pairwise,
339 				       cipher_type);
340 }
341 #else
342 static inline QDF_STATUS
343 osif_cm_disable_netif_queue(struct wlan_objmgr_vdev *vdev)
344 {
345 	return QDF_STATUS_SUCCESS;
346 }
347 #endif
348 
349 #if defined(CONN_MGR_ADV_FEATURE) && defined(WLAN_FEATURE_11BE_MLO)
350 /**
351  * osif_link_reconfig_notify_cb() - Link reconfig notify callback
352  * @vdev: vdev pointer
353  *
354  * Return: QDF_STATUS
355  */
356 static QDF_STATUS
357 osif_link_reconfig_notify_cb(struct wlan_objmgr_vdev *vdev)
358 {
359 	struct vdev_osif_priv *osif_priv;
360 	struct wlan_objmgr_vdev *assoc_vdev;
361 	struct wireless_dev *wdev;
362 	uint8_t link_id;
363 	uint16_t link_mask;
364 	struct pdev_osif_priv *pdev_osif_priv;
365 	struct wlan_objmgr_pdev *pdev;
366 	uint32_t data_len;
367 	struct sk_buff *vendor_event;
368 	struct qdf_mac_addr ap_mld_mac;
369 	QDF_STATUS status;
370 
371 	assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
372 	if (!assoc_vdev) {
373 		osif_err("Failed to get assoc vdev");
374 		return QDF_STATUS_E_INVAL;
375 	}
376 
377 	osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
378 	if (!osif_priv) {
379 		osif_err("Invalid vdev osif priv");
380 		return QDF_STATUS_E_INVAL;
381 	}
382 
383 	wdev = osif_priv->wdev;
384 	if (!wdev) {
385 		osif_err("wdev is null");
386 		return QDF_STATUS_E_INVAL;
387 	}
388 	pdev = wlan_vdev_get_pdev(assoc_vdev);
389 	if (!pdev) {
390 		osif_debug("null pdev");
391 		return QDF_STATUS_E_INVAL;
392 	}
393 	pdev_osif_priv = wlan_pdev_get_ospriv(pdev);
394 	if (!pdev_osif_priv || !pdev_osif_priv->wiphy) {
395 		osif_debug("null wiphy");
396 		return QDF_STATUS_E_INVAL;
397 	}
398 
399 	link_id = wlan_vdev_get_link_id(vdev);
400 	link_mask = 1 << link_id;
401 	osif_debug("link reconfig on vdev %d with link id %d mask 0x%x",
402 		   wlan_vdev_get_id(vdev), link_id, link_mask);
403 
404 	status = wlan_vdev_get_bss_peer_mld_mac(vdev, &ap_mld_mac);
405 	if (QDF_IS_STATUS_ERROR(status)) {
406 		osif_debug("get peer mld failed, vdev %d",
407 			   wlan_vdev_get_id(vdev));
408 		return status;
409 	}
410 	osif_debug("ap mld addr: "QDF_MAC_ADDR_FMT,
411 		   QDF_MAC_ADDR_REF(ap_mld_mac.bytes));
412 
413 	data_len = nla_total_size(QDF_MAC_ADDR_SIZE) +
414 		   nla_total_size(sizeof(uint16_t)) +
415 		   NLMSG_HDRLEN;
416 
417 	vendor_event =
418 	wlan_cfg80211_vendor_event_alloc(pdev_osif_priv->wiphy,
419 					 wdev, data_len,
420 					 QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG_INDEX,
421 					 GFP_KERNEL);
422 	if (!vendor_event) {
423 		osif_debug("wlan_cfg80211_vendor_event_alloc failed");
424 		return QDF_STATUS_E_NOMEM;
425 	}
426 
427 	if (nla_put(vendor_event,
428 		    QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_AP_MLD_ADDR,
429 		    QDF_MAC_ADDR_SIZE, &ap_mld_mac.bytes[0]) ||
430 	    nla_put_u16(vendor_event,
431 			QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_REMOVED_LINKS,
432 			link_mask)) {
433 		osif_debug("QCA_WLAN_VENDOR_ATTR put fail");
434 		wlan_cfg80211_vendor_free_skb(vendor_event);
435 		return QDF_STATUS_E_INVAL;
436 	}
437 
438 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
439 
440 	return QDF_STATUS_SUCCESS;
441 }
442 #else
443 static inline QDF_STATUS
444 osif_link_reconfig_notify_cb(struct wlan_objmgr_vdev *vdev)
445 {
446 	return QDF_STATUS_SUCCESS;
447 }
448 #endif
449 
450 /**
451  * osif_cm_disconnect_start_cb() - Disconnect start callback
452  * @vdev: vdev pointer
453  * @source: Disconnect source
454  *
455  * This callback indicates os_if that disconnection is started
456  * so that os_if can stop all the activity on this connection
457  *
458  * Return: QDF_STATUS
459  */
460 static QDF_STATUS osif_cm_disconnect_start_cb(struct wlan_objmgr_vdev *vdev,
461 					      enum wlan_cm_source source)
462 {
463 	/* Don't stop netif queues for link switch disconnect */
464 	if (source == CM_MLO_LINK_SWITCH_DISCONNECT)
465 		return QDF_STATUS_SUCCESS;
466 
467 	/* Disable netif queue on disconnect start */
468 	return osif_cm_disable_netif_queue(vdev);
469 }
470 
471 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
472 /**
473  * osif_cm_roam_start_cb() - Roam start callback
474  * @vdev: vdev pointer
475  *
476  * This callback indicates os_if that roaming has started
477  * so that os_if can stop all the activity on this connection
478  *
479  * Return: QDF_STATUS
480  */
481 static QDF_STATUS
482 osif_cm_roam_start_cb(struct wlan_objmgr_vdev *vdev)
483 {
484 	osif_cm_perfd_set_cpufreq(true);
485 	return osif_cm_netif_queue_ind(vdev,
486 				       WLAN_STOP_ALL_NETIF_QUEUE,
487 				       WLAN_CONTROL_PATH);
488 }
489 
490 /**
491  * osif_cm_roam_abort_cb() - Roam abort callback
492  * @vdev: vdev pointer
493  *
494  * This callback indicates os_if that roaming has been aborted
495  * so that os_if can resume all the activity on this connection
496  *
497  * Return: QDF_STATUS
498  */
499 static QDF_STATUS
500 osif_cm_roam_abort_cb(struct wlan_objmgr_vdev *vdev)
501 {
502 	osif_cm_perfd_set_cpufreq(false);
503 	osif_cm_napi_serialize(false);
504 	return osif_cm_netif_queue_ind(vdev,
505 				       WLAN_WAKE_ALL_NETIF_QUEUE,
506 				       WLAN_CONTROL_PATH);
507 }
508 
509 /**
510  * osif_cm_roam_cmpl_cb() - Roam sync complete callback
511  * @vdev: vdev pointer
512  *
513  * This callback indicates os_if that roam sync is complete
514  * so that os_if can stop all the activity on this connection
515  *
516  * Return: QDF_STATUS
517  */
518 
519 static QDF_STATUS
520 osif_cm_roam_cmpl_cb(struct wlan_objmgr_vdev *vdev)
521 {
522 	osif_cm_perfd_set_cpufreq(false);
523 	return osif_cm_napi_serialize(false);
524 }
525 
526 /**
527  * osif_cm_get_scan_ie_params() - Function to get scan ie params
528  * @vdev: vdev pointer
529  * @scan_ie: Pointer to scan_ie
530  * @dot11mode_filter: Pointer to dot11mode_filter
531  *
532  * Get scan IE params from adapter corresponds to given vdev
533  *
534  * Return: QDF_STATUS
535  */
536 static QDF_STATUS
537 osif_cm_get_scan_ie_params(struct wlan_objmgr_vdev *vdev,
538 			   struct element_info *scan_ie,
539 			   enum dot11_mode_filter *dot11mode_filter)
540 {
541 	osif_cm_get_scan_ie_params_cb cb = NULL;
542 
543 	if (osif_cm_legacy_ops)
544 		cb = osif_cm_legacy_ops->get_scan_ie_params_cb;
545 	if (cb)
546 		return cb(vdev, scan_ie, dot11mode_filter);
547 
548 	return QDF_STATUS_E_FAILURE;
549 }
550 
551 /**
552  * osif_cm_get_scan_ie_info_cb() - Roam get scan ie params callback
553  * @vdev: vdev pointer
554  * @scan_ie: pointer to scan ie
555  * @dot11mode_filter: pointer to dot11 mode filter
556  *
557  * This callback gets scan ie params from os_if
558  *
559  * Return: QDF_STATUS
560  */
561 
562 static QDF_STATUS
563 osif_cm_get_scan_ie_info_cb(struct wlan_objmgr_vdev *vdev,
564 			    struct element_info *scan_ie,
565 			    enum dot11_mode_filter *dot11mode_filter)
566 {
567 	return osif_cm_get_scan_ie_params(vdev, scan_ie, dot11mode_filter);
568 }
569 
570 /**
571  * osif_cm_roam_rt_stats_evt_cb() - Roam stats callback
572  * @roam_stats: roam_stats_event pointer
573  * @idx: TLV idx for roam_stats_event
574  *
575  * This callback indicates os_if that roam stats event is received
576  * so that os_if can send the event
577  *
578  * Return: void
579  */
580 
581 static void
582 osif_cm_roam_rt_stats_evt_cb(struct roam_stats_event *roam_stats,
583 		      uint8_t idx)
584 {
585 	if (osif_cm_legacy_ops &&
586 	    osif_cm_legacy_ops->roam_rt_stats_event_cb)
587 		osif_cm_legacy_ops->roam_rt_stats_event_cb(roam_stats, idx);
588 }
589 
590 #endif
591 
592 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
593 /**
594  * osif_cm_ft_preauth_cmpl_cb() - Roam ft preauth complete callback
595  * @vdev: vdev pointer
596  * @rsp: preauth response
597  *
598  * This callback indicates os_if that roam ft preauth is complete
599  * so that os_if can send fast transition event
600  *
601  * Return: QDF_STATUS
602  */
603 
604 static QDF_STATUS
605 osif_cm_ft_preauth_cmpl_cb(struct wlan_objmgr_vdev *vdev,
606 			   struct wlan_preauth_rsp *rsp)
607 {
608 	osif_cm_ft_preauth_complete_cb cb = NULL;
609 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
610 
611 	if (osif_cm_legacy_ops)
612 		cb = osif_cm_legacy_ops->ft_preauth_complete_cb;
613 	if (cb)
614 		ret = cb(vdev, rsp);
615 
616 	return ret;
617 }
618 
619 #ifdef FEATURE_WLAN_ESE
620 /**
621  * osif_cm_cckm_preauth_cmpl_cb() - Roam cckm preauth complete callback
622  * @vdev: vdev pointer
623  * @rsp: preauth response
624  *
625  * This callback indicates os_if that roam cckm preauth is complete
626  * so that os_if can send cckm preauth indication to the supplicant
627  * via wireless custom event.
628  *
629  * Return: QDF_STATUS
630  */
631 
632 static QDF_STATUS
633 osif_cm_cckm_preauth_cmpl_cb(struct wlan_objmgr_vdev *vdev,
634 			     struct wlan_preauth_rsp *rsp)
635 {
636 	osif_cm_cckm_preauth_complete_cb cb = NULL;
637 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
638 
639 	if (osif_cm_legacy_ops)
640 		cb = osif_cm_legacy_ops->cckm_preauth_complete_cb;
641 	if (cb)
642 		ret = cb(vdev, rsp);
643 
644 	return ret;
645 }
646 #endif
647 #endif
648 
649 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
650 /**
651  * osif_cm_perfd_reset_cpufreq_ctrl_cb() - Callback to reset CPU freq
652  *
653  * This callback indicates os_if to reset the request to boost CPU freq
654  *
655  * Return: None
656  */
657 static void osif_cm_perfd_reset_cpufreq_ctrl_cb(void)
658 {
659 	osif_cm_perfd_set_cpufreq(false);
660 }
661 #endif
662 
663 static struct mlme_cm_ops cm_ops = {
664 	.mlme_cm_connect_complete_cb = osif_cm_connect_complete_cb,
665 	.mlme_cm_failed_candidate_cb = osif_cm_failed_candidate_cb,
666 	.mlme_cm_update_id_and_src_cb = osif_cm_update_id_and_src_cb,
667 	.mlme_cm_disconnect_complete_cb = osif_cm_disconnect_complete_cb,
668 	.mlme_cm_disconnect_start_cb = osif_cm_disconnect_start_cb,
669 #ifdef CONN_MGR_ADV_FEATURE
670 	.mlme_cm_roam_sync_cb = osif_cm_roam_sync_cb,
671 	.mlme_cm_pmksa_candidate_notify_cb = osif_pmksa_candidate_notify_cb,
672 	.mlme_cm_send_keys_cb = osif_cm_send_keys_cb,
673 	.mlme_cm_link_reconfig_notify_cb = osif_link_reconfig_notify_cb,
674 #endif
675 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
676 	.mlme_cm_roam_start_cb = osif_cm_roam_start_cb,
677 	.mlme_cm_roam_abort_cb = osif_cm_roam_abort_cb,
678 	.mlme_cm_roam_cmpl_cb = osif_cm_roam_cmpl_cb,
679 	.mlme_cm_roam_get_scan_ie_cb = osif_cm_get_scan_ie_info_cb,
680 	.mlme_cm_roam_rt_stats_cb = osif_cm_roam_rt_stats_evt_cb,
681 #endif
682 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
683 	.mlme_cm_ft_preauth_cmpl_cb = osif_cm_ft_preauth_cmpl_cb,
684 #ifdef FEATURE_WLAN_ESE
685 	.mlme_cm_cckm_preauth_cmpl_cb = osif_cm_cckm_preauth_cmpl_cb,
686 #endif
687 #endif
688 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
689 	.mlme_cm_get_vendor_handoff_params_cb =
690 					osif_cm_vendor_handoff_params_cb,
691 #endif
692 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
693 	.mlme_cm_perfd_reset_cpufreq_ctrl_cb =
694 				osif_cm_perfd_reset_cpufreq_ctrl_cb,
695 #endif
696 };
697 
698 /**
699  * osif_cm_get_global_ops() - Get connection manager global ops
700  *
701  * Return: Connection manager global ops
702  */
703 static struct mlme_cm_ops *osif_cm_get_global_ops(void)
704 {
705 	return &cm_ops;
706 }
707 
708 QDF_STATUS osif_cm_register_cb(void)
709 {
710 	mlme_set_osif_cm_cb(osif_cm_get_global_ops);
711 
712 	return QDF_STATUS_SUCCESS;
713 }
714 
715 QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
716 {
717 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
718 	enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
719 
720 	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
721 		return QDF_STATUS_SUCCESS;
722 
723 	if (!osif_priv) {
724 		osif_err("Invalid vdev osif priv");
725 		return QDF_STATUS_E_INVAL;
726 	}
727 
728 	qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock);
729 
730 	return QDF_STATUS_SUCCESS;
731 }
732 
733 QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
734 {
735 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
736 	enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
737 
738 	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
739 		return QDF_STATUS_SUCCESS;
740 
741 	if (!osif_priv) {
742 		osif_err("Invalid vdev osif priv");
743 		return QDF_STATUS_E_INVAL;
744 	}
745 	qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock);
746 
747 	return QDF_STATUS_SUCCESS;
748 }
749 
750 QDF_STATUS osif_cm_connect_comp_ind(struct wlan_objmgr_vdev *vdev,
751 				    struct wlan_cm_connect_resp *rsp,
752 				    enum osif_cb_type type)
753 {
754 	osif_cm_connect_comp_cb cb = NULL;
755 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
756 
757 	if (osif_cm_legacy_ops)
758 		cb = osif_cm_legacy_ops->connect_complete_cb;
759 	if (cb)
760 		ret = cb(vdev, rsp, type);
761 
762 	return ret;
763 }
764 
765 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
766 QDF_STATUS osif_cm_vendor_handoff_params_cb(struct wlan_objmgr_psoc *psoc,
767 					    void *vendor_handoff_context)
768 {
769 	osif_cm_get_vendor_handoff_params_cb cb = NULL;
770 
771 	if (osif_cm_legacy_ops)
772 		cb = osif_cm_legacy_ops->vendor_handoff_params_cb;
773 	if (cb)
774 		return cb(psoc, vendor_handoff_context);
775 
776 	return QDF_STATUS_E_FAILURE;
777 }
778 #endif
779 
780 QDF_STATUS osif_cm_disconnect_comp_ind(struct wlan_objmgr_vdev *vdev,
781 				       struct wlan_cm_discon_rsp *rsp,
782 				       enum osif_cb_type type)
783 {
784 	osif_cm_disconnect_comp_cb cb = NULL;
785 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
786 
787 	if (osif_cm_legacy_ops)
788 		cb = osif_cm_legacy_ops->disconnect_complete_cb;
789 	if (cb)
790 		ret = cb(vdev, rsp, type);
791 
792 	return ret;
793 }
794 
795 #ifdef CONN_MGR_ADV_FEATURE
796 QDF_STATUS osif_cm_netif_queue_ind(struct wlan_objmgr_vdev *vdev,
797 				   enum netif_action_type action,
798 				   enum netif_reason_type reason)
799 {
800 	osif_cm_netif_queue_ctrl_cb cb = NULL;
801 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
802 
803 	if (osif_cm_legacy_ops)
804 		cb = osif_cm_legacy_ops->netif_queue_control_cb;
805 	if (cb)
806 		ret = cb(vdev, action, reason);
807 
808 	return ret;
809 }
810 
811 QDF_STATUS osif_cm_napi_serialize(bool action)
812 {
813 	os_if_cm_napi_serialize_ctrl_cb cb = NULL;
814 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
815 
816 	if (osif_cm_legacy_ops)
817 		cb = osif_cm_legacy_ops->napi_serialize_control_cb;
818 	if (cb)
819 		ret = cb(action);
820 
821 	return ret;
822 }
823 
824 QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
825 			    struct wlan_cm_connect_resp *rsp)
826 {
827 	osif_cm_save_gtk_cb cb = NULL;
828 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
829 
830 	if (osif_cm_legacy_ops)
831 		cb = osif_cm_legacy_ops->save_gtk_cb;
832 	if (cb)
833 		ret = cb(vdev, rsp);
834 
835 	return ret;
836 }
837 
838 QDF_STATUS
839 osif_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
840 		       uint8_t key_index,
841 		       bool pairwise,
842 		       enum wlan_crypto_cipher_type cipher_type)
843 {
844 	osif_cm_send_vdev_keys_cb cb = NULL;
845 
846 	if (osif_cm_legacy_ops)
847 		cb = osif_cm_legacy_ops->send_vdev_keys_cb;
848 	if (cb)
849 		return cb(vdev, key_index, pairwise, cipher_type);
850 
851 	return QDF_STATUS_E_FAILURE;
852 }
853 #endif
854 
855 #ifdef WLAN_FEATURE_FILS_SK
856 QDF_STATUS osif_cm_set_hlp_data(struct net_device *dev,
857 				struct wlan_objmgr_vdev *vdev,
858 				struct wlan_cm_connect_resp *rsp)
859 {
860 	osif_cm_set_hlp_data_cb cb = NULL;
861 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
862 
863 	if (osif_cm_legacy_ops)
864 		cb = osif_cm_legacy_ops->set_hlp_data_cb;
865 	if (cb)
866 		ret = cb(dev, vdev, rsp);
867 
868 	return ret;
869 }
870 #endif
871 
872 void osif_cm_set_legacy_cb(struct osif_cm_ops *osif_legacy_ops)
873 {
874 	osif_cm_legacy_ops = osif_legacy_ops;
875 }
876 
877 void osif_cm_reset_legacy_cb(void)
878 {
879 	osif_cm_legacy_ops = NULL;
880 }
881 
882 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
883 QDF_STATUS osif_cm_perfd_set_cpufreq(bool action)
884 {
885 	os_if_cm_perfd_set_cpufreq_ctrl_cb cb = NULL;
886 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
887 
888 	if (osif_cm_legacy_ops)
889 		cb = osif_cm_legacy_ops->perfd_set_cpufreq_cb;
890 	if (cb)
891 		ret = cb(action);
892 
893 	return ret;
894 }
895 #endif
896