diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 68f3d3fbf55e..e8e69e819667 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4112,6 +4112,7 @@ static const struct nla_policy roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = { [PARAM_FREQ_LIST_SCHEME] = {.type = NLA_NESTED}, [QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_TRIGGERS] = {.type = NLA_U32}, }; /** @@ -4146,6 +4147,35 @@ hdd_send_roam_full_scan_period_to_sme(struct hdd_context *hdd_ctx, return status; } +/** + * hdd_send_roam_triggers_to_sme() - Send roam trigger bitmap to SME + * @hdd_ctx: HDD context + * @vdev_id: vdev id + * @roam_trigger_bitmap: Vendor configured roam trigger bitmap to be configured + * to firmware + * + * Send the roam trigger bitmap received to SME + * + * Return: QDF_STATUS + */ +static QDF_STATUS +hdd_send_roam_triggers_to_sme(struct hdd_context *hdd_ctx, + uint8_t vdev_id, + uint32_t roam_trigger_bitmap) +{ + QDF_STATUS status; + struct roam_triggers triggers; + + triggers.vdev_id = vdev_id; + triggers.trigger_bitmap = roam_trigger_bitmap; + + status = sme_set_roam_triggers(hdd_ctx->mac_handle, &triggers); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Failed to set roam control trigger bitmap"); + + return status; +} + /** * hdd_set_roam_with_control_config() - Set roam control configuration * @hdd_ctx: HDD context @@ -4199,6 +4229,17 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, hdd_err("failed to config full scan period"); } + if (tb2[QCA_ATTR_ROAM_CONTROL_TRIGGERS]) { + hdd_debug("Parse and send roam triggers to firmware"); + value = nla_get_u32(tb2[QCA_ATTR_ROAM_CONTROL_TRIGGERS]); + hdd_debug("Received roam trigger bitmap: 0x%x", value); + status = hdd_send_roam_triggers_to_sme(hdd_ctx, + vdev_id, + value); + if (status) + hdd_err("failed to config roam triggers"); + } + return qdf_status_to_os_return(status); } diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 8d7bc3d2e541..9d61fc93aed4 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -665,7 +665,9 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_SEND_PEER_UNMAP_CONF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 411) -#define SIR_HAL_GET_ISOLATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 412) +#define SIR_HAL_GET_ISOLATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 412) + +#define SIR_HAL_SET_ROAM_TRIGGERS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 413) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 250617bbc999..185cdc851ca2 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3633,4 +3633,19 @@ void sme_chan_to_freq_list( uint32_t *freq_list, const uint8_t *chan_list, uint32_t chan_list_len); + +/** + * sme_set_roam_triggers() - Send roam trigger bitmap to WMA + * @mac_handle: Opaque handle to the MAC context + * @triggers: Carries pointer of the object containing vdev id and + * roam_trigger_bitmap. + * + * Send the roam trigger bitmap received to WMA/WMI. WMI converts + * the bitmap to firmware compatible bitmap as per reasons + * defined @WMI_ROAM_TRIGGER_REASON_ID + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle, + struct roam_triggers *triggers); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 52428bfce90c..c077a5e42b89 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -15994,3 +15994,39 @@ void sme_chan_to_freq_list( freq_list[count] = wlan_reg_chan_to_freq(pdev, (uint32_t)chan_list[count]); } + +QDF_STATUS sme_set_roam_triggers(mac_handle_t mac_handle, + struct 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; + + /* per contract must make a copy of the params when messaging */ + roam_trigger_data = qdf_mem_malloc(sizeof(*roam_trigger_data)); + if (!roam_trigger_data) + return QDF_STATUS_E_NOMEM; + *roam_trigger_data = *triggers; + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(roam_trigger_data); + return status; + } + + /* Serialize the req through MC thread */ + message.bodyptr = roam_trigger_data; + message.type = SIR_HAL_SET_ROAM_TRIGGERS; + status = scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &message); + sme_release_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("failed to post ROAM_TRIGGERS msg"); + qdf_mem_free(roam_trigger_data); + } + + return status; +} diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index b6147b2c4124..a2faf0bfec00 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1607,4 +1607,14 @@ void wma_send_vdev_down(tp_wma_handle wma, struct wma_target_req *req); */ int wma_cold_boot_cal_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len); + +/** + * wma_set_roam_triggers() - Send roam trigger bitmap to WMI + * @wma_handle: wma handle + * @triggers: Carries vdev id and roam trigger bitmap. + * + * Return: Success or Failure status + */ +QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma_handle, + struct roam_triggers *triggers); #endif diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index d8bac2c14715..e5bd79073f41 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -455,6 +455,7 @@ #ifdef WLAN_MWS_INFO_DEBUGFS #define WMA_GET_MWS_COEX_INFO_REQ SIR_HAL_GET_MWS_COEX_INFO_REQ #endif +#define WMA_SET_ROAM_TRIGGERS SIR_HAL_SET_ROAM_TRIGGERS /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 07bac1dc96b2..9edf38a4655c 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -9149,6 +9149,10 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) qdf_mem_free(msg->bodyptr); break; #endif + case WMA_SET_ROAM_TRIGGERS: + wma_set_roam_triggers(wma_handle, msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; default: WMA_LOGD("Unhandled WMA message of type %d", msg->type); if (msg->bodyptr) diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 278a1c6dcbf8..4a4da50d7814 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -5679,3 +5679,24 @@ int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info, wma_send_msg(wma, WMA_ROAM_BLACKLIST_MSG, (void *)dst_list, 0); return 0; } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma, + struct roam_triggers *triggers) +{ + if (!wma_is_vdev_valid(triggers->vdev_id)) { + WMA_LOGE("%s: vdev_id: %d is not active", __func__, + triggers->vdev_id); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_set_roam_triggers(wma->wmi_handle, triggers); +} + +#else +inline QDF_STATUS +wma_set_roam_triggers(tp_wma_handle wma, struct roam_triggers *triggers) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif