diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c index b475419549d7..a5053da0993e 100644 --- a/core/hdd/src/wlan_hdd_station_info.c +++ b/core/hdd/src/wlan_hdd_station_info.c @@ -106,6 +106,8 @@ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT #define DISCONNECT_REASON \ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON +#define BEACON_IES \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES /* * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt @@ -663,9 +665,10 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) { struct sk_buff *skb = NULL; - uint8_t *tmp_hs20 = NULL; - uint32_t nl_buf_len; + uint8_t *tmp_hs20 = NULL, *ies = NULL; + uint32_t nl_buf_len, ie_len = 0; struct hdd_station_ctx *hdd_sta_ctx; + QDF_STATUS status; enum qca_disconnect_reason_codes disconnect_reason = QCA_DISCONNECT_REASON_UNSPECIFIED; @@ -700,6 +703,11 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) nl_buf_len += sizeof(hdd_sta_ctx-> cache_conn_info.vht_operation); + status = sme_get_prev_connected_bss_ies(hdd_ctx->mac_handle, + adapter->vdev_id, + &ies, &ie_len); + if (QDF_IS_STATUS_SUCCESS(status)) + nl_buf_len += ie_len; skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); if (!skb) { @@ -765,10 +773,21 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, goto fail; } + if (ie_len) { + if (nla_put(skb, BEACON_IES, ie_len, ies)) { + hdd_err("Failed to put beacon IEs"); + goto fail; + } + qdf_mem_free(ies); + ie_len = 0; + } + return cfg80211_vendor_cmd_reply(skb); fail: if (skb) kfree_skb(skb); + qdf_mem_free(ies); + ie_len = 0; return -EINVAL; } diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index cbabea63e861..be2e2738972b 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -4102,4 +4102,19 @@ static inline void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle) } #endif +/** + * sme_get_prev_connected_bss_ies() - Get the previous connected AP IEs + * @mac_handle: The handle returned by mac_open. + * @vdev_id: vdev id + * @ies: IEs of the disconnected AP. Currently to carry beacon IEs. + * @ie_len: Length of the @ies + * + * This API extracts the IEs from the previous connected AP info and update + * them to the ies and ie_len. + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_get_prev_connected_bss_ies(mac_handle_t mac_handle, + uint8_t vdev_id, + uint8_t **ies, uint32_t *ie_len); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index abeb0bfc5a2e..0935a413787c 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -16286,3 +16286,50 @@ void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle) } } #endif + +QDF_STATUS sme_get_prev_connected_bss_ies(mac_handle_t mac_handle, + uint8_t vdev_id, + uint8_t **ies, uint32_t *ie_len) +{ + struct csr_roam_session *session; + struct mac_context *mac; + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t len; + uint8_t *beacon_ie; + + if (!mac_handle) { + sme_err("mac_handle is not valid"); + return QDF_STATUS_E_INVAL; + } + mac = MAC_CONTEXT(mac_handle); + session = CSR_GET_SESSION(mac, vdev_id); + if (!session) { + sme_err("session not found"); + return QDF_STATUS_E_INVAL; + } + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to acquire sme lock; status: %d", status); + return status; + } + + len = session->prev_assoc_ap_info.nBeaconLength; + if (!len) { + sme_debug("No IEs to return"); + status = QDF_STATUS_E_INVAL; + goto end; + } + beacon_ie = qdf_mem_malloc(len); + if (!beacon_ie) { + status = QDF_STATUS_E_NOMEM; + goto end; + } + qdf_mem_copy(beacon_ie, session->prev_assoc_ap_info.pbFrames, len); + + *ie_len = len; + *ies = beacon_ie; +end: + sme_release_global_lock(&mac->sme); + return status; +} diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index cddf435bbd6f..d67da795783b 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -9498,6 +9498,22 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, if (session_ptr->is_fils_connection) session_ptr->fils_seq_num = pSmeJoinRsp->fils_seq_num; + len = pSmeJoinRsp->assocReqLength + + pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength; + if (prev_connect_info->pbFrames) + csr_roam_free_connected_info(mac, prev_connect_info); + + prev_connect_info->pbFrames = qdf_mem_malloc(len); + if (prev_connect_info->pbFrames) { + qdf_mem_copy(prev_connect_info->pbFrames, pSmeJoinRsp->frames, + len); + prev_connect_info->nAssocReqLength = + pSmeJoinRsp->assocReqLength; + prev_connect_info->nAssocRspLength = + pSmeJoinRsp->assocRspLength; + prev_connect_info->nBeaconLength = pSmeJoinRsp->beaconLength; + } + if (eSIR_SME_SUCCESS == pSmeJoinRsp->status_code) { if (pCommand && eCsrSmeIssuedAssocToSimilarAP == @@ -9527,7 +9543,6 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, return; } - /* The head of the active list is the request we sent * Try to get back the same profile and roam again */ @@ -9579,22 +9594,6 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, QDF_STATUS_E_FAILURE); } - len = pSmeJoinRsp->assocReqLength + - pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength; - if (prev_connect_info->pbFrames) - csr_roam_free_connected_info(mac, prev_connect_info); - - prev_connect_info->pbFrames = qdf_mem_malloc(len); - if (prev_connect_info->pbFrames) { - qdf_mem_copy(prev_connect_info->pbFrames, pSmeJoinRsp->frames, - len); - prev_connect_info->nAssocReqLength = - pSmeJoinRsp->assocReqLength; - prev_connect_info->nAssocRspLength = - pSmeJoinRsp->assocRspLength; - prev_connect_info->nBeaconLength = pSmeJoinRsp->beaconLength; - } - /* * if userspace has issued disconnection, driver should not continue * connecting @@ -9603,7 +9602,6 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, if (pCommand && !is_dis_pending && session_ptr->join_bssid_count < CSR_MAX_BSSID_COUNT) { csr_roam(mac, pCommand); - csr_roam_free_connected_info(mac, prev_connect_info); return; } @@ -9630,7 +9628,6 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_NOT_ASSOCIATED); csr_roam_complete(mac, eCsrNothingToJoin, NULL, pSmeJoinRsp->vdev_id); - csr_roam_free_connected_info(mac, prev_connect_info); } static QDF_STATUS csr_roam_issue_join(struct mac_context *mac, uint32_t sessionId,