diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 2d4511a744bd..1aa684a4bf9d 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -804,6 +804,7 @@ struct roam_synch_frame_ind { * @vdev_stop_wakelock: wakelock to protect vdev stop op with firmware * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware * @channel: channel + * @roam_offload_enabled: is roam offload enable/disable * @roam_scan_stats_req: cached roam scan stats request * * It stores parameters per vdev in wma. @@ -894,6 +895,7 @@ struct wma_txrx_node { qdf_wake_lock_t vdev_set_key_wakelock; struct roam_synch_frame_ind roam_synch_frame_ind; bool is_waiting_for_key; + bool roam_offload_enabled; uint8_t channel; struct sir_roam_scan_stats *roam_scan_stats_req; }; @@ -1004,7 +1006,6 @@ struct wma_valid_channels { * @get_sta_peer_info: Is a "get peer info" request active? * @peer_macaddr: When @get_one_peer_info is true, the peer's mac address * @thermal_mgmt_info: Thermal mitigation related info - * @roam_offload_enabled: is roam offload enable/disable * @ssdp: ssdp flag * @enable_mc_list: To Check if Multicast list filtering is enabled in FW * @ibss_started: is IBSS started or not @@ -1141,7 +1142,6 @@ typedef struct { bool get_sta_peer_info; struct qdf_mac_addr peer_macaddr; t_thermal_mgmt thermal_mgmt_info; - bool roam_offload_enabled; bool ssdp; bool enable_mc_list; uint8_t ibss_started; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index f3bb351b68d2..864a77ae75a5 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -2977,15 +2977,6 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, /* Initialize roaming offload state */ if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && (self_sta_req->sub_type == 0)) { - wma_handle->roam_offload_enabled = true; - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, - (WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG | - WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG)); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD"); - /* Pass down enable/disable bcast probe rsp to FW */ ret = wma_vdev_set_param( wma_handle->wmi_handle, @@ -6196,6 +6187,7 @@ static void wma_wait_tx_complete(tp_wma_handle wma, max_wait_iterations--; } } + /** * wma_delete_bss() - process delete bss request from upper layer * @wma: wma handle diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 633b781b0aed..080ca1487f19 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1558,7 +1558,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, return QDF_STATUS_E_FAILURE; } - if (!wma_handle->roam_offload_enabled) { + if (!wma_handle->interfaces[roam_req->sessionId].roam_offload_enabled) { /* roam scan offload is not enabled in firmware. * Cannot initialize it in the middle of connection. */ @@ -1750,28 +1750,26 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, } wma_handle->suitable_ap_hb_failure = false; - if (wma_handle->roam_offload_enabled) { - uint32_t mode; - wma_roam_scan_fill_scan_params(wma_handle, mac, - NULL, &scan_params); + wma_roam_scan_fill_scan_params(wma_handle, mac, + NULL, &scan_params); - if (roam_req->reason == REASON_ROAM_STOP_ALL || - roam_req->reason == REASON_DISCONNECTED || - roam_req->reason == REASON_ROAM_SYNCH_FAILED) { + if (roam_req->reason == REASON_ROAM_STOP_ALL || + roam_req->reason == REASON_DISCONNECTED || + roam_req->reason == REASON_ROAM_SYNCH_FAILED) { + mode = WMI_ROAM_SCAN_MODE_NONE; + } else { + if (csr_is_roam_offload_enabled(mac)) + mode = WMI_ROAM_SCAN_MODE_NONE | + WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; + else mode = WMI_ROAM_SCAN_MODE_NONE; - } else { - if (csr_is_roam_offload_enabled(mac)) - mode = WMI_ROAM_SCAN_MODE_NONE | - WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; - else - mode = WMI_ROAM_SCAN_MODE_NONE; - } - - qdf_status = wma_roam_scan_offload_mode(wma_handle, - &scan_params, NULL, mode, - roam_req->sessionId); } + + qdf_status = wma_roam_scan_offload_mode( + wma_handle, + &scan_params, NULL, mode, + roam_req->sessionId); /* * After sending the roam scan mode because of a disconnect, * clear the scan bitmap client as well by sending diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 4f9c72c21b74..8c1ac280fc17 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -4383,6 +4383,106 @@ int wma_rcpi_event_handler(void *handle, uint8_t *cmd_param_info, return 0; } +/** + * wma_set_roam_offload_flag() - Set roam offload flag to fw + * @wma: wma handle + * @vdev_id: vdev id + * @is_set: set or clear + * + * Return: none + */ +static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id, + bool is_set) +{ + QDF_STATUS status; + uint32_t flag = 0; + + if (is_set) + flag = WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG | + WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG; + + WMA_LOGD("%s: vdev_id:%d, is_set:%d, flag:%d, roam_offload_enabled:%d", + __func__, vdev_id, is_set, flag, + wma->interfaces[vdev_id].roam_offload_enabled); + + status = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, flag); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD"); + else + wma->interfaces[vdev_id].roam_offload_enabled = is_set; +} + +/** + * wma_update_roam_offload_flag() - update roam offload flag to fw + * @wma: wma handle + * @vdev_id: vdev id + * @is_connected: connected or disconnected + * + * Return: none + */ +static void wma_update_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id, + bool is_connected) +{ + struct wma_txrx_node *iface; + uint8_t id; + uint8_t roam_offload_vdev_id = WMA_INVALID_VDEV_ID; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t count; + + WMA_LOGD("%s: vdev_id:%d, is_connected:%d", __func__, + vdev_id, is_connected); + + iface = &wma->interfaces[vdev_id]; + + if ((iface->type != WMI_VDEV_TYPE_STA) || + (iface->sub_type != 0)) { + WMA_LOGE("%s: this isn't a STA: %d", + __func__, vdev_id); + return; + } + + if (iface->roaming_in_progress || iface->roam_synch_in_progress) { + WMA_LOGE("%s: roaming in progress: %d", + __func__, vdev_id); + return; + } + + for (id = 0; id < wma->max_bssid; id++) { + if (wma->interfaces[id].roam_offload_enabled) + roam_offload_vdev_id = id; + } + + /* + * If sta connected, and no connected sta interface exist, then set + * set roam offload flag to this sta interface + */ + if (is_connected && (roam_offload_vdev_id == WMA_INVALID_VDEV_ID)) + wma_set_roam_offload_flag(wma, vdev_id, true); + + if (!is_connected && roam_offload_vdev_id == vdev_id) { + /* If sta disconnected and roam offload enaled on this + * interface, then clear roam offload flag + */ + wma_set_roam_offload_flag(wma, vdev_id, false); + + count = policy_mgr_mode_specific_connection_count( + wma->psoc, PM_STA_MODE, list); + WMA_LOGD("%s: valid sta count:%d", __func__, count); + /* + * If there is multi sta connection before this disconnection, + * then set roam offload flag to other connected sta inferface. + */ + if (count > 1) { + for (id = 0; id < count; id++) { + if (list[id] != vdev_id) + wma_set_roam_offload_flag(wma, list[id], + true); + } + } + } +} + #ifdef CONFIG_VDEV_SM QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, struct vdev_up_params *params, @@ -4395,6 +4495,7 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id); return QDF_STATUS_E_FAILURE; } + wma_update_roam_offload_flag(wma, params->vdev_id, true); vdev = &wma->interfaces[params->vdev_id]; status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params); @@ -4420,7 +4521,7 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, params->vdev_id, bssid); return QDF_STATUS_SUCCESS; } - + wma_update_roam_offload_flag(wma, params->vdev_id, true); vdev = &wma->interfaces[params->vdev_id]; status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params); @@ -4440,6 +4541,7 @@ QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id) return QDF_STATUS_E_FAILURE; } + wma_update_roam_offload_flag(wma, vdev_id, false); vdev = &wma->interfaces[vdev_id]; wma->interfaces[vdev_id].roaming_in_progress = false; status = wmi_unified_vdev_down_send(wma->wmi_handle, vdev_id);