diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c index 53bc7f34c5..c53db46965 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c @@ -100,6 +100,45 @@ cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, return QDF_STATUS_SUCCESS; } +/** + * cm_roam_is_per_roam_allowed() - Check if PER roam trigger needs to be + * disabled based on the current connected rates. + * @psoc: Pointer to the psoc object + * @vdev_id: Vdev id + * + * Return: true if PER roam trigger is allowed + */ +static bool +cm_roam_is_per_roam_allowed(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct qdf_mac_addr connected_bssid = {0}; + struct wlan_objmgr_vdev *vdev; + enum wlan_phymode peer_phymode = WLAN_PHYMODE_AUTO; + QDF_STATUS status; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_CM_ID); + if (!vdev) { + mlme_err("Vdev is null for vdev_id:%d", vdev_id); + return false; + } + + status = wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); + + if (QDF_IS_STATUS_ERROR(status)) + return false; + + mlme_get_peer_phymode(psoc, connected_bssid.bytes, &peer_phymode); + if (peer_phymode < WLAN_PHYMODE_11NA_HT20) { + mlme_debug("vdev:%d PER roam trigger disabled for phymode:%d", + peer_phymode, vdev_id); + return false; + } + + return true; +} + #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * cm_roam_reason_vsie() - set roam reason vsie @@ -137,9 +176,21 @@ static void cm_roam_triggers(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct wlan_roam_triggers *params) { + bool is_per_roam_enabled; + params->vdev_id = vdev_id; params->trigger_bitmap = mlme_get_roam_trigger_bitmap(psoc, vdev_id); + + /* + * Disable PER trigger for phymode less than 11n to avoid + * frequent roams as the PER rate threshold is greater than + * 11a/b/g rates + */ + is_per_roam_enabled = cm_roam_is_per_roam_allowed(psoc, vdev_id); + if (!is_per_roam_enabled) + params->trigger_bitmap &= ~BIT(ROAM_TRIGGER_REASON_PER); + params->roam_scan_scheme_bitmap = wlan_cm_get_roam_scan_scheme_bitmap(psoc, vdev_id); wlan_cm_roam_get_vendor_btm_params(psoc, ¶ms->vendor_btm_param); @@ -2765,7 +2816,7 @@ cm_roam_fill_per_roam_request(struct wlan_objmgr_psoc *psoc, } /** - * cm_roam_offload_per_scan() - populates roam offload scan request and sends + * cm_roam_offload_per_config() - populates roam offload scan request and sends * to fw * @psoc: psoc context * @vdev_id: vdev id @@ -2776,8 +2827,18 @@ static QDF_STATUS cm_roam_offload_per_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) { struct wlan_per_roam_config_req *req; + bool is_per_roam_enabled; QDF_STATUS status; + /* + * Disable PER trigger for phymode less than 11n to avoid + * frequent roams as the PER rate threshold is greater than + * 11a/b/g rates + */ + is_per_roam_enabled = cm_roam_is_per_roam_allowed(psoc, vdev_id); + if (!is_per_roam_enabled) + return QDF_STATUS_SUCCESS; + req = qdf_mem_malloc(sizeof(*req)); if (!req) return QDF_STATUS_E_NOMEM;