2 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <linux/devcoredump.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/utsname.h>
28 static const struct ath10k_mem_section qca6174_hw21_register_sections
[] = {
284 static const struct ath10k_mem_section qca6174_hw30_register_sections
[] = {
540 static const struct ath10k_mem_region qca6174_hw10_mem_regions
[] = {
542 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
552 .type
= ATH10K_MEM_REGION_TYPE_REG
,
554 /* RTC_SOC_BASE_ADDRESS */
557 /* WLAN_MBOX_BASE_ADDRESS - RTC_SOC_BASE_ADDRESS */
567 .type
= ATH10K_MEM_REGION_TYPE_REG
,
569 /* STEREO_BASE_ADDRESS */
572 /* USB_BASE_ADDRESS - STEREO_BASE_ADDRESS */
573 .len
= 0x60000 - 0x27000,
583 static const struct ath10k_mem_region qca6174_hw21_mem_regions
[] = {
585 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
595 .type
= ATH10K_MEM_REGION_TYPE_AXI
,
605 .type
= ATH10K_MEM_REGION_TYPE_REG
,
607 .len
= 0x80020 - 0x800,
610 .sections
= qca6174_hw21_register_sections
,
611 .size
= ARRAY_SIZE(qca6174_hw21_register_sections
),
616 static const struct ath10k_mem_region qca6174_hw30_mem_regions
[] = {
618 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
628 .type
= ATH10K_MEM_REGION_TYPE_AXI
,
638 .type
= ATH10K_MEM_REGION_TYPE_REG
,
640 .len
= 0x80020 - 0x800,
643 .sections
= qca6174_hw30_register_sections
,
644 .size
= ARRAY_SIZE(qca6174_hw30_register_sections
),
648 /* IRAM dump must be put last */
650 .type
= ATH10K_MEM_REGION_TYPE_IRAM1
,
660 .type
= ATH10K_MEM_REGION_TYPE_IRAM2
,
671 static const struct ath10k_mem_region qca988x_hw20_mem_regions
[] = {
673 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
683 .type
= ATH10K_MEM_REGION_TYPE_REG
,
693 .type
= ATH10K_MEM_REGION_TYPE_REG
,
704 static const struct ath10k_hw_mem_layout hw_mem_layouts
[] = {
706 .hw_id
= QCA6174_HW_1_0_VERSION
,
708 .regions
= qca6174_hw10_mem_regions
,
709 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
713 .hw_id
= QCA6174_HW_1_1_VERSION
,
715 .regions
= qca6174_hw10_mem_regions
,
716 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
720 .hw_id
= QCA6174_HW_1_3_VERSION
,
722 .regions
= qca6174_hw10_mem_regions
,
723 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
727 .hw_id
= QCA6174_HW_2_1_VERSION
,
729 .regions
= qca6174_hw21_mem_regions
,
730 .size
= ARRAY_SIZE(qca6174_hw21_mem_regions
),
734 .hw_id
= QCA6174_HW_3_0_VERSION
,
736 .regions
= qca6174_hw30_mem_regions
,
737 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
741 .hw_id
= QCA6174_HW_3_2_VERSION
,
743 .regions
= qca6174_hw30_mem_regions
,
744 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
748 .hw_id
= QCA9377_HW_1_1_DEV_VERSION
,
750 .regions
= qca6174_hw30_mem_regions
,
751 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
755 .hw_id
= QCA988X_HW_2_0_VERSION
,
757 .regions
= qca988x_hw20_mem_regions
,
758 .size
= ARRAY_SIZE(qca988x_hw20_mem_regions
),
763 static u32
ath10k_coredump_get_ramdump_size(struct ath10k
*ar
)
765 const struct ath10k_hw_mem_layout
*hw
;
766 const struct ath10k_mem_region
*mem_region
;
770 hw
= ath10k_coredump_get_mem_layout(ar
);
775 mem_region
= &hw
->region_table
.regions
[0];
777 for (i
= 0; i
< hw
->region_table
.size
; i
++) {
778 size
+= mem_region
->len
;
782 /* reserve space for the headers */
783 size
+= hw
->region_table
.size
* sizeof(struct ath10k_dump_ram_data_hdr
);
785 /* make sure it is aligned 16 bytes for debug message print out */
786 size
= ALIGN(size
, 16);
791 const struct ath10k_hw_mem_layout
*ath10k_coredump_get_mem_layout(struct ath10k
*ar
)
795 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
))
798 if (WARN_ON(ar
->target_version
== 0))
801 for (i
= 0; i
< ARRAY_SIZE(hw_mem_layouts
); i
++) {
802 if (ar
->target_version
== hw_mem_layouts
[i
].hw_id
)
803 return &hw_mem_layouts
[i
];
808 EXPORT_SYMBOL(ath10k_coredump_get_mem_layout
);
810 struct ath10k_fw_crash_data
*ath10k_coredump_new(struct ath10k
*ar
)
812 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
814 lockdep_assert_held(&ar
->data_lock
);
816 if (ath10k_coredump_mask
== 0)
817 /* coredump disabled */
820 guid_gen(&crash_data
->guid
);
821 ktime_get_real_ts64(&crash_data
->timestamp
);
825 EXPORT_SYMBOL(ath10k_coredump_new
);
827 static struct ath10k_dump_file_data
*ath10k_coredump_build(struct ath10k
*ar
)
829 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
830 struct ath10k_ce_crash_hdr
*ce_hdr
;
831 struct ath10k_dump_file_data
*dump_data
;
832 struct ath10k_tlv_dump_data
*dump_tlv
;
833 size_t hdr_len
= sizeof(*dump_data
);
834 size_t len
, sofar
= 0;
839 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS
, &ath10k_coredump_mask
))
840 len
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
842 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA
, &ath10k_coredump_mask
))
843 len
+= sizeof(*dump_tlv
) + sizeof(*ce_hdr
) +
844 CE_COUNT
* sizeof(ce_hdr
->entries
[0]);
846 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
))
847 len
+= sizeof(*dump_tlv
) + crash_data
->ramdump_buf_len
;
851 /* This is going to get big when we start dumping FW RAM and such,
852 * so go ahead and use vmalloc.
858 spin_lock_bh(&ar
->data_lock
);
860 dump_data
= (struct ath10k_dump_file_data
*)(buf
);
861 strlcpy(dump_data
->df_magic
, "ATH10K-FW-DUMP",
862 sizeof(dump_data
->df_magic
));
863 dump_data
->len
= cpu_to_le32(len
);
865 dump_data
->version
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION
);
867 guid_copy(&dump_data
->guid
, &crash_data
->guid
);
868 dump_data
->chip_id
= cpu_to_le32(ar
->chip_id
);
869 dump_data
->bus_type
= cpu_to_le32(0);
870 dump_data
->target_version
= cpu_to_le32(ar
->target_version
);
871 dump_data
->fw_version_major
= cpu_to_le32(ar
->fw_version_major
);
872 dump_data
->fw_version_minor
= cpu_to_le32(ar
->fw_version_minor
);
873 dump_data
->fw_version_release
= cpu_to_le32(ar
->fw_version_release
);
874 dump_data
->fw_version_build
= cpu_to_le32(ar
->fw_version_build
);
875 dump_data
->phy_capability
= cpu_to_le32(ar
->phy_capability
);
876 dump_data
->hw_min_tx_power
= cpu_to_le32(ar
->hw_min_tx_power
);
877 dump_data
->hw_max_tx_power
= cpu_to_le32(ar
->hw_max_tx_power
);
878 dump_data
->ht_cap_info
= cpu_to_le32(ar
->ht_cap_info
);
879 dump_data
->vht_cap_info
= cpu_to_le32(ar
->vht_cap_info
);
880 dump_data
->num_rf_chains
= cpu_to_le32(ar
->num_rf_chains
);
882 strlcpy(dump_data
->fw_ver
, ar
->hw
->wiphy
->fw_version
,
883 sizeof(dump_data
->fw_ver
));
885 dump_data
->kernel_ver_code
= 0;
886 strlcpy(dump_data
->kernel_ver
, init_utsname()->release
,
887 sizeof(dump_data
->kernel_ver
));
889 dump_data
->tv_sec
= cpu_to_le64(crash_data
->timestamp
.tv_sec
);
890 dump_data
->tv_nsec
= cpu_to_le64(crash_data
->timestamp
.tv_nsec
);
892 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS
, &ath10k_coredump_mask
)) {
893 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
894 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS
);
895 dump_tlv
->tlv_len
= cpu_to_le32(sizeof(crash_data
->registers
));
896 memcpy(dump_tlv
->tlv_data
, &crash_data
->registers
,
897 sizeof(crash_data
->registers
));
898 sofar
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
901 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA
, &ath10k_coredump_mask
)) {
902 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
903 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA
);
904 dump_tlv
->tlv_len
= cpu_to_le32(sizeof(*ce_hdr
) +
905 CE_COUNT
* sizeof(ce_hdr
->entries
[0]));
906 ce_hdr
= (struct ath10k_ce_crash_hdr
*)(dump_tlv
->tlv_data
);
907 ce_hdr
->ce_count
= cpu_to_le32(CE_COUNT
);
908 memset(ce_hdr
->reserved
, 0, sizeof(ce_hdr
->reserved
));
909 memcpy(ce_hdr
->entries
, crash_data
->ce_crash_data
,
910 CE_COUNT
* sizeof(ce_hdr
->entries
[0]));
911 sofar
+= sizeof(*dump_tlv
) + sizeof(*ce_hdr
) +
912 CE_COUNT
* sizeof(ce_hdr
->entries
[0]);
915 /* Gather ram dump */
916 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
)) {
917 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
918 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA
);
919 dump_tlv
->tlv_len
= cpu_to_le32(crash_data
->ramdump_buf_len
);
920 memcpy(dump_tlv
->tlv_data
, crash_data
->ramdump_buf
,
921 crash_data
->ramdump_buf_len
);
922 sofar
+= sizeof(*dump_tlv
) + crash_data
->ramdump_buf_len
;
925 spin_unlock_bh(&ar
->data_lock
);
930 int ath10k_coredump_submit(struct ath10k
*ar
)
932 struct ath10k_dump_file_data
*dump
;
934 if (ath10k_coredump_mask
== 0)
935 /* coredump disabled */
938 dump
= ath10k_coredump_build(ar
);
940 ath10k_warn(ar
, "no crash dump data found for devcoredump");
944 dev_coredumpv(ar
->dev
, dump
, le32_to_cpu(dump
->len
), GFP_KERNEL
);
949 int ath10k_coredump_create(struct ath10k
*ar
)
951 if (ath10k_coredump_mask
== 0)
952 /* coredump disabled */
955 ar
->coredump
.fw_crash_data
= vzalloc(sizeof(*ar
->coredump
.fw_crash_data
));
956 if (!ar
->coredump
.fw_crash_data
)
962 int ath10k_coredump_register(struct ath10k
*ar
)
964 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
966 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
)) {
967 crash_data
->ramdump_buf_len
= ath10k_coredump_get_ramdump_size(ar
);
969 crash_data
->ramdump_buf
= vzalloc(crash_data
->ramdump_buf_len
);
970 if (!crash_data
->ramdump_buf
)
977 void ath10k_coredump_unregister(struct ath10k
*ar
)
979 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
981 vfree(crash_data
->ramdump_buf
);
984 void ath10k_coredump_destroy(struct ath10k
*ar
)
986 if (ar
->coredump
.fw_crash_data
->ramdump_buf
) {
987 vfree(ar
->coredump
.fw_crash_data
->ramdump_buf
);
988 ar
->coredump
.fw_crash_data
->ramdump_buf
= NULL
;
989 ar
->coredump
.fw_crash_data
->ramdump_buf_len
= 0;
992 vfree(ar
->coredump
.fw_crash_data
);
993 ar
->coredump
.fw_crash_data
= NULL
;