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