xref: /wlan-driver/qca-wifi-host-cmn/os_if/linux/mlme/src/osif_cm_util.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2024 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
osif_cm_mac_to_qca_connect_fail_reason(enum wlan_status_code internal_reason)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 *
osif_cm_qca_reason_to_str(enum qca_disconnect_reason_codes reason)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
osif_cm_mac_to_qca_reason(enum wlan_reason_code internal_reason)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 
osif_cm_reset_id_and_src_no_lock(struct vdev_osif_priv * osif_priv)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 
osif_cm_reset_id_and_src(struct wlan_objmgr_vdev * vdev)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
osif_cm_connect_complete_cb(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)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
osif_cm_failed_candidate_cb(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)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
osif_cm_update_id_and_src_cb(struct wlan_objmgr_vdev * vdev,enum wlan_cm_source source,wlan_cm_id cm_id)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
osif_cm_disconnect_complete_cb(struct wlan_objmgr_vdev * vdev,struct wlan_cm_discon_rsp * rsp)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
osif_cm_unlink_bss(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bssid)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
osif_cm_disable_netif_queue(struct wlan_objmgr_vdev * vdev)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
osif_cm_roam_sync_cb(struct wlan_objmgr_vdev * vdev)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
osif_pmksa_candidate_notify_cb(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bssid,int index,bool preauth)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
osif_cm_send_keys_cb(struct wlan_objmgr_vdev * vdev,uint8_t key_index,bool pairwise,enum wlan_crypto_cipher_type cipher_type)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
osif_cm_disable_netif_queue(struct wlan_objmgr_vdev * vdev)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
osif_link_reconfig_notify_cb(struct wlan_objmgr_vdev * vdev)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
osif_link_reconfig_notify_cb(struct wlan_objmgr_vdev * vdev)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  */
osif_cm_disconnect_start_cb(struct wlan_objmgr_vdev * vdev,enum wlan_cm_source source)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 	    source == CM_MLO_ROAM_INTERNAL_DISCONNECT)
466 		return QDF_STATUS_SUCCESS;
467 
468 	/* Disable netif queue on disconnect start */
469 	return osif_cm_disable_netif_queue(vdev);
470 }
471 
472 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
473 /**
474  * osif_cm_roam_start_cb() - Roam start callback
475  * @vdev: vdev pointer
476  *
477  * This callback indicates os_if that roaming has started
478  * so that os_if can stop all the activity on this connection
479  *
480  * Return: QDF_STATUS
481  */
482 static QDF_STATUS
osif_cm_roam_start_cb(struct wlan_objmgr_vdev * vdev)483 osif_cm_roam_start_cb(struct wlan_objmgr_vdev *vdev)
484 {
485 	osif_cm_perfd_set_cpufreq(true);
486 	return osif_cm_netif_queue_ind(vdev,
487 				       WLAN_STOP_ALL_NETIF_QUEUE,
488 				       WLAN_CONTROL_PATH);
489 }
490 
491 /**
492  * osif_cm_roam_abort_cb() - Roam abort callback
493  * @vdev: vdev pointer
494  *
495  * This callback indicates os_if that roaming has been aborted
496  * so that os_if can resume all the activity on this connection
497  *
498  * Return: QDF_STATUS
499  */
500 static QDF_STATUS
osif_cm_roam_abort_cb(struct wlan_objmgr_vdev * vdev)501 osif_cm_roam_abort_cb(struct wlan_objmgr_vdev *vdev)
502 {
503 	osif_cm_perfd_set_cpufreq(false);
504 	osif_cm_napi_serialize(false);
505 	return osif_cm_netif_queue_ind(vdev,
506 				       WLAN_WAKE_ALL_NETIF_QUEUE,
507 				       WLAN_CONTROL_PATH);
508 }
509 
510 /**
511  * osif_cm_roam_cmpl_cb() - Roam sync complete callback
512  * @vdev: vdev pointer
513  *
514  * This callback indicates os_if that roam sync is complete
515  * so that os_if can stop all the activity on this connection
516  *
517  * Return: QDF_STATUS
518  */
519 
520 static QDF_STATUS
osif_cm_roam_cmpl_cb(struct wlan_objmgr_vdev * vdev)521 osif_cm_roam_cmpl_cb(struct wlan_objmgr_vdev *vdev)
522 {
523 	osif_cm_perfd_set_cpufreq(false);
524 	return osif_cm_napi_serialize(false);
525 }
526 
527 /**
528  * osif_cm_get_scan_ie_params() - Function to get scan ie params
529  * @vdev: vdev pointer
530  * @scan_ie: Pointer to scan_ie
531  * @dot11mode_filter: Pointer to dot11mode_filter
532  *
533  * Get scan IE params from adapter corresponds to given vdev
534  *
535  * Return: QDF_STATUS
536  */
537 static QDF_STATUS
osif_cm_get_scan_ie_params(struct wlan_objmgr_vdev * vdev,struct element_info * scan_ie,enum dot11_mode_filter * dot11mode_filter)538 osif_cm_get_scan_ie_params(struct wlan_objmgr_vdev *vdev,
539 			   struct element_info *scan_ie,
540 			   enum dot11_mode_filter *dot11mode_filter)
541 {
542 	osif_cm_get_scan_ie_params_cb cb = NULL;
543 
544 	if (osif_cm_legacy_ops)
545 		cb = osif_cm_legacy_ops->get_scan_ie_params_cb;
546 	if (cb)
547 		return cb(vdev, scan_ie, dot11mode_filter);
548 
549 	return QDF_STATUS_E_FAILURE;
550 }
551 
552 /**
553  * osif_cm_get_scan_ie_info_cb() - Roam get scan ie params callback
554  * @vdev: vdev pointer
555  * @scan_ie: pointer to scan ie
556  * @dot11mode_filter: pointer to dot11 mode filter
557  *
558  * This callback gets scan ie params from os_if
559  *
560  * Return: QDF_STATUS
561  */
562 
563 static QDF_STATUS
osif_cm_get_scan_ie_info_cb(struct wlan_objmgr_vdev * vdev,struct element_info * scan_ie,enum dot11_mode_filter * dot11mode_filter)564 osif_cm_get_scan_ie_info_cb(struct wlan_objmgr_vdev *vdev,
565 			    struct element_info *scan_ie,
566 			    enum dot11_mode_filter *dot11mode_filter)
567 {
568 	return osif_cm_get_scan_ie_params(vdev, scan_ie, dot11mode_filter);
569 }
570 
571 /**
572  * osif_cm_roam_rt_stats_evt_cb() - Roam stats callback
573  * @roam_stats: roam_stats_event pointer
574  * @idx: TLV idx for roam_stats_event
575  *
576  * This callback indicates os_if that roam stats event is received
577  * so that os_if can send the event
578  *
579  * Return: void
580  */
581 
582 static void
osif_cm_roam_rt_stats_evt_cb(struct roam_stats_event * roam_stats,uint8_t idx)583 osif_cm_roam_rt_stats_evt_cb(struct roam_stats_event *roam_stats,
584 		      uint8_t idx)
585 {
586 	if (osif_cm_legacy_ops &&
587 	    osif_cm_legacy_ops->roam_rt_stats_event_cb)
588 		osif_cm_legacy_ops->roam_rt_stats_event_cb(roam_stats, idx);
589 }
590 
591 #endif
592 
593 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
594 /**
595  * osif_cm_ft_preauth_cmpl_cb() - Roam ft preauth complete callback
596  * @vdev: vdev pointer
597  * @rsp: preauth response
598  *
599  * This callback indicates os_if that roam ft preauth is complete
600  * so that os_if can send fast transition event
601  *
602  * Return: QDF_STATUS
603  */
604 
605 static QDF_STATUS
osif_cm_ft_preauth_cmpl_cb(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)606 osif_cm_ft_preauth_cmpl_cb(struct wlan_objmgr_vdev *vdev,
607 			   struct wlan_preauth_rsp *rsp)
608 {
609 	osif_cm_ft_preauth_complete_cb cb = NULL;
610 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
611 
612 	if (osif_cm_legacy_ops)
613 		cb = osif_cm_legacy_ops->ft_preauth_complete_cb;
614 	if (cb)
615 		ret = cb(vdev, rsp);
616 
617 	return ret;
618 }
619 
620 #ifdef FEATURE_WLAN_ESE
621 /**
622  * osif_cm_cckm_preauth_cmpl_cb() - Roam cckm preauth complete callback
623  * @vdev: vdev pointer
624  * @rsp: preauth response
625  *
626  * This callback indicates os_if that roam cckm preauth is complete
627  * so that os_if can send cckm preauth indication to the supplicant
628  * via wireless custom event.
629  *
630  * Return: QDF_STATUS
631  */
632 
633 static QDF_STATUS
osif_cm_cckm_preauth_cmpl_cb(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)634 osif_cm_cckm_preauth_cmpl_cb(struct wlan_objmgr_vdev *vdev,
635 			     struct wlan_preauth_rsp *rsp)
636 {
637 	osif_cm_cckm_preauth_complete_cb cb = NULL;
638 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
639 
640 	if (osif_cm_legacy_ops)
641 		cb = osif_cm_legacy_ops->cckm_preauth_complete_cb;
642 	if (cb)
643 		ret = cb(vdev, rsp);
644 
645 	return ret;
646 }
647 #endif
648 #endif
649 
650 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
651 /**
652  * osif_cm_perfd_reset_cpufreq_ctrl_cb() - Callback to reset CPU freq
653  *
654  * This callback indicates os_if to reset the request to boost CPU freq
655  *
656  * Return: None
657  */
osif_cm_perfd_reset_cpufreq_ctrl_cb(void)658 static void osif_cm_perfd_reset_cpufreq_ctrl_cb(void)
659 {
660 	osif_cm_perfd_set_cpufreq(false);
661 }
662 #endif
663 
664 static struct mlme_cm_ops cm_ops = {
665 #ifdef CONN_MGR_ADV_FEATURE
666 	.mlme_cm_connect_active_notify_cb = osif_cm_connect_active_notify,
667 #endif
668 	.mlme_cm_connect_complete_cb = osif_cm_connect_complete_cb,
669 	.mlme_cm_failed_candidate_cb = osif_cm_failed_candidate_cb,
670 	.mlme_cm_update_id_and_src_cb = osif_cm_update_id_and_src_cb,
671 	.mlme_cm_disconnect_complete_cb = osif_cm_disconnect_complete_cb,
672 	.mlme_cm_disconnect_start_cb = osif_cm_disconnect_start_cb,
673 #ifdef CONN_MGR_ADV_FEATURE
674 	.mlme_cm_roam_sync_cb = osif_cm_roam_sync_cb,
675 	.mlme_cm_pmksa_candidate_notify_cb = osif_pmksa_candidate_notify_cb,
676 	.mlme_cm_send_keys_cb = osif_cm_send_keys_cb,
677 	.mlme_cm_link_reconfig_notify_cb = osif_link_reconfig_notify_cb,
678 #endif
679 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
680 	.mlme_cm_roam_start_cb = osif_cm_roam_start_cb,
681 	.mlme_cm_roam_abort_cb = osif_cm_roam_abort_cb,
682 	.mlme_cm_roam_cmpl_cb = osif_cm_roam_cmpl_cb,
683 	.mlme_cm_roam_get_scan_ie_cb = osif_cm_get_scan_ie_info_cb,
684 	.mlme_cm_roam_rt_stats_cb = osif_cm_roam_rt_stats_evt_cb,
685 #endif
686 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
687 	.mlme_cm_ft_preauth_cmpl_cb = osif_cm_ft_preauth_cmpl_cb,
688 #ifdef FEATURE_WLAN_ESE
689 	.mlme_cm_cckm_preauth_cmpl_cb = osif_cm_cckm_preauth_cmpl_cb,
690 #endif
691 #endif
692 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
693 	.mlme_cm_get_vendor_handoff_params_cb =
694 					osif_cm_vendor_handoff_params_cb,
695 #endif
696 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
697 	.mlme_cm_perfd_reset_cpufreq_ctrl_cb =
698 				osif_cm_perfd_reset_cpufreq_ctrl_cb,
699 #endif
700 };
701 
702 /**
703  * osif_cm_get_global_ops() - Get connection manager global ops
704  *
705  * Return: Connection manager global ops
706  */
osif_cm_get_global_ops(void)707 static struct mlme_cm_ops *osif_cm_get_global_ops(void)
708 {
709 	return &cm_ops;
710 }
711 
osif_cm_register_cb(void)712 QDF_STATUS osif_cm_register_cb(void)
713 {
714 	mlme_set_osif_cm_cb(osif_cm_get_global_ops);
715 
716 	return QDF_STATUS_SUCCESS;
717 }
718 
osif_cm_osif_priv_init(struct wlan_objmgr_vdev * vdev)719 QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev)
720 {
721 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
722 	enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
723 
724 	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
725 		return QDF_STATUS_SUCCESS;
726 
727 	if (!osif_priv) {
728 		osif_err("Invalid vdev osif priv");
729 		return QDF_STATUS_E_INVAL;
730 	}
731 
732 	qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock);
733 
734 	return QDF_STATUS_SUCCESS;
735 }
736 
osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev * vdev)737 QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
738 {
739 	struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
740 	enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev);
741 
742 	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
743 		return QDF_STATUS_SUCCESS;
744 
745 	if (!osif_priv) {
746 		osif_err("Invalid vdev osif priv");
747 		return QDF_STATUS_E_INVAL;
748 	}
749 	qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock);
750 
751 	return QDF_STATUS_SUCCESS;
752 }
753 
754 #ifdef CONN_MGR_ADV_FEATURE
osif_cm_connect_active_notify(uint8_t vdev_id)755 void osif_cm_connect_active_notify(uint8_t vdev_id)
756 {
757 	if (osif_cm_legacy_ops && osif_cm_legacy_ops->connect_active_notify_cb)
758 		osif_cm_legacy_ops->connect_active_notify_cb(vdev_id);
759 }
760 #endif
761 
osif_cm_connect_comp_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)762 QDF_STATUS osif_cm_connect_comp_ind(struct wlan_objmgr_vdev *vdev,
763 				    struct wlan_cm_connect_resp *rsp,
764 				    enum osif_cb_type type)
765 {
766 	osif_cm_connect_comp_cb cb = NULL;
767 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
768 
769 	if (osif_cm_legacy_ops)
770 		cb = osif_cm_legacy_ops->connect_complete_cb;
771 	if (cb)
772 		ret = cb(vdev, rsp, type);
773 
774 	return ret;
775 }
776 
777 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
osif_cm_vendor_handoff_params_cb(struct wlan_objmgr_psoc * psoc,void * vendor_handoff_context)778 QDF_STATUS osif_cm_vendor_handoff_params_cb(struct wlan_objmgr_psoc *psoc,
779 					    void *vendor_handoff_context)
780 {
781 	osif_cm_get_vendor_handoff_params_cb cb = NULL;
782 
783 	if (osif_cm_legacy_ops)
784 		cb = osif_cm_legacy_ops->vendor_handoff_params_cb;
785 	if (cb)
786 		return cb(psoc, vendor_handoff_context);
787 
788 	return QDF_STATUS_E_FAILURE;
789 }
790 #endif
791 
osif_cm_disconnect_comp_ind(struct wlan_objmgr_vdev * vdev,struct wlan_cm_discon_rsp * rsp,enum osif_cb_type type)792 QDF_STATUS osif_cm_disconnect_comp_ind(struct wlan_objmgr_vdev *vdev,
793 				       struct wlan_cm_discon_rsp *rsp,
794 				       enum osif_cb_type type)
795 {
796 	osif_cm_disconnect_comp_cb cb = NULL;
797 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
798 
799 	if (osif_cm_legacy_ops)
800 		cb = osif_cm_legacy_ops->disconnect_complete_cb;
801 	if (cb)
802 		ret = cb(vdev, rsp, type);
803 
804 	return ret;
805 }
806 
807 #ifdef CONN_MGR_ADV_FEATURE
osif_cm_netif_queue_ind(struct wlan_objmgr_vdev * vdev,enum netif_action_type action,enum netif_reason_type reason)808 QDF_STATUS osif_cm_netif_queue_ind(struct wlan_objmgr_vdev *vdev,
809 				   enum netif_action_type action,
810 				   enum netif_reason_type reason)
811 {
812 	osif_cm_netif_queue_ctrl_cb cb = NULL;
813 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
814 
815 	if (osif_cm_legacy_ops)
816 		cb = osif_cm_legacy_ops->netif_queue_control_cb;
817 	if (cb)
818 		ret = cb(vdev, action, reason);
819 
820 	return ret;
821 }
822 
osif_cm_napi_serialize(bool action)823 QDF_STATUS osif_cm_napi_serialize(bool action)
824 {
825 	os_if_cm_napi_serialize_ctrl_cb cb = NULL;
826 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
827 
828 	if (osif_cm_legacy_ops)
829 		cb = osif_cm_legacy_ops->napi_serialize_control_cb;
830 	if (cb)
831 		ret = cb(action);
832 
833 	return ret;
834 }
835 
osif_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)836 QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
837 			    struct wlan_cm_connect_resp *rsp)
838 {
839 	osif_cm_save_gtk_cb cb = NULL;
840 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
841 
842 	if (osif_cm_legacy_ops)
843 		cb = osif_cm_legacy_ops->save_gtk_cb;
844 	if (cb)
845 		ret = cb(vdev, rsp);
846 
847 	return ret;
848 }
849 
850 QDF_STATUS
osif_cm_send_vdev_keys(struct wlan_objmgr_vdev * vdev,uint8_t key_index,bool pairwise,enum wlan_crypto_cipher_type cipher_type)851 osif_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
852 		       uint8_t key_index,
853 		       bool pairwise,
854 		       enum wlan_crypto_cipher_type cipher_type)
855 {
856 	osif_cm_send_vdev_keys_cb cb = NULL;
857 
858 	if (osif_cm_legacy_ops)
859 		cb = osif_cm_legacy_ops->send_vdev_keys_cb;
860 	if (cb)
861 		return cb(vdev, key_index, pairwise, cipher_type);
862 
863 	return QDF_STATUS_E_FAILURE;
864 }
865 #endif
866 
867 #ifdef WLAN_FEATURE_FILS_SK
osif_cm_set_hlp_data(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)868 QDF_STATUS osif_cm_set_hlp_data(struct net_device *dev,
869 				struct wlan_objmgr_vdev *vdev,
870 				struct wlan_cm_connect_resp *rsp)
871 {
872 	osif_cm_set_hlp_data_cb cb = NULL;
873 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
874 
875 	if (osif_cm_legacy_ops)
876 		cb = osif_cm_legacy_ops->set_hlp_data_cb;
877 	if (cb)
878 		ret = cb(dev, vdev, rsp);
879 
880 	return ret;
881 }
882 #endif
883 
osif_cm_set_legacy_cb(struct osif_cm_ops * osif_legacy_ops)884 void osif_cm_set_legacy_cb(struct osif_cm_ops *osif_legacy_ops)
885 {
886 	osif_cm_legacy_ops = osif_legacy_ops;
887 }
888 
osif_cm_reset_legacy_cb(void)889 void osif_cm_reset_legacy_cb(void)
890 {
891 	osif_cm_legacy_ops = NULL;
892 }
893 
894 #ifdef WLAN_BOOST_CPU_FREQ_IN_ROAM
osif_cm_perfd_set_cpufreq(bool action)895 QDF_STATUS osif_cm_perfd_set_cpufreq(bool action)
896 {
897 	os_if_cm_perfd_set_cpufreq_ctrl_cb cb = NULL;
898 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
899 
900 	if (osif_cm_legacy_ops)
901 		cb = osif_cm_legacy_ops->perfd_set_cpufreq_cb;
902 	if (cb)
903 		ret = cb(action);
904 
905 	return ret;
906 }
907 #endif
908