diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 54d3a094bf0a..3b5d1a59dbf6 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -262,6 +262,7 @@ enum roam_invoke_source_entity { struct mlme_roam_after_data_stall { bool roam_invoke_in_progress; enum roam_invoke_source_entity source; + struct qdf_mac_addr mac_addr; }; /** diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index e3bba1efcdda..ea5baa732c77 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -1019,6 +1019,14 @@ static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, cmd->flags |= (1 << WMI_ROAM_INVOKE_FLAG_FULL_SCAN_IF_NO_CANDIDATE); cmd->reason = ROAM_INVOKE_REASON_NUD_FAILURE; + } else if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)&roaminvoke->bssid)) { + cmd->num_chan = 0; + cmd->num_bssid = 0; + cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP; + cmd->flags |= + (1 << WMI_ROAM_INVOKE_FLAG_FULL_SCAN_IF_NO_CANDIDATE) | + (1 << WMI_ROAM_INVOKE_FLAG_SELECT_CANDIDATE_CONSIDER_SCORE); + cmd->reason = ROAM_INVOKE_REASON_USER_SPACE; } else { cmd->reason = ROAM_INVOKE_REASON_USER_SPACE; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index d08666c9ab0d..096f812bf679 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -20838,6 +20838,12 @@ QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, fastreassoc->bssid[4] = bssid[4]; fastreassoc->bssid[5] = bssid[5]; + qdf_mem_copy(&vdev_roam_params->mac_addr, &bssid, ETH_ALEN); + if (qdf_is_macaddr_zero((struct qdf_mac_addr *)&bssid)) + goto send_evt; + if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)&bssid)) + goto send_evt; + status = sme_get_beacon_frm(mac_handle, profile, bssid, &fastreassoc->frame_buf, &fastreassoc->frame_len, @@ -20871,6 +20877,7 @@ QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, } } +send_evt: msg.type = eWNI_SME_ROAM_INVOKE; msg.reserved = 0; msg.bodyptr = fastreassoc; @@ -20884,8 +20891,11 @@ QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, fastreassoc->frame_len = 0; qdf_mem_free(fastreassoc); } else { + if (qdf_is_macaddr_zero((struct qdf_mac_addr *)&bssid)) + vdev_roam_params->source = CONNECTION_MGR_INITIATED; + else + vdev_roam_params->source = USERSPACE_INITIATED; vdev_roam_params->roam_invoke_in_progress = true; - vdev_roam_params->source = USERSPACE_INITIATED; session->roam_invoke_timer_info.mac = mac_ctx; session->roam_invoke_timer_info.vdev_id = vdev_id; qdf_mc_timer_start(&session->roam_invoke_timer, @@ -21192,6 +21202,16 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx, goto end; } + /* + * If reassoc MAC from user space is broadcast MAC as: + * wpa_cli DRIVER REASSOC ff:ff:ff:ff:ff:ff 0, + * user space invoked roaming candidate selection will base on + * firmware score algorithm, current connection will be kept if + * current AP has highest score. It is requirement from + * customer which can avoid ping-pong roaming. + */ + if (qdf_is_macaddr_broadcast(&vdev_roam_params->mac_addr)) + mlme_debug("Keep current connection"); /* Userspace roam req fail, disconnect with AP */ if (vdev_roam_params->source == USERSPACE_INITIATED || mac_ctx->nud_fail_behaviour == DISCONNECT_AFTER_ROAM_FAIL)