diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 9f2e8c9d18e1..96f84f33c4f4 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -300,4 +300,12 @@ void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev, * Return: None */ void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_get_self_disconnect_ies() - Get diconnect IEs from vdev object + * @vdev: vdev pointer + * + * Return: Returns a pointer to the self disconnect IEs present in vdev object + */ +struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev); #endif diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 5f14a793d20e..69f76624eb4b 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -2419,3 +2419,19 @@ void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) mlme_priv->self_disconnect_ies.len = 0; } } + +struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + struct mlme_legacy_priv *mlme_priv; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_legacy_err("vdev component object is NULL"); + return NULL; + } + + mlme_priv = vdev_mlme->ext_vdev_ptr; + + return &mlme_priv->self_disconnect_ies; +} diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 5485e2363f45..f40980640aa2 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -2898,6 +2898,30 @@ static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context, return status_code; } +/** + * lim_append_ies_to_frame() - Append IEs to the frame + * + * @frame: Pointer to the frame buffer that needs to be populated + * @frame_len: Pointer for current frame length + * @ie: pointer for disconnect IEs + * + * This function is called by lim_send_disassoc_mgmt_frame and + * lim_send_deauth_mgmt_frame APIs as part of disconnection. + * Append IEs and update frame length. + * + * Return: None + */ +static void +lim_append_ies_to_frame(uint8_t *frame, uint32_t *frame_len, + struct wlan_ies *ie) +{ + if (!ie || !ie->len || !ie->data) + return; + qdf_mem_copy(frame, ie->data, ie->len); + *frame_len += ie->len; + pe_debug("Appended IEs len: %u", ie->len); +} + /** * \brief This function is called to send Disassociate frame. * @@ -2928,6 +2952,7 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac, uint8_t txFlag = 0; uint32_t val = 0; uint8_t smeSessionId = 0; + struct wlan_ies *discon_ie; if (!pe_session) { return; @@ -2965,6 +2990,10 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac, nBytes = nPayload + sizeof(tSirMacMgmtHdr); + discon_ie = mlme_get_self_disconnect_ies(pe_session->vdev); + if (discon_ie && discon_ie->len) + nBytes += discon_ie->len; + qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, (void **)&pPacket); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { @@ -3002,6 +3031,11 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac, nStatus); } + /* Copy disconnect IEs to the end of the frame */ + lim_append_ies_to_frame(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + &nPayload, discon_ie); + mlme_free_self_disconnect_ies(pe_session->vdev); + pe_debug("***Sessionid %d Sending Disassociation frame with " "reason %u and waitForAck %d to " QDF_MAC_ADDR_STR " ,From " QDF_MAC_ADDR_STR, pe_session->peSessionId, nReason, @@ -3108,6 +3142,7 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, tpDphHashNode sta; #endif uint8_t smeSessionId = 0; + struct wlan_ies *discon_ie; if (!pe_session) { return; @@ -3145,6 +3180,9 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, } nBytes = nPayload + sizeof(tSirMacMgmtHdr); + discon_ie = mlme_get_self_disconnect_ies(pe_session->vdev); + if (discon_ie && discon_ie->len) + nBytes += discon_ie->len; qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame, (void **)&pPacket); @@ -3181,6 +3219,12 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, pe_warn("There were warnings while packing a De-Authentication (0x%08x)", nStatus); } + + /* Copy disconnect IEs to the end of the frame */ + lim_append_ies_to_frame(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + &nPayload, discon_ie); + mlme_free_self_disconnect_ies(pe_session->vdev); + pe_debug("***Sessionid %d Sending Deauth frame with " "reason %u and waitForAck %d to " QDF_MAC_ADDR_STR " ,From " QDF_MAC_ADDR_STR,