From d4aa277e8bb2caa8fe2d094904980a689f0485b4 Mon Sep 17 00:00:00 2001 From: Vikram Kandukuri Date: Tue, 7 Mar 2017 18:40:13 +0530 Subject: [PATCH] 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 --- dp/inc/cdp_txrx_stats_struct.h | 1 + .../src/service_ready_event_handler.c | 22 ++++ .../inc/wlan_objmgr_psoc_service_ready_api.h | 72 +++++++++++ .../obj_mgr/src/wlan_objmgr_psoc_obj.c | 5 + .../src/wlan_objmgr_psoc_service_ready_api.c | 43 +++++++ wmi/inc/wmi_unified_api.h | 2 + wmi/inc/wmi_unified_priv.h | 3 + wmi/src/wmi_unified_api.c | 21 ++++ wmi/src/wmi_unified_tlv.c | 114 +++++++++++++++++- 9 files changed, 282 insertions(+), 1 deletion(-) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index c39441008e2e..0c439ee75f54 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/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; /* diff --git a/target_if/init_deinit/src/service_ready_event_handler.c b/target_if/init_deinit/src/service_ready_event_handler.c index bf3e6499a754..0ecf8a7702f0 100644 --- a/target_if/init_deinit/src/service_ready_event_handler.c +++ b/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); diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_service_ready_api.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_service_ready_api.h index c9d381301c7c..ca062d7bebef 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_service_ready_api.h +++ b/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_*/ diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c index 7a71ebd5c825..4e75286cd857 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c +++ b/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); diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_service_ready_api.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_service_ready_api.c index 781354384b04..1f015d9a2666 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_service_ready_api.c +++ b/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); diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 68b0226492f4..e4071d36ab3d 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/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 diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 4a0f6ea7a607..9224d5df2e5a 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/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 { diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 9ea40e0ea84f..faacc7711cc1 100644 --- a/wmi/src/wmi_unified_api.c +++ b/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; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 3d766dd44644..af28a6858843 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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(¶m->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, }; /**