diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 582761407c89..99dab76a3325 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1894,6 +1894,35 @@ void wma_process_roam_synch_fail(WMA_HANDLE handle, false; } +/** + * wma_free_roam_synch_frame_ind() - Free the bcn_probe_rsp, reassoc_req, + * reassoc_rsp received as part of the ROAM_SYNC_FRAME event + * + * @iface - interaface corresponding to a vdev + * + * This API is used to free the buffer allocated during the ROAM_SYNC_FRAME + * event + * + */ +static void wma_free_roam_synch_frame_ind(struct wma_txrx_node *iface) +{ + if (iface->roam_synch_frame_ind.bcn_probe_rsp) { + qdf_mem_free(iface->roam_synch_frame_ind.bcn_probe_rsp); + iface->roam_synch_frame_ind.bcn_probe_rsp_len = 0; + iface->roam_synch_frame_ind.bcn_probe_rsp = NULL; + } + if (iface->roam_synch_frame_ind.reassoc_req) { + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); + iface->roam_synch_frame_ind.reassoc_req_len = 0; + iface->roam_synch_frame_ind.reassoc_req = NULL; + } + if (iface->roam_synch_frame_ind.reassoc_rsp) { + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); + iface->roam_synch_frame_ind.reassoc_rsp_len = 0; + iface->roam_synch_frame_ind.reassoc_rsp = NULL; + } +} + /** * wma_fill_data_synch_frame_event() - Fill the the roam sync data buffer using * synch frame event data @@ -2038,12 +2067,14 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, wmi_key_material *key; struct wma_txrx_node *iface = NULL; wmi_roam_fils_synch_tlv_param *fils_info; + int status = -EINVAL; synch_event = param_buf->fixed_param; roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id; roam_synch_ind_ptr->authStatus = synch_event->auth_status; roam_synch_ind_ptr->roamReason = synch_event->roam_reason; roam_synch_ind_ptr->rssi = synch_event->rssi; + iface = &wma->interfaces[synch_event->vdev_id]; WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid, roam_synch_ind_ptr->bssid.bytes); WMA_LOGD("%s: roamedVdevId %d authStatus %d roamReason %d rssi %d isBeacon %d", @@ -2055,11 +2086,10 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context, roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA))) { WMA_LOGE("LFR3: CSR Roam synch cb failed"); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } - iface = &wma->interfaces[synch_event->vdev_id]; - /* * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in * synch_event driver would have received bcn_probe_rsp, reassoc_req @@ -2072,19 +2102,22 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, WMA_LOGE("LFR3: bcn_probe_rsp is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. bcn_probe_rsp != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } if (!iface->roam_synch_frame_ind.reassoc_rsp) { WMA_LOGE("LFR3: reassoc_rsp is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_rsp != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } if (!iface->roam_synch_frame_ind.reassoc_req) { WMA_LOGE("LFR3: reassoc_req is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_req != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } wma_fill_data_synch_frame_event(wma, roam_synch_ind_ptr, iface); } else { @@ -2120,7 +2153,8 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, __func__, fils_info->kek_len, fils_info->pmk_len); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } roam_synch_ind_ptr->kek_len = fils_info->kek_len; @@ -2143,6 +2177,7 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, roam_synch_ind_ptr->update_erp_next_seq_num, roam_synch_ind_ptr->next_erp_seq_num); } + wma_free_roam_synch_frame_ind(iface); return 0; } @@ -2477,25 +2512,25 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, WMA_LOGD("LFR3:Synch Frame event"); if (!event) { WMA_LOGE("event param null"); - goto cleanup_label; + return status; } param_buf = (WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *) event; if (!param_buf) { WMA_LOGE("received null buf from target"); - goto cleanup_label; + return status; } synch_frame_event = param_buf->fixed_param; if (!synch_frame_event) { WMA_LOGE("received null event data from target"); - goto cleanup_label; + return status; } if (synch_frame_event->vdev_id >= wma->max_bssid) { WMA_LOGE("received invalid vdev_id %d", synch_frame_event->vdev_id); - goto cleanup_label; + return status; } vdev_id = synch_frame_event->vdev_id; @@ -2503,7 +2538,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, if (wma_is_roam_synch_in_progress(wma, vdev_id)) { WMA_LOGE("Ignoring this event as it is unexpected"); - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } WMA_LOGD("LFR3: Received ROAM_SYNCH_FRAME_EVENT"); @@ -2519,6 +2555,9 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, iface->roam_synch_frame_ind.is_beacon = synch_frame_event->is_beacon; + if (iface->roam_synch_frame_ind.bcn_probe_rsp) + qdf_mem_free(iface->roam_synch_frame_ind. + bcn_probe_rsp); iface->roam_synch_frame_ind.bcn_probe_rsp = qdf_mem_malloc(iface->roam_synch_frame_ind. bcn_probe_rsp_len); @@ -2527,7 +2566,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. bcn_probe_rsp != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind. bcn_probe_rsp, @@ -2539,6 +2579,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, iface->roam_synch_frame_ind.reassoc_req_len = synch_frame_event->reassoc_req_len; + if (iface->roam_synch_frame_ind.reassoc_req) + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); iface->roam_synch_frame_ind.reassoc_req = qdf_mem_malloc(iface->roam_synch_frame_ind. reassoc_req_len); @@ -2547,7 +2589,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_req != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_req, param_buf->reassoc_req_frame, @@ -2555,9 +2598,18 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, } if (synch_frame_event->reassoc_rsp_len) { + if (!iface->roam_synch_frame_ind.bcn_probe_rsp || + !iface->roam_synch_frame_ind.reassoc_req) { + WMA_LOGE("failed: No probe or reassoc rsp"); + wma_free_roam_synch_frame_ind(iface); + return status; + } iface->roam_synch_frame_ind.reassoc_rsp_len = synch_frame_event->reassoc_rsp_len; + if (iface->roam_synch_frame_ind.reassoc_rsp) + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); + iface->roam_synch_frame_ind.reassoc_rsp = qdf_mem_malloc(iface->roam_synch_frame_ind. reassoc_rsp_len); @@ -2566,29 +2618,14 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_rsp != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_rsp, param_buf->reassoc_rsp_frame, iface->roam_synch_frame_ind.reassoc_rsp_len); } return 0; - -cleanup_label: - if (iface && (iface->roam_synch_frame_ind.bcn_probe_rsp)) { - qdf_mem_free(iface->roam_synch_frame_ind. - bcn_probe_rsp); - iface->roam_synch_frame_ind.bcn_probe_rsp = NULL; - } - if (iface && (iface->roam_synch_frame_ind.reassoc_req)) { - qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); - iface->roam_synch_frame_ind.reassoc_req = NULL; - } - if (iface && (iface->roam_synch_frame_ind.reassoc_rsp)) { - qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); - iface->roam_synch_frame_ind.reassoc_rsp = NULL; - } - return status; } #define RSN_CAPS_SHIFT 16