瀏覽代碼

qcacmn: Static and Dynamic chain mask selection

Host support for Static and Dynamic chain mask selection.
parse new TLVs from ext service ready,copy tables to
wlan_objmgr_soc object.

CRs-Fixed: 2016643.
Change-Id: Ia4735eb4c7774c381df01f56696e8c86fc6c56ab
Vikram Kandukuri 8 年之前
父節點
當前提交
d4aa277e8b

+ 1 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -475,6 +475,7 @@ typedef enum _ol_ath_param_t {
 	OL_ATH_COEX_VER_CFG = 347,
 	OL_ATH_PARAM_DUMP_TARGET = 348,
 	OL_ATH_PARAM_PDEV_TO_REO_DEST = 349,
+	OL_ATH_PARAM_DUMP_CHAINMASK_TABLES = 350,
 } ol_ath_param_t;
 
 /*

+ 22 - 0
target_if/init_deinit/src/service_ready_event_handler.c

@@ -136,6 +136,20 @@ static int populate_service_ready_ext_param(void *handle, uint8_t *evt,
 	return 0;
 }
 
+static int populate_chainmaks_tables(void *handle, uint8_t *evt,
+		struct wlan_psoc_host_chainmask_table *param)
+{
+	QDF_STATUS status;
+
+	status = wmi_extract_chainmask_tables(handle, evt, param);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("failed to parse wmi service ready ext param");
+		return qdf_status_to_os_return(status);
+	}
+
+	return 0;
+}
+
 static int populate_mac_phy_capability(void *handle, uint8_t *evt,
 	struct wlan_psoc_host_hw_mode_caps *hw_cap, uint8_t *total_mac_phy,
 	struct wlan_objmgr_psoc_ext_service_ready_param *service_param)
@@ -291,6 +305,14 @@ int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle,
 	if (err_code)
 		goto free_param_and_exit;
 
+	if (wlan_objmgr_ext_service_ready_chainmask_table_caplist_alloc(
+				&(service_param->service_ext_param)) == QDF_STATUS_SUCCESS) {
+		err_code = populate_chainmaks_tables(wmi_handle, event,
+				&(service_param->service_ext_param.chainmask_table[0]));
+		if (err_code)
+			goto free_param_and_exit;
+	}
+
 	legacy_callback = target_if_get_psoc_legacy_service_ready_cb();
 	err_code = legacy_callback(wmi_service_ready_ext_event_id,
 				  scn_handle, event, data_len);

+ 72 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_service_ready_api.h

@@ -31,6 +31,7 @@
 #define PSOC_MAX_HW_MODE (2)
 #define PSOC_MAX_MAC_PHY_CAP (5)
 #define PSOC_MAX_PHY_REG_CAP (3)
+#define PSOC_MAX_CHAINMASK_TABLES (5)
 
 /* forward declaration of object manager psoc object type */
 struct wlan_objmgr_psoc;
@@ -198,6 +199,7 @@ struct wlan_psoc_host_ppe_threshold {
  * @he_cap_phy_info_5G: 5G HE capability phy field
  * @he_ppet2G: 2G HE PPET info
  * @he_ppet5G: 5G HE PPET info
+ * @chainmask_table_id: chain mask table id
  */
 struct wlan_psoc_host_mac_phy_caps {
 	uint32_t hw_mode_id;
@@ -231,6 +233,7 @@ struct wlan_psoc_host_mac_phy_caps {
 	uint32_t he_cap_phy_info_5G[PSOC_HOST_MAX_PHY_SIZE];
 	struct wlan_psoc_host_ppe_threshold he_ppet2G;
 	struct wlan_psoc_host_ppe_threshold he_ppet5G;
+	uint32_t chainmask_table_id;
 };
 
 /**
@@ -246,6 +249,47 @@ struct wlan_psoc_host_hw_mode_caps {
 	uint32_t hw_mode_config_type;
 };
 
+/**
+ * struct wlan_psoc_host_chainmask_capabilities - chain mask capabilities list
+ * @supports_chan_width_20: channel width 20 support for this chain mask.
+ * @supports_chan_width_40: channel width 40 support for this chain mask.
+ * @supports_chan_width_80: channel width 80 support for this chain mask.
+ * @supports_chan_width_160: channel width 160 support for this chain mask.
+ * @supports_chan_width_80P80: channel width 80P80 support for this chain mask.
+ * @chain_mask_2G: 2G support for this chain mask.
+ * @chain_mask_5G: 5G support for this chain mask.
+ * @chain_mask_tx: Tx support for this chain mask.
+ * @chain_mask_rx: Rx support for this chain mask.
+ * @supports_aDFS: Agile DFS support for this chain mask.
+ * @chainmask: chain mask value.
+ */
+struct wlan_psoc_host_chainmask_capabilities {
+	uint32_t supports_chan_width_20:1,
+		 supports_chan_width_40:1,
+		 supports_chan_width_80:1,
+		 supports_chan_width_160:1,
+		 supports_chan_width_80P80:1,
+		 reserved:22,
+		 chain_mask_2G:1,
+		 chain_mask_5G:1,
+		 chain_mask_tx:1,
+		 chain_mask_rx:1,
+		 supports_aDFS:1;
+	uint32_t chainmask;
+};
+
+/**
+ * struct wlan_psoc_host_chainmask_table - chain mask table
+ * @table_id: tableid.
+ * @num_valid_chainmasks: num valid chainmasks.
+ * @cap_list: pointer to wlan_psoc_host_chainmask_capabilities list.
+ */
+struct wlan_psoc_host_chainmask_table {
+	uint32_t table_id;
+	uint32_t num_valid_chainmasks;
+	struct wlan_psoc_host_chainmask_capabilities *cap_list;
+};
+
 /**
  * struct wlan_psoc_host_service_ext_param - EXT service base params in event
  * @default_conc_scan_config_bits: Default concurrenct scan config
@@ -257,6 +301,8 @@ struct wlan_psoc_host_hw_mode_caps {
  *                        Value 0 means FW hasn't given any limit to host.
  * @num_hw_modes: Number of HW modes in event
  * @num_phy: Number of Phy mode.
+ * @num_chainmask_tables: Number of chain mask tables.
+ * @chainmask_table: Available chain mask tables.
  */
 struct wlan_psoc_host_service_ext_param {
 	uint32_t default_conc_scan_config_bits;
@@ -267,6 +313,8 @@ struct wlan_psoc_host_service_ext_param {
 	uint32_t max_bssid_rx_filters;
 	uint32_t num_hw_modes;
 	uint32_t num_phy;
+	uint32_t num_chainmask_tables;
+	struct wlan_psoc_host_chainmask_table chainmask_table[PSOC_MAX_CHAINMASK_TABLES];
 };
 
 /**
@@ -309,4 +357,28 @@ void
 wlan_objmgr_populate_ext_service_ready_data(struct wlan_objmgr_psoc *psoc,
 	struct wlan_objmgr_psoc_ext_service_ready_param *ext_service_data);
 
+/**
+ * wlan_objmgr_ext_service_ready_chainmask_table_caplist_alloc()
+ *	- allocate chainmask table capability list.
+ * @service_ext_param: pointer to server ext param.
+ *
+ * Allocates capability list based on num_valid_chainmasks for that table.
+ *
+ * Return: QDF Status.
+ */
+QDF_STATUS wlan_objmgr_ext_service_ready_chainmask_table_caplist_alloc(
+		struct wlan_psoc_host_service_ext_param *service_ext_param);
+
+/**
+ * wlan_objmgr_ext_service_ready_chainmask_table_caplist_free()
+ *	-free chainmask table capability list.
+ * @service_ext_param: pointer to server ext param.
+ *
+ * free capability list based on num_valid_chainmasks for that table.
+ *
+ * Return: QDF Status.
+ */
+QDF_STATUS wlan_objmgr_ext_service_ready_chainmask_table_caplist_free(
+		struct wlan_psoc_host_service_ext_param *service_ext_param);
+
 #endif /* _WLAN_OBJMGR_PSOC_SERVICE_READY_API_H_*/

+ 5 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c

@@ -90,12 +90,17 @@ static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
 
 static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc)
 {
+	struct wlan_psoc_host_service_ext_param *ext_param =
+		&(psoc->ext_service_param.service_ext_param);
+
 	/* Detach PSOC from global object's psoc list  */
 	if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) {
 		qdf_print("%s: PSOC object detach failed\n", __func__);
 		return QDF_STATUS_E_FAILURE;
 	}
 	wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list);
+	wlan_objmgr_ext_service_ready_chainmask_table_caplist_free(ext_param);
+
 	qdf_spinlock_destroy(&psoc->psoc_lock);
 	qdf_mem_free(psoc);
 

+ 43 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_service_ready_api.c

@@ -43,3 +43,46 @@ wlan_objmgr_populate_ext_service_ready_data(struct wlan_objmgr_psoc *psoc,
 	wlan_psoc_obj_unlock(psoc);
 }
 EXPORT_SYMBOL(wlan_objmgr_populate_ext_service_ready_data);
+
+QDF_STATUS wlan_objmgr_ext_service_ready_chainmask_table_caplist_alloc(
+		struct wlan_psoc_host_service_ext_param *service_ext_param)
+{
+	int i;
+	uint32_t alloc_size;
+
+	if (service_ext_param->num_chainmask_tables > 0) {
+		for (i = 0; i < service_ext_param->num_chainmask_tables; i++) {
+			alloc_size = (sizeof(struct wlan_psoc_host_chainmask_capabilities) *
+					service_ext_param->chainmask_table[i].num_valid_chainmasks);
+			service_ext_param->chainmask_table[i].cap_list = qdf_mem_alloc_outline(NULL, alloc_size);
+			if (service_ext_param->chainmask_table[i].cap_list == NULL) {
+				wlan_objmgr_ext_service_ready_chainmask_table_caplist_free(service_ext_param);
+				return QDF_STATUS_E_NOMEM;
+			}
+		}
+		return QDF_STATUS_SUCCESS;
+	} else {
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_ext_service_ready_chainmask_table_caplist_alloc);
+
+QDF_STATUS wlan_objmgr_ext_service_ready_chainmask_table_caplist_free(
+		struct wlan_psoc_host_service_ext_param *service_ext_param)
+{
+	struct wlan_psoc_host_chainmask_table *table = NULL;
+	int i;
+
+	for (i = 0; i < service_ext_param->num_chainmask_tables; i++) {
+		table =  &(service_ext_param->chainmask_table[i]);
+		if (table->cap_list) {
+			qdf_mem_free(table->cap_list);
+			table->cap_list = NULL;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_ext_service_ready_chainmask_table_caplist_free);

+ 2 - 0
wmi/inc/wmi_unified_api.h

@@ -1421,6 +1421,8 @@ QDF_STATUS wmi_extract_peer_delete_response_event(void *wmi_hdl,
 		uint8_t *evt_buf,
 		struct wmi_host_peer_delete_response_event *param);
 
+QDF_STATUS wmi_extract_chainmask_tables(void *wmi_hdl, uint8_t *evt_buf,
+		struct wlan_psoc_host_chainmask_table *chainmask_table);
 /**
  * wmi_unified_dfs_phyerr_offload_en_cmd() - enable dfs phyerr offload
  * @wmi_handle: wmi handle

+ 3 - 0
wmi/inc/wmi_unified_priv.h

@@ -1287,6 +1287,9 @@ QDF_STATUS (*extract_reg_chan_list_update_event)(wmi_unified_t wmi_handle,
 						 struct cur_regulatory_info
 						 *reg_info,
 						 uint32_t len);
+QDF_STATUS (*extract_chainmask_tables)(wmi_unified_t wmi_handle,
+		uint8_t *evt_buf,
+		struct wlan_psoc_host_chainmask_table *chainmask_table);
 };
 
 struct target_abi_version {

+ 21 - 0
wmi/src/wmi_unified_api.c

@@ -6570,3 +6570,24 @@ wmi_unified_dfs_phyerr_offload_dis_cmd(void *wmi_hdl,
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+/*
+ * wmi_extract_chainmask_tables_tlv() - extract chain mask tables
+ * @wmi_handle: wmi handle
+ * @evt_buf: pointer to event buffer.
+ * @chainmask_table: pointer to struct wlan_psoc_host_chainmask_table
+ *
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_extract_chainmask_tables(void *wmi_hdl, uint8_t *evt_buf,
+		struct wlan_psoc_host_chainmask_table *chainmask_table)
+{
+	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
+
+	if (wmi_handle->ops->extract_chainmask_tables)
+		return wmi_handle->ops->extract_chainmask_tables(wmi_handle,
+				evt_buf, chainmask_table);
+
+	return QDF_STATUS_E_FAILURE;
+}

+ 113 - 1
wmi/src/wmi_unified_tlv.c

@@ -16016,6 +16016,87 @@ static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * extract_chainmask_tables_tlv() - extract chain mask tables from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param param: Pointer to hold evt buf
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle,
+		uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table)
+{
+	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
+	WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps;
+	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
+	uint8_t i = 0, j = 0;
+
+	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
+	if (!param_buf)
+		return QDF_STATUS_E_INVAL;
+
+	hw_caps = param_buf->soc_hw_mode_caps;
+	if (!hw_caps)
+		return QDF_STATUS_E_INVAL;
+
+	if (!hw_caps->num_chainmask_tables)
+		return QDF_STATUS_E_INVAL;
+
+	chainmask_caps = param_buf->mac_phy_chainmask_caps;
+
+	if (chainmask_caps == NULL)
+		return QDF_STATUS_E_INVAL;
+
+	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
+
+		qdf_print("Dumping chain mask combo data for table : %d\n", i);
+		for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) {
+
+			chainmask_table[i].cap_list[j].chainmask =
+				chainmask_caps->chainmask;
+
+			chainmask_table[i].cap_list[j].supports_chan_width_20 =
+				WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].supports_chan_width_40 =
+				WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].supports_chan_width_80 =
+				WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].supports_chan_width_160 =
+				WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].supports_chan_width_80P80 =
+				WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].chain_mask_2G =
+				WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].chain_mask_5G =
+				WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].chain_mask_tx =
+				WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].chain_mask_rx =
+				WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags);
+
+			chainmask_table[i].cap_list[j].supports_aDFS =
+				WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags);
+
+			qdf_print("supported_flags: 0x%08x  chainmasks: 0x%08x\n",
+					chainmask_caps->supported_flags,
+					chainmask_caps->chainmask
+				 );
+			chainmask_caps++;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * extract_service_ready_ext_tlv() - extract basic extended service ready params
  * from event
@@ -16032,6 +16113,8 @@ static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
 	wmi_service_ready_ext_event_fixed_param *ev;
 	WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps;
 	WMI_SOC_HAL_REG_CAPABILITIES *reg_caps;
+	WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo;
+	uint8_t i = 0;
 
 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
 	if (!param_buf)
@@ -16062,6 +16145,32 @@ static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle,
 	else
 		param->num_phy = 0;
 
+	param->num_chainmask_tables = hw_caps->num_chainmask_tables;
+
+	qdf_print("Num chain mask tables: %d\n", hw_caps->num_chainmask_tables);
+
+	chain_mask_combo = param_buf->mac_phy_chainmask_combo;
+
+	if (chain_mask_combo == NULL)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_print("Dumping chain mask combo data\n");
+
+	for (i = 0; i < hw_caps->num_chainmask_tables; i++) {
+
+		qdf_print("table_id : %d Num valid chainmasks: %d\n",
+				chain_mask_combo->chainmask_table_id,
+				chain_mask_combo->num_valid_chainmask
+			 );
+
+		param->chainmask_table[i].table_id =
+			chain_mask_combo->chainmask_table_id;
+		param->chainmask_table[i].num_valid_chainmasks =
+			chain_mask_combo->num_valid_chainmask;
+		chain_mask_combo++;
+	}
+	qdf_print("chain mask combo end\n");
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -16197,6 +16306,7 @@ static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv(
 				 sizeof(param->he_ppet2G));
 	qdf_mem_copy(&param->he_ppet5G, &mac_phy_caps->he_ppet5G,
 				sizeof(param->he_ppet5G));
+	param->chainmask_table_id = mac_phy_caps->chainmask_table_id;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -17185,7 +17295,9 @@ struct wmi_ops tlv_ops =  {
 	.send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv,
 	.send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv,
 	.extract_reg_chan_list_update_event =
-				extract_reg_chan_list_update_event_tlv,
+		extract_reg_chan_list_update_event_tlv,
+	.extract_chainmask_tables =
+		extract_chainmask_tables_tlv,
 };
 
 /**