diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 0ee74c075712..1c101be51707 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1999,6 +1999,9 @@ QDF_STATUS (*extract_oem_response_param) QDF_STATUS (*extract_hw_mode_resp_event)(wmi_unified_t wmi_handle, void *evt_buf, uint32_t *cmd_status); +QDF_STATUS (*send_set_roam_trigger_cmd)(wmi_unified_t wmi_handle, + uint32_t vdev_id, + uint32_t trigger_bitmap); }; /* Forward declartion for psoc*/ diff --git a/wmi/inc/wmi_unified_roam_api.h b/wmi/inc/wmi_unified_roam_api.h index f5db6e2ce6a7..b47ebd7c8479 100644 --- a/wmi/inc/wmi_unified_roam_api.h +++ b/wmi/inc/wmi_unified_roam_api.h @@ -381,4 +381,17 @@ QDF_STATUS wmi_unified_invoke_neighbor_report_cmd( wmi_unified_t wmi_handle, struct wmi_invoke_neighbor_report_params *params); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * wmi_unified_set_roam_triggers() - send roam trigger bitmap + * @wmi_handle: wmi handle + * @triggers: Roam trigger bitmap params as defined @roam_control_trigger_reason + * + * This function passes the roam trigger bitmap to fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle, + struct roam_triggers *triggers); +#endif #endif /* _WMI_UNIFIED_ROAM_API_H_ */ diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h index 7660fcbbf0a0..50aec4557ed1 100644 --- a/wmi/inc/wmi_unified_roam_param.h +++ b/wmi/inc/wmi_unified_roam_param.h @@ -761,4 +761,50 @@ struct wmi_invoke_neighbor_report_params { struct mac_ssid ssid; }; +/** + * enum roam_control_trigger_reason - Bitmap of roaming triggers + * + * @ROAM_TRIGGER_REASON_PER: Set if the roam has to be triggered based on + * a bad packet error rates (PER). + * @ROAM_TRIGGER_REASON_BEACON_MISS: Set if the roam has to be triggered + * based on beacon misses from the connected AP. + * @ROAM_TRIGGER_REASON_POOR_RSSI: Set if the roam has to be triggered + * due to poor RSSI of the connected AP. + * @ROAM_TRIGGER_REASON_BETTER_RSSI: Set if the roam has to be triggered + * upon finding a BSSID with a better RSSI than the connected BSSID. + * Here the RSSI of the current BSSID need not be poor. + * @ROAM_TRIGGER_REASON_PERIODIC: Set if the roam has to be triggered + * by triggering a periodic scan to find a better AP to roam. + * @ROAM_TRIGGER_REASON_DENSE: Set if the roam has to be triggered + * when the connected channel environment is too noisy/congested. + * @ROAM_TRIGGER_REASON_BTM: Set if the roam has to be triggered + * when BTM Request frame is received from the connected AP. + * @ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered + * when the channel utilization is goes above the configured threshold. + * + * Set the corresponding roam trigger reason bit to consider it for roam + * trigger. + */ +enum roam_control_trigger_reason { + ROAM_CONTROL_TRIGGER_REASON_PER = 1 << 0, + ROAM_CONTROL_TRIGGER_REASON_BEACON_MISS = 1 << 1, + ROAM_CONTROL_TRIGGER_REASON_POOR_RSSI = 1 << 2, + ROAM_CONTROL_TRIGGER_REASON_BETTER_RSSI = 1 << 3, + ROAM_CONTROL_TRIGGER_REASON_PERIODIC = 1 << 4, + ROAM_CONTROL_TRIGGER_REASON_DENSE = 1 << 5, + ROAM_CONTROL_TRIGGER_REASON_BTM = 1 << 6, + ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD = 1 << 7, +}; + +/** + * struct roam_triggers - vendor configured roam triggers + * @vdev_id: vdev id + * @trigger_bitmap: vendor configured roam trigger bitmap as + * defined @enum roam_control_trigger_reason + */ +struct roam_triggers { + uint32_t vdev_id; + uint32_t trigger_bitmap; +}; + #endif /* _WMI_UNIFIED_ROAM_PARAM_H_ */ diff --git a/wmi/src/wmi_unified_roam_api.c b/wmi/src/wmi_unified_roam_api.c index c66c9347998e..93b774b8bcf2 100644 --- a/wmi/src/wmi_unified_roam_api.c +++ b/wmi/src/wmi_unified_roam_api.c @@ -320,3 +320,14 @@ QDF_STATUS wmi_unified_invoke_neighbor_report_cmd( return QDF_STATUS_E_FAILURE; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle, + struct roam_triggers *triggers) +{ + if (wmi_handle->ops->send_set_roam_trigger_cmd) + return wmi_handle->ops->send_set_roam_trigger_cmd(wmi_handle, + triggers->vdev_id, triggers->trigger_bitmap); + + return QDF_STATUS_E_FAILURE; +} +#endif diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c index 917af1dc7d93..93fc30a20239 100644 --- a/wmi/src/wmi_unified_roam_tlv.c +++ b/wmi/src/wmi_unified_roam_tlv.c @@ -2435,6 +2435,121 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } + +/** + * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap + * + * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers + * + * Converts the controlled roam trigger reason bitmap of + * type @roam_control_trigger_reason to firmware trigger + * reason bitmap as defined in + * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param + * + * Return: trigger_reason_bitmask as defined in + * wmi_roam_enable_disable_trigger_reason_fixed_param + */ +static uint32_t +convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap) +{ + uint32_t fw_trigger_bitmap = 0, all_bitmap; + + /* Enable the complete trigger bitmap when all bits are set in + * the control config bitmap + */ + all_bitmap = (ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD << 1) - 1; + if (trigger_reason_bitmap == all_bitmap) + return (BIT(WMI_ROAM_TRIGGER_REASON_MAX) - 1); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PER) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BEACON_MISS) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_POOR_RSSI) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BETTER_RSSI) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PERIODIC) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_DENSE) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BTM) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM); + + if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD); + + return fw_trigger_bitmap; +} + +/** + * get_internal_mandatory_roam_triggers() - Internal triggers to be added + * + * Return: the bitmap of mandatory triggers to be sent to firmware but not given + * by user. + */ +static uint32_t +get_internal_mandatory_roam_triggers(void) +{ + return BIT(WMI_ROAM_TRIGGER_REASON_FORCED); +} + +/** + * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw + * + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @trigger_bitmap: roam trigger bitmap to be enabled + * + * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw. + * + * Return: QDF_STATUS + */ +static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle, + uint32_t vdev_id, + uint32_t trigger_bitmap) +{ + wmi_buf_t buf; + wmi_roam_enable_disable_trigger_reason_fixed_param *cmd; + uint16_t len = sizeof(*cmd); + int ret; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *) + wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_enable_disable_trigger_reason_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->trigger_reason_bitmask = + convert_control_roam_trigger_reason_bitmap(trigger_bitmap); + WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x", + trigger_bitmap, cmd->trigger_reason_bitmask); + cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers(); + WMI_LOGD("WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID vdev id: %d final trigger_bitmap: 0x%x", + cmd->vdev_id, cmd->trigger_reason_bitmask); + wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, vdev_id, 0); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID); + if (QDF_IS_STATUS_ERROR(ret)) { + WMI_LOGE("Failed to send set roam triggers command ret = %d", + ret); + wmi_buf_free(buf); + } + return ret; +} #else static inline QDF_STATUS send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle, @@ -2456,6 +2571,14 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle, { return QDF_STATUS_E_FAILURE; } + +static QDF_STATUS +send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle, + uint32_t vdev_id, + uint32_t trigger_bitmap) +{ + return QDF_STATUS_E_FAILURE; +} #endif /** @@ -2630,6 +2753,7 @@ void wmi_roam_attach_tlv(wmi_unified_t wmi_handle) ops->send_idle_roam_params = send_idle_roam_params_tlv; ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv; ops->send_roam_preauth_status = send_roam_preauth_status_tlv; + ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv, wmi_lfr_subnet_detection_attach_tlv(wmi_handle); wmi_rssi_monitor_attach_tlv(wmi_handle);