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_roam_rsp.c 20 * 21 * This file maintains definitaions of roam response apis. 22 */ 23 24 #include <linux/version.h> 25 #include <linux/nl80211.h> 26 #include <net/cfg80211.h> 27 #include <wlan_osif_priv.h> 28 #include "osif_cm_rsp.h" 29 #include <osif_cm_util.h> 30 #include <wlan_cfg80211.h> 31 #include <wlan_cfg80211_scan.h> 32 #include "wlan_mlo_mgr_sta.h" 33 #include "wlan_mlo_mgr_link_switch.h" 34 #ifdef CONN_MGR_ADV_FEATURE 35 #include "wlan_mlme_ucfg_api.h" 36 #endif 37 #include "wlan_crypto_global_api.h" 38 #include <osif_cm_req.h> 39 40 #ifdef CONN_MGR_ADV_FEATURE 41 #ifdef WLAN_FEATURE_FILS_SK 42 static inline void osif_update_fils_hlp_data(struct net_device *dev, 43 struct wlan_objmgr_vdev *vdev, 44 struct wlan_cm_connect_resp *rsp) 45 { 46 if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len) 47 osif_cm_set_hlp_data(dev, vdev, rsp); 48 } 49 #else 50 static inline void osif_update_fils_hlp_data(struct net_device *dev, 51 struct wlan_objmgr_vdev *vdev, 52 struct wlan_cm_connect_resp *rsp) 53 { 54 } 55 #endif 56 57 #if defined CFG80211_ROAMED_API_UNIFIED || \ 58 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) 59 #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT 60 static 61 void osif_copy_roamed_info(struct cfg80211_roam_info *info, 62 struct cfg80211_bss *bss) 63 { 64 info->links[0].bss = bss; 65 } 66 #else 67 static 68 void osif_copy_roamed_info(struct cfg80211_roam_info *info, 69 struct cfg80211_bss *bss) 70 { 71 info->bss = bss; 72 } 73 #endif 74 75 #if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO) 76 static void 77 osif_roam_populate_mlo_info_for_link(struct wlan_objmgr_vdev *roamed_vdev, 78 struct cfg80211_roam_info *roam_info, 79 uint8_t link_id, struct cfg80211_bss *bss, 80 uint8_t *self_link_addr) 81 { 82 if (bss) { 83 osif_debug("Link_id :%d", link_id); 84 roam_info->valid_links |= BIT(link_id); 85 roam_info->links[link_id].bssid = bss->bssid; 86 roam_info->links[link_id].bss = bss; 87 roam_info->links[link_id].addr = self_link_addr; 88 } 89 90 mlo_mgr_osif_update_connect_info(roamed_vdev, link_id); 91 } 92 93 static void 94 osif_populate_partner_links_roam_mlo_params(struct wlan_objmgr_vdev *roamed_vdev, 95 struct wlan_cm_connect_resp *rsp, 96 struct cfg80211_roam_info *roam_info_params) 97 { 98 struct wlan_objmgr_pdev *pdev; 99 struct mlo_link_info *rsp_partner_info; 100 struct mlo_partner_info assoc_partner_info = {0}; 101 struct cfg80211_bss *bss = NULL; 102 QDF_STATUS qdf_status; 103 uint8_t link_id = 0, num_links; 104 int i; 105 106 pdev = wlan_vdev_get_pdev(roamed_vdev); 107 if (!pdev) 108 return; 109 110 qdf_status = osif_get_partner_info_from_mlie(rsp, &assoc_partner_info); 111 if (QDF_IS_STATUS_ERROR(qdf_status)) 112 return; 113 114 num_links = rsp->ml_parnter_info.num_partner_links; 115 for (i = 0 ; i < num_links; i++) { 116 struct mlo_link_info *link_info; 117 rsp_partner_info = &rsp->ml_parnter_info.partner_link_info[i]; 118 119 qdf_status = osif_get_link_id_from_assoc_ml_ie(rsp_partner_info, 120 &assoc_partner_info, 121 &link_id); 122 if (QDF_IS_STATUS_ERROR(qdf_status)) 123 continue; 124 125 link_info = mlo_mgr_get_ap_link_by_link_id( 126 roamed_vdev->mlo_dev_ctx, 127 link_id); 128 if (!link_info) { 129 osif_debug("link info not found for link_id:%d", 130 link_id); 131 continue; 132 } 133 134 bss = osif_get_chan_bss_from_kernel(roamed_vdev, 135 rsp_partner_info, rsp); 136 137 osif_roam_populate_mlo_info_for_link(roamed_vdev, 138 roam_info_params, 139 link_id, bss, 140 link_info->link_addr.bytes); 141 } 142 } 143 144 static QDF_STATUS 145 osif_fill_peer_mld_mac_roam_info(struct wlan_objmgr_vdev *vdev, 146 struct wlan_cm_connect_resp *rsp, 147 struct cfg80211_roam_info *roam_info_params) 148 { 149 struct wlan_objmgr_peer *peer_obj; 150 151 peer_obj = wlan_objmgr_get_peer_by_mac(wlan_vdev_get_psoc(vdev), 152 rsp->bssid.bytes, WLAN_OSIF_ID); 153 if (!peer_obj) 154 return QDF_STATUS_E_INVAL; 155 156 roam_info_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj); 157 158 wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID); 159 160 return QDF_STATUS_SUCCESS; 161 } 162 163 static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev, 164 struct wlan_cm_connect_resp *rsp, 165 struct cfg80211_bss *bss, 166 struct cfg80211_roam_info *info) 167 { 168 QDF_STATUS qdf_status; 169 uint8_t assoc_link_id; 170 171 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 172 return; 173 174 qdf_status = osif_fill_peer_mld_mac_roam_info(vdev, rsp, 175 info); 176 if (QDF_IS_STATUS_ERROR(qdf_status)) { 177 osif_err("Unable to fill peer mld address: %d", qdf_status); 178 return; 179 } 180 181 assoc_link_id = wlan_vdev_get_link_id(vdev); 182 osif_roam_populate_mlo_info_for_link(vdev, info, 183 assoc_link_id, bss, 184 wlan_vdev_mlme_get_macaddr(vdev)); 185 186 osif_populate_partner_links_roam_mlo_params(vdev, rsp, info); 187 } 188 #else 189 static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev, 190 struct wlan_cm_connect_resp *rsp, 191 struct cfg80211_bss *bss, 192 struct cfg80211_roam_info *info) 193 {} 194 #endif 195 /** 196 * osif_roamed_ind() - send roamed indication to cfg80211 197 * @dev: network device 198 * @vdev: vdev object 199 * @rsp: CM connect response 200 * @bss: cfg80211 roamed bss pointer 201 * @req_ie: IEs used in reassociation request 202 * @req_ie_len: Length of the @req_ie 203 * @resp_ie: IEs received in successful reassociation response 204 * @resp_ie_len: Length of @resp_ie 205 * 206 * Return: none 207 */ 208 static void osif_roamed_ind(struct net_device *dev, 209 struct wlan_objmgr_vdev *vdev, 210 struct wlan_cm_connect_resp *rsp, 211 struct cfg80211_bss *bss, 212 const uint8_t *req_ie, 213 size_t req_ie_len, const uint8_t *resp_ie, 214 size_t resp_ie_len) 215 { 216 struct cfg80211_roam_info info = {0}; 217 218 osif_copy_roamed_info(&info, bss); 219 info.req_ie = req_ie; 220 info.req_ie_len = req_ie_len; 221 info.resp_ie = resp_ie; 222 info.resp_ie_len = resp_ie_len; 223 osif_fill_mlo_roam_params(vdev, rsp, bss, &info); 224 cfg80211_roamed(dev, &info, qdf_mem_malloc_flags()); 225 } 226 #else 227 static inline void osif_roamed_ind(struct net_device *dev, 228 struct wlan_objmgr_vdev *vdev, 229 struct wlan_cm_connect_resp *rsp, 230 struct cfg80211_bss *bss, 231 const uint8_t *req_ie, 232 size_t req_ie_len, const uint8_t *resp_ie, 233 size_t resp_ie_len) 234 235 { 236 cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len, 237 qdf_mem_malloc_flags()); 238 } 239 #endif 240 241 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 242 #ifdef WLAN_FEATURE_FILS_SK 243 /** 244 * osif_add_fils_params_roam_auth_event() - Adds FILS params in roam auth 245 * @skb: SK buffer 246 * @roam_info: Roam info 247 * 248 * API adds fils params[pmk, pmkid, next sequence number] to roam auth event 249 * 250 * Return: zero on success, error code on failure 251 */ 252 static int 253 osif_add_fils_params_roam_auth_event(struct sk_buff *skb, 254 struct wlan_roam_sync_info *roam_info) 255 { 256 if (roam_info->pmk_len && 257 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK, 258 roam_info->pmk_len, roam_info->pmk)) { 259 osif_err("pmk send fail"); 260 return -EINVAL; 261 } 262 263 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID, 264 PMKID_LEN, roam_info->pmkid)) { 265 osif_err("pmkid send fail"); 266 return -EINVAL; 267 } 268 269 osif_debug("Update ERP Seq Num %d, Next ERP Seq Num %d", 270 roam_info->update_erp_next_seq_num, 271 roam_info->next_erp_seq_num); 272 if (roam_info->update_erp_next_seq_num && 273 nla_put_u16(skb, 274 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM, 275 roam_info->next_erp_seq_num)) { 276 osif_err("ERP seq num send fail"); 277 return -EINVAL; 278 } 279 280 return 0; 281 } 282 #else 283 static inline int 284 osif_add_fils_params_roam_auth_event(struct sk_buff *skb, 285 struct wlan_roam_sync_info *roam_info) 286 { 287 return 0; 288 } 289 #endif 290 291 /** 292 * osif_get_roam_reason() - convert wmi roam reason to 293 * enum qca_roam_reason 294 * @roam_scan_trigger: wmi roam scan trigger ID 295 * 296 * Return: Meaningful qca_roam_reason from enum WMI_ROAM_TRIGGER_REASON_ID 297 */ 298 static enum qca_roam_reason osif_get_roam_reason(uint16_t roam_scan_trigger) 299 { 300 switch (roam_scan_trigger) { 301 case ROAM_TRIGGER_REASON_PER: 302 return QCA_ROAM_REASON_PER; 303 case ROAM_TRIGGER_REASON_BMISS: 304 return QCA_ROAM_REASON_BEACON_MISS; 305 case ROAM_TRIGGER_REASON_LOW_RSSI: 306 case ROAM_TRIGGER_REASON_BACKGROUND: 307 return QCA_ROAM_REASON_POOR_RSSI; 308 case ROAM_TRIGGER_REASON_HIGH_RSSI: 309 return QCA_ROAM_REASON_BETTER_RSSI; 310 case ROAM_TRIGGER_REASON_DENSE: 311 return QCA_ROAM_REASON_CONGESTION; 312 case ROAM_TRIGGER_REASON_FORCED: 313 return QCA_ROAM_REASON_USER_TRIGGER; 314 case ROAM_TRIGGER_REASON_BTM: 315 return QCA_ROAM_REASON_BTM; 316 case ROAM_TRIGGER_REASON_BSS_LOAD: 317 return QCA_ROAM_REASON_BSS_LOAD; 318 default: 319 return QCA_ROAM_REASON_UNKNOWN; 320 } 321 322 return QCA_ROAM_REASON_UNKNOWN; 323 } 324 325 #ifdef WLAN_FEATURE_11BE_MLO 326 327 static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev) 328 { 329 struct wlan_objmgr_peer *peer; 330 331 peer = wlan_vdev_get_bsspeer(vdev); 332 if (peer) 333 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) 334 return wlan_peer_mlme_get_mldaddr(peer); 335 else 336 return wlan_peer_get_macaddr(peer); 337 else 338 return NULL; 339 } 340 341 /** 342 * osif_send_roam_auth_mlo_links_event() - API to send roam auth mlo 343 * links event response to kernel 344 * @skb : sk buffer pointer 345 * @vdev: vdev pointer 346 * @osif_priv: osif vdev private data 347 * @rsp: Connection manager response 348 * 349 * This is called when wlan driver needs to send the mlo links roaming 350 * information after roaming. 351 * 352 * Context: Any context. 353 * Return: int 354 */ 355 static int 356 osif_send_roam_auth_mlo_links_event(struct sk_buff *skb, 357 struct wlan_objmgr_vdev *vdev, 358 struct vdev_osif_priv *osif_priv, 359 struct wlan_cm_connect_resp *rsp) 360 { 361 struct wlan_objmgr_psoc *psoc; 362 bool roam_offload_enable; 363 uint8_t i; 364 struct nlattr *mlo_links; 365 struct nlattr *mlo_links_info; 366 struct wlan_objmgr_vdev *link_vdev; 367 uint8_t link_vdev_id, link_id; 368 struct qdf_mac_addr link_addr; 369 370 if (!vdev) 371 return -EINVAL; 372 373 psoc = wlan_vdev_get_psoc(vdev); 374 ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable); 375 376 if (!roam_offload_enable) 377 return -EINVAL; 378 379 mlo_links = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS); 380 if (!mlo_links) { 381 osif_err("nla_nest_start error"); 382 return -EINVAL; 383 } 384 385 for (i = 0; i < rsp->ml_parnter_info.num_partner_links; i++) { 386 mlo_links_info = nla_nest_start(skb, i); 387 if (!mlo_links_info) { 388 osif_err("nla nest start fail"); 389 return -EINVAL; 390 } 391 392 osif_debug("send roam auth for partner link:%d", 393 rsp->ml_parnter_info.partner_link_info[i].link_id); 394 if (nla_put_u8(skb, 395 QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID, 396 rsp->ml_parnter_info.partner_link_info[i].link_id)) { 397 osif_err("nla put fail"); 398 return -EINVAL; 399 } 400 401 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID, 402 ETH_ALEN, 403 (void *)&rsp->ml_parnter_info.partner_link_info[i].link_addr)) { 404 osif_err("nla put fail"); 405 return -EINVAL; 406 } 407 408 link_vdev_id = 409 rsp->ml_parnter_info.partner_link_info[i].vdev_id; 410 link_id = rsp->ml_parnter_info.partner_link_info[i].link_id; 411 412 /* Standby link */ 413 if (link_vdev_id == WLAN_INVALID_VDEV_ID) { 414 struct mlo_link_info *standby_info = 415 mlo_mgr_get_ap_link_by_link_id( 416 vdev->mlo_dev_ctx, 417 link_id); 418 if (standby_info) { 419 link_addr = standby_info->link_addr; 420 } else { 421 osif_err("link addr is null for id:%d", 422 link_id); 423 return -EINVAL; 424 } 425 } else { 426 link_vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 427 psoc, link_vdev_id, 428 WLAN_OSIF_CM_ID); 429 if (!link_vdev) { 430 osif_err("link vdev is null"); 431 return -EINVAL; 432 } 433 434 qdf_copy_macaddr(&link_addr, 435 (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(link_vdev)); 436 wlan_objmgr_vdev_release_ref(link_vdev, 437 WLAN_OSIF_CM_ID); 438 } 439 440 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR, 441 ETH_ALEN, link_addr.bytes)) { 442 osif_err("nla put fail"); 443 return -EINVAL; 444 } 445 nla_nest_end(skb, mlo_links_info); 446 } 447 448 nla_nest_end(skb, mlo_links); 449 450 return 0; 451 } 452 #else 453 static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev) 454 { 455 struct wlan_objmgr_peer *peer; 456 457 peer = wlan_vdev_get_bsspeer(vdev); 458 if (peer) 459 return wlan_peer_get_macaddr(peer); 460 else 461 return NULL; 462 } 463 464 static inline int 465 osif_send_roam_auth_mlo_links_event(struct sk_buff *skb, 466 struct wlan_objmgr_vdev *vdev, 467 struct vdev_osif_priv *osif_priv, 468 struct wlan_cm_connect_resp *rsp) 469 { 470 return 0; 471 } 472 #endif 473 474 /** 475 * osif_send_roam_auth_event() - API to send roam auth event response to kernel 476 * @vdev: vdev pointer 477 * @osif_priv: OS private structure of vdev 478 * @rsp: Connection manager response 479 * @req_ie: request IE 480 * @req_ie_len: request IE length 481 * @resp_ie: response IE 482 * @resp_ie_len: response IE length 483 * 484 * This is called when wlan driver needs to send the roaming and 485 * authorization information after roaming. 486 * 487 * The information that would be sent is the request RSN IE, response 488 * RSN IE and BSSID of the newly roamed AP. 489 * 490 * If the Authorized status is authenticated, then additional parameters 491 * like PTK's KCK and KEK and Replay Counter would also be passed to the 492 * supplicant. 493 * 494 * The supplicant upon receiving this event would ignore the legacy 495 * cfg80211_roamed call and use the entire information from this event. 496 * The cfg80211_roamed should still co-exist since the kernel will 497 * make use of the parameters even if the supplicant ignores it. 498 * 499 * 500 * Context: Any context. 501 * Return: int 502 */ 503 static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev, 504 struct vdev_osif_priv *osif_priv, 505 struct wlan_cm_connect_resp *rsp, 506 const uint8_t *req_ie, 507 size_t req_ie_len, const uint8_t *resp_ie, 508 size_t resp_ie_len) 509 { 510 struct wlan_objmgr_psoc *psoc; 511 uint32_t fils_params_len; 512 struct sk_buff *skb = NULL; 513 struct wlan_roam_sync_info *roaming_info; 514 int status; 515 int32_t akm; 516 bool roam_offload_enable; 517 uint8_t *bss_mac_addr; 518 uint8_t num_of_links = 0; 519 520 psoc = wlan_vdev_get_psoc(vdev); 521 ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable); 522 523 if (!roam_offload_enable) 524 return 0; 525 526 roaming_info = rsp->roaming_info; 527 528 /* 529 * PMK is sent from FW in Roam Synch Event for FILS Roaming. 530 * In that case, add three more NL attributes.ie. PMK, PMKID 531 * and ERP next sequence number. Add corresponding lengths 532 * with 3 extra NL message headers for each of the 533 * aforementioned params. 534 */ 535 fils_params_len = roaming_info->pmk_len + PMKID_LEN + 536 sizeof(uint16_t) + (3 * NLMSG_HDRLEN); 537 538 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 539 #ifdef WLAN_FEATURE_11BE_MLO 540 num_of_links = rsp->ml_parnter_info.num_partner_links; 541 #endif 542 skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy, 543 osif_priv->wdev, 544 (ETH_ALEN * num_of_links) + 545 (sizeof(uint8_t) * num_of_links) + 546 (ETH_ALEN * num_of_links) + 547 req_ie_len + resp_ie_len + 548 sizeof(uint8_t) + REPLAY_CTR_LEN + 549 roaming_info->kck_len + roaming_info->kek_len + 550 sizeof(uint16_t) + sizeof(uint8_t) + 551 (9 * NLMSG_HDRLEN) + fils_params_len, 552 QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX, 553 qdf_mem_malloc_flags()); 554 } else { 555 skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy, 556 osif_priv->wdev, 557 ETH_ALEN + req_ie_len + 558 resp_ie_len + 559 sizeof(uint8_t) + REPLAY_CTR_LEN + 560 roaming_info->kck_len + roaming_info->kek_len + 561 sizeof(uint16_t) + sizeof(uint8_t) + 562 (9 * NLMSG_HDRLEN) + fils_params_len, 563 QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX, 564 qdf_mem_malloc_flags()); 565 } 566 if (!skb) { 567 osif_err("cfg80211_vendor_event_alloc failed"); 568 return -1; 569 } 570 571 bss_mac_addr = osif_get_bss_mac_addr(vdev); 572 if (!bss_mac_addr) { 573 osif_err("Invalid bss mac addr"); 574 goto nla_put_failure; 575 } 576 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, 577 ETH_ALEN, bss_mac_addr) || 578 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, 579 req_ie_len, req_ie) || 580 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, 581 resp_ie_len, resp_ie)) { 582 osif_err("nla put fail"); 583 goto nla_put_failure; 584 } 585 586 if (roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED) { 587 osif_debug("Include Auth Params TLV's"); 588 if (nla_put_u8(skb, 589 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, 590 true)) { 591 osif_err("nla put fail"); 592 goto nla_put_failure; 593 } 594 akm = wlan_crypto_get_param(vdev, 595 WLAN_CRYPTO_PARAM_KEY_MGMT); 596 /* if FT or CCKM connection: dont send replay counter */ 597 if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) && 598 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK) && 599 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) && 600 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) && 601 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM) && 602 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY) && 603 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) && 604 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) && 605 !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK_SHA384) && 606 nla_put(skb, 607 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, 608 REPLAY_CTR_LEN, 609 roaming_info->replay_ctr)) { 610 osif_err("non FT/non CCKM connection"); 611 osif_err("failed to send replay counter"); 612 goto nla_put_failure; 613 } 614 if (roaming_info->kek_len > MAX_KEK_LENGTH || 615 roaming_info->kck_len > MAX_KCK_LEN || 616 nla_put(skb, 617 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, 618 roaming_info->kck_len, roaming_info->kck) || 619 nla_put(skb, 620 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, 621 roaming_info->kek_len, roaming_info->kek)) { 622 osif_err("nla put fail, kek_len %d", 623 roaming_info->kek_len); 624 goto nla_put_failure; 625 } 626 627 if (nla_put_u16(skb, 628 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON, 629 osif_get_roam_reason(roaming_info->roam_reason))) { 630 osif_err("roam reason send failure"); 631 goto nla_put_failure; 632 } 633 634 status = osif_add_fils_params_roam_auth_event(skb, 635 roaming_info); 636 if (status) 637 goto nla_put_failure; 638 /* 639 * Save the gtk rekey parameters in HDD STA context. They will 640 * be used next time when host enables GTK offload and goes 641 * into power save state. 642 */ 643 osif_cm_save_gtk(vdev, rsp); 644 osif_debug("replay_ctr 0x%llx kck %d kek %d", 645 *((uint64_t *)roaming_info->replay_ctr), 646 roaming_info->kck_len, 647 roaming_info->kek_len); 648 649 } else { 650 osif_debug("No Auth Params TLV's"); 651 if (nla_put_u8(skb, 652 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, 653 false)) { 654 osif_err("nla put fail"); 655 goto nla_put_failure; 656 } 657 } 658 659 osif_debug("Auth Status = %d Subnet Change Status = %d", 660 roaming_info->auth_status, 661 roaming_info->subnet_change_status); 662 /* 663 * Add subnet change status if subnet has changed 664 * 0 = unchanged 665 * 1 = changed 666 * 2 = unknown 667 */ 668 if (roaming_info->subnet_change_status) { 669 if (nla_put_u8(skb, 670 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS, 671 roaming_info->subnet_change_status)) { 672 osif_err("nla put fail"); 673 goto nla_put_failure; 674 } 675 } 676 677 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 678 status = osif_send_roam_auth_mlo_links_event(skb, vdev, 679 osif_priv, 680 rsp); 681 if (status) { 682 osif_err("Send mlo link fail"); 683 goto nla_put_failure; 684 } 685 } 686 cfg80211_vendor_event(skb, qdf_mem_malloc_flags()); 687 return 0; 688 689 nla_put_failure: 690 kfree_skb(skb); 691 return -1; 692 } 693 #else 694 static inline int 695 osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev, 696 struct vdev_osif_priv *osif_priv, 697 struct wlan_cm_connect_resp *rsp, 698 const uint8_t *req_ie, 699 size_t req_ie_len, const uint8_t *resp_ie, 700 size_t resp_ie_len) 701 { 702 return 0; 703 } 704 #endif 705 706 static void osif_cm_get_reassoc_req_ie_data(struct element_info *assoc_req, 707 size_t *ie_data_len, 708 const uint8_t **ie_data_ptr) 709 { 710 /* Validate IE and length */ 711 if (!assoc_req->len || !assoc_req->ptr || 712 assoc_req->len <= WLAN_REASSOC_REQ_IES_OFFSET) 713 return; 714 715 *ie_data_len = assoc_req->len - WLAN_REASSOC_REQ_IES_OFFSET; 716 *ie_data_ptr = assoc_req->ptr + WLAN_REASSOC_REQ_IES_OFFSET; 717 } 718 719 void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev, 720 struct vdev_osif_priv *osif_priv, 721 struct wlan_cm_connect_resp *rsp) 722 { 723 struct net_device *dev = osif_priv->wdev->netdev; 724 size_t req_len = 0; 725 const uint8_t *req_ie = NULL; 726 size_t rsp_len = 0; 727 const uint8_t *rsp_ie = NULL; 728 struct cfg80211_bss *bss; 729 struct ieee80211_channel *chan; 730 struct wlan_objmgr_psoc *psoc; 731 QDF_STATUS status; 732 733 if (wlan_vdev_mlme_is_mlo_vdev(vdev) && 734 wlan_vdev_mlme_is_mlo_link_vdev(vdev)) 735 return; 736 737 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) 738 return; 739 740 psoc = wlan_vdev_get_psoc(vdev); 741 if (!psoc) 742 return; 743 744 chan = ieee80211_get_channel(osif_priv->wdev->wiphy, rsp->freq); 745 746 bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan, 747 rsp->bssid.bytes, rsp->ssid.ssid, 748 rsp->ssid.length); 749 if (!bss) { 750 osif_warn("BSS "QDF_MAC_ADDR_FMT" is null, issue disconnect", 751 QDF_MAC_ADDR_REF(rsp->bssid.bytes)); 752 goto issue_disconnect; 753 } 754 755 if (rsp->is_assoc) 756 osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req, 757 &req_len, &req_ie); 758 else 759 osif_cm_get_reassoc_req_ie_data(&rsp->connect_ies.assoc_req, 760 &req_len, &req_ie); 761 osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp, 762 &rsp_len, &rsp_ie); 763 osif_roamed_ind(dev, vdev, rsp, bss, req_ie, req_len, rsp_ie, rsp_len); 764 osif_send_roam_auth_event(vdev, osif_priv, rsp, req_ie, req_len, rsp_ie, 765 rsp_len); 766 767 osif_update_fils_hlp_data(dev, vdev, rsp); 768 return; 769 770 issue_disconnect: 771 status = osif_cm_disconnect(dev, vdev, REASON_UNSPEC_FAILURE); 772 if (QDF_IS_STATUS_ERROR(status)) 773 osif_err("Disconnect failed with status %d", status); 774 } 775 776 QDF_STATUS 777 osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev, 778 struct qdf_mac_addr *bssid, 779 int index, bool preauth) 780 { 781 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); 782 struct wireless_dev *wdev; 783 784 if (!osif_priv) { 785 osif_err("Invalid vdev osif priv"); 786 return QDF_STATUS_E_INVAL; 787 } 788 789 wdev = osif_priv->wdev; 790 if (!wdev) { 791 osif_err("wdev is null"); 792 return QDF_STATUS_E_INVAL; 793 } 794 795 osif_debug("is going to notify supplicant of:"); 796 osif_info(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(bssid->bytes)); 797 798 cfg80211_pmksa_candidate_notify(wdev->netdev, index, 799 bssid->bytes, 800 preauth, qdf_mem_malloc_flags()); 801 return QDF_STATUS_SUCCESS; 802 } 803 #endif /* CONN_MGR_ADV_FEATURE */ 804