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_mem_region qca99x0_hw20_mem_regions[] = {
706 .type = ATH10K_MEM_REGION_TYPE_DRAM,
716 .type = ATH10K_MEM_REGION_TYPE_REG,
726 .type = ATH10K_MEM_REGION_TYPE_IOSRAM,
736 .type = ATH10K_MEM_REGION_TYPE_IOREG,
746 .type = ATH10K_MEM_REGION_TYPE_IOREG,
756 .type = ATH10K_MEM_REGION_TYPE_IOREG,
766 .type = ATH10K_MEM_REGION_TYPE_IOREG,
776 .type = ATH10K_MEM_REGION_TYPE_IOREG,
787 static const struct ath10k_mem_region qca9984_hw10_mem_regions[] = {
789 .type = ATH10K_MEM_REGION_TYPE_DRAM,
799 .type = ATH10K_MEM_REGION_TYPE_REG,
809 .type = ATH10K_MEM_REGION_TYPE_IOSRAM,
819 .type = ATH10K_MEM_REGION_TYPE_IOREG,
829 .type = ATH10K_MEM_REGION_TYPE_IOREG,
839 .type = ATH10K_MEM_REGION_TYPE_IOREG,
849 .type = ATH10K_MEM_REGION_TYPE_IOREG,
859 .type = ATH10K_MEM_REGION_TYPE_IOREG,
870 static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
872 .hw_id = QCA6174_HW_1_0_VERSION,
874 .regions = qca6174_hw10_mem_regions,
875 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
879 .hw_id = QCA6174_HW_1_1_VERSION,
881 .regions = qca6174_hw10_mem_regions,
882 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
886 .hw_id = QCA6174_HW_1_3_VERSION,
888 .regions = qca6174_hw10_mem_regions,
889 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
893 .hw_id = QCA6174_HW_2_1_VERSION,
895 .regions = qca6174_hw21_mem_regions,
896 .size = ARRAY_SIZE(qca6174_hw21_mem_regions),
900 .hw_id = QCA6174_HW_3_0_VERSION,
902 .regions = qca6174_hw30_mem_regions,
903 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
907 .hw_id = QCA6174_HW_3_2_VERSION,
909 .regions = qca6174_hw30_mem_regions,
910 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
914 .hw_id = QCA9377_HW_1_1_DEV_VERSION,
916 .regions = qca6174_hw30_mem_regions,
917 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
921 .hw_id = QCA988X_HW_2_0_VERSION,
923 .regions = qca988x_hw20_mem_regions,
924 .size = ARRAY_SIZE(qca988x_hw20_mem_regions),
928 .hw_id = QCA9984_HW_1_0_DEV_VERSION,
930 .regions = qca9984_hw10_mem_regions,
931 .size = ARRAY_SIZE(qca9984_hw10_mem_regions),
935 .hw_id = QCA9888_HW_2_0_DEV_VERSION,
937 .regions = qca9984_hw10_mem_regions,
938 .size = ARRAY_SIZE(qca9984_hw10_mem_regions),
942 .hw_id = QCA99X0_HW_2_0_DEV_VERSION,
944 .regions = qca99x0_hw20_mem_regions,
945 .size = ARRAY_SIZE(qca99x0_hw20_mem_regions),
951 static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
953 const struct ath10k_hw_mem_layout *hw;
954 const struct ath10k_mem_region *mem_region;
958 hw = ath10k_coredump_get_mem_layout(ar);
963 mem_region = &hw->region_table.regions[0];
965 for (i = 0; i < hw->region_table.size; i++) {
966 size += mem_region->len;
970 /* reserve space for the headers */
971 size += hw->region_table.size * sizeof(struct ath10k_dump_ram_data_hdr);
973 /* make sure it is aligned 16 bytes for debug message print out */
974 size = ALIGN(size, 16);
979 const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar)
983 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
986 if (WARN_ON(ar->target_version == 0))
989 for (i = 0; i < ARRAY_SIZE(hw_mem_layouts); i++) {
990 if (ar->target_version == hw_mem_layouts[i].hw_id)
991 return &hw_mem_layouts[i];
996 EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
998 struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
1000 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1002 lockdep_assert_held(&ar->data_lock);
1004 if (ath10k_coredump_mask == 0)
1005 /* coredump disabled */
1008 guid_gen(&crash_data->guid);
1009 ktime_get_real_ts64(&crash_data->timestamp);
1013 EXPORT_SYMBOL(ath10k_coredump_new);
1015 static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
1017 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1018 struct ath10k_ce_crash_hdr *ce_hdr;
1019 struct ath10k_dump_file_data *dump_data;
1020 struct ath10k_tlv_dump_data *dump_tlv;
1021 size_t hdr_len = sizeof(*dump_data);
1022 size_t len, sofar = 0;
1027 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask))
1028 len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
1030 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask))
1031 len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
1032 CE_COUNT * sizeof(ce_hdr->entries[0]);
1034 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
1035 len += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
1039 /* This is going to get big when we start dumping FW RAM and such,
1040 * so go ahead and use vmalloc.
1046 spin_lock_bh(&ar->data_lock);
1048 dump_data = (struct ath10k_dump_file_data *)(buf);
1049 strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP",
1050 sizeof(dump_data->df_magic));
1051 dump_data->len = cpu_to_le32(len);
1053 dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION);
1055 guid_copy(&dump_data->guid, &crash_data->guid);
1056 dump_data->chip_id = cpu_to_le32(ar->chip_id);
1057 dump_data->bus_type = cpu_to_le32(0);
1058 dump_data->target_version = cpu_to_le32(ar->target_version);
1059 dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major);
1060 dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor);
1061 dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release);
1062 dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build);
1063 dump_data->phy_capability = cpu_to_le32(ar->phy_capability);
1064 dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power);
1065 dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power);
1066 dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info);
1067 dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info);
1068 dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains);
1070 strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
1071 sizeof(dump_data->fw_ver));
1073 dump_data->kernel_ver_code = 0;
1074 strlcpy(dump_data->kernel_ver, init_utsname()->release,
1075 sizeof(dump_data->kernel_ver));
1077 dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
1078 dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec);
1080 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask)) {
1081 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1082 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
1083 dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
1084 memcpy(dump_tlv->tlv_data, &crash_data->registers,
1085 sizeof(crash_data->registers));
1086 sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
1089 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask)) {
1090 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1091 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
1092 dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) +
1093 CE_COUNT * sizeof(ce_hdr->entries[0]));
1094 ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
1095 ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
1096 memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
1097 memcpy(ce_hdr->entries, crash_data->ce_crash_data,
1098 CE_COUNT * sizeof(ce_hdr->entries[0]));
1099 sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
1100 CE_COUNT * sizeof(ce_hdr->entries[0]);
1103 /* Gather ram dump */
1104 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
1105 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1106 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA);
1107 dump_tlv->tlv_len = cpu_to_le32(crash_data->ramdump_buf_len);
1108 if (crash_data->ramdump_buf_len) {
1109 memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf,
1110 crash_data->ramdump_buf_len);
1111 sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
1115 spin_unlock_bh(&ar->data_lock);
1120 int ath10k_coredump_submit(struct ath10k *ar)
1122 struct ath10k_dump_file_data *dump;
1124 if (ath10k_coredump_mask == 0)
1125 /* coredump disabled */
1128 dump = ath10k_coredump_build(ar);
1130 ath10k_warn(ar, "no crash dump data found for devcoredump");
1134 dev_coredumpv(ar->dev, dump, le32_to_cpu(dump->len), GFP_KERNEL);
1139 int ath10k_coredump_create(struct ath10k *ar)
1141 if (ath10k_coredump_mask == 0)
1142 /* coredump disabled */
1145 ar->coredump.fw_crash_data = vzalloc(sizeof(*ar->coredump.fw_crash_data));
1146 if (!ar->coredump.fw_crash_data)
1152 int ath10k_coredump_register(struct ath10k *ar)
1154 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1156 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
1157 crash_data->ramdump_buf_len = ath10k_coredump_get_ramdump_size(ar);
1159 if (!crash_data->ramdump_buf_len)
1162 crash_data->ramdump_buf = vzalloc(crash_data->ramdump_buf_len);
1163 if (!crash_data->ramdump_buf)
1170 void ath10k_coredump_unregister(struct ath10k *ar)
1172 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1174 vfree(crash_data->ramdump_buf);
1177 void ath10k_coredump_destroy(struct ath10k *ar)
1179 if (ar->coredump.fw_crash_data->ramdump_buf) {
1180 vfree(ar->coredump.fw_crash_data->ramdump_buf);
1181 ar->coredump.fw_crash_data->ramdump_buf = NULL;
1182 ar->coredump.fw_crash_data->ramdump_buf_len = 0;
1185 vfree(ar->coredump.fw_crash_data);
1186 ar->coredump.fw_crash_data = NULL;