diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index ffa64524a8..38f313f286 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -147,6 +147,7 @@ struct hdd_conn_flag { * @ch_width: channel width of operating channel * @max_tx_bitrate: Max tx bitrate supported by the AP * to which currently sta is connected. + * @prev_ap_bcn_ie: ap beacon IE information to which sta is currently connected */ struct hdd_connection_info { eConnectionState conn_state; @@ -186,6 +187,7 @@ struct hdd_connection_info { char connect_time[HDD_TIME_STRING_LEN]; enum phy_ch_width ch_width; struct rate_info max_tx_bitrate; + struct element_info prev_ap_bcn_ie; }; /* Forward declarations */ diff --git a/core/hdd/src/wlan_hdd_cm_connect.c b/core/hdd/src/wlan_hdd_cm_connect.c index 8f6d82eab0..a4d8cb4af6 100644 --- a/core/hdd/src/wlan_hdd_cm_connect.c +++ b/core/hdd/src/wlan_hdd_cm_connect.c @@ -766,6 +766,44 @@ static void hdd_cm_connect_failure(struct wlan_objmgr_vdev *vdev, } } +/** + * hdd_cm_update_prev_ap_ie() - Update the connected AP IEs + * @hdd_sta_ctx: Station context. + * @rsp: Connect response + * + * This API updates the connected ap beacon IEs to station context connection + * info. + * + * Return: None + */ +static void hdd_cm_update_prev_ap_ie(struct hdd_station_ctx *hdd_sta_ctx, + struct wlan_cm_connect_resp *rsp) +{ + struct element_info *bcn_probe_rsp = &rsp->connect_ies.bcn_probe_rsp; + struct element_info *bcn_ie; + uint32_t len; + + bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; + if (bcn_ie->ptr) { + qdf_mem_free(bcn_ie->ptr); + bcn_ie->ptr = NULL; + bcn_ie->len = 0; + } + + if (bcn_probe_rsp->ptr && + bcn_probe_rsp->len > sizeof(struct wlan_frame_hdr)) { + len = bcn_probe_rsp->len - sizeof(struct wlan_frame_hdr); + bcn_ie->ptr = qdf_mem_malloc(len); + if (!bcn_ie->ptr) { + bcn_ie->len = 0; + return; + } + qdf_mem_copy(bcn_ie->ptr, bcn_probe_rsp->ptr + + sizeof(struct wlan_frame_hdr), len); + bcn_ie->len = len; + } +} + static void hdd_cm_save_bss_info(struct hdd_adapter *adapter, struct wlan_cm_connect_resp *rsp) { @@ -843,6 +881,7 @@ static void hdd_cm_save_bss_info(struct hdd_adapter *adapter, sizeof(hdd_sta_ctx->cache_conn_info)); hdd_copy_he_operation(hdd_sta_ctx, &assoc_resp->he_op); + hdd_cm_update_prev_ap_ie(hdd_sta_ctx, rsp); } qdf_mem_free(assoc_resp); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index b047732449..0e60eb1c0e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6619,6 +6619,7 @@ void hdd_cleanup_conn_info(struct hdd_adapter *adapter) { struct hdd_station_ctx *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct element_info *bcn_ie; if (!hdd_sta_ctx) return; @@ -6627,6 +6628,13 @@ void hdd_cleanup_conn_info(struct hdd_adapter *adapter) qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); hdd_sta_ctx->cache_conn_info.he_operation = NULL; } + bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; + + if (bcn_ie->ptr) { + qdf_mem_free(bcn_ie->ptr); + bcn_ie->ptr = NULL; + bcn_ie->len = 0; + } } void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c index 6733acbd20..7d660bbd40 100644 --- a/core/hdd/src/wlan_hdd_station_info.c +++ b/core/hdd/src/wlan_hdd_station_info.c @@ -669,6 +669,35 @@ static uint32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx) } #endif +static uint32_t hdd_get_prev_connected_bss_ies_len( + struct hdd_station_ctx *hdd_sta_ctx) +{ + return hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len; +} + +static uint32_t hdd_add_prev_connected_bss_ies( + struct sk_buff *skb, + struct hdd_station_ctx *hdd_sta_ctx) +{ + struct element_info *bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; + + if (bcn_ie->len) { + if (nla_put(skb, BEACON_IES, bcn_ie->len, bcn_ie->ptr)) { + hdd_err("Failed to put beacon IEs: bytes left: %d, ie_len: %u ", + skb_tailroom(skb), bcn_ie->len); + return -EINVAL; + } + + hdd_nofl_debug("Beacon IEs len: %u", bcn_ie->len); + + qdf_mem_free(bcn_ie->ptr); + bcn_ie->ptr = NULL; + bcn_ie->len = 0; + } + + return 0; +} + /** * hdd_get_station_info() - send BSS information to supplicant * @hdd_ctx: pointer to hdd context @@ -680,10 +709,9 @@ 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, *ies = NULL; - uint32_t nl_buf_len, ie_len = 0, hdd_he_op_len = 0; + uint8_t *tmp_hs20 = NULL; + uint32_t nl_buf_len, hdd_he_op_len = 0; struct hdd_station_ctx *hdd_sta_ctx; - QDF_STATUS status; hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -721,11 +749,7 @@ 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; + nl_buf_len += hdd_get_prev_connected_bss_ies_len(hdd_sta_ctx); hdd_he_op_len = hdd_get_he_op_len(hdd_sta_ctx); nl_buf_len += hdd_he_op_len; @@ -809,16 +833,9 @@ 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: bytes left: %d, ie_len: %u total buf_len: %u", - skb_tailroom(skb), ie_len, nl_buf_len); - goto fail; - } - - hdd_nofl_debug("Beacon IEs len: %u", ie_len); - - qdf_mem_free(ies); + if (hdd_add_prev_connected_bss_ies(skb, hdd_sta_ctx)) { + hdd_err("put fail total buf_len: %u", nl_buf_len); + goto fail; } hdd_nofl_debug( @@ -840,7 +857,6 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, fail: if (skb) kfree_skb(skb); - qdf_mem_free(ies); return -EINVAL; } diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 5b2b902542..3f2186e213 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -4347,21 +4347,6 @@ QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs, void *context), void *context); #endif /* FEATURE_ANI_LEVEL_REQUEST */ -/** - * 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); /* * sme_vdev_self_peer_delete_resp() - Response for self peer delete * @del_vdev_params: parameters for which vdev self peer has been deleted diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 7e224e2c7c..a75c2680c4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15752,53 +15752,6 @@ QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs, } #endif /* FEATURE_ANI_LEVEL_REQUEST */ -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 mac_context *mac = MAC_CONTEXT(mac_handle); - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t len; - uint8_t *beacon_ie; - struct rso_config *rso_cfg; - struct wlan_objmgr_vdev *vdev; - struct element_info *bcn_ie; - - vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, - WLAN_LEGACY_SME_ID); - if (!vdev) - return QDF_STATUS_E_INVAL; - - rso_cfg = wlan_cm_get_rso_config(vdev); - if (!rso_cfg) { - status = QDF_STATUS_E_INVAL; - goto end; - } - - bcn_ie = &rso_cfg->prev_ap_bcn_ie; - - if (!bcn_ie->len) { - sme_debug("No IEs to return"); - status = QDF_STATUS_E_INVAL; - goto end; - } - - len = bcn_ie->len; - beacon_ie = qdf_mem_malloc(len); - if (!beacon_ie) { - status = QDF_STATUS_E_NOMEM; - goto end; - } - qdf_mem_copy(beacon_ie, bcn_ie->ptr, len); - - *ie_len = len; - *ies = beacon_ie; -end: - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - - return status; -} - #ifdef FEATURE_MONITOR_MODE_SUPPORT QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle,