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