1 /* 2 * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: osif_cm_connect_rsp.c 19 * 20 * This file maintains definitaions of connect response apis. 21 */ 22 23 #include <linux/version.h> 24 #include <linux/nl80211.h> 25 #include <net/cfg80211.h> 26 #include "wlan_osif_priv.h" 27 #include "osif_cm_rsp.h" 28 #include "osif_cm_util.h" 29 #include "wlan_cfg80211.h" 30 #include "wlan_cfg80211_scan.h" 31 32 #ifdef CONN_MGR_ADV_FEATURE 33 void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req, 34 size_t *ie_data_len, 35 const uint8_t **ie_data_ptr) 36 { 37 /* Validate IE and length */ 38 if (!assoc_req->len || !assoc_req->ptr || 39 assoc_req->len <= WLAN_ASSOC_REQ_IES_OFFSET) 40 return; 41 42 *ie_data_len = assoc_req->len - WLAN_ASSOC_REQ_IES_OFFSET; 43 *ie_data_ptr = assoc_req->ptr + WLAN_ASSOC_REQ_IES_OFFSET; 44 } 45 46 void osif_cm_get_assoc_rsp_ie_data(struct element_info *assoc_rsp, 47 size_t *ie_data_len, 48 const uint8_t **ie_data_ptr) 49 { 50 /* Validate IE and length */ 51 if (!assoc_rsp->len || !assoc_rsp->ptr || 52 assoc_rsp->len <= WLAN_ASSOC_RSP_IES_OFFSET) 53 return; 54 55 *ie_data_len = assoc_rsp->len - WLAN_ASSOC_RSP_IES_OFFSET; 56 *ie_data_ptr = assoc_rsp->ptr + WLAN_ASSOC_RSP_IES_OFFSET; 57 } 58 59 #else 60 61 void osif_cm_get_assoc_req_ie_data(struct element_info *assoc_req, 62 size_t *ie_data_len, 63 const uint8_t **ie_data_ptr) 64 { 65 *ie_data_len = assoc_req->len; 66 *ie_data_ptr = assoc_req->ptr; 67 } 68 69 void osif_cm_get_assoc_rsp_ie_data(struct element_info *assoc_rsp, 70 size_t *ie_data_len, 71 const uint8_t **ie_data_ptr) 72 { 73 *ie_data_len = assoc_rsp->len; 74 *ie_data_ptr = assoc_rsp->ptr; 75 } 76 77 #endif 78 79 /** 80 * osif_validate_connect_and_reset_src_id() - Validate connect response and 81 * resets source and id 82 * @osif_priv: Pointer to vdev osif priv 83 * @rsp: Connection manager connect response 84 * 85 * This function validates connect response and if the connect 86 * response is valid, resets the source and id of the command 87 * 88 * Context: Any context. Takes and releases cmd id spinlock. 89 * Return: QDF_STATUS 90 */ 91 static QDF_STATUS 92 osif_validate_connect_and_reset_src_id(struct vdev_osif_priv *osif_priv, 93 struct wlan_cm_connect_resp *rsp) 94 { 95 QDF_STATUS status = QDF_STATUS_SUCCESS; 96 97 /* 98 * Do not send to kernel if last osif cookie doesnt match or 99 * or source is CM_OSIF_CFG_CONNECT with success status. 100 * If cookie matches reset the cookie and source. 101 */ 102 qdf_spinlock_acquire(&osif_priv->cm_info.cmd_id_lock); 103 if (rsp->cm_id != osif_priv->cm_info.last_id || 104 (osif_priv->cm_info.last_source == CM_OSIF_CFG_CONNECT && 105 QDF_IS_STATUS_SUCCESS(rsp->connect_status))) { 106 osif_debug("Ignore as cm_id(0x%x)/src(%d) != cm_id(0x%x)/src(%d) OR source is CFG connect with status %d", 107 rsp->cm_id, CM_OSIF_CONNECT, 108 osif_priv->cm_info.last_id, 109 osif_priv->cm_info.last_source, 110 rsp->connect_status); 111 status = QDF_STATUS_E_INVAL; 112 goto rel_lock; 113 } 114 115 osif_cm_reset_id_and_src_no_lock(osif_priv); 116 rel_lock: 117 qdf_spinlock_release(&osif_priv->cm_info.cmd_id_lock); 118 119 return status; 120 } 121 122 static enum ieee80211_statuscode 123 osif_get_statuscode(enum wlan_status_code status) 124 { 125 return (enum ieee80211_statuscode)status; 126 } 127 128 static enum ieee80211_statuscode 129 osif_get_connect_status_code(struct wlan_cm_connect_resp *rsp) 130 { 131 enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS; 132 133 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) { 134 if (rsp->status_code) 135 status = osif_get_statuscode(rsp->status_code); 136 else 137 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 138 } 139 140 return status; 141 } 142 143 /** 144 * osif_convert_timeout_reason() - Convert to kernel specific enum 145 * @timeout_reason: reason for connect timeout 146 * 147 * This function is used to convert host timeout 148 * reason enum to kernel specific enum. 149 * 150 * Context: Any context. 151 * Return: nl timeout enum 152 */ 153 154 static enum nl80211_timeout_reason 155 osif_convert_timeout_reason(enum wlan_cm_connect_fail_reason reason) 156 { 157 switch (reason) { 158 case CM_JOIN_TIMEOUT: 159 return NL80211_TIMEOUT_SCAN; 160 case CM_AUTH_TIMEOUT: 161 return NL80211_TIMEOUT_AUTH; 162 case CM_ASSOC_TIMEOUT: 163 return NL80211_TIMEOUT_ASSOC; 164 default: 165 return NL80211_TIMEOUT_UNSPECIFIED; 166 } 167 } 168 169 #if defined CFG80211_CONNECT_BSS || \ 170 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) 171 172 #if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \ 173 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) 174 /** 175 * osif_connect_timeout() - API to send connection timeout reason 176 * @dev: network device 177 * @bssid: bssid to which we want to associate 178 * @reason: reason for connect timeout 179 * 180 * This API is used to send connection timeout reason to supplicant 181 * 182 * Context: Any context. 183 * Return: Void 184 */ 185 static void 186 osif_connect_timeout(struct net_device *dev, const u8 *bssid, 187 enum wlan_cm_connect_fail_reason reason) 188 { 189 enum nl80211_timeout_reason nl_timeout_reason; 190 191 nl_timeout_reason = osif_convert_timeout_reason(reason); 192 193 osif_debug("nl_timeout_reason %d", nl_timeout_reason); 194 195 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL, 196 nl_timeout_reason); 197 } 198 199 /** 200 * __osif_connect_bss() - API to send connection status to supplicant 201 * @dev: network device 202 * @bss: bss info 203 * @connect_rsp: Connection manager connect response 204 * 205 * Context: Any context. 206 * Return: void 207 */ 208 static void __osif_connect_bss(struct net_device *dev, 209 struct cfg80211_bss *bss, 210 struct wlan_cm_connect_resp *rsp, 211 enum ieee80211_statuscode status) 212 { 213 enum nl80211_timeout_reason nl_timeout_reason; 214 size_t req_len = 0; 215 const uint8_t *req_ptr = NULL; 216 size_t rsp_len = 0; 217 const uint8_t *rsp_ptr = NULL; 218 219 nl_timeout_reason = osif_convert_timeout_reason(rsp->reason); 220 221 osif_debug("nl_timeout_reason %d", nl_timeout_reason); 222 223 osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req, 224 &req_len, &req_ptr); 225 osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp, 226 &rsp_len, &rsp_ptr); 227 228 cfg80211_connect_bss(dev, rsp->bssid.bytes, bss, 229 req_ptr, req_len, rsp_ptr, rsp_len, status, 230 GFP_KERNEL, nl_timeout_reason); 231 } 232 #else /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */ 233 234 #if defined CFG80211_CONNECT_TIMEOUT || \ 235 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) 236 static void osif_connect_timeout( 237 struct net_device *dev, 238 const u8 *bssid, 239 enum wlan_cm_connect_fail_reason reason) 240 { 241 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL); 242 } 243 #endif 244 245 static void __osif_connect_bss(struct net_device *dev, 246 struct cfg80211_bss *bss, 247 struct wlan_cm_connect_resp *rsp, 248 ieee80211_statuscode status) 249 { 250 size_t req_len = 0; 251 const uint8_t *req_ptr = NULL; 252 size_t rsp_len = 0; 253 const uint8_t *rsp_ptr = NULL; 254 255 osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req, 256 &req_len, &req_ptr); 257 osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp, 258 &rsp_len, &rsp_ptr); 259 260 cfg80211_connect_bss(dev, rsp->bssid.bytes, bss, 261 req_ptr, req_len, rsp_ptr, rsp_len, 262 status, GFP_KERNEL); 263 } 264 #endif /* CFG80211_CONNECT_TIMEOUT_REASON_CODE */ 265 266 /** 267 * osif_connect_bss() - API to send connection status to supplicant 268 * @dev: network device 269 * @bss: bss info 270 * @connect_rsp: Connection manager connect response 271 * 272 * The API is a wrapper to send connection status to supplicant 273 * 274 * Context: Any context. 275 * Return: Void 276 */ 277 #if defined CFG80211_CONNECT_TIMEOUT || \ 278 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) 279 static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss, 280 struct wlan_cm_connect_resp *rsp) 281 { 282 enum ieee80211_statuscode status = WLAN_STATUS_SUCCESS; 283 284 osif_enter_dev(dev); 285 286 if (rsp->reason == CM_JOIN_TIMEOUT || 287 rsp->reason == CM_AUTH_TIMEOUT || 288 rsp->reason == CM_ASSOC_TIMEOUT) { 289 osif_connect_timeout(dev, rsp->bssid.bytes, 290 rsp->reason); 291 } else { 292 status = osif_get_connect_status_code(rsp); 293 294 __osif_connect_bss(dev, bss, rsp, status); 295 } 296 } 297 #else /* CFG80211_CONNECT_TIMEOUT */ 298 static void osif_connect_bss(struct net_device *dev, struct cfg80211_bss *bss, 299 struct wlan_cm_connect_resp *rsp) 300 { 301 enum ieee80211_statuscode status; 302 303 osif_enter_dev(dev); 304 305 status = osif_get_connect_status_code(rsp); 306 __osif_connect_bss(dev, bss, rsp, status); 307 } 308 #endif /* CFG80211_CONNECT_TIMEOUT */ 309 310 #if defined(WLAN_FEATURE_FILS_SK) 311 312 #if (defined(CFG80211_CONNECT_DONE) || \ 313 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) && \ 314 (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)) 315 316 #if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \ 317 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) 318 /** 319 * osif_populate_fils_params() - Populate FILS keys to connect response 320 * @conn_rsp_params: connect response to supplicant 321 * @fils_ie: Fils ie information from connection manager 322 * 323 * Context: Any context. 324 * Return: None 325 */ 326 static void 327 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params, 328 struct fils_connect_rsp_params *fils_ie) 329 { 330 /* Increment seq number to be used for next FILS */ 331 rsp_params->fils_erp_next_seq_num = fils_ie->fils_seq_num + 1; 332 rsp_params->update_erp_next_seq_num = true; 333 rsp_params->fils_kek = fils_ie->kek; 334 rsp_params->fils_kek_len = fils_ie->kek_len; 335 rsp_params->pmk = fils_ie->fils_pmk; 336 rsp_params->pmk_len = fils_ie->fils_pmk_len; 337 rsp_params->pmkid = fils_ie->fils_pmkid; 338 osif_debug("erp_next_seq_num:%d", rsp_params->fils_erp_next_seq_num); 339 } 340 #else /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */ 341 static inline void 342 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params, 343 struct fils_connect_rsp_params *fils_ie) 344 345 { } 346 #endif /* CFG80211_FILS_SK_OFFLOAD_SUPPORT */ 347 348 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) 349 /** 350 * osif_populate_fils_params() - Populate FILS keys to connect response 351 * @conn_rsp_params: connect response to supplicant 352 * @fils_ie: Fils ie information from connection manager 353 * 354 * Context: Any context. 355 * Return: None 356 */ 357 static void 358 osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params, 359 struct fils_connect_rsp_params *fils_ie) 360 361 { 362 /* Increament seq number to be used for next FILS */ 363 rsp_params->fils.erp_next_seq_num = fils_ie->fils_seq_num + 1; 364 rsp_params->fils.update_erp_next_seq_num = true; 365 rsp_params->fils.kek = fils_ie->kek; 366 rsp_params->fils.kek_len = fils_ie->kek_len; 367 rsp_params->fils.pmk = fils_ie->fils_pmk; 368 rsp_params->fils.pmk_len = fils_ie->fils_pmk_len; 369 rsp_params->fils.pmkid = fils_ie->fils_pmkid; 370 osif_debug("erp_next_seq_num:%d", rsp_params->fils.erp_next_seq_num); 371 } 372 #endif /* CFG80211_CONNECT_DONE */ 373 374 #if defined(CFG80211_CONNECT_DONE) || \ 375 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) 376 377 /** 378 * osif_connect_done() - Wrapper API to call cfg80211_connect_done 379 * @dev: network device 380 * @bss: bss info 381 * @connect_rsp: Connection manager connect response 382 * @vdev: pointer to vdev 383 * 384 * This API is used as wrapper to send FILS key/sequence number 385 * params etc. to supplicant in case of FILS connection 386 * 387 * Context: Any context. 388 * Return: None 389 */ 390 static void osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss, 391 struct wlan_cm_connect_resp *rsp, 392 struct wlan_objmgr_vdev *vdev) 393 { 394 struct cfg80211_connect_resp_params conn_rsp_params; 395 enum ieee80211_statuscode status; 396 397 osif_enter_dev(dev); 398 399 status = osif_get_connect_status_code(rsp); 400 qdf_mem_zero(&conn_rsp_params, sizeof(conn_rsp_params)); 401 402 if (!rsp->connect_ies.fils_ie) { 403 conn_rsp_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE; 404 } else { 405 conn_rsp_params.status = status; 406 conn_rsp_params.bssid = rsp->bssid.bytes; 407 conn_rsp_params.timeout_reason = 408 osif_convert_timeout_reason(rsp->reason); 409 osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req, 410 &conn_rsp_params.req_ie_len, 411 &conn_rsp_params.req_ie); 412 osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp, 413 &conn_rsp_params.resp_ie_len, 414 &conn_rsp_params.resp_ie); 415 conn_rsp_params.bss = bss; 416 osif_populate_fils_params(&conn_rsp_params, 417 rsp->connect_ies.fils_ie); 418 osif_cm_save_gtk(vdev, rsp); 419 } 420 421 osif_debug("Connect resp status %d", conn_rsp_params.status); 422 cfg80211_connect_done(dev, &conn_rsp_params, GFP_KERNEL); 423 if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len) 424 osif_cm_set_hlp_data(dev, vdev, rsp); 425 } 426 #else /* CFG80211_CONNECT_DONE */ 427 static inline void 428 osif_connect_done(struct net_device *dev, struct cfg80211_bss *bss, 429 struct wlan_cm_connect_resp *rsp, 430 struct wlan_objmgr_vdev *vdev) 431 { } 432 #endif /* CFG80211_CONNECT_DONE */ 433 #endif /* WLAN_FEATURE_FILS_SK */ 434 435 #if defined(WLAN_FEATURE_FILS_SK) && \ 436 (defined(CFG80211_CONNECT_DONE) || \ 437 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))) 438 /** 439 * osif_fils_update_connect_results() - API to send fils connection status to 440 * supplicant. 441 * @dev: network device 442 * @bss: bss info 443 * @connect_rsp: Connection manager connect response 444 * @vdev: pointer to vdev 445 * 446 * The API is a wrapper to send connection status to supplicant 447 * 448 * Context: Any context. 449 * Return: 0 if success else failure 450 */ 451 static int osif_update_connect_results(struct net_device *dev, 452 struct cfg80211_bss *bss, 453 struct wlan_cm_connect_resp *rsp, 454 struct wlan_objmgr_vdev *vdev) 455 { 456 if (!rsp->is_fils_connection) { 457 osif_debug("fils IE is NULL"); 458 return -EINVAL; 459 } 460 osif_connect_done(dev, bss, rsp, vdev); 461 462 return 0; 463 } 464 #else /* WLAN_FEATURE_FILS_SK && CFG80211_CONNECT_DONE */ 465 466 static inline int osif_update_connect_results(struct net_device *dev, 467 struct cfg80211_bss *bss, 468 struct wlan_cm_connect_resp *rsp, 469 struct wlan_objmgr_vdev *vdev) 470 { 471 return -EINVAL; 472 } 473 #endif /* WLAN_FEATURE_FILS_SK && CFG80211_CONNECT_DONE */ 474 475 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev, 476 struct vdev_osif_priv *osif_priv, 477 struct wlan_cm_connect_resp *rsp) 478 { 479 struct cfg80211_bss *bss = NULL; 480 struct ieee80211_channel *chan; 481 482 if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) { 483 chan = ieee80211_get_channel(osif_priv->wdev->wiphy, 484 rsp->freq); 485 bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan, 486 rsp->bssid.bytes, 487 rsp->ssid.ssid, 488 rsp->ssid.length); 489 } 490 491 if (osif_update_connect_results(osif_priv->wdev->netdev, bss, 492 rsp, vdev)) 493 osif_connect_bss(osif_priv->wdev->netdev, bss, rsp); 494 } 495 #else /* CFG80211_CONNECT_BSS */ 496 static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev, 497 struct vdev_osif_priv *osif_priv, 498 struct wlan_cm_connect_resp *rsp) 499 { 500 enum ieee80211_statuscode status; 501 size_t req_len = 0; 502 const uint8_t *req_ptr = NULL; 503 size_t rsp_len = 0; 504 const uint8_t *rsp_ptr = NULL; 505 506 status = osif_get_connect_status_code(rsp); 507 osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req, 508 &req_len, &req_ptr); 509 osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp, 510 &rsp_len, &rsp_ptr); 511 cfg80211_connect_result(osif_priv->wdev->netdev, 512 rsp->bssid.bytes, req_ptr, req_len, 513 rsp_ptr, rsp_len, status, GFP_KERNEL); 514 } 515 #endif /* CFG80211_CONNECT_BSS */ 516 517 #ifdef CONN_MGR_ADV_FEATURE 518 static inline 519 bool osif_cm_is_unlink_bss_required(struct wlan_cm_connect_resp *rsp) 520 { 521 if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) 522 return false; 523 524 if (rsp->reason == CM_NO_CANDIDATE_FOUND || 525 rsp->reason == CM_JOIN_TIMEOUT || 526 rsp->reason == CM_AUTH_TIMEOUT || 527 rsp->reason == CM_ASSOC_TIMEOUT) 528 return true; 529 530 return false; 531 } 532 static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev, 533 struct vdev_osif_priv *osif_priv, 534 struct wlan_cm_connect_resp *rsp) 535 { 536 if (osif_cm_is_unlink_bss_required(rsp)) 537 osif_cm_unlink_bss(vdev, osif_priv, &rsp->bssid, rsp->ssid.ssid, 538 rsp->ssid.length); 539 } 540 #else 541 static inline void osif_check_and_unlink_bss(struct wlan_objmgr_vdev *vdev, 542 struct vdev_osif_priv *osif_priv, 543 struct wlan_cm_connect_resp *rsp) 544 {} 545 #endif 546 547 QDF_STATUS osif_connect_handler(struct wlan_objmgr_vdev *vdev, 548 struct wlan_cm_connect_resp *rsp) 549 { 550 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 551 QDF_STATUS status; 552 553 osif_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " Connect with " QDF_MAC_ADDR_FMT " SSID \"%.*s\" is %s cm_id 0x%x cm_reason %d status_code %d is_reassoc %d", 554 osif_priv->wdev->netdev->name, rsp->vdev_id, 555 QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)), 556 QDF_MAC_ADDR_REF(rsp->bssid.bytes), 557 rsp->ssid.length, rsp->ssid.ssid, 558 rsp->connect_status ? "FAILURE" : "SUCCESS", rsp->cm_id, 559 rsp->reason, rsp->status_code, rsp->is_reassoc); 560 561 osif_check_and_unlink_bss(vdev, osif_priv, rsp); 562 563 status = osif_validate_connect_and_reset_src_id(osif_priv, rsp); 564 if (QDF_IS_STATUS_ERROR(status)) { 565 osif_cm_connect_comp_ind(vdev, rsp, OSIF_NOT_HANDLED); 566 return status; 567 } 568 569 osif_cm_connect_comp_ind(vdev, rsp, OSIF_PRE_USERSPACE_UPDATE); 570 if (rsp->is_reassoc) 571 osif_indicate_reassoc_results(vdev, osif_priv, rsp); 572 else 573 osif_indcate_connect_results(vdev, osif_priv, rsp); 574 osif_cm_connect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE); 575 576 return QDF_STATUS_SUCCESS; 577 } 578 579 QDF_STATUS osif_failed_candidate_handler(struct wlan_objmgr_vdev *vdev, 580 struct wlan_cm_connect_resp *rsp) 581 { 582 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 583 584 osif_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " Connect with " QDF_MAC_ADDR_FMT " SSID \"%.*s\" FAILED cm_id 0x%x cm_reason %d reason_code %d", 585 osif_priv->wdev->netdev->name, rsp->vdev_id, 586 QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)), 587 QDF_MAC_ADDR_REF(rsp->bssid.bytes), 588 rsp->ssid.length, rsp->ssid.ssid, rsp->cm_id, 589 rsp->reason, rsp->status_code); 590 591 osif_check_and_unlink_bss(vdev, osif_priv, rsp); 592 593 return QDF_STATUS_SUCCESS; 594 } 595