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
;