From c871ecddbd2400020f069bcca16e312f7eb780dd Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 6 Jul 2020 15:04:52 +0530 Subject: [PATCH] qcacld-3.0: Send roam triggers from vendor cmd to firmware Userspace can configure different roam control params as defined in qca_vendor_attr_roam_control through the roam subcmd QCA_NL80211_VENDOR_SUBCMD_ROAM and the below attributes: QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_SCHEME QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD QCA_ATTR_ROAM_CONTROL_USER_REASON Send value of above attribute to fw through command WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID for trigger reason WMI_ROAM_TRIGGER_REASON_BTM_WTC. Change-Id: I17502eebab56652192164144b7ebdadb32033117 CRs-Fixed: 2729119 --- .../dispatcher/inc/wlan_cm_roam_api.h | 56 +++ .../inc/wlan_cm_roam_public_srtuct.h | 47 +++ .../dispatcher/src/wlan_cm_roam_api.c | 82 ++++ components/wmi/inc/wmi_unified_roam_api.h | 2 +- components/wmi/inc/wmi_unified_roam_param.h | 11 - components/wmi/src/wmi_unified_roam_api.c | 4 +- components/wmi/src/wmi_unified_roam_tlv.c | 352 ++++++++++-------- core/hdd/src/wlan_hdd_cfg80211.c | 28 +- core/hdd/src/wlan_hdd_main.c | 4 +- core/mac/inc/sir_api.h | 2 +- core/sme/inc/csr_neighbor_roam.h | 2 +- core/sme/inc/sme_api.h | 14 +- core/sme/src/common/sme_api.c | 28 +- core/sme/src/csr/csr_api_roam.c | 4 + core/sme/src/csr/csr_neighbor_roam.c | 2 +- core/wma/inc/wma_internal.h | 2 +- core/wma/src/wma_scan_roam.c | 7 +- 17 files changed, 469 insertions(+), 178 deletions(-) diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h index cbd6b1f86de6..679dd2cefb98 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h @@ -28,6 +28,9 @@ #include "wlan_mlme_main.h" #include "wlan_mlme_api.h" +/* Default value of reason code */ +#define DISABLE_VENDOR_BTM_CONFIG 2 + #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats @@ -117,6 +120,44 @@ wlan_cm_dual_sta_is_freq_allowed(struct wlan_objmgr_psoc *psoc, uint32_t freq, void wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc, struct scan_filter *filter); +/** + * wlan_cm_roam_set_vendor_btm_params - API to set vendor btm params + * @psoc: PSOC pointer + * @vdev_id: VDEV id + * @param: vendor configured roam trigger param + * + * Return: none + */ +void +wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params + *param); +/** + * wlan_cm_roam_disable_vendor_btm - API to disable vendor btm by default + * reason + * @psoc: PSOC pointer + * @vdev_id: VDEV id + * + * Return: none + */ +void +wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); + +/** + * wlan_cm_roam_get_vendor_btm_params - API to get vendor btm param + * @psoc: PSOC pointer + * @vdev_id: VDEV id + * @param: vendor configured roam trigger param + * + * Return: none + */ +void +wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params + *param); + #else static inline void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, @@ -159,5 +200,20 @@ wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf, return true; } +static inline void +wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{} + +static inline void +wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params *param) +{} + +static inline void +wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params *param) +{} #endif /* FEATURE_ROAM_OFFLOAD */ #endif /* WLAN_CM_ROAM_API_H__ */ diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h index 1f83ad9e2ceb..5d0399e83377 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h @@ -127,15 +127,62 @@ struct wlan_cm_roam_tx_ops { struct set_pcl_req *req); }; +/** + * enum roam_scan_freq_scheme - Scan mode for triggering roam + * ROAM_SCAN_FREQ_SCHEME_NO_SCAN: Indicates the fw to not scan. + * ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN: Indicates the firmware to + * trigger partial frequency scans. + * ROAM_SCAN_FREQ_SCHEME_FULL_SCAN: Indicates the firmware to + * trigger full frequency scans. + */ +enum roam_scan_freq_scheme { + ROAM_SCAN_FREQ_SCHEME_NO_SCAN = 0, + ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN = 1, + ROAM_SCAN_FREQ_SCHEME_FULL_SCAN = 2, +}; + +/** + * struct wlan_cm_roam_vendor_btm_params - vendor config roam control param + * @scan_freq_scheme: scan frequency scheme from enum + * qca_roam_scan_freq_scheme + * @connected_rssi_threshold: RSSI threshold of the current + * connected AP + * @candidate_rssi_threshold: RSSI threshold of the + * candidate AP + * @user_roam_reason: Roam triggered reason code, value zero is for enable + * and non zero value is disable + */ +struct wlan_cm_roam_vendor_btm_params { + uint32_t scan_freq_scheme; + uint32_t connected_rssi_threshold; + uint32_t candidate_rssi_threshold; + uint32_t user_roam_reason; +}; + +/** + * struct wlan_roam_triggers - vendor configured roam triggers + * @vdev_id: vdev id + * @trigger_bitmap: vendor configured roam trigger bitmap as + * defined @enum roam_control_trigger_reason + * @control_param: roam trigger param + */ +struct wlan_roam_triggers { + uint32_t vdev_id; + uint32_t trigger_bitmap; + struct wlan_cm_roam_vendor_btm_params vendor_btm_param; +}; + /** * struct wlan_cm_roam - Connection manager roam configs, state and roam * data related structure * @tx_ops: Roam Tx ops to send roam offload commands to firmware * @pcl_vdev_cmd_active: Flag to check if vdev level pcl command needs to be * sent or PDEV level PCL command needs to be sent + * @control_param: vendor configured roam control param */ struct wlan_cm_roam { struct wlan_cm_roam_tx_ops tx_ops; bool pcl_vdev_cmd_active; + struct wlan_cm_roam_vendor_btm_params vendor_btm_param; }; #endif diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index 2a74fba2fdb6..cfd608a72bce 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c @@ -179,4 +179,86 @@ wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc, } qdf_mem_free(channel_list); } + +void +wlan_cm_roam_disable_vendor_btm(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return; + } + + /* Set default value of reason code */ + mlme_priv->cm_roam.vendor_btm_param.user_roam_reason = + DISABLE_VENDOR_BTM_CONFIG; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); +} + +void +wlan_cm_roam_set_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params + *param) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return; + } + + qdf_mem_copy(&mlme_priv->cm_roam.vendor_btm_param, param, + sizeof(struct wlan_cm_roam_vendor_btm_params)); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); +} + +void +wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct wlan_cm_roam_vendor_btm_params *param) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return; + } + + qdf_mem_copy(param, &mlme_priv->cm_roam.vendor_btm_param, + sizeof(struct wlan_cm_roam_vendor_btm_params)); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); +} #endif diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h index 8a5046ba6498..0867c92bc015 100644 --- a/components/wmi/inc/wmi_unified_roam_api.h +++ b/components/wmi/inc/wmi_unified_roam_api.h @@ -178,7 +178,7 @@ wmi_unified_roam_invoke_cmd(wmi_unified_t wmi_handle, * 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); + struct wlan_roam_triggers *triggers); /** * wmi_unified_send_disconnect_roam_params() - Send disconnect roam trigger diff --git a/components/wmi/inc/wmi_unified_roam_param.h b/components/wmi/inc/wmi_unified_roam_param.h index c2c74f872a45..5a7fd64b2a9e 100644 --- a/components/wmi/inc/wmi_unified_roam_param.h +++ b/components/wmi/inc/wmi_unified_roam_param.h @@ -712,17 +712,6 @@ struct wmi_invoke_neighbor_report_params { struct wlan_ssid ssid; }; -/** - * 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; -}; - /** * set_pcl_cmd_params - Set PCL command params * @vdev_id: Vdev id diff --git a/components/wmi/src/wmi_unified_roam_api.c b/components/wmi/src/wmi_unified_roam_api.c index dfdc4e58d70e..b92156f91b62 100644 --- a/components/wmi/src/wmi_unified_roam_api.c +++ b/components/wmi/src/wmi_unified_roam_api.c @@ -337,11 +337,11 @@ QDF_STATUS wmi_unified_get_roam_scan_ch_list(wmi_unified_t wmi_handle, #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle, - struct roam_triggers *triggers) + struct wlan_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); + triggers); return QDF_STATUS_E_FAILURE; } diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 3a4c88b28e91..4ed459b16c13 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -921,6 +921,206 @@ static QDF_STATUS send_roam_invoke_cmd_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 = BIT(ROAM_TRIGGER_REASON_MAX) - 1; + if (trigger_reason_bitmap == all_bitmap) + return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1; + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT); + + if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_ESS_RSSI)) + fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_ESS_RSSI); + + 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); +} + +/** + * convert_roam_trigger_scan_mode() - Function to convert unified Roam trigger + * scan mode enum to TLV specific ROAM_TRIGGER_SCAN_MODE + * @scan_freq_scheme: scan freq scheme coming from userspace + * + * Return: ROAM_TRIGGER_SCAN_MODE + */ +static WMI_ROAM_TRIGGER_SCAN_MODE +convert_roam_trigger_scan_mode(enum roam_scan_freq_scheme scan_freq_scheme) +{ + switch (scan_freq_scheme) { + case ROAM_SCAN_FREQ_SCHEME_NO_SCAN: + return ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION; + case ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN: + return ROAM_TRIGGER_SCAN_MODE_PARTIAL; + case ROAM_SCAN_FREQ_SCHEME_FULL_SCAN: + return ROAM_TRIGGER_SCAN_MODE_FULL; + default: + return ROAM_TRIGGER_SCAN_MODE_NONE; + } +} + +/** + * 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, + struct wlan_roam_triggers *triggers) +{ + wmi_buf_t buf; + wmi_roam_enable_disable_trigger_reason_fixed_param *cmd; + uint16_t len = sizeof(*cmd); + int ret; + uint8_t *buf_ptr; + wmi_configure_roam_trigger_parameters + *roam_trigger_parameters; + + len += WMI_TLV_HDR_SIZE + + sizeof(wmi_configure_roam_trigger_parameters); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + + 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 = triggers->vdev_id; + cmd->trigger_reason_bitmask = + convert_control_roam_trigger_reason_bitmap(triggers->trigger_bitmap); + WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x", + triggers->trigger_bitmap, cmd->trigger_reason_bitmask); + cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers(); + WMI_LOGD("vdev id: %d final trigger_bitmap: 0x%x", + cmd->vdev_id, cmd->trigger_reason_bitmask); + + buf_ptr += sizeof(wmi_roam_enable_disable_trigger_reason_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_configure_roam_trigger_parameters)); + buf_ptr += WMI_TLV_HDR_SIZE; + + roam_trigger_parameters = + (wmi_configure_roam_trigger_parameters *)buf_ptr; + WMITLV_SET_HDR(&roam_trigger_parameters->tlv_header, + WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters, + WMITLV_GET_STRUCT_TLVLEN( + wmi_configure_roam_trigger_parameters)); + + roam_trigger_parameters->trigger_reason = + WMI_ROAM_TRIGGER_REASON_WTC_BTM; + if (triggers->vendor_btm_param.user_roam_reason == 0) + roam_trigger_parameters->enable = 1; + roam_trigger_parameters->scan_mode = + convert_roam_trigger_scan_mode(triggers->vendor_btm_param. + scan_freq_scheme); + roam_trigger_parameters->trigger_rssi_threshold = + triggers->vendor_btm_param.connected_rssi_threshold; + roam_trigger_parameters->cand_ap_min_rssi_threshold = + triggers->vendor_btm_param.candidate_rssi_threshold; + roam_trigger_parameters->roam_score_delta_percentage = 0; + roam_trigger_parameters->reason_code = + triggers->vendor_btm_param.user_roam_reason; + + wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, + triggers->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; +} + /** * send_vdev_set_pcl_cmd_tlv() - Send WMI_VDEV_SET_PCL_CMDID to FW * @wmi_handle: wmi handle @@ -1072,6 +1272,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle) send_process_roam_synch_complete_cmd_tlv; ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv; ops->send_vdev_set_pcl_cmd = send_vdev_set_pcl_cmd_tlv; + ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv; } #else static inline QDF_STATUS @@ -2619,148 +2820,6 @@ 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 = BIT(ROAM_TRIGGER_REASON_MAX) - 1; - if (trigger_reason_bitmap == all_bitmap) - return BIT(WMI_ROAM_TRIGGER_EXT_REASON_MAX) - 1; - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_NONE)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_NONE); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PER)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BMISS)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_LOW_RSSI)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_HIGH_RSSI)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_PERIODIC)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_MAWC)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_MAWC); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DENSE)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BACKGROUND)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BACKGROUND); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_FORCED)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_FORCED); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BTM)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_UNIT_TEST)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_UNIT_TEST); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_BSS_LOAD)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_DEAUTH)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DEAUTH); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_IDLE)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_IDLE); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_STA_KICKOUT)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_STA_KICKOUT); - - if (trigger_reason_bitmap & BIT(ROAM_TRIGGER_REASON_ESS_RSSI)) - fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_ESS_RSSI); - - 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("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, @@ -2782,14 +2841,6 @@ 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 /** @@ -2961,7 +3012,6 @@ 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); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index bf528ebfa1ce..930c477a22b8 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -153,6 +153,7 @@ #include "wlan_hdd_apf.h" #include "wlan_hdd_cfr.h" #include "wlan_hdd_ioctl.h" +#include "wlan_cm_roam_api.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -4508,6 +4509,10 @@ roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = { [QCA_ATTR_ROAM_CONTROL_TRIGGERS] = {.type = NLA_U32}, [QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA] = {.type = NLA_NESTED}, [QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_USER_REASON] = {.type = NLA_U32}, }; /** @@ -4625,7 +4630,7 @@ hdd_send_roam_triggers_to_sme(struct hdd_context *hdd_ctx, uint32_t roam_trigger_bitmap) { QDF_STATUS status; - struct roam_triggers triggers; + struct wlan_roam_triggers triggers; struct hdd_adapter *adapter; adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); @@ -4838,6 +4843,7 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, QDF_STATUS status = QDF_STATUS_SUCCESS; struct nlattr *tb2[QCA_ATTR_ROAM_CONTROL_MAX + 1], *attr; uint32_t value; + struct wlan_cm_roam_vendor_btm_params param = {0}; hdd_enter(); /* The command must carry PARAM_ROAM_CONTROL_CONFIG */ @@ -4945,6 +4951,26 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, hdd_err("failed to set candidate selection criteria"); } + attr = tb2[QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME]; + if (attr) + param.scan_freq_scheme = nla_get_u32(attr); + + attr = tb2[QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD]; + if (attr) + param.connected_rssi_threshold = nla_get_u32(attr); + + attr = tb2[QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD]; + if (attr) + param.candidate_rssi_threshold = nla_get_u32(attr); + + attr = tb2[QCA_ATTR_ROAM_CONTROL_USER_REASON]; + if (attr) + param.user_roam_reason = nla_get_u32(attr); + else + param.user_roam_reason = DISABLE_VENDOR_BTM_CONFIG; + wlan_cm_roam_set_vendor_btm_params(hdd_ctx->psoc, vdev_id, ¶m); + sme_send_vendor_btm_params(hdd_ctx->mac_handle, vdev_id); + return qdf_status_to_os_return(status); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6da46ec52428..0981d19f6ddf 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -190,6 +190,7 @@ #include #include "wlan_global_lmac_if_api.h" #include "wlan_coex_ucfg_api.h" +#include "wlan_cm_roam_api.h" #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -5367,7 +5368,8 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc); mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, adapter->vdev_id, roam_triggers); - + wlan_cm_roam_disable_vendor_btm(hdd_ctx->psoc, + adapter->vdev_id); ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); sme_cli_set_command( diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index ed5f6503fdbe..52413bb66e1c 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -2217,7 +2217,7 @@ struct roam_offload_scan_req { struct wmi_disconnect_roam_params disconnect_roam_params; #endif struct roam_ext_params roam_params; - struct roam_triggers roam_triggers; + struct wlan_roam_triggers roam_triggers; uint8_t middle_of_roaming; uint32_t hi_rssi_scan_max_count; uint32_t hi_rssi_scan_rssi_delta; diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index 25d69cc9eb8d..f8a040d117c9 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -263,7 +263,7 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ptr); #define REASON_SUPPLICANT_INIT_ROAMING 46 #define REASON_SUPPLICANT_DE_INIT_ROAMING 47 #define REASON_DRIVER_DISABLED 48 -#define REASON_ROAM_CONTROL_CONFIG_RESTORED 49 +#define REASON_ROAM_CONTROL_CONFIG_CHANGED 49 #define REASON_ROAM_CONTROL_CONFIG_ENABLED 50 #define REASON_ROAM_CANDIDATE_FOUND 51 #define REASON_ROAM_HANDOFF_DONE 52 diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index cb2af46fcd8e..0206d476a4c9 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -4069,7 +4069,7 @@ void sme_chan_to_freq_list( * Return: QDF_STATUS */ QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle, - struct roam_triggers *triggers); + struct wlan_roam_triggers *triggers); /** * sme_set_roam_config_enable() - Cache roam config status in SME @@ -4087,6 +4087,18 @@ QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle, uint8_t vdev_id, uint8_t roam_control_enable); +/** + * sme_send_vendor_btm_params - Send vendor btm params to FW + * @hdd_ctx: HDD context + * @vdev_id: vdev id + * + * Send roam trigger param to firmware if valid. + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id); + /** * sme_get_roam_config_status() - Get roam config status from SME * @mac_handle: Opaque handle to the MAC context diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index a43bad1aae9b..dc04dcba35d4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -64,7 +64,6 @@ #include "wlan_mlme_ucfg_api.h" #include "wlan_psoc_mlme_api.h" #include "mac_init_api.h" -#include "wlan_cm_roam_public_srtuct.h" #include "wlan_cm_roam_api.h" #include "wlan_cm_tgt_if_tx_api.h" @@ -15981,12 +15980,12 @@ static QDF_STATUS sme_enable_roaming(struct mac_context *mac, uint32_t vdev_id, } QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle, - struct roam_triggers *triggers) + struct wlan_roam_triggers *triggers) { QDF_STATUS status; struct mac_context *mac = MAC_CONTEXT(mac_handle); struct scheduler_msg message = {0}; - struct roam_triggers *roam_trigger_data; + struct wlan_roam_triggers *roam_trigger_data; mlme_set_roam_trigger_bitmap(mac->psoc, triggers->vdev_id, triggers->trigger_bitmap); @@ -16028,6 +16027,29 @@ QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle, return status; } +QDF_STATUS +sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (vdev_id >= WLAN_MAX_VDEVS) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), vdev_id); + return QDF_STATUS_E_INVAL; + } + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) + csr_roam_update_cfg(mac, vdev_id, + REASON_ROAM_CONTROL_CONFIG_CHANGED); + sme_release_global_lock(&mac->sme); + } + + return status; +} + QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle, uint8_t vdev_id, uint8_t roam_control_enable) diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 8f5c0f495d52..48899cfaa592 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -19223,6 +19223,10 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, else if (command == ROAM_SCAN_OFFLOAD_STOP) csr_update_11k_offload_params(mac_ctx, session, req_buf, FALSE); + wlan_cm_roam_get_vendor_btm_params(mac_ctx->psoc, session_id, + &req_buf->roam_triggers. + vendor_btm_param); + prev_roaming_state = mlme_get_roam_state(mac_ctx->psoc, session_id); /* Update PER config to FW. No need to update in case of stop command, diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index e8ae4c0739ea..192cea1e2a82 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -637,7 +637,7 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ctx) static void csr_roam_restore_default_config(struct mac_context *mac_ctx, uint8_t vdev_id) { - struct roam_triggers triggers; + struct wlan_roam_triggers triggers; sme_set_roam_config_enable(MAC_HANDLE(mac_ctx), vdev_id, 0); diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index bb416dadd18f..79852d8b71ae 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1809,7 +1809,7 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len); * Return: Success or Failure status */ QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma_handle, - struct roam_triggers *triggers); + struct wlan_roam_triggers *triggers); /** * wma_get_ani_level_evt_handler - event handler to fetch ani level diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index bb5d4cfbc5ee..c29b5ea97577 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2072,7 +2072,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, * disconnect */ if (mode == WMI_ROAM_SCAN_MODE_NONE) { - struct roam_triggers roam_triggers; + struct wlan_roam_triggers roam_triggers; roam_triggers.vdev_id = roam_req->sessionId; roam_triggers.trigger_bitmap = 0; @@ -2213,6 +2213,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, wma_send_disconnect_roam_params(wma_handle, roam_req); wma_send_idle_roam_params(wma_handle, roam_req); + wma_set_roam_triggers(wma_handle, &roam_req->roam_triggers); break; @@ -6435,7 +6436,7 @@ int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info, #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma, - struct roam_triggers *triggers) + struct wlan_roam_triggers *triggers) { if (!wma_is_vdev_valid(triggers->vdev_id)) return QDF_STATUS_E_INVAL; @@ -6543,7 +6544,7 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event, #endif /* WLAN_FEATURE_FIPS */ #else inline QDF_STATUS -wma_set_roam_triggers(tp_wma_handle wma, struct roam_triggers *triggers) +wma_set_roam_triggers(tp_wma_handle wma, struct wlan_roam_triggers *triggers) { return QDF_STATUS_E_NOSUPPORT; }