ath11k: Add support for sram dump
cover ath11k: Add support for sram dump
From: Baochen Qiang <[email protected]>
On-board sram contains valuable infomation for debug, this patch adds a new interface named "sram" in debugfs with which we can dump sram content using following cmd:
cat /sys/kernel/ath11k/<pdev name>/sram > sram.dump
Baochen Qiang (3):
ath11k: Split PCI write/read functions
ath11k: Move pdev debugfs creation ahead
ath11k: Implement sram dump interface
drivers/net/wireless/ath/ath11k/core.c | 31 +++++--- drivers/net/wireless/ath/ath11k/debugfs.c | 85 +++++++++++++++++++-- drivers/net/wireless/ath/ath11k/debugfs.h | 14 ++++ drivers/net/wireless/ath/ath11k/hif.h | 10 +++ drivers/net/wireless/ath/ath11k/hw.c | 10 +++ drivers/net/wireless/ath/ath11k/hw.h | 8 ++ drivers/net/wireless/ath/ath11k/pci.c | 91 ++++++++++++++++++----- 7 files changed, 214 insertions(+), 35 deletions(-)
Signature · 1 line
2.25.1
PATCH 1/3 ath11k: Split PCI write/read functions
From: Baochen Qiang <[email protected]>
ath11k_pci_write32/read32 tries to wake up MHI before doing actual write/read work, which means each time a u32 is written/read, MHI wake up is performed. This is not necessary in case where we do a large amount of write/read, cause only one time of wake up is needed. So split each one into two parts, the first part does MHI get/put and the second one does actual write/read work.
Also avoid the put operation if the previous get operation fails.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
--- drivers/net/wireless/ath/ath11k/pci.c | 61 ++++++++++++++++++--------- 1 file changed, 42 insertions(+), 19 deletions(-)
drivers/net/wireless/ath/ath11k/pci.c +42 -19
@@ -174,18 +174,11 @@ static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab,return window_start; } -void ath11k_pci_write32 (struct ath11k_base *ab,u32 offset,u32 value) +void ath11k_pci_do_write32 (struct ath11k_base *ab,u32 offset,u32 value) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab);u32 window_start; -/* for offset beyond BAR + 4K - 32, may -* need to wakeup MHI to access. -*/ -if (test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && - offset >=ACCESS_ALWAYS_OFF ) -mhi_device_get_sync (ab_pci->mhi_ctrl->mhi_dev); -if (offset <WINDOW_START ) {iowrite32 (value, ab->mem + offset); }else {
@@ -205,23 +198,33 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) (offset & WINDOW_RANGE_MASK)); } } - -if (test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && - offset >=ACCESS_ALWAYS_OFF ) -mhi_device_put (ab_pci->mhi_ctrl->mhi_dev); } -u32 ath11k_pci_read32 (struct ath11k_base *ab,u32 offset) +void ath11k_pci_write32 (struct ath11k_base *ab,u32 offset,u32 value) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab); -u32 val, window_start; +bool wakeup_required; +int ret;/* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. */ -if (test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && - offset >=ACCESS_ALWAYS_OFF ) -mhi_device_get_sync (ab_pci->mhi_ctrl->mhi_dev); + wakeup_required =test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && + offset >=ACCESS_ALWAYS_OFF ; + +if (wakeup_required) + ret =mhi_device_get_sync (ab_pci->mhi_ctrl->mhi_dev); + +ath11k_pci_do_write32 (ab, offset, value); + +if (wakeup_required && !ret) +mhi_device_put (ab_pci->mhi_ctrl->mhi_dev); +} + +u32 ath11k_pci_do_read32 (struct ath11k_base *ab,u32 offset) +{ +struct ath11k_pci *ab_pci =ath11k_pci_priv (ab); +u32 val, window_start;if (offset <WINDOW_START ) { val =ioread32 (ab->mem + offset);
@@ -243,8 +246,28 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) } } -if (test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && - offset >=ACCESS_ALWAYS_OFF ) +return val; +} + +u32 ath11k_pci_read32 (struct ath11k_base *ab,u32 offset) +{ +struct ath11k_pci *ab_pci =ath11k_pci_priv (ab); +u32 val; +bool wakeup_required; +int ret; + +/* for offset beyond BAR + 4K - 32, may +* need to wakeup MHI to access. +*/ + wakeup_required =test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && + offset >=ACCESS_ALWAYS_OFF ; + +if (wakeup_required) + ret =mhi_device_get_sync (ab_pci->mhi_ctrl->mhi_dev); + + val =ath11k_pci_do_read32 (ab, offset); + +if (wakeup_required && !ret)mhi_device_put (ab_pci->mhi_ctrl->mhi_dev);return val;
Signature · 7 lines
2.25.1 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
Re: [PATCH 1/3] ath11k: Split PCI write/read functions
Quoted 7 lines · Jouni Malinen
ath11k_pci_write32/read32 tries to wake up MHI before doing actual write/read work, which means each time a u32 is written/read, MHI wake up is performed. This is not necessary in case where we do a large amount of write/read, cause only one time of wake up is needed. So split each one into two parts, the first part does MHI get/put and the second one does actual write/read work.
Quoted 8 lines
Also avoid the put operation if the previous get operation fails.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1Signed-off-by Baochen Qiang <[email protected]>Signed-off-by Jouni Malinen <[email protected]>Signed-off-by Kalle Valo <[email protected]>
This causes new warnings:
drivers/net/wireless/ath/ath11k/pci.c:177:6: error: no previous prototype for 'ath11k_pci_do_write32' [-Werror=missing-prototypes] drivers/net/wireless/ath/ath11k/pci.c:224:5: error: no previous prototype for 'ath11k_pci_do_read32' [-Werror=missing-prototypes]
I fixed them in the pending branch like this:
drivers/net/wireless/ath/ath11k/pci.c +2 -2
@@ -174,7 +174,7 @@ static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab,return window_start; } -void ath11k_pci_do_write32 (struct ath11k_base *ab,u32 offset,u32 value) +static void ath11k_pci_do_write32 (struct ath11k_base *ab,u32 offset,u32 value) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab);u32 window_start;
@@ -221,7 +221,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)mhi_device_put (ab_pci->mhi_ctrl->mhi_dev); } -u32 ath11k_pci_do_read32 (struct ath11k_base *ab,u32 offset) +static u32 ath11k_pci_do_read32 (struct ath11k_base *ab,u32 offset) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab);u32 val, window_start;
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH 1/3] ath11k: Split PCI write/read functions
In reply to Jouni MalinenQuoted 7 lines · Jouni Malinen
ath11k_pci_write32/read32 tries to wake up MHI before doing actual write/read work, which means each time a u32 is written/read, MHI wake up is performed. This is not necessary in case where we do a large amount of write/read, cause only one time of wake up is needed. So split each one into two parts, the first part does MHI get/put and the second one does actual write/read work.
Quoted 8 lines
Also avoid the put operation if the previous get operation fails.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1Signed-off-by Baochen Qiang <[email protected]>Signed-off-by Jouni Malinen <[email protected]>Signed-off-by Kalle Valo <[email protected]>
This causes new warnings:
drivers/net/wireless/ath/ath11k/pci.c:177:6: error: no previous prototype for 'ath11k_pci_do_write32' [-Werror=missing-prototypes] drivers/net/wireless/ath/ath11k/pci.c:224:5: error: no previous prototype for 'ath11k_pci_do_read32' [-Werror=missing-prototypes]
I fixed them in the pending branch like this:
drivers/net/wireless/ath/ath11k/pci.c +2 -2
@@ -174,7 +174,7 @@ static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab,return window_start; } -void ath11k_pci_do_write32 (struct ath11k_base *ab,u32 offset,u32 value) +static void ath11k_pci_do_write32 (struct ath11k_base *ab,u32 offset,u32 value) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab);u32 window_start;
@@ -221,7 +221,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)mhi_device_put (ab_pci->mhi_ctrl->mhi_dev); } -u32 ath11k_pci_do_read32 (struct ath11k_base *ab,u32 offset) +static u32 ath11k_pci_do_read32 (struct ath11k_base *ab,u32 offset) {struct ath11k_pci *ab_pci =ath11k_pci_priv (ab);u32 val, window_start;
Signature · 9 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
PATCH 2/3 ath11k: Move pdev debugfs creation ahead
In reply to Jouni MalinenFrom: Baochen Qiang <[email protected]>
The sram dump debugfs interface has to be put under pdev directory located under /sys/kernel/debug/ath11k/<pdev name>. Currently pdev directory is created after firmware is ready, this is too late for sram dump. Suppose that if errors happen and ath11k fails to reach firmware ready, we have no way to dump sram content to debug cause the interface has not been created yet. So move it ahead.
Also move pdev debugfs destroy to ath11k_core_soc_destroy as a mirror.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
--- drivers/net/wireless/ath/ath11k/core.c | 23 +++++++++++++---------- drivers/net/wireless/ath/ath11k/debugfs.c | 21 +++++++++++++++------ drivers/net/wireless/ath/ath11k/debugfs.h | 9 +++++++++ 3 files changed, 37 insertions(+), 16 deletions(-)
drivers/net/wireless/ath/ath11k/core.c +13 -10
@@ -701,14 +701,22 @@ static int ath11k_core_soc_create(struct ath11k_base *ab) goto err_qmi_deinit; } + ret =ath11k_debugfs_pdev_create (ab); +if (ret) { +ath11k_err (ab,"failed to create core pdev debugfs: %d\n" , ret); + goto err_debugfs_reg; + } + ret =ath11k_hif_power_up (ab);if (ret) {ath11k_err (ab,"failed to power up :%d\n" , ret); - goto err_debugfs_reg; + goto err_pdev_debug; }return 0 ; +err_pdev_debug: +ath11k_debugfs_pdev_destroy (ab); err_debugfs_reg:ath11k_debugfs_soc_destroy (ab); err_qmi_deinit:
@@ -718,6 +726,7 @@ static int ath11k_core_soc_create(struct ath11k_base *ab)static void ath11k_core_soc_destroy (struct ath11k_base *ab) { +ath11k_debugfs_pdev_destroy (ab);ath11k_debugfs_soc_destroy (ab);ath11k_dp_free (ab);ath11k_reg_free (ab);
@@ -728,16 +737,13 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) {int ret; - ret =ath11k_debugfs_pdev_create (ab); -if (ret) { -ath11k_err (ab,"failed to create core pdev debugfs: %d\n" , ret); -return ret; - } +ath11k_debugfs_crash_trigger_create (ab); +ath11k_debugfs_dp_stats_create (ab); ret =ath11k_mac_register (ab);if (ret) {ath11k_err (ab,"failed register the radio with mac80211: %d\n" , ret); - goto err_pdev_debug; +return ret; } ret =ath11k_dp_pdev_alloc (ab);
@@ -767,8 +773,6 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)ath11k_dp_pdev_free (ab); err_mac_unregister:ath11k_mac_unregister (ab); -err_pdev_debug: -ath11k_debugfs_pdev_destroy (ab);return ret; }
@@ -780,7 +784,6 @@ static void ath11k_core_pdev_destroy(struct ath11k_base *ab)ath11k_mac_unregister (ab);ath11k_hif_irq_disable (ab);ath11k_dp_pdev_free (ab); -ath11k_debugfs_pdev_destroy (ab); } static int ath11k_core_start(struct ath11k_base *ab,
drivers/net/wireless/ath/ath11k/debugfs.c +15 -6
@@ -831,20 +831,29 @@ static const struct file_operations fops_soc_dp_stats = { .llseek = default_llseek, }; -int ath11k_debugfs_pdev_create (struct ath11k_base *ab) +void ath11k_debugfs_crash_trigger_create (struct ath11k_base *ab) {if (test_bit (ATH11K_FLAG_REGISTERED , &ab->dev_flags)) -return 0 ; - - ab->debugfs_soc =debugfs_create_dir (ab->hw_params.name, ab->debugfs_ath11k); -if (IS_ERR (ab->debugfs_soc)) -return PTR_ERR (ab->debugfs_soc); +return ;debugfs_create_file ("simulate_fw_crash" ,0600 , ab->debugfs_soc, ab, &fops_simulate_fw_crash); +} + +void ath11k_debugfs_dp_stats_create (struct ath11k_base *ab) +{ +if (test_bit (ATH11K_FLAG_REGISTERED , &ab->dev_flags)) +return ;debugfs_create_file ("soc_dp_stats" ,0600 , ab->debugfs_soc, ab, &fops_soc_dp_stats); +} + +int ath11k_debugfs_pdev_create (struct ath11k_base *ab) +{ + ab->debugfs_soc =debugfs_create_dir (ab->hw_params.name, ab->debugfs_ath11k); +if (IS_ERR (ab->debugfs_soc)) +return PTR_ERR (ab->debugfs_soc);return 0 ; }
drivers/net/wireless/ath/ath11k/debugfs.h +9 -0
@@ -145,6 +145,8 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar) return ar->debug.rx_filter; } +void ath11k_debugfs_crash_trigger_create (struct ath11k_base *ab); +void ath11k_debugfs_dp_stats_create (struct ath11k_base *ab);#else static inline int ath11k_debugfs_soc_create (struct ath11k_base *ab) {
@@ -212,6 +214,13 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)return 0 ; } +static inline void ath11k_debugfs_crash_trigger_create (struct ath11k_base *ab) +{ +} + +static inline void ath11k_debugfs_dp_stats_create (struct ath11k_base *ab) +{ +}#endif /* CONFIG_MAC80211_DEBUGFS*/ #endif /* _ATH11K_DEBUGFS_H_ */
Signature · 7 lines
2.25.1 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k
Re: [PATCH 2/3] ath11k: Move pdev debugfs creation ahead
Quoted 8 lines · Jouni Malinen
From: Baochen Qiang <[email protected]>
The sram dump debugfs interface has to be put under pdev directory located under /sys/kernel/debug/ath11k/<pdev name>. Currently pdev directory is created after firmware is ready, this is too late for sram dump. Suppose that if errors happen and ath11k fails to reach firmware ready, we have no way to dump sram content to debug cause the interface has not been created yet. So move it ahead.
I'm not sure about this. What will happen with other debugfs files now that they are created before the firmware is ready, doesn't that create race conditions?
Also we need to do some refactoring in debugfs, for example see Anil's patch:
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
So I recommend dropping patch 2 for now and get the basic sram dump functionality ready first. After that we can discuss how to handle firmware crashes during driver initialisation, maybe coredump would be a better approach?
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH 2/3] ath11k: Move pdev debugfs creation ahead
Quoted 18 lines · Kalle Valo
Quoted 8 lines · Jouni Malinen
From: Baochen Qiang <[email protected]>
The sram dump debugfs interface has to be put under pdev directory located under /sys/kernel/debug/ath11k/<pdev name>. Currently pdev directory is created after firmware is ready, this is too late for sram dump. Suppose that if errors happen and ath11k fails to reach firmware ready, we have no way to dump sram content to debug cause the interface has not been created yet. So move it ahead.
I'm not sure about this. What will happen with other debugfs files now that they are created before the firmware is ready, doesn't that create race conditions?
Also we need to do some refactoring in debugfs, for example see Anil's patch:
Quoted 6 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
So I recommend dropping patch 2 for now and get the basic sram dump functionality ready first. After that we can discuss how to handle firmware crashes during driver initialisation, maybe coredump would be a better approach?
Sure, Kalle, let's get basic functionality ready first.
PATCH 3/3 ath11k: Implement sram dump interface
In reply to Jouni MalinenFrom: Baochen Qiang <[email protected]>
Currently this feature is enabled for QCA6390/WCN6855.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
--- drivers/net/wireless/ath/ath11k/core.c | 8 +++ drivers/net/wireless/ath/ath11k/debugfs.c | 64 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/debugfs.h | 5 ++ drivers/net/wireless/ath/ath11k/hif.h | 10 ++++ drivers/net/wireless/ath/ath11k/hw.c | 10 ++++ drivers/net/wireless/ath/ath11k/hw.h | 8 +++ drivers/net/wireless/ath/ath11k/pci.c | 30 +++++++++++ 7 files changed, 135 insertions(+)
drivers/net/wireless/ath/ath11k/core.c +8 -0
@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .sram_dump = NULL, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = false, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .sram_dump = NULL, }, { .name = "qca6390 hw2.0",
@@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, + .sram_dump = &sram_dump_qca6390, }, { .name = "qcn9074 hw1.0",
@@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_mem_mode = 2, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .fix_l1ss = true, + .sram_dump = NULL, }, { .name = "wcn6855 hw2.0",
@@ -269,6 +273,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_mem_mode = 0, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .fix_l1ss = false, + .sram_dump = &sram_dump_wcn6855, }, };
@@ -707,6 +712,9 @@ static int ath11k_core_soc_create(struct ath11k_base *ab) goto err_debugfs_reg; } +if (ab->hw_params.sram_dump) +ath11k_debugfs_sram_dump_create (ab); + ret =ath11k_hif_power_up (ab);if (ret) {ath11k_err (ab,"failed to power up :%d\n" , ret);
drivers/net/wireless/ath/ath11k/debugfs.c +64 -0
73 lines not on this page · raw message
drivers/net/wireless/ath/ath11k/debugfs.h +5 -0
@@ -147,6 +147,7 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)void ath11k_debugfs_crash_trigger_create (struct ath11k_base *ab);void ath11k_debugfs_dp_stats_create (struct ath11k_base *ab); +void ath11k_debugfs_sram_dump_create (struct ath11k_base *ab);#else static inline int ath11k_debugfs_soc_create (struct ath11k_base *ab) {
@@ -221,6 +222,10 @@ static inline void ath11k_debugfs_crash_trigger_create(struct ath11k_base *ab)static inline void ath11k_debugfs_dp_stats_create (struct ath11k_base *ab) { } + +static inline void ath11k_debugfs_sram_dump_create (struct ath11k_base *ab) +{ +}#endif /* CONFIG_MAC80211_DEBUGFS*/ #endif /* _ATH11K_DEBUGFS_H_ */
drivers/net/wireless/ath/ath11k/hif.h +10 -0
@@ -29,6 +29,7 @@ struct ath11k_hif_ops {void (*ce_irq_enable)(struct ath11k_base *ab);void (*ce_irq_disable)(struct ath11k_base *ab);void (*get_ce_msi_idx)(struct ath11k_base *ab,u32 ce_id,u32 *msi_idx); +int (*dump_sram)(struct ath11k_base *ab,u8 *buf,u32 start,u32 end); };static inline void ath11k_hif_ce_irq_enable (struct ath11k_base *ab)
@@ -134,4 +135,13 @@ static inline void ath11k_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id, else *msi_data_idx = ce_id; } + +static inline int ath11k_hif_dump_sram (struct ath11k_base *ab,u8 *buf, +u32 start,u32 end) +{ +if (!ab->hif.ops->dump_sram) +return -EOPNOTSUPP ; + +return ab->hif.ops->dump_sram (ab, buf, start, end); +}#endif /* _HIF_H_ */
drivers/net/wireless/ath/ath11k/hw.c +10 -0
@@ -2124,3 +2124,13 @@ const struct ath11k_hw_regs wcn6855_regs = { .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_pcs_osc_dtct_config_base = 0x01e0c628, }; + +const struct ath11k_hw_sram_dump sram_dump_qca6390 = { + .start =0x01400000 , + .end =0x0171ffff , +}; + +const struct ath11k_hw_sram_dump sram_dump_wcn6855 = { + .start =0x01400000 , + .end =0x0177ffff , +};
drivers/net/wireless/ath/ath11k/hw.h +8 -0
@@ -120,6 +120,11 @@ struct ath11k_hw_ring_mask {u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX ]; }; +struct ath11k_hw_sram_dump { +u32 start; +u32 end; +}; +struct ath11k_hw_params {const char *name;u16 hw_rev;
@@ -173,6 +178,7 @@ struct ath11k_hw_params {bool supports_suspend;u32 hal_desc_sz;bool fix_l1ss; +const struct ath11k_hw_sram_dump *sram_dump; };struct ath11k_hw_ops {
@@ -336,4 +342,6 @@ extern const struct ath11k_hw_regs qca6390_regs;extern const struct ath11k_hw_regs qcn9074_regs;extern const struct ath11k_hw_regs wcn6855_regs; +extern const struct ath11k_hw_sram_dump sram_dump_qca6390; +extern const struct ath11k_hw_sram_dump sram_dump_wcn6855;#endif
drivers/net/wireless/ath/ath11k/pci.c +30 -0
@@ -273,6 +273,35 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)return val; } +static int ath11k_pci_dump_sram (struct ath11k_base *ab,u8 *buf, +u32 start,u32 end) +{ +struct ath11k_pci *ab_pci =ath11k_pci_priv (ab); +u32 i; +int ret; +bool wakeup_required; +u32 *data = (u32 *)buf; + +/* for offset beyond BAR + 4K - 32, may +* need to wakeup MHI to access. +*/ + wakeup_required =test_bit (ATH11K_PCI_FLAG_INIT_DONE , &ab_pci->flags) && + end >=ACCESS_ALWAYS_OFF ; +if (wakeup_required) { + ret =mhi_device_get_sync (ab_pci->mhi_ctrl->mhi_dev); +if (ret) +ath11k_warn (ab,"%s: failed to wakeup MHI: %d\n" , __func__, ret); + } + +for (i = start; i < end +1 ; i +=4 ) + *data++ =ath11k_pci_do_read32 (ab, i); + +if (wakeup_required && !ret) +mhi_device_put (ab_pci->mhi_ctrl->mhi_dev); + +return 0 ; +} +static void ath11k_pci_soc_global_reset (struct ath11k_base *ab) {u32 val, delay;
@@ -1213,6 +1242,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = { .ce_irq_enable = ath11k_pci_hif_ce_irq_enable, .ce_irq_disable = ath11k_pci_hif_ce_irq_disable, .get_ce_msi_idx = ath11k_pci_get_ce_msi_idx, + .dump_sram = ath11k_pci_dump_sram, };static void ath11k_pci_read_hw_version (struct ath11k_base *ab,u32 *major,u32 *minor)
Signature · 1 line
2.25.1