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