diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index cb730ad9ecd8..537f5dec9bda 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -80,6 +80,82 @@ struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev) return plat_env; } +/** + * cnss_get_mem_seg_count - Get segment count of memory + * @type: memory type + * @seg: segment count + * + * Return: 0 on success, negative value on failure + */ +int cnss_get_mem_seg_count(enum cnss_remote_mem_type type, u32 *seg) +{ + struct cnss_plat_data *plat_priv; + + plat_priv = cnss_get_plat_priv(NULL); + if (!plat_priv) + return -ENODEV; + + switch (type) { + case CNSS_REMOTE_MEM_TYPE_FW: + *seg = plat_priv->fw_mem_seg_len; + break; + case CNSS_REMOTE_MEM_TYPE_QDSS: + *seg = plat_priv->qdss_mem_seg_len; + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(cnss_get_mem_seg_count); + +/** + * cnss_get_mem_segment_info - Get memory info of different type + * @type: memory type + * @segment: array to save the segment info + * @seg: segment count + * + * Return: 0 on success, negative value on failure + */ +int cnss_get_mem_segment_info(enum cnss_remote_mem_type type, + struct cnss_mem_segment segment[], + u32 segment_count) +{ + struct cnss_plat_data *plat_priv; + u32 i; + + plat_priv = cnss_get_plat_priv(NULL); + if (!plat_priv) + return -ENODEV; + + switch (type) { + case CNSS_REMOTE_MEM_TYPE_FW: + if (segment_count > plat_priv->fw_mem_seg_len) + segment_count = plat_priv->fw_mem_seg_len; + for (i = 0; i < segment_count; i++) { + segment[i].size = plat_priv->fw_mem[i].size; + segment[i].va = plat_priv->fw_mem[i].va; + segment[i].pa = plat_priv->fw_mem[i].pa; + } + break; + case CNSS_REMOTE_MEM_TYPE_QDSS: + if (segment_count > plat_priv->qdss_mem_seg_len) + segment_count = plat_priv->qdss_mem_seg_len; + for (i = 0; i < segment_count; i++) { + segment[i].size = plat_priv->qdss_mem[i].size; + segment[i].va = plat_priv->qdss_mem[i].va; + segment[i].pa = plat_priv->qdss_mem[i].pa; + } + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(cnss_get_mem_segment_info); + static int cnss_pm_notify(struct notifier_block *b, unsigned long event, void *p) { diff --git a/include/net/cnss2.h b/include/net/cnss2.h index cf05c0b13529..149487b56b06 100644 --- a/include/net/cnss2.h +++ b/include/net/cnss2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _NET_CNSS2_H #define _NET_CNSS2_H @@ -169,6 +169,18 @@ enum cnss_recovery_reason { CNSS_REASON_TIMEOUT, }; +enum cnss_remote_mem_type { + CNSS_REMOTE_MEM_TYPE_FW, + CNSS_REMOTE_MEM_TYPE_QDSS, + CNSS_REMOTE_MEM_TYPE_MAX, +}; + +struct cnss_mem_segment { + size_t size; + void *va; + phys_addr_t pa; +}; + extern int cnss_wlan_register_driver(struct cnss_wlan_driver *driver); extern void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver); extern void cnss_device_crashed(struct device *dev); @@ -241,5 +253,8 @@ extern int cnss_set_fw_log_mode(struct device *dev, uint8_t fw_log_mode); extern int cnss_set_pcie_gen_speed(struct device *dev, u8 pcie_gen_speed); extern int cnss_pci_get_reg_dump(struct device *dev, uint8_t *buffer, uint32_t len); - +extern int cnss_get_mem_seg_count(enum cnss_remote_mem_type type, u32 *seg); +extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type, + struct cnss_mem_segment segment[], + u32 segment_count); #endif /* _NET_CNSS2_H */