1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
9 #include <linux/devcoredump.h>
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12 #include <linux/utsname.h>
17 static const struct ath10k_mem_section qca6174_hw21_register_sections
[] = {
273 static const struct ath10k_mem_section qca6174_hw30_register_sections
[] = {
529 static const struct ath10k_mem_region qca6174_hw10_mem_regions
[] = {
531 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
541 .type
= ATH10K_MEM_REGION_TYPE_REG
,
543 /* RTC_SOC_BASE_ADDRESS */
546 /* WLAN_MBOX_BASE_ADDRESS - RTC_SOC_BASE_ADDRESS */
556 .type
= ATH10K_MEM_REGION_TYPE_REG
,
558 /* STEREO_BASE_ADDRESS */
561 /* USB_BASE_ADDRESS - STEREO_BASE_ADDRESS */
562 .len
= 0x60000 - 0x27000,
572 static const struct ath10k_mem_region qca6174_hw21_mem_regions
[] = {
574 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
584 .type
= ATH10K_MEM_REGION_TYPE_AXI
,
594 .type
= ATH10K_MEM_REGION_TYPE_REG
,
596 .len
= 0x80020 - 0x800,
599 .sections
= qca6174_hw21_register_sections
,
600 .size
= ARRAY_SIZE(qca6174_hw21_register_sections
),
605 static const struct ath10k_mem_region qca6174_hw30_mem_regions
[] = {
607 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
617 .type
= ATH10K_MEM_REGION_TYPE_AXI
,
627 .type
= ATH10K_MEM_REGION_TYPE_REG
,
629 .len
= 0x80020 - 0x800,
632 .sections
= qca6174_hw30_register_sections
,
633 .size
= ARRAY_SIZE(qca6174_hw30_register_sections
),
637 /* IRAM dump must be put last */
639 .type
= ATH10K_MEM_REGION_TYPE_IRAM1
,
649 .type
= ATH10K_MEM_REGION_TYPE_IRAM2
,
660 static const struct ath10k_mem_region qca988x_hw20_mem_regions
[] = {
662 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
672 .type
= ATH10K_MEM_REGION_TYPE_REG
,
682 .type
= ATH10K_MEM_REGION_TYPE_REG
,
693 static const struct ath10k_mem_region qca99x0_hw20_mem_regions
[] = {
695 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
705 .type
= ATH10K_MEM_REGION_TYPE_REG
,
715 .type
= ATH10K_MEM_REGION_TYPE_IOSRAM
,
725 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
735 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
745 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
755 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
765 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
776 static const struct ath10k_mem_region qca9984_hw10_mem_regions
[] = {
778 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
788 .type
= ATH10K_MEM_REGION_TYPE_REG
,
798 .type
= ATH10K_MEM_REGION_TYPE_IOSRAM
,
808 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
818 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
828 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
838 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
848 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
859 static const struct ath10k_mem_section ipq4019_soc_reg_range
[] = {
860 {0x080000, 0x080004},
861 {0x080020, 0x080024},
862 {0x080028, 0x080050},
863 {0x0800d4, 0x0800ec},
864 {0x08010c, 0x080118},
865 {0x080284, 0x080290},
866 {0x0802a8, 0x0802b8},
867 {0x0802dc, 0x08030c},
871 static const struct ath10k_mem_region qca4019_hw10_mem_regions
[] = {
873 .type
= ATH10K_MEM_REGION_TYPE_DRAM
,
883 .type
= ATH10K_MEM_REGION_TYPE_REG
,
893 .type
= ATH10K_MEM_REGION_TYPE_REG
,
903 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
913 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
923 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
933 .type
= ATH10K_MEM_REGION_TYPE_IOREG
,
943 .type
= ATH10K_MEM_REGION_TYPE_REG
,
945 .len
= 0x083fff - 0x080000,
948 .sections
= ipq4019_soc_reg_range
,
949 .size
= ARRAY_SIZE(ipq4019_soc_reg_range
),
954 static const struct ath10k_hw_mem_layout hw_mem_layouts
[] = {
956 .hw_id
= QCA6174_HW_1_0_VERSION
,
957 .hw_rev
= ATH10K_HW_QCA6174
,
959 .regions
= qca6174_hw10_mem_regions
,
960 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
964 .hw_id
= QCA6174_HW_1_1_VERSION
,
965 .hw_rev
= ATH10K_HW_QCA6174
,
967 .regions
= qca6174_hw10_mem_regions
,
968 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
972 .hw_id
= QCA6174_HW_1_3_VERSION
,
973 .hw_rev
= ATH10K_HW_QCA6174
,
975 .regions
= qca6174_hw10_mem_regions
,
976 .size
= ARRAY_SIZE(qca6174_hw10_mem_regions
),
980 .hw_id
= QCA6174_HW_2_1_VERSION
,
981 .hw_rev
= ATH10K_HW_QCA6174
,
983 .regions
= qca6174_hw21_mem_regions
,
984 .size
= ARRAY_SIZE(qca6174_hw21_mem_regions
),
988 .hw_id
= QCA6174_HW_3_0_VERSION
,
989 .hw_rev
= ATH10K_HW_QCA6174
,
991 .regions
= qca6174_hw30_mem_regions
,
992 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
996 .hw_id
= QCA6174_HW_3_2_VERSION
,
997 .hw_rev
= ATH10K_HW_QCA6174
,
999 .regions
= qca6174_hw30_mem_regions
,
1000 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
1004 .hw_id
= QCA9377_HW_1_1_DEV_VERSION
,
1005 .hw_rev
= ATH10K_HW_QCA9377
,
1007 .regions
= qca6174_hw30_mem_regions
,
1008 .size
= ARRAY_SIZE(qca6174_hw30_mem_regions
),
1012 .hw_id
= QCA988X_HW_2_0_VERSION
,
1013 .hw_rev
= ATH10K_HW_QCA988X
,
1015 .regions
= qca988x_hw20_mem_regions
,
1016 .size
= ARRAY_SIZE(qca988x_hw20_mem_regions
),
1020 .hw_id
= QCA9984_HW_1_0_DEV_VERSION
,
1021 .hw_rev
= ATH10K_HW_QCA9984
,
1023 .regions
= qca9984_hw10_mem_regions
,
1024 .size
= ARRAY_SIZE(qca9984_hw10_mem_regions
),
1028 .hw_id
= QCA9888_HW_2_0_DEV_VERSION
,
1029 .hw_rev
= ATH10K_HW_QCA9888
,
1031 .regions
= qca9984_hw10_mem_regions
,
1032 .size
= ARRAY_SIZE(qca9984_hw10_mem_regions
),
1036 .hw_id
= QCA99X0_HW_2_0_DEV_VERSION
,
1037 .hw_rev
= ATH10K_HW_QCA99X0
,
1039 .regions
= qca99x0_hw20_mem_regions
,
1040 .size
= ARRAY_SIZE(qca99x0_hw20_mem_regions
),
1044 .hw_id
= QCA4019_HW_1_0_DEV_VERSION
,
1045 .hw_rev
= ATH10K_HW_QCA4019
,
1047 .regions
= qca4019_hw10_mem_regions
,
1048 .size
= ARRAY_SIZE(qca4019_hw10_mem_regions
),
1053 static u32
ath10k_coredump_get_ramdump_size(struct ath10k
*ar
)
1055 const struct ath10k_hw_mem_layout
*hw
;
1056 const struct ath10k_mem_region
*mem_region
;
1060 hw
= ath10k_coredump_get_mem_layout(ar
);
1065 mem_region
= &hw
->region_table
.regions
[0];
1067 for (i
= 0; i
< hw
->region_table
.size
; i
++) {
1068 size
+= mem_region
->len
;
1072 /* reserve space for the headers */
1073 size
+= hw
->region_table
.size
* sizeof(struct ath10k_dump_ram_data_hdr
);
1075 /* make sure it is aligned 16 bytes for debug message print out */
1076 size
= ALIGN(size
, 16);
1081 const struct ath10k_hw_mem_layout
*ath10k_coredump_get_mem_layout(struct ath10k
*ar
)
1085 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
))
1088 if (WARN_ON(ar
->target_version
== 0))
1091 for (i
= 0; i
< ARRAY_SIZE(hw_mem_layouts
); i
++) {
1092 if (ar
->target_version
== hw_mem_layouts
[i
].hw_id
&&
1093 ar
->hw_rev
== hw_mem_layouts
[i
].hw_rev
)
1094 return &hw_mem_layouts
[i
];
1099 EXPORT_SYMBOL(ath10k_coredump_get_mem_layout
);
1101 struct ath10k_fw_crash_data
*ath10k_coredump_new(struct ath10k
*ar
)
1103 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
1105 lockdep_assert_held(&ar
->dump_mutex
);
1107 if (ath10k_coredump_mask
== 0)
1108 /* coredump disabled */
1111 guid_gen(&crash_data
->guid
);
1112 ktime_get_real_ts64(&crash_data
->timestamp
);
1116 EXPORT_SYMBOL(ath10k_coredump_new
);
1118 static struct ath10k_dump_file_data
*ath10k_coredump_build(struct ath10k
*ar
)
1120 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
1121 struct ath10k_ce_crash_hdr
*ce_hdr
;
1122 struct ath10k_dump_file_data
*dump_data
;
1123 struct ath10k_tlv_dump_data
*dump_tlv
;
1124 size_t hdr_len
= sizeof(*dump_data
);
1125 size_t len
, sofar
= 0;
1130 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS
, &ath10k_coredump_mask
))
1131 len
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
1133 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA
, &ath10k_coredump_mask
))
1134 len
+= sizeof(*dump_tlv
) + sizeof(*ce_hdr
) +
1135 CE_COUNT
* sizeof(ce_hdr
->entries
[0]);
1137 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
))
1138 len
+= sizeof(*dump_tlv
) + crash_data
->ramdump_buf_len
;
1142 /* This is going to get big when we start dumping FW RAM and such,
1143 * so go ahead and use vmalloc.
1149 mutex_lock(&ar
->dump_mutex
);
1151 dump_data
= (struct ath10k_dump_file_data
*)(buf
);
1152 strlcpy(dump_data
->df_magic
, "ATH10K-FW-DUMP",
1153 sizeof(dump_data
->df_magic
));
1154 dump_data
->len
= cpu_to_le32(len
);
1156 dump_data
->version
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION
);
1158 guid_copy(&dump_data
->guid
, &crash_data
->guid
);
1159 dump_data
->chip_id
= cpu_to_le32(ar
->bus_param
.chip_id
);
1160 dump_data
->bus_type
= cpu_to_le32(0);
1161 dump_data
->target_version
= cpu_to_le32(ar
->target_version
);
1162 dump_data
->fw_version_major
= cpu_to_le32(ar
->fw_version_major
);
1163 dump_data
->fw_version_minor
= cpu_to_le32(ar
->fw_version_minor
);
1164 dump_data
->fw_version_release
= cpu_to_le32(ar
->fw_version_release
);
1165 dump_data
->fw_version_build
= cpu_to_le32(ar
->fw_version_build
);
1166 dump_data
->phy_capability
= cpu_to_le32(ar
->phy_capability
);
1167 dump_data
->hw_min_tx_power
= cpu_to_le32(ar
->hw_min_tx_power
);
1168 dump_data
->hw_max_tx_power
= cpu_to_le32(ar
->hw_max_tx_power
);
1169 dump_data
->ht_cap_info
= cpu_to_le32(ar
->ht_cap_info
);
1170 dump_data
->vht_cap_info
= cpu_to_le32(ar
->vht_cap_info
);
1171 dump_data
->num_rf_chains
= cpu_to_le32(ar
->num_rf_chains
);
1173 strlcpy(dump_data
->fw_ver
, ar
->hw
->wiphy
->fw_version
,
1174 sizeof(dump_data
->fw_ver
));
1176 dump_data
->kernel_ver_code
= 0;
1177 strlcpy(dump_data
->kernel_ver
, init_utsname()->release
,
1178 sizeof(dump_data
->kernel_ver
));
1180 dump_data
->tv_sec
= cpu_to_le64(crash_data
->timestamp
.tv_sec
);
1181 dump_data
->tv_nsec
= cpu_to_le64(crash_data
->timestamp
.tv_nsec
);
1183 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS
, &ath10k_coredump_mask
)) {
1184 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
1185 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS
);
1186 dump_tlv
->tlv_len
= cpu_to_le32(sizeof(crash_data
->registers
));
1187 memcpy(dump_tlv
->tlv_data
, &crash_data
->registers
,
1188 sizeof(crash_data
->registers
));
1189 sofar
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
1192 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA
, &ath10k_coredump_mask
)) {
1193 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
1194 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA
);
1195 dump_tlv
->tlv_len
= cpu_to_le32(struct_size(ce_hdr
, entries
,
1197 ce_hdr
= (struct ath10k_ce_crash_hdr
*)(dump_tlv
->tlv_data
);
1198 ce_hdr
->ce_count
= cpu_to_le32(CE_COUNT
);
1199 memset(ce_hdr
->reserved
, 0, sizeof(ce_hdr
->reserved
));
1200 memcpy(ce_hdr
->entries
, crash_data
->ce_crash_data
,
1201 CE_COUNT
* sizeof(ce_hdr
->entries
[0]));
1202 sofar
+= sizeof(*dump_tlv
) + sizeof(*ce_hdr
) +
1203 CE_COUNT
* sizeof(ce_hdr
->entries
[0]);
1206 /* Gather ram dump */
1207 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
)) {
1208 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
1209 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA
);
1210 dump_tlv
->tlv_len
= cpu_to_le32(crash_data
->ramdump_buf_len
);
1211 memcpy(dump_tlv
->tlv_data
, crash_data
->ramdump_buf
,
1212 crash_data
->ramdump_buf_len
);
1213 sofar
+= sizeof(*dump_tlv
) + crash_data
->ramdump_buf_len
;
1216 mutex_unlock(&ar
->dump_mutex
);
1221 int ath10k_coredump_submit(struct ath10k
*ar
)
1223 struct ath10k_dump_file_data
*dump
;
1225 if (ath10k_coredump_mask
== 0)
1226 /* coredump disabled */
1229 dump
= ath10k_coredump_build(ar
);
1231 ath10k_warn(ar
, "no crash dump data found for devcoredump");
1235 dev_coredumpv(ar
->dev
, dump
, le32_to_cpu(dump
->len
), GFP_KERNEL
);
1240 int ath10k_coredump_create(struct ath10k
*ar
)
1242 if (ath10k_coredump_mask
== 0)
1243 /* coredump disabled */
1246 ar
->coredump
.fw_crash_data
= vzalloc(sizeof(*ar
->coredump
.fw_crash_data
));
1247 if (!ar
->coredump
.fw_crash_data
)
1253 int ath10k_coredump_register(struct ath10k
*ar
)
1255 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
1257 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA
, &ath10k_coredump_mask
)) {
1258 crash_data
->ramdump_buf_len
= ath10k_coredump_get_ramdump_size(ar
);
1260 crash_data
->ramdump_buf
= vzalloc(crash_data
->ramdump_buf_len
);
1261 if (!crash_data
->ramdump_buf
)
1268 void ath10k_coredump_unregister(struct ath10k
*ar
)
1270 struct ath10k_fw_crash_data
*crash_data
= ar
->coredump
.fw_crash_data
;
1272 vfree(crash_data
->ramdump_buf
);
1275 void ath10k_coredump_destroy(struct ath10k
*ar
)
1277 if (ar
->coredump
.fw_crash_data
->ramdump_buf
) {
1278 vfree(ar
->coredump
.fw_crash_data
->ramdump_buf
);
1279 ar
->coredump
.fw_crash_data
->ramdump_buf
= NULL
;
1280 ar
->coredump
.fw_crash_data
->ramdump_buf_len
= 0;
1283 vfree(ar
->coredump
.fw_crash_data
);
1284 ar
->coredump
.fw_crash_data
= NULL
;