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