diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 0607a79230..e8cfa81cb9 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1958,6 +1958,12 @@ struct roam_fils_params { * @roam_fils_params: roam fils params * @rct_validity_timer: duration value for which the entries in * roam candidate table are valid + * @roam_scan_inactivity_time: inactivity monitoring time in ms for which the + * device is considered to be inactive + * @roam_inactive_data_packet_count: Maximum allowed data packets count during + * roam_scan_inactivity_time. + * @roam_scan_period_after_inactivity: Roam scan period in ms after device is + * in inactive state. */ struct roam_offload_scan_params { uint8_t is_roam_req_valid; @@ -1992,6 +1998,9 @@ struct roam_offload_scan_params { uint32_t assoc_ie_length; uint8_t assoc_ie[MAX_ASSOC_IE_LENGTH]; bool add_fils_tlv; + uint32_t roam_scan_inactivity_time; + uint32_t roam_inactive_data_packet_count; + uint32_t roam_scan_period_after_inactivity; #ifdef WLAN_FEATURE_FILS_SK struct roam_fils_params roam_fils_params; #endif diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 3d7e14c7af..75aeb9176d 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -553,9 +553,7 @@ QDF_STATUS (*send_roam_scan_offload_cmd)(wmi_unified_t wmi_handle, uint32_t command, uint32_t vdev_id); QDF_STATUS (*send_roam_scan_offload_scan_period_cmd)(wmi_unified_t wmi_handle, - uint32_t scan_period, - uint32_t scan_age, - uint32_t vdev_id); + struct roam_scan_period_params *params); QDF_STATUS (*send_roam_scan_offload_chan_list_cmd)(wmi_unified_t wmi_handle, uint8_t chan_count, diff --git a/wmi/inc/wmi_unified_roam_api.h b/wmi/inc/wmi_unified_roam_api.h index 5cc8ee360f..12bb1414d1 100644 --- a/wmi/inc/wmi_unified_roam_api.h +++ b/wmi/inc/wmi_unified_roam_api.h @@ -207,18 +207,15 @@ QDF_STATUS wmi_unified_roam_scan_offload_cmd(void *wmi_hdl, /** * wmi_unified_roam_scan_offload_scan_period() - set roam offload scan period * @wmi_handle: wmi handle - * @scan_period: scan period - * @scan_age: scan age - * @vdev_id: vdev id + * @param: pointer to roam scan period params to be sent to fw * * Send WMI_ROAM_SCAN_PERIOD parameters to fw. * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_roam_scan_offload_scan_period(void *wmi_hdl, - uint32_t scan_period, - uint32_t scan_age, - uint32_t vdev_id); +QDF_STATUS +wmi_unified_roam_scan_offload_scan_period(wmi_unified_t wmi_handle, + struct roam_scan_period_params *param); /** * wmi_unified_roam_scan_offload_chan_list_cmd() - set roam offload channel list diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h index e8b74edf36..8997500e69 100644 --- a/wmi/inc/wmi_unified_roam_param.h +++ b/wmi/inc/wmi_unified_roam_param.h @@ -126,6 +126,27 @@ struct roam_offload_scan_rssi_params { uint32_t flags; }; +/** + * struct roam_scan_period_params - Roam scan period parameters + * @vdev_id: Vdev for which the scan period parameters are sent + * @scan_period: Opportunistic scan runs on a timer for scan_period + * @scan_age: Duration after which the scan entries are to be aged out + * @roam_scan_inactivity_time: inactivity monitoring time in ms for which the + * device is considered to be inactive + * @roam_inactive_data_packet_count: Maximum allowed data packets count during + * roam_scan_inactivity_time. + * @roam_scan_period_after_inactivity: Roam scan period in ms after device is + * in inactive state. + */ +struct roam_scan_period_params { + uint32_t vdev_id; + uint32_t scan_period; + uint32_t scan_age; + uint32_t roam_scan_inactivity_time; + uint32_t roam_inactive_data_packet_count; + uint32_t roam_scan_period_after_inactivity; +}; + /** * struct wmi_mawc_roam_params - Motion Aided wireless connectivity params * @vdev_id: VDEV on which the parameters should be applied @@ -407,16 +428,102 @@ struct scoring_param { struct param_slot_scoring oce_wan_scoring; }; +/* + * Currently roam score delta value and min rssi values are sent + * for 2 triggers + */ +#define NUM_OF_ROAM_TRIGGERS 2 +#define IDLE_ROAM_TRIGGER 0 +#define BTM_ROAM_TRIGGER 1 + +#define DEAUTH_MIN_RSSI 0 +#define BMISS_MIN_RSSI 1 + +/** + * enum roam_trigger_reason - Reason for triggering roam + * ROAM_TRIGGER_REASON_NONE: Roam trigger reason none + * ROAM_TRIGGER_REASON_PER: Roam triggered due to packet error + * ROAM_TRIGGER_REASON_BMISS: Roam triggered due to beacon miss + * ROAM_TRIGGER_REASON_LOW_RSSI: Roam triggered due to low RSSI of current + * connected AP. + * ROAM_TRIGGER_REASON_HIGH_RSSI: Roam triggered because sta is connected to + * a AP in 2.4GHz band and a better 5GHz AP is available + * ROAM_TRIGGER_REASON_PERIODIC: Roam triggered as better AP was found during + * periodic roam scan. + * ROAM_TRIGGER_REASON_MAWC: Motion Aided WiFi Connectivity triggered roam. + * ROAM_TRIGGER_REASON_DENSE: Roaming triggered due to dense environment + * detected. + * ROAM_TRIGGER_REASON_BACKGROUND: Roam triggered due to current AP having + * poor rssi and scan candidate found in scan results provided by other + * scan clients. + * ROAM_TRIGGER_REASON_FORCED: Forced roam trigger. + * ROAM_TRIGGER_REASON_BTM: Roam triggered due to AP sent BTM query with + * Disassoc imminent bit set. + * ROAM_TRIGGER_REASON_UNIT_TEST: Roam triggered due to unit test command. + * ROAM_TRIGGER_REASON_BSS_LOAD: Roam triggered due to high channel utilization + * in the current connected channel + * ROAM_TRIGGER_REASON_DEAUTH: Roam triggered due to deauth received from the + * current connected AP. + * ROAM_TRIGGER_REASON_IDLE: Roam triggered due to inactivity of the device. + * ROAM_TRIGGER_REASON_MAX: Maximum number of roam triggers + */ +enum roam_trigger_reason { + ROAM_TRIGGER_REASON_NONE = 0, + ROAM_TRIGGER_REASON_PER, + ROAM_TRIGGER_REASON_BMISS, + ROAM_TRIGGER_REASON_LOW_RSSI, + ROAM_TRIGGER_REASON_HIGH_RSSI, + ROAM_TRIGGER_REASON_PERIODIC, + ROAM_TRIGGER_REASON_MAWC, + ROAM_TRIGGER_REASON_DENSE, + ROAM_TRIGGER_REASON_BACKGROUND, + ROAM_TRIGGER_REASON_FORCED, + ROAM_TRIGGER_REASON_BTM, + ROAM_TRIGGER_REASON_UNIT_TEST, + ROAM_TRIGGER_REASON_BSS_LOAD, + ROAM_TRIGGER_REASON_DEAUTH, + ROAM_TRIGGER_REASON_IDLE, + ROAM_TRIGGER_REASON_MAX, +}; + +/** + * struct roam_trigger_min_rssi - structure to hold minimum rssi value of + * candidate APs for each roam trigger + * @min_rssi: minimum RSSI of candidate AP for the trigger reason specified in + * trigger_id + * @trigger_reason: Roam trigger reason + */ +struct roam_trigger_min_rssi { + int32_t min_rssi; + enum roam_trigger_reason trigger_reason; +}; + +/** + * struct roam_trigger_score_delta - structure to hold roam score delta value of + * candidate APs for each roam trigger + * @roam_score_delta: delta value in score of the candidate AP for the roam + * trigger mentioned in the trigger_id. + * @trigger_reason: Roam trigger reason + */ +struct roam_trigger_score_delta { + uint32_t roam_score_delta; + enum roam_trigger_reason trigger_reason; +}; + /** * struct ap_profile_params - ap profile params * @vdev_id: vdev id * @profile: ap profile to match candidate * @param: scoring params to short candidate + * @min_rssi_params: Min RSSI values for different roam triggers + * @score_delta_params: Roam score delta values for different triggers */ struct ap_profile_params { uint8_t vdev_id; struct ap_profile profile; struct scoring_param param; + struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_TRIGGERS]; + struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS]; }; /** @@ -524,6 +631,8 @@ struct hlp_params { * @disassoc_timer_threshold: threshold value till which the firmware can * wait before triggering the roam scan after receiving the disassoc iminent * @btm_query_bitmask: bitmask to btm query with candidate list + * @btm_candidate_min_score: Minimum score of the AP to consider it as a + * candidate if the roam trigger is BTM kickout. */ struct wmi_btm_config { uint8_t vdev_id; @@ -533,6 +642,7 @@ struct wmi_btm_config { uint32_t btm_sticky_time; uint32_t disassoc_timer_threshold; uint32_t btm_query_bitmask; + uint32_t btm_candidate_min_score; }; /** @@ -541,11 +651,19 @@ struct wmi_btm_config { * @bss_load_threshold: BSS load threshold after which roam scan should trigger * @bss_load_sample_time: Time duration in milliseconds for which the bss load * trigger needs to be enabled + * @rssi_threshold_5ghz: RSSI threshold of the current connected AP below which + * roam should be triggered if bss load threshold exceeds the configured value. + * This value is applicable only when we are connected in 5GHz band. + * @rssi_threshold_24ghz: RSSI threshold of the current connected AP below which + * roam should be triggered if bss load threshold exceeds the configured value. + * This value is applicable only when we are connected in 2.4GHz band. */ struct wmi_bss_load_config { uint32_t vdev_id; uint32_t bss_load_threshold; uint32_t bss_load_sample_time; + int32_t rssi_threshold_5ghz; + int32_t rssi_threshold_24ghz; }; /** diff --git a/wmi/src/wmi_unified_roam_api.c b/wmi/src/wmi_unified_roam_api.c index 8aea64cd38..925b5e0f8d 100644 --- a/wmi/src/wmi_unified_roam_api.c +++ b/wmi/src/wmi_unified_roam_api.c @@ -193,16 +193,13 @@ QDF_STATUS wmi_unified_roam_scan_offload_cmd(void *wmi_hdl, return QDF_STATUS_E_FAILURE; } -QDF_STATUS wmi_unified_roam_scan_offload_scan_period(void *wmi_hdl, - uint32_t scan_period, - uint32_t scan_age, - uint32_t vdev_id) +QDF_STATUS +wmi_unified_roam_scan_offload_scan_period(wmi_unified_t wmi_handle, + struct roam_scan_period_params *param) { - wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; - if (wmi_handle->ops->send_roam_scan_offload_scan_period_cmd) - return wmi_handle->ops->send_roam_scan_offload_scan_period_cmd(wmi_handle, - scan_period, scan_age, vdev_id); + return wmi_handle->ops->send_roam_scan_offload_scan_period_cmd( + wmi_handle, param); return QDF_STATUS_E_FAILURE; } diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c index 3270c482a0..e519baae30 100644 --- a/wmi/src/wmi_unified_roam_tlv.c +++ b/wmi/src/wmi_unified_roam_tlv.c @@ -1383,29 +1383,84 @@ send_roam_scan_mode_cmd: return status; } +/** + * convert_roam_trigger_reason() - Function to convert unified Roam trigger + * enum to TLV specific WMI_ROAM_TRIGGER_REASON_ID + * @reason: Roam trigger reason + * + * Return: WMI_ROAM_TRIGGER_REASON_ID + */ +static WMI_ROAM_TRIGGER_REASON_ID +convert_roam_trigger_reason(enum roam_trigger_reason trigger_reason) { + + switch (trigger_reason) { + case ROAM_TRIGGER_REASON_NONE: + return WMI_ROAM_TRIGGER_REASON_NONE; + case ROAM_TRIGGER_REASON_PER: + return WMI_ROAM_TRIGGER_REASON_PER; + case ROAM_TRIGGER_REASON_BMISS: + return WMI_ROAM_TRIGGER_REASON_BMISS; + case ROAM_TRIGGER_REASON_LOW_RSSI: + return WMI_ROAM_TRIGGER_REASON_LOW_RSSI; + case ROAM_TRIGGER_REASON_HIGH_RSSI: + return WMI_ROAM_TRIGGER_REASON_HIGH_RSSI; + case ROAM_TRIGGER_REASON_PERIODIC: + return WMI_ROAM_TRIGGER_REASON_PERIODIC; + case ROAM_TRIGGER_REASON_MAWC: + return WMI_ROAM_TRIGGER_REASON_MAWC; + case ROAM_TRIGGER_REASON_DENSE: + return WMI_ROAM_TRIGGER_REASON_DENSE; + case ROAM_TRIGGER_REASON_BACKGROUND: + return WMI_ROAM_TRIGGER_REASON_BACKGROUND; + case ROAM_TRIGGER_REASON_FORCED: + return WMI_ROAM_TRIGGER_REASON_FORCED; + case ROAM_TRIGGER_REASON_BTM: + return WMI_ROAM_TRIGGER_REASON_BTM; + case ROAM_TRIGGER_REASON_UNIT_TEST: + return WMI_ROAM_TRIGGER_REASON_UNIT_TEST; + case ROAM_TRIGGER_REASON_BSS_LOAD: + return WMI_ROAM_TRIGGER_REASON_BSS_LOAD; + case ROAM_TRIGGER_REASON_DEAUTH: + return WMI_ROAM_TRIGGER_REASON_DEAUTH; + case ROAM_TRIGGER_REASON_IDLE: + return WMI_ROAM_TRIGGER_REASON_IDLE; + case ROAM_TRIGGER_REASON_MAX: + return WMI_ROAM_TRIGGER_REASON_MAX; + default: + return WMI_ROAM_TRIGGER_REASON_NONE; + } +} + /** * send_roam_scan_offload_ap_profile_cmd_tlv() - set roam ap profile in fw * @wmi_handle: wmi handle * @ap_profile_p: ap profile - * @vdev_id: vdev id * * Send WMI_ROAM_AP_PROFILE to firmware * * Return: CDF status */ -static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, - struct ap_profile_params *ap_profile) +static QDF_STATUS +send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, + struct ap_profile_params *ap_profile) { wmi_buf_t buf = NULL; QDF_STATUS status; - int len; + size_t len; uint8_t *buf_ptr; wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; wmi_roam_cnd_scoring_param *score_param; wmi_ap_profile *profile; + wmi_roam_score_delta_param *score_delta_param; + wmi_roam_cnd_min_rssi_param *min_rssi_param; + enum roam_trigger_reason trig_reason; len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); len += sizeof(*score_param); + len += WMI_TLV_HDR_SIZE; + len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param); + len += WMI_TLV_HDR_SIZE; + len += NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param); buf = wmi_buf_alloc(wmi_handle, len); if (!buf) { return QDF_STATUS_E_NOMEM; @@ -1562,6 +1617,62 @@ static QDF_STATUS send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_ha score_param->roam_score_delta_pcnt, score_param->roam_score_delta_mask); + buf_ptr += sizeof(*score_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + (NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param))); + buf_ptr += WMI_TLV_HDR_SIZE; + + score_delta_param = (wmi_roam_score_delta_param *)buf_ptr; + WMITLV_SET_HDR(&score_delta_param->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_score_delta_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param)); + trig_reason = + ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].trigger_reason; + score_delta_param->roam_trigger_reason = + convert_roam_trigger_reason(trig_reason); + score_delta_param->roam_score_delta = + ap_profile->score_delta_param[IDLE_ROAM_TRIGGER].roam_score_delta; + + buf_ptr += sizeof(*score_delta_param); + score_delta_param = (wmi_roam_score_delta_param *)buf_ptr; + WMITLV_SET_HDR(&score_delta_param->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_score_delta_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_score_delta_param)); + trig_reason = + ap_profile->score_delta_param[BTM_ROAM_TRIGGER].trigger_reason; + score_delta_param->roam_trigger_reason = + convert_roam_trigger_reason(trig_reason); + score_delta_param->roam_score_delta = + ap_profile->score_delta_param[BTM_ROAM_TRIGGER].roam_score_delta; + + buf_ptr += sizeof(*score_delta_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + (NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param))); + buf_ptr += WMI_TLV_HDR_SIZE; + + min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr; + WMITLV_SET_HDR(&min_rssi_param->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param)); + trig_reason = + ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].trigger_reason; + min_rssi_param->roam_trigger_reason = + convert_roam_trigger_reason(trig_reason); + min_rssi_param->candidate_min_rssi = + ap_profile->min_rssi_params[DEAUTH_MIN_RSSI].min_rssi; + + buf_ptr += sizeof(*min_rssi_param); + min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr; + WMITLV_SET_HDR(&min_rssi_param->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param)); + trig_reason = + ap_profile->min_rssi_params[BMISS_MIN_RSSI].trigger_reason; + min_rssi_param->roam_trigger_reason = + convert_roam_trigger_reason(trig_reason); + min_rssi_param->candidate_min_rssi = + ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi; + wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0); status = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ROAM_AP_PROFILE); @@ -1631,18 +1742,16 @@ error: /** * send_roam_scan_offload_scan_period_cmd_tlv() - set roam offload scan period * @wmi_handle: wmi handle - * @scan_period: scan period - * @scan_age: scan age - * @vdev_id: vdev id + * @param: roam scan parameters to be sent to firmware * * Send WMI_ROAM_SCAN_PERIOD parameters to fw. * - * Return: CDF status + * Return: QDF status */ -static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_handle, - uint32_t scan_period, - uint32_t scan_age, - uint32_t vdev_id) +static QDF_STATUS +send_roam_scan_offload_scan_period_cmd_tlv( + wmi_unified_t wmi_handle, + struct roam_scan_period_params *param) { QDF_STATUS status; wmi_buf_t buf = NULL; @@ -1664,26 +1773,33 @@ static QDF_STATUS send_roam_scan_offload_scan_period_cmd_tlv(wmi_unified_t wmi_h WMITLV_GET_STRUCT_TLVLEN (wmi_roam_scan_period_fixed_param)); /* fill in scan period values */ - scan_period_fp->vdev_id = vdev_id; - scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ - scan_period_fp->roam_scan_age = scan_age; + scan_period_fp->vdev_id = param->vdev_id; + scan_period_fp->roam_scan_period = param->scan_period; /* 20 seconds */ + scan_period_fp->roam_scan_age = param->scan_age; + scan_period_fp->inactivity_time_period = + param->roam_scan_inactivity_time; + scan_period_fp->roam_inactive_count = + param->roam_inactive_data_packet_count; + scan_period_fp->roam_scan_period_after_inactivity = + param->roam_scan_period_after_inactivity; + + WMI_LOGD("%s: roam_scan_period=%d, roam_scan_age=%d", __func__, + scan_period_fp->roam_scan_period, + scan_period_fp->roam_scan_age); + WMI_LOGD("%s: inactiviy period:%d inactive count:%d period after inactivity:%d", + __func__, scan_period_fp->inactivity_time_period, + scan_period_fp->roam_inactive_count, + scan_period_fp->roam_scan_period_after_inactivity); wmi_mtrace(WMI_ROAM_SCAN_PERIOD, NO_SESSION, 0); - status = wmi_unified_cmd_send(wmi_handle, buf, - len, WMI_ROAM_SCAN_PERIOD); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_ROAM_SCAN_PERIOD); if (QDF_IS_STATUS_ERROR(status)) { - WMI_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", - status); - goto error; + wmi_buf_free(buf); + return status; } - WMI_LOGI("%s: WMI --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", - __func__, scan_period, scan_age); return QDF_STATUS_SUCCESS; -error: - wmi_buf_free(buf); - - return status; } /** @@ -2044,6 +2160,7 @@ static QDF_STATUS send_btm_config_cmd_tlv(wmi_unified_t wmi_handle, cmd->stick_time_seconds = params->btm_sticky_time; cmd->disassoc_timer_threshold = params->disassoc_timer_threshold; cmd->btm_bitmap = params->btm_query_bitmask; + cmd->btm_candidate_min_score = params->btm_candidate_min_score; wmi_mtrace(WMI_ROAM_BTM_CONFIG_CMDID, cmd->vdev_id, 0); if (wmi_unified_cmd_send(wmi_handle, buf, len, @@ -2089,6 +2206,13 @@ send_roam_bss_load_config_tlv(wmi_unified_t wmi_handle, cmd->vdev_id = params->vdev_id; cmd->bss_load_threshold = params->bss_load_threshold; cmd->monitor_time_window = params->bss_load_sample_time; + cmd->rssi_2g_threshold = params->rssi_threshold_24ghz; + cmd->rssi_5g_threshold = params->rssi_threshold_5ghz; + + WMI_LOGD("%s: vdev:%d bss_load_thres:%d monitor_time:%d rssi_2g:%d rssi_5g:%d", + __func__, cmd->vdev_id, cmd->bss_load_threshold, + cmd->monitor_time_window, cmd->rssi_2g_threshold, + cmd->rssi_5g_threshold); wmi_mtrace(WMI_ROAM_BSS_LOAD_CONFIG_CMDID, cmd->vdev_id, 0); if (wmi_unified_cmd_send(wmi_handle, buf, len,