summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNitesh Shah <niteshs@codeaurora.org>2016-09-22 19:27:58 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-10-07 09:49:02 -0700
commit877ad5d74dc92cd3ad9ac1206fb8da9da1825c92 (patch)
tree3996f3361580508c02b1e575db340095c79d06d3
parentd60bde2bb6d1ffb4716149821069d5cd8c98f8f3 (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.h12
-rw-r--r--core/wma/inc/wma_api.h2
-rw-r--r--core/wma/src/wma_main.c205
-rw-r--r--core/wma/src/wma_utils.c97
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