qcacmn: Converge initial HOST FW handshake

Implement service ready, ext service ready
ready event handler, init command preparation
and other required APIs

Change-Id: Iaf707227c1e94bb492dd86bd2d0916a1cf875498
CRs-Fixed: 2177109
This commit is contained in:
Srinivas Pitla
2017-12-21 10:24:42 +05:30
کامیت شده توسط snandini
والد 9af4f65f61
کامیت cc75651c34
14فایلهای تغییر یافته به همراه2265 افزوده شده و 674 حذف شده

مشاهده پرونده

@@ -498,7 +498,7 @@ QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
ext_param = target_psoc_get_service_ext_param(tgt_psoc_info);
wlan_ext_service_ready_chainmask_table_free(ext_param);
init_deinit_chainmask_table_free(ext_param);
wlan_psoc_set_tgt_if_handle(psoc, NULL);

مشاهده پرونده

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_cmd_api.h
*
* Public APIs to prepare and send init command
*/
#ifndef _INIT_DEINIT_INIT_CMD_H_
#define _INIT_DEINIT_INIT_CMD_H_
/* max size if 256k */
#define HOST_MEM_CHUNK_MAX_SIZE (256 * 1024)
#define HOST_MEM_CHUNK_MAX_SIZE_POWER2 (8 + 10)
#define TXBF_CV_POOL0 2
#define TXBF_CV_POOL1 3
#define TXBF_CV_POOL2 4
#define HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED 0x8
/**
* enum wlan_fw_mem_prio - defines FW Memory requirement type
* @FW_MEM_HIGH_PRIORITY: Memory requires contiguous memory allocation
* @FW_MEM_LOW_PRIORITY: Memory can be fragmented
* @FW_PRIORITY_MAX: Invalid type
*/
enum wlan_fw_mem_prio {
FW_MEM_HIGH_PRIORITY = 0,
FW_MEM_LOW_PRIORITY,
FW_PRIORITY_MAX
};
/**
* init_deinit_handle_host_mem_req() - handle host memory request
* @psoc: PSOC object
* @tgt_info: PSOC_INFO object
* @event: Event buffer from FW
*
* API to handle memory request from FW and allocate memory chunks
*
* Return: SUCCESS on successful memory allocation
* On FAILURE (appropriate failure codes are returned)
*/
QDF_STATUS init_deinit_handle_host_mem_req(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info, uint8_t *event);
/**
* init_deinit_free_num_units() - Free allocated mem chunks
* @psoc: PSOC object
* @tgt_info: PSOC_INFO object
*
* API to free memory
*
* Return: SUCCESS on successful memory free
* On FAILURE (appropriate failure codes are returned)
*/
QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl);
/**
* init_deinit_derive_band_to_mac_param() - Derive band to mac param
* @psoc: PSOC object
* @tgt_info: PSOC_INFO object
* @band_to_mac: BAND_TO_MAC object
*
* API to derive band to mac param
*
* Return: void
*/
void init_deinit_derive_band_to_mac_param(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info,
struct wmi_host_pdev_band_to_mac *band_to_mac);
/**
* init_deinit_prepare_send_init_cmd() - prepare send init cmd
* @psoc: PSOC object
* @tgt_info: PSOC_INFO object
*
* API to prepare send init command
*
* Return: void
*/
void init_deinit_prepare_send_init_cmd(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
#endif /* _INIT_DEINIT_INIT_CMD_H_*/

مشاهده پرونده

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_deinit_ucfg.h
*
* Public APIs to get target_if info
*/
#ifndef _INIT_DEINIT_UCFG_H_
#define _INIT_DEINIT_UCFG_H_
/**
* ucfg_get_service_param() - get service param
* @psoc: pointer to psoc
*
* API to get service parameters
*
* Return: service parameter array pointer
*/
uint32_t *ucfg_get_service_param(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_is_service_param_bit_enabled() - check service param bit enabled
* @service_param: Service bitmap array
* @bit_idx: Service bit index to be checked
*
* API to check service param bitmap
*
* Return: true, if service is enabled
* false, if service is not enabled
*/
bool ucfg_is_service_param_bit_enabled(uint32_t *service_param,
uint16_t bit_idx);
/**
* ucfg_get_dfs_offload() - get dfs offload
* @psoc: pointer to psoc
* @is_tgt_offload: boolean flag for offload enabled/disabled
*
* API to get dfs offload
*
* Return: SUCCESS, if API is invoked without any failures
*/
QDF_STATUS ucfg_get_dfs_offload(struct wlan_objmgr_psoc *psoc,
bool *is_tgt_offload);
/**
* ucfg_get_tgt_res_cfg() - get target resource config
* @psoc: pointer to psoc
*
* API to get target resource config
*
* Return: target resource configuration
*/
target_resource_config *ucfg_get_tgt_res_cfg(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_get_target_cap() - get target capability
* @psoc: pointer to psoc
*
* API to get target capability
*
* Return: target capability Information
*/
struct wlan_psoc_target_capability_info *ucfg_get_target_cap(
struct wlan_objmgr_psoc *psoc);
/**
* ucfg_get_pdev_idx() - get pdev id
* @pdev: pointer to pdev
*
* API to get pdev id
*
* Return: pdev id
*/
int32_t ucfg_get_pdev_idx(struct wlan_objmgr_pdev *pdev);
/**
* ucfg_get_pdev_target_type() - check pdev target type
* @pdev: pointer to pdev
* @target_type: target type ptr, it is assigned with pdev target_type
* target type stores the radio code
*
* API to check pdev target type
*
* Return: Success if found required target type else Failure
*/
QDF_STATUS ucfg_get_pdev_target_type(struct wlan_objmgr_pdev *pdev,
uint32_t *target_type);
/**
* ucfg_get_tgt_type() - get target type
* @psoc: pointer to psoc
*
* API to get target type
*
* Return: target type (value to identify particular radio)
*/
uint32_t ucfg_get_tgt_type(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_get_tgt_version() - get target version
* @psoc: pointer to psoc
*
* API to get target version
*
* Return: target version
*/
uint32_t ucfg_get_tgt_version(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_get_tgt_revision() - get target revision
* @psoc: pointer to psoc
*
* API to get target revision
*
* Return: target revision
*/
uint32_t ucfg_get_tgt_revision(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_is_target_ar900b() - checks the target type
* @psoc: pointer to psoc
*
* API to check target type
*
* Return: True on presence of required target type else false
*/
bool ucfg_is_target_ar900b(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_get_pdev_wmi_handle() - get pdev wmi handle
* @pdev: pointer to dev
*
* API to get wmi handle
*
* Return: wmi handle
*/
void *ucfg_get_pdev_wmi_handle(struct wlan_objmgr_pdev *pdev);
#endif /* _INIT_DEINIT_UCFG_H_ */

مشاهده پرونده

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_event_handler.h
*
* Public API file for common WMI event handlers
*/
#ifndef _INIT_EVENT_HANDLER_H_
#define _INIT_EVENT_HANDLER_H_
/**
* init_deinit_register_tgt_psoc_ev_handlers() - register tgt if handlers
* @psoc: PSOC object
*
* API to register tgt handlers
*
* Return: SUCCESS on successful registration
*/
QDF_STATUS init_deinit_register_tgt_psoc_ev_handlers(
struct wlan_objmgr_psoc *psoc);
#endif /* _INIT_EVENT_HANDLER_H_ */

مشاهده پرونده

@@ -1,68 +0,0 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: wmi_unified_event_handler.h
*
* Public API file for common WMI event handlers
*/
#ifndef _WMI_UNIFIED_EVENT_HANDLER_H_
#define _WMI_UNIFIED_EVENT_HANDLER_H_
#include "athdefs.h"
#include "osapi_linux.h"
#include "a_types.h"
#include "a_debug.h"
#include "ol_if_athvar.h"
#include "ol_defines.h"
#include "qdf_types.h"
#include "qdf_util.h"
#include "wmi_unified_priv.h"
#include "wmi_unified_param.h"
#include "wlan_objmgr_psoc_obj.h"
#include "target_if.h"
#include "target_if_scan.h"
#include "target_if_reg.h"
/**
* init_deinit_service_ready_event_handler() - service ready handler
* @handle: opaqueue pointer to scn
* @event: pointer to event buffer
* @event_len: event length
*
* WMI common event handler for WMI_SERVICE_READY_EVENTID
*
* Return: 0 for success, negative error code for failure
*/
int init_deinit_service_ready_event_handler(ol_scn_t handle, uint8_t *event,
uint32_t event_len);
/**
* init_deinit_service_ext_ready_event_handler() - ext service ready handler
* @handle: opaqueue pointer to scn
* @event: pointer to event buffer
* @event_len: event length
*
* WMI common event handler for WMI_SERVICE_READY_EXT_EVENTID
*
* Return: 0 for success, negative error code for failure
*/
int init_deinit_service_ext_ready_event_handler(ol_scn_t handle, uint8_t *event,
uint32_t event_len);
#endif /* _WMI_UNIFIED_EVENT_HANDLER_H_ */

مشاهده پرونده

@@ -0,0 +1,298 @@
/*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: service_ready_param.h
*
* Public structures to access (ext)service ready data
*/
#ifndef _SERVICE_READY_PARAM_H_
#define _SERVICE_READY_PARAM_H_
#include "qdf_types.h"
/**
* struct wlan_psoc_hal_reg_capability - hal reg table in psoc
* @eeprom_rd: regdomain value specified in EEPROM
* @eeprom_rd_ext: regdomain
* @regcap1: CAP1 capabilities bit map
* @regcap2: REGDMN EEPROM CAP
* @wireless_modes: REGDMN MODE
* @low_2ghz_chan: lower 2.4GHz channels
* @high_2ghz_chan: higher 2.4 GHz channels
* @low_5ghz_chan: lower 5 GHz channels
* @high_5ghz_chan: higher 5 GHz channels
*/
struct wlan_psoc_hal_reg_capability {
uint32_t eeprom_rd;
uint32_t eeprom_rd_ext;
uint32_t regcap1;
uint32_t regcap2;
uint32_t wireless_modes;
uint32_t low_2ghz_chan;
uint32_t high_2ghz_chan;
uint32_t low_5ghz_chan;
uint32_t high_5ghz_chan;
};
/**
* struct wlan_psoc_target_capability_info - target capabilities in psoc
* @phy_capability: PHY capabilities
* @max_frag_entry: Maximum frag entries
* @num_rf_chains: Number of RF chains supported
* @ht_cap_info: HT cap info
* @vht_cap_info: VHT cap info
* @vht_supp_mcs: VHT Supported MCS
* @hw_min_tx_power: HW minimum tx power
* @hw_max_tx_power: HW maximum tx power
* @sys_cap_info: sys capability info
* @min_pkt_size_enable: Enterprise mode short pkt enable
* @max_bcn_ie_size: Max beacon and probe rsp IE offload size
* @max_num_scan_channels: Max scan channels
* @max_supported_macs: max supported MCS
* @wmi_fw_sub_feat_caps: FW sub feature capabilities
* @txrx_chainmask: TXRX chain mask
* @default_dbs_hw_mode_index: DBS hw mode index
* @num_msdu_desc: number of msdu desc
* @fw_version: FW build version
* @fw_version_1: Second dword of FW version (Valid for non-tlv FW)
*/
struct wlan_psoc_target_capability_info {
uint32_t phy_capability;
uint32_t max_frag_entry;
uint32_t num_rf_chains;
uint32_t ht_cap_info;
uint32_t vht_cap_info;
uint32_t vht_supp_mcs;
uint32_t hw_min_tx_power;
uint32_t hw_max_tx_power;
uint32_t sys_cap_info;
uint32_t min_pkt_size_enable;
uint32_t max_bcn_ie_size;
uint32_t max_num_scan_channels;
uint32_t max_supported_macs;
uint32_t wmi_fw_sub_feat_caps;
uint32_t txrx_chainmask;
uint32_t default_dbs_hw_mode_index;
uint32_t num_msdu_desc;
uint32_t fw_version;
uint32_t fw_version_1;
};
/**
* struct wlan_psoc_host_ppe_threshold - PPE threshold
* @numss_m1: NSS - 1
* @ru_bit_mask: RU bit mask indicating the supported RU's
* @ppet16_ppet8_ru3_ru0: ppet8 and ppet16 for max num ss
*/
struct wlan_psoc_host_ppe_threshold {
uint32_t numss_m1;
uint32_t ru_bit_mask;
uint32_t ppet16_ppet8_ru3_ru0[PSOC_HOST_MAX_NUM_SS];
};
/**
* struct wlan_psoc_host_mac_phy_caps - Phy caps recvd in EXT service
* @hw_mode_id: identify a particular set of HW characteristics,
* as specified by the subsequent fields. WMI_MAC_PHY_CAPABILITIES
* element must be mapped to its parent WMI_HW_MODE_CAPABILITIES
* element using hw_mode_id. No particular ordering of
* WMI_MAC_PHY_CAPABILITIES elements should be
* assumed, though in practice the elements may always be ordered
* by hw_mode_id.
* @pdev_id: pdev_id starts with 1. pdev_id 1 => phy_id 0, pdev_id 2 => phy_id 1
* @phy_id: Starts with 0
* @bitmap of supported modulations
* @supported_bands: supported bands, enum WLAN_BAND_CAPABILITY
* @ampdu_density: ampdu density 0 for no restriction, 1 for 1/4 us,
* 2 for 1/2 us, 3 for 1 us,4 for 2 us, 5 for 4 us,
* 6 for 8 us,7 for 16 us
* @max_bw_supported_2G: max bw supported 2G, enum wmi_channel_width
* @ht_cap_info_2G: WMI HT Capability, WMI_HT_CAP defines
* @vht_cap_info_2G: VHT capability info field of 802.11ac, WMI_VHT_CAP defines
* @vht_supp_mcs_2G: VHT Supported MCS Set field Rx/Tx same
* The max VHT-MCS for n SS subfield (where n = 1,...,8) is encoded as
* follows
* - 0 indicates support for VHT-MCS 0-7 for n spatial streams
* - 1 indicates support for VHT-MCS 0-8 for n spatial streams
* - 2 indicates support for VHT-MCS 0-9 for n spatial streams
* - 3 indicates that n spatial streams is not supported
* @he_cap_info_2G: HE capability info field of 802.11ax, WMI_HE_CAP defines
* @he_supp_mcs_2G: HE Supported MCS Set field Rx/Tx same
* @tx_chain_mask_2G: Valid Transmit chain mask
* @rx_chain_mask_2G: Valid Receive chain mask
* @max_bw_supported_5G: max bw supported 5G, enum wmi_channel_width
* @ht_cap_info_5G: WMI HT Capability, WMI_HT_CAP defines
* @vht_cap_info_5G: VHT capability info field of 802.11ac, WMI_VHT_CAP defines
* @vht_supp_mcs_5G: VHT Supported MCS Set field Rx/Tx same
* The max VHT-MCS for n SS subfield (where n = 1,...,8) is encoded as
* follows
* - 0 indicates support for VHT-MCS 0-7 for n spatial streams
* - 1 indicates support for VHT-MCS 0-8 for n spatial streams
* - 2 indicates support for VHT-MCS 0-9 for n spatial streams
* - 3 indicates that n spatial streams is not supported
* @he_cap_info_5G: HE capability info field of 802.11ax, WMI_HE_CAP defines
* @he_supp_mcs_5G: HE Supported MCS Set field Rx/Tx same
* @tx_chain_mask_5G: Valid Transmit chain mask
* @rx_chain_mask_5G: Valid Receive chain mask
* @he_cap_phy_info_2G: 2G HE capability phy field
* @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;
uint32_t pdev_id;
uint32_t phy_id;
uint32_t supports_11b:1,
supports_11g:1,
supports_11a:1,
supports_11n:1,
supports_11ac:1,
supports_11ax:1;
uint32_t supported_bands;
uint32_t ampdu_density;
uint32_t max_bw_supported_2G;
uint32_t ht_cap_info_2G;
uint32_t vht_cap_info_2G;
uint32_t vht_supp_mcs_2G;
uint32_t he_cap_info_2G;
uint32_t he_supp_mcs_2G;
uint32_t tx_chain_mask_2G;
uint32_t rx_chain_mask_2G;
uint32_t max_bw_supported_5G;
uint32_t ht_cap_info_5G;
uint32_t vht_cap_info_5G;
uint32_t vht_supp_mcs_5G;
uint32_t he_cap_info_5G;
uint32_t he_supp_mcs_5G;
uint32_t tx_chain_mask_5G;
uint32_t rx_chain_mask_5G;
uint32_t he_cap_phy_info_2G[PSOC_HOST_MAX_PHY_SIZE];
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;
};
/**
* struct wlan_psoc_host_hw_mode_caps - HW mode capabilities in EXT event
* @hw_mode_id: identify a particular set of HW characteristics,
* as specified by the subsequent fields
* @phy_id_map: BIT0 represents phy_id 0, BIT1 represent phy_id 1 and so on
* @hw_mode_config_type: HW mode config type
*/
struct wlan_psoc_host_hw_mode_caps {
uint32_t hw_mode_id;
uint32_t phy_id_map;
uint32_t hw_mode_config_type;
};
/**
* struct wlan_psoc_host_dbr_ring_caps - Direct buffer rx module ring
* capability maintained by PSOC
* @pdev_id: Pdev id of the pdev
* @mod_id: Module id
* @ring_elems_min: Minimum number of pointers in the ring
* @min_buf_size: Minimum size of each buffer entry in the ring
* @min_buf_align: Minimum alignment of the addresses in the ring
*/
struct wlan_psoc_host_dbr_ring_caps {
uint32_t pdev_id;
uint32_t mod_id;
uint32_t ring_elems_min;
uint32_t min_buf_size;
uint32_t min_buf_align;
};
/**
* 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
* @default_fw_config_bits: Default HW config bits
* @wlan_psoc_host_ppe_threshold ppet: Host PPE threshold struct
* @he_cap_info: HE capabality info
* @mpdu_density: units are microseconds
* @max_bssid_rx_filters: Maximum no of BSSID based RX filters host can program
* Value 0 means FW hasn't given any limit to host.
* @fw_build_vers_ext: Extended FW build version info.
* bits 27:0 rsvd
* bits 31:28 CRM sub ID
* @num_hw_modes: Number of HW modes in event
* @num_phy: Number of Phy mode.
* @num_chainmask_tables: Number of chain mask tables.
* @num_dbr_ring_caps: Number of direct buf rx ring capabilities
* @chainmask_table: Available chain mask tables.
*/
struct wlan_psoc_host_service_ext_param {
uint32_t default_conc_scan_config_bits;
uint32_t default_fw_config_bits;
struct wlan_psoc_host_ppe_threshold ppet;
uint32_t he_cap_info;
uint32_t mpdu_density;
uint32_t max_bssid_rx_filters;
uint32_t fw_build_vers_ext;
uint32_t num_hw_modes;
uint32_t num_phy;
uint32_t num_chainmask_tables;
uint32_t num_dbr_ring_caps;
struct wlan_psoc_host_chainmask_table
chainmask_table[PSOC_MAX_CHAINMASK_TABLES];
};
#endif /* _SERVICE_READY_PARAM_H_*/

مشاهده پرونده

@@ -0,0 +1,241 @@
/*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: service_ready_util.h
*
* Public APIs to access (ext)service ready data from psoc object
*/
#ifndef _SERVICE_READY_UTIL_H_
#define _SERVICE_READY_UTIL_H_
#include "wlan_objmgr_psoc_obj.h"
#include "service_ready_param.h"
#include "target_if.h"
/**
* init_deinit_chainmask_table_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 init_deinit_chainmask_table_alloc(
struct wlan_psoc_host_service_ext_param *service_ext_param);
/**
* init_deinit_chainmask_table_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 init_deinit_chainmask_table_free(
struct wlan_psoc_host_service_ext_param *service_ext_param);
/**
* init_deinit_populate_service_bitmap() - populate service bitmap
* @wmi_handle: wmi handle
* @event: event buffer received from FW
* @service_bitmap: service bitmap information
*
* API to populate service bit map
*
* Return: zero on successful population of service bitmap or failure flag
*/
int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event,
uint32_t *service_bitmap);
/**
* init_deinit_populate_fw_version_cmd() - populate FW version
* @wmi_handle: wmi handle
* @event: event buffer received from FW
*
* API to populate FW version
*
* Return: zero on successful population of fw_version command or failure flag
*/
int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event);
/**
* init_deinit_populate_target_cap() - populate target cap
* @wmi_handle: wmi handle
* @event: event buffer received from FW
* @cap: target capability info object
*
* API to populate target cap
*
* Return: zero on successful population of target cap or failure flag
*/
int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event,
struct wlan_psoc_target_capability_info *cap);
/**
* init_deinit_populate_service_ready_ext_param() - populate service ready ext
* parameter
* @handle: WMI handle pointer
* @evt: event buffer received from FW
* @param: service ext param object
*
* API to populate service ready ext param
*
* Return: zero on successful parsing of service ready ext parameter or failure
*/
int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt,
struct wlan_psoc_host_service_ext_param *param);
/**
* init_deinit_populate_chainmask_tables() - populate chainmaks tables
* @handle: WMI handle pointer
* @evt: event buffer received from FW
* @param: chainmaks_table object
*
* API to populate chainmaks tables
*
* Return: zero on successful parsing of chainmaks tables or failure flag
*/
int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt,
struct wlan_psoc_host_chainmask_table *param);
/**
* init_deinit_populate_mac_phy_capability() - populate mac phy capability
* @handle: WMI handle pointer
* @evt: event buffer received from FW
* @hw_cap: hw_mode_caps object
* @info: tgt_info object
*
* API to populate mac phy capability
*
* Return: zero on successful population of mac physical capability or failure
*/
int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt,
struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info);
/**
* init_deinit_populate_hw_mode_capability() - populate hw mode capability
* @wmi_handle: WMI handle pointer
* @event: event buffer received from FW
* @tgt_hdl: target_psoc_info object
*
* API to populate hw mode capability
*
* Return: zero on successful parsing of hw mode capability or failure
*/
int init_deinit_populate_hw_mode_capability(void *wmi_handle,
uint8_t *event, struct target_psoc_info *tgt_hdl);
/**
* init_deinit_populate_dbr_ring_cap() - populate dbr ring capability
* @psoc: PSOC object
* @handle: WMI handle pointer
* @event: event buffer received from FW
* @info: tgt_info object
*
* API to populate dbr ring capability
*
* Return: zero on successful parsing of dbr ring capability or failure
*/
int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc,
void *handle, uint8_t *event,
struct tgt_info *info);
/**
* init_deinit_populate_phy_reg_cap() - populate phy reg capability
* @psoc: PSOC object
* @wmi_handle: WMI handle pointer
* @event: event buffer received from FW
* @info: tgt_info object
* @service_ready: service ready determiner
*
* API to populate phy reg capability
*
* Return: zero on successful parsing of physical reg capability or failure flag
*/
int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
void *wmi_handle, uint8_t *event,
struct tgt_info *info, bool service_ready);
/**
* init_deinit_validate_160_80p80_fw_caps() - validate 160 80p80 fw caps
* @psoc: PSOC object
* @tgt_info: target_psoc_info object
*
* API to validate 160 80p80 fw caps
*
* Return: SUCCESS on successful validation of 160 80p80 forward caps or Failure
*/
QDF_STATUS init_deinit_validate_160_80p80_fw_caps(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
/**
* init_deinit_chainmask_config() - config chainmask
* @psoc: PSOC object
* @tgt_info: target_psoc_info object
*
* API to config chainmask
*
* Return: none
*/
void init_deinit_chainmask_config(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
/**
* init_deinit_is_service_ext_msg() - check service ext message
* @psoc: PSOC object
* @tgt_info: target_psoc_info object
*
* API to check whether service ext message is enabled
*
* Return: SUCCESS on successful check of service_ext message or Failure
*/
QDF_STATUS init_deinit_is_service_ext_msg(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
/**
* init_deinit_is_preferred_hw_mode_supported() - check support of preferred
* hw mode
* @psoc: PSOC object
* @tgt_info: target_psoc_info object
*
* API to check whether preferred hardware mode is enabled
*
* Return: True on support of preferred hardware support or False
*/
bool init_deinit_is_preferred_hw_mode_supported(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
/**
* init_deinit_wakeup_host_wait() - wakeup host wait
* @psoc: PSOC object
* @tgt_info: target_psoc_info object
*
* API to wakeup FW ready wait queue
*
* Return: None
*/
void init_deinit_wakeup_host_wait(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_info);
#endif /* _SERVICE_READY_UTIL_H_*/

مشاهده پرونده

@@ -0,0 +1,480 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_cmd_api.c
*
* WMI Init command prepare & send APIs
*/
#include <qdf_status.h>
#include <qdf_types.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <target_if.h>
#include <service_ready_util.h>
#include <wlan_tgt_def_config.h>
#include <wlan_reg_ucfg_api.h>
#include <init_cmd_api.h>
#include <wlan_defs.h>
#include <target_if_scan.h>
/**
* init_deinit_alloc_host_mem_chunk() - allocates chunk of memory requested
* by FW.
* @psoc: PSOC object
* @tgt_hdl: Target PSOC info
* @req_id: request id
* @idx: chunk id
* @num_units: Number of units
* @unit_len: Unit length
* @num_unit_info: Num unit info
*
* API to allocate host memory chunk requested by FW
*
* Return: num_units on successful allocation
* 0 on failure
*/
static uint32_t init_deinit_alloc_host_mem_chunk(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl,
u_int32_t req_id, u_int32_t idx, u_int32_t num_units,
u_int32_t unit_len, u_int32_t num_unit_info)
{
qdf_dma_addr_t paddr;
uint32_t ichunk = 0;
struct tgt_info *info;
qdf_device_t qdf_dev;
info = (&tgt_hdl->info);
if (!num_units || !unit_len)
return 0;
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
/*
* We have skip smaller chunks memory allocation for TXBF_CV buffer
* as Firmware is expecting continuous memory
*/
if (!((num_unit_info & HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED) &&
(req_id == TXBF_CV_POOL0 || req_id == TXBF_CV_POOL1 ||
req_id == TXBF_CV_POOL2))) {
ichunk = ((num_units * unit_len) >>
HOST_MEM_CHUNK_MAX_SIZE_POWER2);
if (ichunk)
num_units = num_units / (ichunk + 1);
}
info->mem_chunks[idx].vaddr = NULL;
/* reduce the requested allocation by half until allocation succeeds */
while (!info->mem_chunks[idx].vaddr && num_units) {
info->mem_chunks[idx].vaddr = qdf_mem_alloc_consistent(qdf_dev,
qdf_dev->dev, num_units * unit_len, &paddr);
if (info->mem_chunks[idx].vaddr == NULL) {
if (num_unit_info &
HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED) {
num_units = 0;
target_if_err("mem chink alloc failed for %d",
idx);
break;
}
/* reduce length by half */
num_units = (num_units >> 1);
} else {
info->mem_chunks[idx].paddr = paddr;
info->mem_chunks[idx].len = num_units*unit_len;
info->mem_chunks[idx].req_id = req_id;
}
}
target_if_info(
"req_id %d idx %d num_units %d unit_len %d",
req_id, idx, num_units, unit_len);
return num_units;
}
/* Host mem size units, it is used for round-off */
#define HOST_MEM_SIZE_UNIT 4
/**
* init_deinit_alloc_host_mem() - allocates amount of memory requested by FW.
* @psoc: PSOC object
* @tgt_hdl: Target PSOC info
* @req_id: request id
* @num_units: Number of units
* @unit_len: Unit length
* @num_unit_info: Num unit info
*
* API to allocate host memory requested by FW
*
* Return: QDF_STATUS_SUCCESS on successful allocation
* QDF_STATUS_E_FAILURE on failure
*/
static QDF_STATUS init_deinit_alloc_host_mem(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl, u_int32_t req_id,
u_int32_t num_units, u_int32_t unit_len,
u_int32_t num_unit_info)
{
struct tgt_info *info;
uint32_t remaining_units;
uint32_t allocated_units = 0;
uint32_t idx;
info = (&tgt_hdl->info);
/* adjust the length to nearest multiple of unit size */
unit_len = (unit_len + (HOST_MEM_SIZE_UNIT - 1)) &
(~(HOST_MEM_SIZE_UNIT - 1));
idx = info->num_mem_chunks;
remaining_units = num_units;
while (remaining_units) {
if (idx == MAX_MEM_CHUNKS) {
target_if_err(
"REACHED MAX CHUNK LIMIT for mem units %d",
num_units);
target_if_err(
"unit len %d requested by FW, only allocated %d",
unit_len, (num_units - remaining_units));
info->num_mem_chunks = idx;
return QDF_STATUS_E_FAILURE;
}
if ((tgt_hdl->tif_ops) &&
(tgt_hdl->tif_ops->mem_mgr_alloc_chunk))
allocated_units = tgt_hdl->tif_ops->mem_mgr_alloc_chunk(
psoc, tgt_hdl, req_id, idx,
remaining_units,
unit_len, num_unit_info);
else
allocated_units = init_deinit_alloc_host_mem_chunk(
psoc, tgt_hdl, req_id, idx,
remaining_units,
unit_len, num_unit_info);
if (allocated_units == 0) {
target_if_err("FAILED TO ALLOC mem unit len %d",
unit_len);
target_if_err("units requested %d units allocated %d",
num_units, (num_units - remaining_units));
info->num_mem_chunks = idx;
return QDF_STATUS_E_NOMEM;
}
remaining_units -= allocated_units;
++idx;
}
info->num_mem_chunks = idx;
return QDF_STATUS_SUCCESS;
}
/**
* init_deinit_alloc_num_units() - allocates num units requested by FW.
* @psoc: PSOC object
* @tgt_hdl: Target PSOC info
* @mem_reqs: pointer to mem req
* @num_units: Number
* @i: FW priority
* @idx: Index
*
* API to allocate num units of host memory requested by FW
*
* Return: QDF_STATUS_SUCCESS on successful allocation
* QDF_STATUS_E_FAILURE on failure
*/
static QDF_STATUS init_deinit_alloc_num_units(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl,
host_mem_req *mem_reqs, uint16_t fw_prio,
uint16_t idx)
{
struct tgt_info *info;
uint32_t num_units;
QDF_STATUS status;
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return QDF_STATUS_E_INVAL;
}
info = (&tgt_hdl->info);
if (((fw_prio == FW_MEM_HIGH_PRIORITY) &&
(mem_reqs[idx].num_unit_info &
HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)) ||
((fw_prio == FW_MEM_LOW_PRIORITY) &&
(!(mem_reqs[idx].num_unit_info &
HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)))) {
/* First allocate the memory that requires contiguous memory */
num_units = mem_reqs[idx].num_units;
if (mem_reqs[idx].num_unit_info) {
if (mem_reqs[idx].num_unit_info &
NUM_UNITS_IS_NUM_PEERS) {
/*
* number of units allocated is equal to number
* of peers, 1 extra for self peer on target.
* this needs to be fixed, host and target can
* get out of sync
*/
num_units = info->wlan_res_cfg.num_peers + 1;
}
if (mem_reqs[idx].num_unit_info &
NUM_UNITS_IS_NUM_ACTIVE_PEERS) {
/*
* Requesting allocation of memory using
* num_active_peers in qcache. if qcache is
* disabled in host, then it should allocate
* memory for num_peers instead of
* num_active_peers.
*/
if (info->wlan_res_cfg.num_active_peers)
num_units =
info->wlan_res_cfg.num_active_peers + 1;
else
num_units =
info->wlan_res_cfg.num_peers + 1;
}
}
target_if_info("idx %d req %d num_units %d num_unit_info %d unit size %d actual units %d",
idx, mem_reqs[idx].req_id,
mem_reqs[idx].num_units,
mem_reqs[idx].num_unit_info,
mem_reqs[idx].unit_size, num_units);
status = init_deinit_alloc_host_mem(psoc, tgt_hdl,
mem_reqs[idx].req_id, num_units,
mem_reqs[idx].unit_size,
mem_reqs[idx].num_unit_info);
if (status == QDF_STATUS_E_FAILURE) {
target_if_err(
"psoc:(%pK) num_mem_chunk exceeds supp number",
psoc);
return QDF_STATUS_E_FAILURE;
} else if (status == QDF_STATUS_E_NOMEM) {
target_if_err("soc:(%pK) mem alloc failure", psoc);
return QDF_STATUS_E_NOMEM;
}
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
struct tgt_info *info;
qdf_device_t qdf_dev;
uint32_t idx;
QDF_STATUS status;
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return QDF_STATUS_E_INVAL;
}
if ((tgt_hdl->tif_ops) &&
(tgt_hdl->tif_ops->mem_mgr_free_chunks)) {
status = tgt_hdl->tif_ops->mem_mgr_free_chunks(psoc, tgt_hdl);
} else {
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
info = (&tgt_hdl->info);
for (idx = 0; idx < info->num_mem_chunks; idx++) {
qdf_mem_free_consistent(
qdf_dev, qdf_dev->dev,
info->mem_chunks[idx].len,
info->mem_chunks[idx].vaddr,
info->mem_chunks[idx].paddr,
qdf_get_dma_mem_context(
(&(info->mem_chunks[idx])), memctx));
info->mem_chunks[idx].vaddr = NULL;
info->mem_chunks[idx].paddr = 0;
info->mem_chunks[idx].len = 0;
}
info->num_mem_chunks = 0;
status = QDF_STATUS_SUCCESS;
}
return status;
}
QDF_STATUS init_deinit_handle_host_mem_req(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl, uint8_t *event)
{
uint8_t num_mem_reqs;
host_mem_req *mem_reqs;
uint32_t i;
uint32_t idx;
QDF_STATUS status = QDF_STATUS_SUCCESS;
void *wmi_handle;
struct tgt_info *info;
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return QDF_STATUS_E_INVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
info = (&tgt_hdl->info);
mem_reqs = wmi_extract_host_mem_req_from_service_ready(wmi_handle,
event, &num_mem_reqs);
if (!num_mem_reqs)
return QDF_STATUS_SUCCESS;
for (i = 0; i < FW_PRIORITY_MAX; i++) {
for (idx = 0; idx < num_mem_reqs; idx++) {
status = init_deinit_alloc_num_units(psoc, tgt_hdl,
mem_reqs, i, idx);
if (status != QDF_STATUS_SUCCESS)
return status;
}
}
return status;
}
void init_deinit_derive_band_to_mac_param(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl,
struct wmi_host_pdev_band_to_mac *band_to_mac)
{
uint8_t i;
struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
struct tgt_info *info;
if (!tgt_hdl) {
target_if_err("target_psoc_info is null ");
return;
}
info = (&tgt_hdl->info);
reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
if (!reg_cap) {
target_if_err("reg cap is NULL");
return;
}
for (i = 0; i < target_psoc_get_num_radios(tgt_hdl); i++) {
mac_phy_cap = &info->mac_phy_cap[i];
if (mac_phy_cap->supported_bands ==
(WMI_HOST_WLAN_5G_CAPABILITY |
WMI_HOST_WLAN_2G_CAPABILITY)) {
/*Supports both 5G and 2G. Use freq from both radios*/
target_if_info("Supports both 2G and 5G");
band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
band_to_mac[i].start_freq =
reg_cap[i].low_2ghz_chan;
band_to_mac[i].end_freq =
reg_cap[i].high_5ghz_chan;
} else if (mac_phy_cap->supported_bands ==
WMI_HOST_WLAN_2G_CAPABILITY) {
band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
band_to_mac[i].start_freq =
reg_cap[i].low_2ghz_chan;
band_to_mac[i].end_freq =
reg_cap[i].high_2ghz_chan;
reg_cap[mac_phy_cap->phy_id].low_5ghz_chan = 0;
reg_cap[mac_phy_cap->phy_id].high_5ghz_chan = 0;
target_if_info(
"2G radio - pdev_id = %d start_freq = %d end_freq= %d",
band_to_mac[i].pdev_id,
band_to_mac[i].start_freq,
band_to_mac[i].end_freq);
} else if (mac_phy_cap->supported_bands ==
WMI_HOST_WLAN_5G_CAPABILITY) {
band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
band_to_mac[i].start_freq =
reg_cap[i].low_5ghz_chan;
band_to_mac[i].end_freq =
reg_cap[i].high_5ghz_chan;
reg_cap[mac_phy_cap->phy_id].low_2ghz_chan = 0;
reg_cap[mac_phy_cap->phy_id].high_2ghz_chan = 0;
target_if_info(
"5G radio -pdev_id = %d start_freq = %d end_freq =%d\n",
band_to_mac[i].pdev_id,
band_to_mac[i].start_freq,
band_to_mac[i].end_freq);
}
}
}
void init_deinit_prepare_send_init_cmd(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
struct wmi_init_cmd_param init_param = {0};
struct tgt_info *info;
void *wmi_handle;
QDF_STATUS ret_val;
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
info = (&tgt_hdl->info);
init_param.res_cfg = &info->wlan_res_cfg;
init_param.num_mem_chunks = info->num_mem_chunks;
init_param.mem_chunks = info->mem_chunks;
if (init_deinit_is_service_ext_msg(psoc, tgt_hdl) ==
QDF_STATUS_SUCCESS) {
init_param.hw_mode_id = info->preferred_hw_mode;
/* Temp change, until FW submits support for handling this TLV
* For single mode, skip sending hw_mode
*/
if (info->preferred_hw_mode == WMI_HOST_HW_MODE_SINGLE)
init_param.hw_mode_id = WMI_HOST_HW_MODE_MAX;
init_param.num_band_to_mac = target_psoc_get_num_radios(
tgt_hdl);
init_deinit_derive_band_to_mac_param(psoc, tgt_hdl,
init_param.band_to_mac);
}
ret_val = target_if_alloc_pdevs(psoc, tgt_hdl);
if (ret_val != QDF_STATUS_SUCCESS)
return;
ret_val = target_if_update_pdev_tgt_info(psoc, tgt_hdl);
if (ret_val != QDF_STATUS_SUCCESS)
return;
target_if_info("FW version 0x%x ", info->target_caps.fw_version);
if (init_deinit_is_service_ext_msg(psoc, tgt_hdl) ==
QDF_STATUS_SUCCESS)
target_if_info("0x%x\n",
info->service_ext_param.fw_build_vers_ext);
else
target_if_info("0x%x\n", info->target_caps.fw_version_1);
wmi_unified_init_cmd_send(wmi_handle, &init_param);
/* Set Max scans allowed */
target_if_scan_set_max_active_scans(psoc,
WLAN_MAX_ACTIVE_SCANS_ALLOWED);
}

مشاهده پرونده

@@ -0,0 +1,267 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_deinit_ucfg.c
*
* APIs to get/set target_if params
*/
#include <qdf_status.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <target_if.h>
#include <target_type.h>
#include <init_deinit_ucfg.h>
#include <qdf_module.h>
uint32_t *ucfg_get_service_param(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return NULL;
}
tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return NULL;
}
return target_psoc_get_service_bitmap(tgt_hdl);
}
struct wlan_psoc_target_capability_info *ucfg_get_target_cap(
struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return NULL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return NULL;
}
return target_psoc_get_target_caps(tgt_hdl);
}
bool ucfg_is_service_param_bit_enabled(uint32_t *service_param,
uint16_t bit_idx)
{
bool retval = false;
if (((service_param)[(bit_idx) / (sizeof(uint32_t))] &
(1 << ((bit_idx) % (sizeof(uint32_t))))) != 0)
retval = true;
return retval;
}
/* dfs offload service bit */
#define DFS_SERVICE_PHYERR_OFFLOAD 113
QDF_STATUS ucfg_get_dfs_offload(struct wlan_objmgr_psoc *psoc,
bool *is_tgt_offload)
{
uint32_t *service_bitmap;
*is_tgt_offload = false;
if (!psoc) {
target_if_err("psoc is null");
return QDF_STATUS_E_FAILURE;
}
service_bitmap = ucfg_get_service_param(psoc);
if (!service_bitmap) {
target_if_err("pdev is null");
return QDF_STATUS_E_FAILURE;
}
*is_tgt_offload = ucfg_is_service_param_bit_enabled(service_bitmap,
DFS_SERVICE_PHYERR_OFFLOAD);
return QDF_STATUS_SUCCESS;
}
target_resource_config *ucfg_get_tgt_res_cfg(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return NULL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return NULL;
}
return target_psoc_get_wlan_res_cfg(tgt_hdl);
}
int32_t ucfg_get_pdev_idx(struct wlan_objmgr_pdev *pdev)
{
struct target_pdev_info *tgt_hdl;
if (!pdev) {
target_if_err("pdev is null");
return 0xffffffff;
}
tgt_hdl = (struct target_pdev_info *)wlan_pdev_get_tgt_if_handle(
pdev);
if (!tgt_hdl) {
target_if_err("target_pdev_info is null");
return 0xffffffff;
}
return target_pdev_get_pdev_idx(tgt_hdl);
}
uint32_t ucfg_get_tgt_type(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return 0;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return 0;
}
return target_psoc_get_target_type(tgt_hdl);
}
qdf_export_symbol(ucfg_get_tgt_type);
QDF_STATUS ucfg_get_pdev_target_type(struct wlan_objmgr_pdev *pdev,
uint32_t *target_type)
{
struct wlan_objmgr_psoc *psoc;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
target_if_err("psoc is NULL");
return QDF_STATUS_E_FAILURE;
}
*target_type = ucfg_get_tgt_type(psoc);
return QDF_STATUS_SUCCESS;
}
uint32_t ucfg_get_tgt_version(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
return target_psoc_get_target_ver(tgt_hdl);
}
uint32_t ucfg_get_tgt_revision(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
return target_psoc_get_target_rev(tgt_hdl);
}
qdf_export_symbol(ucfg_get_tgt_revision);
bool ucfg_is_target_ar900b(struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
uint32_t target_type;
if (!psoc) {
target_if_err("psoc is null\n");
return false;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return false;
}
target_type = tgt_hdl->info.target_type;
switch (target_type) {
case TARGET_TYPE_AR900B:
case TARGET_TYPE_QCA9984:
case TARGET_TYPE_IPQ4019:
case TARGET_TYPE_QCA9888:
return true;
default:
return false;
}
return false;
}
void *ucfg_get_pdev_wmi_handle(struct wlan_objmgr_pdev *pdev)
{
struct target_pdev_info *tgt_hdl;
if (!pdev) {
target_if_err("pdev is null");
return NULL;
}
tgt_hdl = (struct target_pdev_info *)wlan_pdev_get_tgt_if_handle(
pdev);
if (!tgt_hdl) {
target_if_err("target_pdev_info is null");
return NULL;
}
return target_pdev_get_wmi_handle(tgt_hdl);
}

مشاهده پرونده

@@ -0,0 +1,426 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: init_event_handler.c
*
* WMI common event handler implementation source file
*/
#include <qdf_status.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <target_if.h>
#include <target_if_reg.h>
#include <init_event_handler.h>
#include <service_ready_util.h>
#include <service_ready_param.h>
#include <init_cmd_api.h>
static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
int err_code;
struct wlan_objmgr_psoc *psoc;
struct target_psoc_info *tgt_hdl;
wmi_legacy_service_ready_callback legacy_callback;
void *wmi_handle;
QDF_STATUS ret_val;
if (!scn_handle) {
target_if_err("scn handle NULL in service ready handler");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null in service ready handler");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null in service ready ev");
return -EINVAL;
}
ret_val = target_if_sw_version_check(psoc, tgt_hdl, event);
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
err_code = init_deinit_populate_service_bitmap(wmi_handle, event,
tgt_hdl->info.service_bitmap);
if (err_code)
goto exit;
err_code = init_deinit_populate_fw_version_cmd(wmi_handle, event);
if (err_code)
goto exit;
err_code = init_deinit_populate_target_cap(wmi_handle, event,
&(tgt_hdl->info.target_caps));
if (err_code)
goto exit;
err_code = init_deinit_populate_phy_reg_cap(psoc, wmi_handle, event,
&(tgt_hdl->info), true);
if (err_code)
goto exit;
if (init_deinit_validate_160_80p80_fw_caps(psoc, tgt_hdl) !=
QDF_STATUS_SUCCESS) {
wlan_psoc_nif_op_flag_set(psoc, WLAN_SOC_OP_VHT_INVALID_CAP);
}
target_if_ext_res_cfg_enable(psoc, tgt_hdl, event);
if (wmi_service_enabled(wmi_handle, wmi_service_tt))
wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_TT_SUPPORT);
if (wmi_service_enabled(wmi_handle, wmi_service_widebw_scan))
wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_WIDEBAND_SCAN);
if (wmi_service_enabled(wmi_handle, wmi_service_check_cal_version))
wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_SW_CAL);
target_if_info(" TT support %d, Wide BW Scan %d, SW cal %d",
wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_TT_SUPPORT),
wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_WIDEBAND_SCAN),
wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_SW_CAL));
target_if_mesh_support_enable(psoc, tgt_hdl, event);
target_if_smart_antenna_enable(psoc, tgt_hdl, event);
target_if_peer_cfg_enable(psoc, tgt_hdl, event);
target_if_atf_cfg_enable(psoc, tgt_hdl, event);
target_if_qwrap_cfg_enable(psoc, tgt_hdl, event);
target_if_lteu_cfg_enable(psoc, tgt_hdl, event);
/* override derived value, if it exceeds max peer count */
if ((wlan_psoc_get_max_peer_count(psoc) >
tgt_hdl->info.wlan_res_cfg.num_active_peers) &&
(wlan_psoc_get_max_peer_count(psoc) <
(tgt_hdl->info.wlan_res_cfg.num_peers -
tgt_hdl->info.wlan_res_cfg.num_vdevs))) {
tgt_hdl->info.wlan_res_cfg.num_peers =
wlan_psoc_get_max_peer_count(psoc) +
tgt_hdl->info.wlan_res_cfg.num_vdevs;
}
legacy_callback = target_if_get_psoc_legacy_service_ready_cb();
if (!legacy_callback) {
err_code = -EINVAL;
goto exit;
}
err_code = legacy_callback(wmi_service_ready_event_id,
scn_handle, event, data_len);
init_deinit_chainmask_config(psoc, tgt_hdl);
if (wmi_service_enabled(wmi_handle, wmi_service_mgmt_tx_wmi)) {
wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_WMI_MGMT_REF);
target_if_info("WMI mgmt service enabled");
} else {
wlan_psoc_nif_fw_ext_cap_clear(psoc,
WLAN_SOC_CEXT_WMI_MGMT_REF);
target_if_info("WMI mgmt service disabled");
}
err_code = init_deinit_handle_host_mem_req(psoc, tgt_hdl, event);
if (err_code != QDF_STATUS_SUCCESS)
goto exit;
target_if_reg_set_offloaded_info(psoc);
if (!wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
target_if_info("No EXT message, send init command");
tgt_hdl->info.wmi_service_ready = TRUE;
target_psoc_set_num_radios(tgt_hdl, 1);
/* send init command */
init_deinit_prepare_send_init_cmd(psoc, tgt_hdl);
} else {
target_if_info("Wait for EXT message");
}
target_if_btcoex_cfg_enable(psoc, tgt_hdl, event);
exit:
return err_code;
}
static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
int err_code;
struct wlan_objmgr_psoc *psoc;
struct target_psoc_info *tgt_hdl;
void *wmi_handle;
struct tgt_info *info;
if (!scn_handle) {
target_if_err("scn handle NULL in service ready handler");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null in service ready handler");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null in service ready ev");
return -EINVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
info = (&tgt_hdl->info);
err_code = init_deinit_populate_dbr_ring_cap(psoc, wmi_handle,
event, info);
if (err_code)
goto exit;
err_code = init_deinit_populate_service_ready_ext_param(wmi_handle,
event, &(info->service_ext_param));
if (err_code)
goto exit;
target_psoc_set_num_radios(tgt_hdl, 0);
err_code = init_deinit_populate_hw_mode_capability(wmi_handle,
event, tgt_hdl);
if (err_code)
goto exit;
if (init_deinit_is_preferred_hw_mode_supported(psoc, tgt_hdl)
== FALSE)
return -EINVAL;
target_if_print_service_ready_ext_param(psoc, tgt_hdl);
err_code = init_deinit_populate_phy_reg_cap(psoc, wmi_handle,
event, info, false);
if (err_code)
goto exit;
target_if_add_11ax_modes(psoc, tgt_hdl);
if (init_deinit_chainmask_table_alloc(
&(info->service_ext_param)) ==
QDF_STATUS_SUCCESS) {
err_code = init_deinit_populate_chainmask_tables(wmi_handle,
event,
&(info->service_ext_param.chainmask_table[0]));
if (err_code)
goto exit;
}
info->wlan_res_cfg.num_vdevs = (target_psoc_get_num_radios(tgt_hdl) *
info->wlan_res_cfg.num_vdevs);
info->wlan_res_cfg.beacon_tx_offload_max_vdev =
(target_psoc_get_num_radios(tgt_hdl) *
info->wlan_res_cfg.beacon_tx_offload_max_vdev);
info->wmi_service_ready = TRUE;
init_deinit_prepare_send_init_cmd(psoc, tgt_hdl);
exit:
return err_code;
}
static int init_deinit_service_available_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
struct wlan_objmgr_psoc *psoc;
struct target_psoc_info *tgt_hdl;
void *wmi_handle;
if (!scn_handle) {
target_if_err("scn handle NULL");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
if (wmi_save_ext_service_bitmap(wmi_handle, event, NULL) !=
QDF_STATUS_SUCCESS) {
target_if_err("Failed to save ext service bitmap");
return -EINVAL;
}
return 0;
}
/* MAC address fourth byte index */
#define MAC_BYTE_4 4
static int init_deinit_ready_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
struct target_psoc_info *tgt_hdl;
void *wmi_handle;
struct wmi_host_fw_abi_ver fw_ver;
uint8_t myaddr[WLAN_MACADDR_LEN];
struct tgt_info *info;
uint8_t i;
struct wmi_host_ready_ev_param ready_ev;
if (!scn_handle) {
target_if_err("scn handle NULL");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info is null");
return -EINVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
info = (&tgt_hdl->info);
if (wmi_extract_fw_abi_version(wmi_handle, event, &fw_ver) ==
QDF_STATUS_SUCCESS) {
info->version.wlan_ver = fw_ver.sw_version;
info->version.wlan_ver = fw_ver.abi_version;
}
if (wmi_check_and_update_fw_version(wmi_handle, event) < 0) {
target_if_err("Version mismatch with FW");
return -EINVAL;
}
if (wmi_extract_ready_event_params(wmi_handle, event, &ready_ev) !=
QDF_STATUS_SUCCESS) {
target_if_err("Failed to extract ready event");
return -EINVAL;
}
if ((ready_ev.num_total_peer != 0) &&
(info->wlan_res_cfg.num_peers != ready_ev.num_total_peer)) {
/* FW allocated number of peers is different than host
* requested. Update host max with FW reported value.
*/
target_if_info("Host Requested %d peers. FW Supports %d peers",
info->wlan_res_cfg.num_peers,
ready_ev.num_total_peer);
info->wlan_res_cfg.num_peers = ready_ev.num_total_peer;
}
/* Indicate to the waiting thread that the ready
* event was received
*/
info->wlan_init_status = wmi_ready_extract_init_status(
wmi_handle, event);
/* copy the mac addr */
wmi_ready_extract_mac_addr(wmi_handle, event, myaddr);
/* Set hw address in PSOC object */
wlan_psoc_set_hw_macaddr(psoc, myaddr);
for (i = 0; i < target_psoc_get_num_radios(tgt_hdl); i++) {
/* Temp change -
* This may eihter come from FW or host needs derive.
*/
myaddr[MAC_BYTE_4] += i;
pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_INIT_DEINIT_ID);
if (!pdev) {
target_if_err(" PDEV %d is NULL", i);
return -EINVAL;
}
wlan_pdev_set_hw_macaddr(pdev, myaddr);
wlan_objmgr_pdev_release_ref(pdev, WLAN_INIT_DEINIT_ID);
}
tgt_hdl->info.wmi_ready = TRUE;
init_deinit_wakeup_host_wait(psoc, tgt_hdl);
return 0;
}
QDF_STATUS init_deinit_register_tgt_psoc_ev_handlers(
struct wlan_objmgr_psoc *psoc)
{
struct target_psoc_info *tgt_hdl;
void *wmi_handle;
QDF_STATUS retval = QDF_STATUS_SUCCESS;
if (!psoc) {
target_if_err("psoc is null in register wmi handler");
return QDF_STATUS_E_FAILURE;
}
tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(
psoc);
if (!tgt_hdl) {
target_if_err("target_psoc_info null in register wmi hadler");
return QDF_STATUS_E_FAILURE;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
retval = wmi_unified_register_event_handler(wmi_handle,
wmi_service_ready_event_id,
init_deinit_service_ready_event_handler,
WMI_RX_WORK_CTX);
retval = wmi_unified_register_event_handler(wmi_handle,
wmi_service_ready_ext_event_id,
init_deinit_service_ext_ready_event_handler,
WMI_RX_WORK_CTX);
retval = wmi_unified_register_event_handler(wmi_handle,
wmi_service_available_event_id,
init_deinit_service_available_handler,
WMI_RX_UMAC_CTX);
retval = wmi_unified_register_event_handler(wmi_handle,
wmi_ready_event_id,
init_deinit_ready_event_handler,
WMI_RX_WORK_CTX);
return retval;
}

مشاهده پرونده

@@ -1,393 +0,0 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: wmi_unified_event_handler.c
*
* WMI common event handler implementation source file
*/
#include "service_ready_event_handler.h"
#include "wlan_objmgr_psoc_service_ready_api.h"
static int populate_service_bitmap(void *wmi_handle, uint8_t *event,
uint32_t *service_bitmap)
{
QDF_STATUS status;
status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap);
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse service bitmap");
return qdf_status_to_os_return(status);
}
return 0;
}
static int populate_target_cap(void *wmi_handle, uint8_t *event,
struct wlan_psoc_target_capability_info *cap)
{
QDF_STATUS status;
status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap);
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse target cap");
return qdf_status_to_os_return(status);
}
return 0;
}
static int populate_hal_reg_cap(void *wmi_handle, uint8_t *event,
struct wlan_psoc_hal_reg_capability *cap)
{
QDF_STATUS status;
status = wmi_extract_hal_reg_cap(wmi_handle, event, cap);
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse hal reg cap");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_service_ready_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
int err_code;
struct wlan_objmgr_psoc_service_ready_param *service_param;
struct wlan_objmgr_psoc *psoc;
wmi_legacy_service_ready_callback legacy_callback;
void *wmi_handle;
if (!scn_handle) {
WMI_LOGE("scn handle NULL in service ready handler");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
WMI_LOGE("psoc is null in service ready handler");
return -EINVAL;
}
wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
service_param = qdf_mem_malloc(sizeof(*service_param));
if (!service_param) {
WMI_LOGE("memory alloc failed for psoc service ready");
return -ENOMEM;
}
err_code = populate_service_bitmap(wmi_handle, event,
service_param->service_bitmap);
if (err_code)
goto free_param_and_exit;
err_code = populate_target_cap(wmi_handle, event,
&(service_param->target_caps));
if (err_code)
goto free_param_and_exit;
err_code = populate_hal_reg_cap(wmi_handle, event,
&(service_param->hal_reg_cap));
if (err_code)
goto free_param_and_exit;
legacy_callback = target_if_get_psoc_legacy_service_ready_cb();
if (!legacy_callback) {
err_code = -EINVAL;
goto free_param_and_exit;
}
err_code = legacy_callback(wmi_service_ready_event_id,
scn_handle, event, data_len);
wlan_objmgr_populate_service_ready_data(psoc, service_param);
target_if_scan_set_max_active_scans(psoc,
WLAN_MAX_ACTIVE_SCANS_ALLOWED);
target_if_reg_set_offloaded_info(psoc);
free_param_and_exit:
qdf_mem_free(service_param);
return err_code;
}
static int populate_service_ready_ext_param(void *handle, uint8_t *evt,
struct wlan_psoc_host_service_ext_param *param)
{
QDF_STATUS status;
status = wmi_extract_service_ready_ext(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_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)
{
QDF_STATUS status;
uint32_t hw_mode_id;
uint32_t phy_bit_map;
uint8_t mac_phy_id;
hw_mode_id = hw_cap->hw_mode_id;
phy_bit_map = hw_cap->phy_id_map;
WMI_LOGE("hw_mode_id %d phy_bit_map 0x%x", hw_mode_id, phy_bit_map);
mac_phy_id = 0;
while (phy_bit_map) {
if (*total_mac_phy >= PSOC_MAX_MAC_PHY_CAP) {
WMI_LOGE("total mac phy exceeds max limit %d",
*total_mac_phy);
return -EINVAL;
}
status = wmi_extract_mac_phy_cap_service_ready_ext(handle,
evt, hw_mode_id, mac_phy_id,
&(service_param->mac_phy_cap[*total_mac_phy]));
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse mac phy capability");
return qdf_status_to_os_return(status);
}
(*total_mac_phy)++;
phy_bit_map &= (phy_bit_map - 1);
mac_phy_id++;
}
WMI_LOGE("total_mac_phy %d", *total_mac_phy);
return 0;
}
static int get_hw_mode(void *handle, uint8_t *evt, uint8_t i,
struct wlan_psoc_host_hw_mode_caps *cap)
{
QDF_STATUS status;
status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt, i, cap);
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse hw mode capability");
return qdf_status_to_os_return(status);
}
return 0;
}
static int populate_hw_mode_capability(void *wmi_handle,
uint8_t *event, uint8_t *total_mac_phy,
struct wlan_objmgr_psoc_ext_service_ready_param *service_param)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint8_t hw_idx;
uint32_t num_hw_modes;
num_hw_modes = service_param->service_ext_param.num_hw_modes;
if (num_hw_modes > PSOC_MAX_HW_MODE) {
WMI_LOGE("invalid num_hw_modes %d", num_hw_modes);
return -EINVAL;
}
WMI_LOGE("num_hw_modes %d", num_hw_modes);
for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) {
status = get_hw_mode(wmi_handle, event, hw_idx,
&service_param->hw_mode_caps[hw_idx]);
if (status)
goto return_exit;
status = populate_mac_phy_capability(wmi_handle, event,
&service_param->hw_mode_caps[hw_idx],
total_mac_phy, service_param);
if (status)
goto return_exit;
}
return_exit:
return qdf_status_to_os_return(status);
}
static int populate_dbr_ring_capability(void *handle, uint8_t *event,
struct wlan_objmgr_psoc_ext_service_ready_param *service_param)
{
uint8_t cap_idx;
uint32_t num_dbr_ring_caps;
QDF_STATUS status = QDF_STATUS_SUCCESS;
num_dbr_ring_caps = service_param->service_ext_param.num_dbr_ring_caps;
WMI_LOGE("Num DMA Capabilities = %d", num_dbr_ring_caps);
if (!num_dbr_ring_caps) {
return 0;
}
service_param->dbr_ring_cap = qdf_mem_malloc(
sizeof(struct wlan_psoc_host_dbr_ring_caps) *
num_dbr_ring_caps);
if (!service_param->dbr_ring_cap) {
WMI_LOGE("Mem alloc for DMA cap failed");
return -EINVAL;
}
for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
status = wmi_extract_dbr_ring_cap_service_ready_ext(handle,
event, cap_idx,
&(service_param->dbr_ring_cap[cap_idx]));
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("Extraction of DMA cap failed");
goto free_and_return;
}
}
return 0;
free_and_return:
qdf_mem_free(service_param->dbr_ring_cap);
service_param->dbr_ring_cap = NULL;
return qdf_status_to_os_return(status);
}
static int populate_phy_reg_capability(void *handle, uint8_t *event,
struct wlan_objmgr_psoc_ext_service_ready_param *service_param)
{
uint8_t reg_idx;
uint32_t num_phy_reg_cap;
QDF_STATUS status = QDF_STATUS_SUCCESS;
num_phy_reg_cap = service_param->service_ext_param.num_phy;
if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) {
WMI_LOGE("Invalid num_phy_reg_cap %d", num_phy_reg_cap);
return -EINVAL;
}
WMI_LOGE("num_phy_reg_cap %d", num_phy_reg_cap);
for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) {
status = wmi_extract_reg_cap_service_ready_ext(handle, event,
reg_idx, &(service_param->reg_cap[reg_idx]));
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("failed to parse reg cap");
return qdf_status_to_os_return(status);
}
}
return qdf_status_to_os_return(status);
}
int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle,
uint8_t *event,
uint32_t data_len)
{
int err_code;
struct wlan_objmgr_psoc_ext_service_ready_param *service_param;
struct wlan_objmgr_psoc *psoc;
wmi_legacy_service_ready_callback legacy_callback;
void *wmi_handle;
if (!scn_handle) {
WMI_LOGE("scn handle NULL in service ready handler");
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
if (!psoc) {
WMI_LOGE("psoc is null in service ready handler");
return -EINVAL;
}
wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
service_param =
qdf_mem_malloc(sizeof(*service_param));
if (!service_param) {
WMI_LOGE("ext_service_ready_param alloc failed");
return QDF_STATUS_E_NOMEM;
}
err_code = populate_service_ready_ext_param(wmi_handle,
event, &(service_param->service_ext_param));
if (err_code)
goto free_param_and_exit;
psoc->total_mac_phy = 0;
err_code = populate_hw_mode_capability(wmi_handle,
event,
&psoc->total_mac_phy,
service_param);
if (err_code)
goto free_param_and_exit;
err_code = populate_phy_reg_capability(wmi_handle,
event, service_param);
if (err_code)
goto free_param_and_exit;
if (wlan_objmgr_ext_service_ready_chainmask_table_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;
}
err_code = populate_dbr_ring_capability(wmi_handle,
event, service_param);
if (err_code)
goto free_param_and_exit;
wlan_objmgr_populate_ext_service_ready_data(psoc, service_param);
legacy_callback = target_if_get_psoc_legacy_service_ready_cb();
if (!legacy_callback) {
err_code = -EINVAL;
goto free_param_and_exit;
}
err_code = legacy_callback(wmi_service_ready_ext_event_id,
scn_handle, event, data_len);
target_if_scan_set_max_active_scans(psoc,
WLAN_MAX_ACTIVE_SCANS_ALLOWED);
free_param_and_exit:
qdf_mem_free(service_param);
return err_code;
}

مشاهده پرونده

@@ -0,0 +1,539 @@
/*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: service_ready_util.c
*
* Public APIs implementation source file for accessing (ext)service ready
* data from psoc object
*/
#include "service_ready_util.h"
#include <wlan_reg_ucfg_api.h>
#include <target_type.h>
#include <qdf_module.h>
QDF_STATUS init_deinit_chainmask_table_alloc(
struct wlan_psoc_host_service_ext_param *ser_ext_par)
{
int i;
uint32_t alloc_size;
QDF_STATUS status;
if (ser_ext_par->num_chainmask_tables > 0) {
status = QDF_STATUS_SUCCESS;
for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
alloc_size =
(sizeof(struct wlan_psoc_host_chainmask_capabilities) *
ser_ext_par->chainmask_table[i].num_valid_chainmasks);
ser_ext_par->chainmask_table[i].cap_list =
qdf_mem_alloc_outline(NULL, alloc_size);
if (!ser_ext_par->chainmask_table[i].cap_list) {
init_deinit_chainmask_table_free(ser_ext_par);
status = QDF_STATUS_E_NOMEM;
break;
}
}
} else {
status = QDF_STATUS_E_NOSUPPORT;
}
return status;
}
qdf_export_symbol(init_deinit_chainmask_table_alloc);
QDF_STATUS init_deinit_chainmask_table_free(
struct wlan_psoc_host_service_ext_param *ser_ext_par)
{
struct wlan_psoc_host_chainmask_table *table;
int i;
for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
table = &(ser_ext_par->chainmask_table[i]);
if (table->cap_list) {
qdf_mem_free(table->cap_list);
table->cap_list = NULL;
}
}
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(init_deinit_chainmask_table_free);
int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event,
uint32_t *service_bitmap)
{
QDF_STATUS status;
status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse service bitmap");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event)
{
QDF_STATUS status;
status = wmi_unified_save_fw_version_cmd(wmi_handle, event);
if (QDF_IS_STATUS_ERROR(status))
target_if_err("failed to save fw version");
return 0;
}
int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event,
struct wlan_psoc_target_capability_info *cap)
{
QDF_STATUS status;
status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse target cap");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt,
struct wlan_psoc_host_service_ext_param *param)
{
QDF_STATUS status;
status = wmi_extract_service_ready_ext(handle, evt, param);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse wmi service ready ext param");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_populate_chainmask_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)) {
target_if_err("failed to parse wmi service ready ext param");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt,
struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info)
{
QDF_STATUS status;
uint32_t hw_mode_id;
uint32_t phy_bit_map;
uint8_t mac_phy_id;
hw_mode_id = hw_cap->hw_mode_id;
phy_bit_map = hw_cap->phy_id_map;
target_if_info("hw_mode_id %d phy_bit_map 0x%x",
hw_mode_id, phy_bit_map);
mac_phy_id = 0;
while (phy_bit_map) {
if (info->total_mac_phy_cnt >= PSOC_MAX_MAC_PHY_CAP) {
target_if_err("total mac phy exceeds max limit %d",
info->total_mac_phy_cnt);
return -EINVAL;
}
status = wmi_extract_mac_phy_cap_service_ready_ext(handle,
evt, hw_mode_id, mac_phy_id,
&(info->mac_phy_cap[info->total_mac_phy_cnt]));
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse mac phy capability");
return qdf_status_to_os_return(status);
}
info->total_mac_phy_cnt++;
phy_bit_map &= (phy_bit_map - 1);
mac_phy_id++;
}
target_if_info("total_mac_phy_cnt %d", info->total_mac_phy_cnt);
return 0;
}
static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx,
struct wlan_psoc_host_hw_mode_caps *cap)
{
QDF_STATUS status;
status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt,
hw_idx, cap);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse hw mode capability");
return qdf_status_to_os_return(status);
}
return 0;
}
int init_deinit_populate_hw_mode_capability(void *wmi_handle,
uint8_t *event, struct target_psoc_info *tgt_hdl)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint8_t hw_idx;
uint32_t num_hw_modes;
struct wlan_psoc_host_hw_mode_caps hw_mode_caps[PSOC_MAX_HW_MODE];
uint32_t preferred_mode;
struct tgt_info *info;
info = &tgt_hdl->info;
num_hw_modes = info->service_ext_param.num_hw_modes;
if (num_hw_modes > PSOC_MAX_HW_MODE) {
target_if_err("invalid num_hw_modes %d", num_hw_modes);
return -EINVAL;
}
target_if_info("num_hw_modes %d", num_hw_modes);
qdf_mem_zero(&hw_mode_caps, sizeof(hw_mode_caps));
preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl);
for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) {
status = get_hw_mode(wmi_handle, event, hw_idx,
&hw_mode_caps[hw_idx]);
if (status)
goto return_exit;
if (preferred_mode &&
(hw_mode_caps[hw_idx].hw_mode_id != preferred_mode))
continue;
status = init_deinit_populate_mac_phy_capability(wmi_handle,
event, &hw_mode_caps[hw_idx], info);
if (status)
goto return_exit;
if (preferred_mode &&
(hw_mode_caps[hw_idx].hw_mode_id == preferred_mode)) {
info->num_radios = info->total_mac_phy_cnt;
target_if_info("num radios is %d\n", info->num_radios);
}
}
return_exit:
return qdf_status_to_os_return(status);
}
int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc,
void *handle, uint8_t *event, struct tgt_info *info)
{
uint8_t cap_idx;
uint32_t num_dbr_ring_caps;
QDF_STATUS status = QDF_STATUS_SUCCESS;
num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps;
target_if_info("Num DMA Capabilities = %d", num_dbr_ring_caps);
if (!num_dbr_ring_caps)
return 0;
info->dbr_ring_cap = qdf_mem_malloc(
sizeof(struct wlan_psoc_host_dbr_ring_caps) *
num_dbr_ring_caps);
if (!info->dbr_ring_cap) {
target_if_err("Mem alloc for DMA cap failed");
return -EINVAL;
}
for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
status = wmi_extract_dbr_ring_cap_service_ready_ext(handle,
event, cap_idx,
&(info->dbr_ring_cap[cap_idx]));
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("Extraction of DMA cap failed");
goto free_and_return;
}
}
return 0;
free_and_return:
qdf_mem_free(info->dbr_ring_cap);
info->dbr_ring_cap = NULL;
return qdf_status_to_os_return(status);
}
int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
void *handle, uint8_t *event,
struct tgt_info *info, bool service_ready)
{
uint8_t reg_idx;
uint32_t num_phy_reg_cap;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_psoc_hal_reg_capability cap;
struct wlan_psoc_host_hal_reg_capabilities_ext
reg_cap[PSOC_MAX_PHY_REG_CAP];
if (service_ready) {
status = wmi_extract_hal_reg_cap(handle, event, &cap);
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse hal reg cap");
return qdf_status_to_os_return(status);
}
info->service_ext_param.num_phy = 1;
num_phy_reg_cap = 1;
reg_cap[0].phy_id = 0;
qdf_mem_copy(&(reg_cap[0].eeprom_reg_domain), &cap,
sizeof(struct wlan_psoc_hal_reg_capability));
target_if_info("FW wireless modes 0x%x",
reg_cap[0].wireless_modes);
} else {
num_phy_reg_cap = info->service_ext_param.num_phy;
if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) {
target_if_err("Invalid num_phy_reg_cap %d",
num_phy_reg_cap);
return -EINVAL;
}
target_if_info("num_phy_reg_cap %d", num_phy_reg_cap);
for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) {
status = wmi_extract_reg_cap_service_ready_ext(handle,
event, reg_idx, &(reg_cap[reg_idx]));
if (QDF_IS_STATUS_ERROR(status)) {
target_if_err("failed to parse reg cap");
return qdf_status_to_os_return(status);
}
}
}
status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap);
return qdf_status_to_os_return(status);
}
static bool init_deinit_regdmn_160mhz_support(
struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
{
return ((hal_cap->wireless_modes &
WMI_HOST_REGDMN_MODE_11AC_VHT160) != 0);
}
static bool init_deinit_regdmn_80p80mhz_support(
struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
{
return ((hal_cap->wireless_modes &
WMI_HOST_REGDMN_MODE_11AC_VHT80_80) != 0);
}
static bool init_deinit_vht_160mhz_is_supported(uint32_t vhtcap)
{
return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) != 0);
}
static bool init_deinit_vht_80p80mhz_is_supported(uint32_t vhtcap)
{
return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) != 0);
}
static bool init_deinit_vht_160mhz_shortgi_is_supported(uint32_t vhtcap)
{
return ((vhtcap & WLAN_VHTCAP_SHORTGI_160) != 0);
}
QDF_STATUS init_deinit_validate_160_80p80_fw_caps(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
bool wireless_mode_160mhz = false;
bool wireless_mode_80p80mhz = false;
bool vhtcap_160mhz = false;
bool vhtcap_80p80_160mhz = false;
bool vhtcap_160mhz_sgi = false;
bool valid = false;
struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
void *wmi_handle;
if (!tgt_hdl) {
target_if_err(
"target_psoc_info is null in validate 160n80p80 cap check");
return QDF_STATUS_E_INVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
if ((tgt_hdl->info.target_type == TARGET_TYPE_QCA8074) ||
(tgt_hdl->info.target_type == TARGET_TYPE_QCA6290)) {
/**
* Return true for now. This is not available in
* qca8074 fw yet
*/
return QDF_STATUS_SUCCESS;
}
reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
if (reg_cap == NULL) {
target_if_err("reg cap is NULL");
return QDF_STATUS_E_FAILURE;
}
/* NOTE: Host driver gets vht capability and supported channel
* width / channel frequency range from FW/HALPHY and obeys it.
* Host driver is unaware of any physical filters or any other
* hardware factors that can impact these capabilities.
* These need to be correctly determined by firmware.
*/
/*This table lists all valid and invalid combinations
* WMODE160 WMODE80_80 VHTCAP_160 VHTCAP_80+80_160 IsCombinationvalid?
* 0 0 0 0 YES
* 0 0 0 1 NO
* 0 0 1 0 NO
* 0 0 1 1 NO
* 0 1 0 0 NO
* 0 1 0 1 NO
* 0 1 1 0 NO
* 0 1 1 1 NO
* 1 0 0 0 NO
* 1 0 0 1 NO
* 1 0 1 0 YES
* 1 0 1 1 NO
* 1 1 0 0 NO
* 1 1 0 1 YES
* 1 1 1 0 NO
* 1 1 1 1 NO
*/
/* NOTE: Last row in above table is invalid because value corresponding
* to both VHTCAP_160 and VHTCAP_80+80_160 being set is reserved as per
* 802.11ac. Only one of them can be set at a time.
*/
wireless_mode_160mhz = init_deinit_regdmn_160mhz_support(reg_cap);
wireless_mode_80p80mhz = init_deinit_regdmn_80p80mhz_support(reg_cap);
vhtcap_160mhz = init_deinit_vht_160mhz_is_supported(
tgt_hdl->info.target_caps.vht_cap_info);
vhtcap_80p80_160mhz = init_deinit_vht_80p80mhz_is_supported(
tgt_hdl->info.target_caps.vht_cap_info);
vhtcap_160mhz_sgi = init_deinit_vht_160mhz_shortgi_is_supported(
tgt_hdl->info.target_caps.vht_cap_info);
if (!(wireless_mode_160mhz || wireless_mode_80p80mhz ||
vhtcap_160mhz || vhtcap_80p80_160mhz)) {
valid = QDF_STATUS_SUCCESS;
} else if (wireless_mode_160mhz && !wireless_mode_80p80mhz &&
vhtcap_160mhz && !vhtcap_80p80_160mhz) {
valid = QDF_STATUS_SUCCESS;
} else if (wireless_mode_160mhz && wireless_mode_80p80mhz &&
!vhtcap_160mhz && vhtcap_160mhz_sgi) {
valid = QDF_STATUS_SUCCESS;
}
if (valid == QDF_STATUS_SUCCESS) {
/*
* Ensure short GI for 160 MHz is enabled
* only if 160/80+80 is supported.
*/
if (vhtcap_160mhz_sgi &&
!(vhtcap_160mhz || vhtcap_80p80_160mhz)) {
valid = QDF_STATUS_E_FAILURE;
}
}
/* Invalid config specified by FW */
if (valid != QDF_STATUS_SUCCESS) {
target_if_err("Invalid 160/80+80 MHz config specified by FW. Take care of it first");
target_if_err("wireless_mode_160mhz: %d, wireless_mode_80p80mhz: %d",
wireless_mode_160mhz, wireless_mode_80p80mhz);
target_if_err("vhtcap_160mhz: %d, vhtcap_80p80_160mhz: %d,vhtcap_160mhz_sgi: %d",
vhtcap_160mhz, vhtcap_80p80_160mhz,
vhtcap_160mhz_sgi);
}
return valid;
}
void init_deinit_chainmask_config(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
tgt_hdl->info.wlan_res_cfg.tx_chain_mask =
((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
tgt_hdl->info.wlan_res_cfg.rx_chain_mask =
((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
}
QDF_STATUS init_deinit_is_service_ext_msg(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
void *wmi_handle;
if (!tgt_hdl) {
target_if_err(
"psoc target_psoc_info is null in service ext msg");
return QDF_STATUS_E_INVAL;
}
wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg))
return QDF_STATUS_SUCCESS;
else
return QDF_STATUS_E_FAILURE;
}
bool init_deinit_is_preferred_hw_mode_supported(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
uint16_t i;
struct tgt_info *info;
if (!tgt_hdl) {
target_if_err(
"psoc target_psoc_info is null in service ext msg");
return FALSE;
}
info = &tgt_hdl->info;
for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) {
if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode)
return TRUE;
}
return FALSE;
}
void init_deinit_wakeup_host_wait(
struct wlan_objmgr_psoc *psoc,
struct target_psoc_info *tgt_hdl)
{
if (!tgt_hdl) {
target_if_err("psoc target_psoc_info is null in target ready");
return;
}
qdf_wake_up(&tgt_hdl->info.event_queue);
}

مشاهده پرونده

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
@@ -21,6 +21,8 @@
* DOC: target_if_reg.h
* This file contains regulatory target interface
*/
#ifndef __TARGET_IF_REG_H__
#define __TARGET_IF_REG_H__
/**
* target_if_register_regulatory_tx_ops() - register regulatory tx ops
@@ -38,3 +40,5 @@ QDF_STATUS target_if_register_regulatory_tx_ops(struct wlan_lmac_if_tx_ops
* Return: Success or Failure
*/
QDF_STATUS target_if_reg_set_offloaded_info(struct wlan_objmgr_psoc *psoc);
#endif /* __TARGET_IF_REG_H__ */