1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
10 #include <linux/devcoredump.h>
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/utsname.h>
18 static const struct ath10k_mem_section qca6174_hw21_register_sections[] = {
274 static const struct ath10k_mem_section qca6174_hw30_sdio_register_sections[] = {
504 /* EFUSE0,1,2 is disabled here
505 * because its state may be reset
507 * {0x24800, 0x24804},
508 * {0x25000, 0x25004},
509 * {0x25800, 0x25804},
527 /* DBI windows is skipped here, it can be only accessed when pcie
528 * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 &&
529 * PCIE_CTRL_APP_LTSSM_ENALBE=0.
530 * {0x3C000 , 0x3C004},
535 /* SI register is skipped here.
536 * Because it will cause bus hang
538 * {0x50000, 0x50018},
545 static const struct ath10k_mem_section qca6174_hw30_register_sections[] = {
801 static const struct ath10k_mem_region qca6174_hw10_mem_regions[] = {
803 .type = ATH10K_MEM_REGION_TYPE_DRAM,
813 .type = ATH10K_MEM_REGION_TYPE_REG,
815 /* RTC_SOC_BASE_ADDRESS */
818 /* WLAN_MBOX_BASE_ADDRESS - RTC_SOC_BASE_ADDRESS */
828 .type = ATH10K_MEM_REGION_TYPE_REG,
830 /* STEREO_BASE_ADDRESS */
833 /* USB_BASE_ADDRESS - STEREO_BASE_ADDRESS */
834 .len = 0x60000 - 0x27000,
844 static const struct ath10k_mem_region qca6174_hw21_mem_regions[] = {
846 .type = ATH10K_MEM_REGION_TYPE_DRAM,
856 .type = ATH10K_MEM_REGION_TYPE_AXI,
866 .type = ATH10K_MEM_REGION_TYPE_REG,
868 .len = 0x80020 - 0x800,
871 .sections = qca6174_hw21_register_sections,
872 .size = ARRAY_SIZE(qca6174_hw21_register_sections),
877 static const struct ath10k_mem_region qca6174_hw30_sdio_mem_regions[] = {
879 .type = ATH10K_MEM_REGION_TYPE_DRAM,
889 .type = ATH10K_MEM_REGION_TYPE_AXI,
899 .type = ATH10K_MEM_REGION_TYPE_IRAM1,
909 .type = ATH10K_MEM_REGION_TYPE_IRAM2,
919 .type = ATH10K_MEM_REGION_TYPE_REG,
921 .len = 0x80020 - 0x800,
924 .sections = qca6174_hw30_sdio_register_sections,
925 .size = ARRAY_SIZE(qca6174_hw30_sdio_register_sections),
930 static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
932 .type = ATH10K_MEM_REGION_TYPE_DRAM,
942 .type = ATH10K_MEM_REGION_TYPE_AXI,
952 .type = ATH10K_MEM_REGION_TYPE_REG,
954 .len = 0x80020 - 0x800,
957 .sections = qca6174_hw30_register_sections,
958 .size = ARRAY_SIZE(qca6174_hw30_register_sections),
962 /* IRAM dump must be put last */
964 .type = ATH10K_MEM_REGION_TYPE_IRAM1,
974 .type = ATH10K_MEM_REGION_TYPE_IRAM2,
985 static const struct ath10k_mem_region qca988x_hw20_mem_regions[] = {
987 .type = ATH10K_MEM_REGION_TYPE_DRAM,
997 .type = ATH10K_MEM_REGION_TYPE_REG,
1000 .name = "REG_PART1",
1007 .type = ATH10K_MEM_REGION_TYPE_REG,
1010 .name = "REG_PART2",
1018 static const struct ath10k_mem_region qca99x0_hw20_mem_regions[] = {
1020 .type = ATH10K_MEM_REGION_TYPE_DRAM,
1030 .type = ATH10K_MEM_REGION_TYPE_REG,
1040 .type = ATH10K_MEM_REGION_TYPE_IOSRAM,
1050 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1053 .name = "APB REG 1",
1060 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1063 .name = "APB REG 2",
1070 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1080 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1090 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1101 static const struct ath10k_mem_region qca9984_hw10_mem_regions[] = {
1103 .type = ATH10K_MEM_REGION_TYPE_DRAM,
1113 .type = ATH10K_MEM_REGION_TYPE_REG,
1123 .type = ATH10K_MEM_REGION_TYPE_IOSRAM,
1133 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1136 .name = "APB REG 1",
1143 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1146 .name = "APB REG 2",
1153 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1163 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1173 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1184 static const struct ath10k_mem_section ipq4019_soc_reg_range[] = {
1185 {0x080000, 0x080004},
1186 {0x080020, 0x080024},
1187 {0x080028, 0x080050},
1188 {0x0800d4, 0x0800ec},
1189 {0x08010c, 0x080118},
1190 {0x080284, 0x080290},
1191 {0x0802a8, 0x0802b8},
1192 {0x0802dc, 0x08030c},
1193 {0x082000, 0x083fff}
1196 static const struct ath10k_mem_region qca4019_hw10_mem_regions[] = {
1198 .type = ATH10K_MEM_REGION_TYPE_DRAM,
1208 .type = ATH10K_MEM_REGION_TYPE_REG,
1218 .type = ATH10K_MEM_REGION_TYPE_REG,
1228 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1231 .name = "APB REG 1",
1238 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1241 .name = "APB REG 2",
1248 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1258 .type = ATH10K_MEM_REGION_TYPE_IOREG,
1268 .type = ATH10K_MEM_REGION_TYPE_REG,
1270 .len = 0x083fff - 0x080000,
1271 .name = "REG_TOTAL",
1273 .sections = ipq4019_soc_reg_range,
1274 .size = ARRAY_SIZE(ipq4019_soc_reg_range),
1279 static const struct ath10k_mem_region wcn399x_hw10_mem_regions[] = {
1281 /* MSA region start is not fixed, hence it is assigned at runtime */
1282 .type = ATH10K_MEM_REGION_TYPE_MSA,
1292 static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
1294 .hw_id = QCA6174_HW_1_0_VERSION,
1295 .hw_rev = ATH10K_HW_QCA6174,
1296 .bus = ATH10K_BUS_PCI,
1298 .regions = qca6174_hw10_mem_regions,
1299 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
1303 .hw_id = QCA6174_HW_1_1_VERSION,
1304 .hw_rev = ATH10K_HW_QCA6174,
1305 .bus = ATH10K_BUS_PCI,
1307 .regions = qca6174_hw10_mem_regions,
1308 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
1312 .hw_id = QCA6174_HW_1_3_VERSION,
1313 .hw_rev = ATH10K_HW_QCA6174,
1314 .bus = ATH10K_BUS_PCI,
1316 .regions = qca6174_hw10_mem_regions,
1317 .size = ARRAY_SIZE(qca6174_hw10_mem_regions),
1321 .hw_id = QCA6174_HW_2_1_VERSION,
1322 .hw_rev = ATH10K_HW_QCA6174,
1323 .bus = ATH10K_BUS_PCI,
1325 .regions = qca6174_hw21_mem_regions,
1326 .size = ARRAY_SIZE(qca6174_hw21_mem_regions),
1330 .hw_id = QCA6174_HW_3_0_VERSION,
1331 .hw_rev = ATH10K_HW_QCA6174,
1332 .bus = ATH10K_BUS_PCI,
1334 .regions = qca6174_hw30_mem_regions,
1335 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
1339 .hw_id = QCA6174_HW_3_2_VERSION,
1340 .hw_rev = ATH10K_HW_QCA6174,
1341 .bus = ATH10K_BUS_PCI,
1343 .regions = qca6174_hw30_mem_regions,
1344 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
1348 .hw_id = QCA6174_HW_3_2_VERSION,
1349 .hw_rev = ATH10K_HW_QCA6174,
1350 .bus = ATH10K_BUS_SDIO,
1352 .regions = qca6174_hw30_sdio_mem_regions,
1353 .size = ARRAY_SIZE(qca6174_hw30_sdio_mem_regions),
1357 .hw_id = QCA9377_HW_1_1_DEV_VERSION,
1358 .hw_rev = ATH10K_HW_QCA9377,
1359 .bus = ATH10K_BUS_PCI,
1361 .regions = qca6174_hw30_mem_regions,
1362 .size = ARRAY_SIZE(qca6174_hw30_mem_regions),
1366 .hw_id = QCA988X_HW_2_0_VERSION,
1367 .hw_rev = ATH10K_HW_QCA988X,
1368 .bus = ATH10K_BUS_PCI,
1370 .regions = qca988x_hw20_mem_regions,
1371 .size = ARRAY_SIZE(qca988x_hw20_mem_regions),
1375 .hw_id = QCA9984_HW_1_0_DEV_VERSION,
1376 .hw_rev = ATH10K_HW_QCA9984,
1377 .bus = ATH10K_BUS_PCI,
1379 .regions = qca9984_hw10_mem_regions,
1380 .size = ARRAY_SIZE(qca9984_hw10_mem_regions),
1384 .hw_id = QCA9888_HW_2_0_DEV_VERSION,
1385 .hw_rev = ATH10K_HW_QCA9888,
1386 .bus = ATH10K_BUS_PCI,
1388 .regions = qca9984_hw10_mem_regions,
1389 .size = ARRAY_SIZE(qca9984_hw10_mem_regions),
1393 .hw_id = QCA99X0_HW_2_0_DEV_VERSION,
1394 .hw_rev = ATH10K_HW_QCA99X0,
1395 .bus = ATH10K_BUS_PCI,
1397 .regions = qca99x0_hw20_mem_regions,
1398 .size = ARRAY_SIZE(qca99x0_hw20_mem_regions),
1402 .hw_id = QCA4019_HW_1_0_DEV_VERSION,
1403 .hw_rev = ATH10K_HW_QCA4019,
1404 .bus = ATH10K_BUS_AHB,
1406 .regions = qca4019_hw10_mem_regions,
1407 .size = ARRAY_SIZE(qca4019_hw10_mem_regions),
1411 .hw_id = WCN3990_HW_1_0_DEV_VERSION,
1412 .hw_rev = ATH10K_HW_WCN3990,
1413 .bus = ATH10K_BUS_SNOC,
1415 .regions = wcn399x_hw10_mem_regions,
1416 .size = ARRAY_SIZE(wcn399x_hw10_mem_regions),
1421 static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
1423 const struct ath10k_hw_mem_layout *hw;
1424 const struct ath10k_mem_region *mem_region;
1428 hw = ath10k_coredump_get_mem_layout(ar);
1433 mem_region = &hw->region_table.regions[0];
1435 for (i = 0; i < hw->region_table.size; i++) {
1436 size += mem_region->len;
1440 /* reserve space for the headers */
1441 size += hw->region_table.size * sizeof(struct ath10k_dump_ram_data_hdr);
1443 /* make sure it is aligned 16 bytes for debug message print out */
1444 size = ALIGN(size, 16);
1449 const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar)
1451 if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
1454 return _ath10k_coredump_get_mem_layout(ar);
1456 EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
1458 const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar)
1462 if (WARN_ON(ar->target_version == 0))
1465 for (i = 0; i < ARRAY_SIZE(hw_mem_layouts); i++) {
1466 if (ar->target_version == hw_mem_layouts[i].hw_id &&
1467 ar->hw_rev == hw_mem_layouts[i].hw_rev &&
1468 hw_mem_layouts[i].bus == ar->hif.bus)
1469 return &hw_mem_layouts[i];
1475 struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
1477 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1479 lockdep_assert_held(&ar->dump_mutex);
1481 if (ath10k_coredump_mask == 0)
1482 /* coredump disabled */
1485 guid_gen(&crash_data->guid);
1486 ktime_get_real_ts64(&crash_data->timestamp);
1490 EXPORT_SYMBOL(ath10k_coredump_new);
1492 static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
1494 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1495 struct ath10k_ce_crash_hdr *ce_hdr;
1496 struct ath10k_dump_file_data *dump_data;
1497 struct ath10k_tlv_dump_data *dump_tlv;
1498 size_t hdr_len = sizeof(*dump_data);
1499 size_t len, sofar = 0;
1504 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask))
1505 len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
1507 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask))
1508 len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
1509 CE_COUNT * sizeof(ce_hdr->entries[0]);
1511 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
1512 len += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
1516 /* This is going to get big when we start dumping FW RAM and such,
1517 * so go ahead and use vmalloc.
1523 mutex_lock(&ar->dump_mutex);
1525 dump_data = (struct ath10k_dump_file_data *)(buf);
1526 strscpy(dump_data->df_magic, "ATH10K-FW-DUMP",
1527 sizeof(dump_data->df_magic));
1528 dump_data->len = cpu_to_le32(len);
1530 dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION);
1532 guid_copy(&dump_data->guid, &crash_data->guid);
1533 dump_data->chip_id = cpu_to_le32(ar->bus_param.chip_id);
1534 dump_data->bus_type = cpu_to_le32(0);
1535 dump_data->target_version = cpu_to_le32(ar->target_version);
1536 dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major);
1537 dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor);
1538 dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release);
1539 dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build);
1540 dump_data->phy_capability = cpu_to_le32(ar->phy_capability);
1541 dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power);
1542 dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power);
1543 dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info);
1544 dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info);
1545 dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains);
1547 strscpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
1548 sizeof(dump_data->fw_ver));
1550 dump_data->kernel_ver_code = 0;
1551 strscpy(dump_data->kernel_ver, init_utsname()->release,
1552 sizeof(dump_data->kernel_ver));
1554 dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
1555 dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec);
1557 if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask)) {
1558 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1559 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
1560 dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
1561 memcpy(dump_tlv->tlv_data, &crash_data->registers,
1562 sizeof(crash_data->registers));
1563 sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
1566 if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask)) {
1567 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1568 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
1569 dump_tlv->tlv_len = cpu_to_le32(struct_size(ce_hdr, entries,
1571 ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
1572 ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
1573 memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
1574 memcpy(ce_hdr->entries, crash_data->ce_crash_data,
1575 CE_COUNT * sizeof(ce_hdr->entries[0]));
1576 sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
1577 CE_COUNT * sizeof(ce_hdr->entries[0]);
1580 /* Gather ram dump */
1581 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
1582 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
1583 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA);
1584 dump_tlv->tlv_len = cpu_to_le32(crash_data->ramdump_buf_len);
1585 if (crash_data->ramdump_buf_len) {
1586 memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf,
1587 crash_data->ramdump_buf_len);
1588 sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
1592 mutex_unlock(&ar->dump_mutex);
1597 int ath10k_coredump_submit(struct ath10k *ar)
1599 struct ath10k_dump_file_data *dump;
1601 if (ath10k_coredump_mask == 0)
1602 /* coredump disabled */
1605 dump = ath10k_coredump_build(ar);
1607 ath10k_warn(ar, "no crash dump data found for devcoredump");
1611 dev_coredumpv(ar->dev, dump, le32_to_cpu(dump->len), GFP_KERNEL);
1616 int ath10k_coredump_create(struct ath10k *ar)
1618 if (ath10k_coredump_mask == 0)
1619 /* coredump disabled */
1622 ar->coredump.fw_crash_data = vzalloc(sizeof(*ar->coredump.fw_crash_data));
1623 if (!ar->coredump.fw_crash_data)
1629 int ath10k_coredump_register(struct ath10k *ar)
1631 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1633 if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) {
1634 crash_data->ramdump_buf_len = ath10k_coredump_get_ramdump_size(ar);
1636 if (!crash_data->ramdump_buf_len)
1639 crash_data->ramdump_buf = vzalloc(crash_data->ramdump_buf_len);
1640 if (!crash_data->ramdump_buf)
1647 void ath10k_coredump_unregister(struct ath10k *ar)
1649 struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
1651 vfree(crash_data->ramdump_buf);
1654 void ath10k_coredump_destroy(struct ath10k *ar)
1656 if (ar->coredump.fw_crash_data->ramdump_buf) {
1657 vfree(ar->coredump.fw_crash_data->ramdump_buf);
1658 ar->coredump.fw_crash_data->ramdump_buf = NULL;
1659 ar->coredump.fw_crash_data->ramdump_buf_len = 0;
1662 vfree(ar->coredump.fw_crash_data);
1663 ar->coredump.fw_crash_data = NULL;