Kaynağa Gözat

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
Nitesh Shah 8 yıl önce
ebeveyn
işleme
877ad5d74d
4 değiştirilmiş dosya ile 221 ekleme ve 95 silme
  1. 12 0
      core/wma/inc/wma.h
  2. 0 2
      core/wma/inc/wma_api.h
  3. 202 3
      core/wma/src/wma_main.c
  4. 7 90
      core/wma/src/wma_utils.c

+ 12 - 0
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
 

+ 0 - 2
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,

+ 202 - 3
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));
 	}
 }
 
@@ -4800,6 +4799,200 @@ static void wma_print_populate_soc_caps(t_wma_handle *wma_handle)
 	WMA_LOGI("%s: <====== HW mode cap printing ends ======>\n", __func__);
 }
 
+/**
+ * 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
@@ -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)

+ 7 - 90
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(
@@ -2771,58 +2776,6 @@ bool wma_is_hw_dbs_capable(void)
 	return false;
 }
 
-/**
- * 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
@@ -3092,42 +3045,6 @@ bool wma_is_dbs_enable(void)
 	return false;
 }
 
-/**
- * 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