diff options
| author | Nitesh Shah <niteshs@codeaurora.org> | 2016-09-22 19:27:58 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-10-07 09:49:02 -0700 |
| commit | 877ad5d74dc92cd3ad9ac1206fb8da9da1825c92 (patch) | |
| tree | 3996f3361580508c02b1e575db340095c79d06d3 | |
| parent | d60bde2bb6d1ffb4716149821069d5cd8c98f8f3 (diff) | |
qcacld-3.0: Update hw_mode_list as per WMI_SERVICE_READY_EXT_EVENT
Driver updates its hw_mode_list entries as per hw_mode_list
given by firmware during WMI_SERVICE_READY_EVENT.
The enhancement is to update hw_mode_list entries in the driver
using the values received in WMI_SERVICE_READY_EXT_EVENT from
the firmware.
Change-Id: I5e4d97523cb7fd018767d5d2fda841f03b2406f6
CRs-Fixed: 1070005
| -rw-r--r-- | core/wma/inc/wma.h | 12 | ||||
| -rw-r--r-- | core/wma/inc/wma_api.h | 2 | ||||
| -rw-r--r-- | core/wma/src/wma_main.c | 205 | ||||
| -rw-r--r-- | core/wma/src/wma_utils.c | 97 |
4 files changed, 221 insertions, 95 deletions
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index f22aea6dac5d..c1be1096a6f2 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1070,6 +1070,18 @@ struct dbs_hw_mode_info { uint32_t *hw_mode_list; }; +/** + * struct mac_ss_bw_info - hw_mode_list PHY/MAC params for each MAC + * @mac_tx_stream: Max TX stream + * @mac_rx_stream: Max RX stream + * @mac_bw: Max bandwidth + */ +struct mac_ss_bw_info { + uint32_t mac_tx_stream; + uint32_t mac_rx_stream; + uint32_t mac_bw; +}; + /* Current HTC credit is 2, pool size of 50 is sufficient */ #define WMI_DESC_POOL_MAX 50 diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index ecbead7e438f..0f2355335324 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -192,7 +192,6 @@ QDF_STATUS wma_get_hw_mode_from_idx(uint32_t idx, struct sir_hw_mode_params *hw_mode); int8_t wma_get_num_dbs_hw_modes(void); bool wma_is_hw_dbs_capable(void); -bool wma_is_hw_agile_dfs_capable(void); int8_t wma_get_mac_id_of_vdev(uint32_t vdev_id); void wma_update_intf_hw_mode_params(uint32_t vdev_id, uint32_t mac_id, uint32_t cfgd_hw_mode_index); @@ -202,7 +201,6 @@ void wma_set_dbs_capability_ut(uint32_t dbs); QDF_STATUS wma_get_dbs_hw_modes(bool *one_by_one_dbs, bool *two_by_two_dbs); QDF_STATUS wma_get_current_hw_mode(struct sir_hw_mode_params *hw_mode); bool wma_is_dbs_enable(void); -bool wma_is_agile_dfs_enable(void); QDF_STATUS wma_get_updated_scan_config(uint32_t *scan_config, bool dbs_scan, bool dbs_plus_agile_scan, diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 296bbe3bda9d..ef657c461bab 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -4159,9 +4159,8 @@ void wma_dump_dbs_hw_mode(tp_wma_handle wma_handle) WMI_DBS_HW_MODE_MAC1_TX_STREAMS_GET(param), WMI_DBS_HW_MODE_MAC1_RX_STREAMS_GET(param), WMI_DBS_HW_MODE_MAC1_BANDWIDTH_GET(param)); - WMA_LOGA("%s:[%d] DBS:%d Agile DFS:%d", __func__, i, - WMI_DBS_HW_MODE_DBS_MODE_GET(param), - WMI_DBS_HW_MODE_AGILE_DFS_GET(param)); + WMA_LOGA("%s:[%d] DBS:%d", __func__, i, + WMI_DBS_HW_MODE_DBS_MODE_GET(param)); } } @@ -4801,6 +4800,200 @@ static void wma_print_populate_soc_caps(t_wma_handle *wma_handle) } /** + * wma_map_wmi_channel_width_to_hw_mode_bw() - returns bandwidth + * in terms of hw_mode_bandwidth + * @width: bandwidth in terms of wmi_channel_width + * + * This function returns the bandwidth in terms of hw_mode_bandwidth. + * + * Return: BW in terms of hw_mode_bandwidth. + */ +enum hw_mode_bandwidth wma_map_wmi_channel_width_to_hw_mode_bw( + wmi_channel_width width) +{ + switch (width) { + case WMI_CHAN_WIDTH_20: + return HW_MODE_20_MHZ; + case WMI_CHAN_WIDTH_40: + return HW_MODE_40_MHZ; + case WMI_CHAN_WIDTH_80: + return HW_MODE_80_MHZ; + case WMI_CHAN_WIDTH_160: + return HW_MODE_160_MHZ; + case WMI_CHAN_WIDTH_80P80: + return HW_MODE_80_PLUS_80_MHZ; + case WMI_CHAN_WIDTH_5: + return HW_MODE_5_MHZ; + case WMI_CHAN_WIDTH_10: + return HW_MODE_10_MHZ; + default: + return HW_MODE_BW_NONE; + } + + return HW_MODE_BW_NONE; +} + +/** + * wma_get_hw_mode_params() - get TX-RX stream and bandwidth + * supported from the capabilities. + * @caps: PHY capability + * @info: param to store TX-RX stream and BW information + * + * This function will calculate TX-RX stream and bandwidth supported + * as per the PHY capability, and assign to mac_ss_bw_info. + * + * Return: none + */ +static void wma_get_hw_mode_params(WMI_MAC_PHY_CAPABILITIES *caps, + struct mac_ss_bw_info *info) +{ + if (!caps) { + WMA_LOGE("%s: Invalid capabilities", __func__); + return; + } + + info->mac_tx_stream = wma_get_num_of_setbits_from_bitmask( + QDF_MAX(caps->tx_chain_mask_2G, + caps->tx_chain_mask_5G)); + info->mac_rx_stream = wma_get_num_of_setbits_from_bitmask( + QDF_MAX(caps->rx_chain_mask_2G, + caps->rx_chain_mask_5G)); + info->mac_bw = wma_map_wmi_channel_width_to_hw_mode_bw( + QDF_MAX(caps->max_bw_supported_2G, + caps->max_bw_supported_5G)); +} + +/** + * wma_set_hw_mode_params() - sets TX-RX stream, bandwidth and + * DBS in hw_mode_list + * @wma_handle: pointer to wma global structure + * @mac0_ss_bw_info: TX-RX streams, BW for MAC0 + * @mac1_ss_bw_info: TX-RX streams, BW for MAC1 + * @pos: refers to hw_mode_index + * @dbs_mode: dbs_mode for the dbs_hw_mode + * + * This function sets TX-RX stream, bandwidth and DBS mode in + * hw_mode_list. + * + * Return: none + */ +static void wma_set_hw_mode_params(t_wma_handle *wma_handle, + struct mac_ss_bw_info mac0_ss_bw_info, + struct mac_ss_bw_info mac1_ss_bw_info, + uint32_t pos, uint32_t dbs_mode) +{ + WMI_DBS_HW_MODE_MAC0_TX_STREAMS_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_tx_stream); + WMI_DBS_HW_MODE_MAC0_RX_STREAMS_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_rx_stream); + WMI_DBS_HW_MODE_MAC0_BANDWIDTH_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_bw); + WMI_DBS_HW_MODE_MAC1_TX_STREAMS_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_tx_stream); + WMI_DBS_HW_MODE_MAC1_RX_STREAMS_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_rx_stream); + WMI_DBS_HW_MODE_MAC1_BANDWIDTH_SET( + wma_handle->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_bw); + WMI_DBS_HW_MODE_DBS_MODE_SET( + wma_handle->hw_mode.hw_mode_list[pos], + dbs_mode); + WMI_DBS_HW_MODE_AGILE_DFS_SET( + wma_handle->hw_mode.hw_mode_list[pos], + 0); +} + +/** + * wma_update_hw_mode_list() - updates hw_mode_list + * @wma_handle: pointer to wma global structure + * + * This function updates hw_mode_list with tx_streams, rx_streams, + * bandwidth, dbs and agile dfs for each hw_mode. + * + * Returns: 0 for success else failure. + */ +static QDF_STATUS wma_update_hw_mode_list(t_wma_handle *wma_handle) +{ + struct extended_caps *phy_caps; + WMI_MAC_PHY_CAPABILITIES *tmp; + uint32_t i, dbs_mode, hw_config_type, j = 0; + struct mac_ss_bw_info mac0_ss_bw_info = {0}; + struct mac_ss_bw_info mac1_ss_bw_info = {0}; + + if (!wma_handle) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return QDF_STATUS_E_FAILURE; + } + + phy_caps = &wma_handle->phy_caps; + if (!phy_caps) { + WMA_LOGE("%s: Invalid phy capabilities", __func__); + return QDF_STATUS_SUCCESS; + } + + if (!phy_caps->num_hw_modes.num_hw_modes) { + WMA_LOGE("%s: Number of HW modes: %d", + __func__, phy_caps->num_hw_modes.num_hw_modes); + return QDF_STATUS_SUCCESS; + } + + /* + * This list was updated as part of service ready event. Re-populate + * HW mode list from the device capabilities. + */ + if (wma_handle->hw_mode.hw_mode_list) { + qdf_mem_free(wma_handle->hw_mode.hw_mode_list); + wma_handle->hw_mode.hw_mode_list = NULL; + WMA_LOGI("%s: DBS list is freed", __func__); + } + + wma_handle->num_dbs_hw_modes = phy_caps->num_hw_modes.num_hw_modes; + wma_handle->hw_mode.hw_mode_list = + qdf_mem_malloc(sizeof(*wma_handle->hw_mode.hw_mode_list) * + wma_handle->num_dbs_hw_modes); + if (!wma_handle->hw_mode.hw_mode_list) { + WMA_LOGE("%s: Memory allocation failed for DBS", __func__); + return QDF_STATUS_E_FAILURE; + } + + WMA_LOGA("%s: Updated HW mode list: Num modes:%d", + __func__, wma_handle->num_dbs_hw_modes); + + for (i = 0; i < wma_handle->num_dbs_hw_modes; i++) { + /* Update for MAC0 */ + tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + wma_get_hw_mode_params(tmp, &mac0_ss_bw_info); + hw_config_type = + phy_caps->each_hw_mode_cap[i].hw_mode_config_type; + dbs_mode = 0; + mac1_ss_bw_info.mac_tx_stream = 0; + mac1_ss_bw_info.mac_rx_stream = 0; + mac1_ss_bw_info.mac_bw = 0; + + /* SBS and DBS have dual MAC. Upto 2 MACs are considered. */ + if ((hw_config_type == WMI_HW_MODE_DBS) || + (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || + (hw_config_type == WMI_HW_MODE_SBS)) { + /* Update for MAC1 */ + tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + wma_get_hw_mode_params(tmp, &mac1_ss_bw_info); + dbs_mode = 1; + } + + /* Updating HW mode list */ + wma_set_hw_mode_params(wma_handle, mac0_ss_bw_info, + mac1_ss_bw_info, i, dbs_mode); + } + wma_dump_dbs_hw_mode(wma_handle); + return QDF_STATUS_SUCCESS; +} + +/** * wma_populate_soc_caps() - populate entire SOC's capabilities * @wma_handle: pointer to wma global structure * @param_buf: pointer to param of service ready extension event from fw @@ -4988,6 +5181,12 @@ int wma_rx_service_ready_ext_event(void *handle, uint8_t *event, } wma_populate_soc_caps(wma_handle, param_buf); + ret = wma_update_hw_mode_list(wma_handle); + if (QDF_IS_STATUS_ERROR(ret)) { + WMA_LOGE("Failed to update hw mode list"); + return -EINVAL; + } + WMA_LOGA("WMA --> WMI_INIT_CMDID"); status = wmi_unified_send_saved_init_cmd(wma_handle->wmi_handle); if (status != EOK) diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 945e139adfc2..b4aab11b8e34 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -2572,7 +2572,12 @@ static int8_t wma_get_matching_hw_mode_index(tp_wma_handle wma, t_mac0_bw = WMI_DBS_HW_MODE_MAC0_BANDWIDTH_GET( wma->hw_mode.hw_mode_list[i]); - if (t_mac0_bw != mac0_bw) + /* + * Firmware advertises max bw capability as CBW 80+80 + * for single MAC. Thus CBW 20/40/80 should also be + * supported, if CBW 80+80 is supported. + */ + if (t_mac0_bw < mac0_bw) continue; t_mac1_tx_ss = WMI_DBS_HW_MODE_MAC1_TX_STREAMS_GET( @@ -2587,7 +2592,7 @@ static int8_t wma_get_matching_hw_mode_index(tp_wma_handle wma, t_mac1_bw = WMI_DBS_HW_MODE_MAC1_BANDWIDTH_GET( wma->hw_mode.hw_mode_list[i]); - if (t_mac1_bw != mac1_bw) + if (t_mac1_bw < mac1_bw) continue; dbs_mode = WMI_DBS_HW_MODE_DBS_MODE_GET( @@ -2772,58 +2777,6 @@ bool wma_is_hw_dbs_capable(void) } /** - * wma_is_hw_agile_dfs_capable() - Check if HW is agile DFS capable - * - * Checks if the HW is agile DFS capable - * - * Return: true if the HW is agile DFS capable - */ -bool wma_is_hw_agile_dfs_capable(void) -{ - tp_wma_handle wma; - uint32_t param, i, found = 0; - - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s: Invalid WMA handle", __func__); - return false; - } - - if (!wma_is_agile_dfs_enable()) { - WMA_LOGI("%s: Agile DFS is disabled", __func__); - return false; - } - - WMA_LOGI("%s: DBS service bit map: %d", __func__, - WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - - /* The agreement with FW is that to know if the target is Agile DFS - * capable, DBS needs to be supported in the service bit map and - * Agile DFS needs to be supported in the HW mode list - */ - if (!(WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) - return false; - - for (i = 0; i < wma->num_dbs_hw_modes; i++) { - param = wma->hw_mode.hw_mode_list[i]; - WMA_LOGI("%s: HW param: %x", __func__, param); - if (WMI_DBS_HW_MODE_AGILE_DFS_GET(param)) { - WMA_LOGI("%s: HW %d is agile DFS capable", - __func__, i); - found = 1; - break; - } - } - - if (found) - return true; - - return false; -} - -/** * wma_get_mac_id_of_vdev() - Get MAC id corresponding to a vdev * @vdev_id: VDEV whose MAC ID is required * @@ -3093,42 +3046,6 @@ bool wma_is_dbs_enable(void) } /** - * wma_is_agile_dfs_enable() - Check if master Agile DFS control is enabled - * - * Checks if the master Agile DFS control is enabled. This will be used - * to override any other Agile DFS capability - * - * Return: True if master Agile DFS control is enabled - */ -bool wma_is_agile_dfs_enable(void) -{ - tp_wma_handle wma; - - if (wma_is_dual_mac_disabled_in_ini()) - return false; - - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s: Invalid WMA handle", __func__); - return false; - } - - WMA_LOGD("%s: DFS=%d Single mac with DFS=%d", __func__, - WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET( - wma->dual_mac_cfg.cur_fw_mode_config), - WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET( - wma->dual_mac_cfg.cur_scan_config)); - - if ((WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET( - wma->dual_mac_cfg.cur_fw_mode_config)) && - (WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET( - wma->dual_mac_cfg.cur_scan_config))) - return true; - - return false; -} - -/** * wma_get_updated_scan_config() - Get the updated scan configuration * @scan_config: Pointer containing the updated scan config * @dbs_scan: 0 or 1 indicating if DBS scan needs to be enabled/disabled |
