mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00

Move the iwl_trans_pcie_dump_regs() function to utils.c in the PCIe directory since it operates on PCIe registers and is not hardware-dependent. Refactor the pcie_dbg_dumped_once indicator, previously part of the iwl_trans_pcie struct, into a static variable within the iwl_trans_pcie_dump_regs() function, where it is used. Signed-off-by: Rotem Kerem <rotem.kerem@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250612144708.06950459ce97.I3105158eb9ae698efebe4b9ada1093aeb1f1b869@changeid
104 lines
3.2 KiB
C
104 lines
3.2 KiB
C
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
/*
|
|
* Copyright (C) 2025 Intel Corporation
|
|
*/
|
|
|
|
#include <linux/pci.h>
|
|
#include <linux/gfp.h>
|
|
|
|
#include "iwl-io.h"
|
|
#include "pcie/utils.h"
|
|
|
|
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans, struct pci_dev *pdev)
|
|
{
|
|
#define PCI_DUMP_SIZE 352
|
|
#define PCI_MEM_DUMP_SIZE 64
|
|
#define PCI_PARENT_DUMP_SIZE 524
|
|
#define PREFIX_LEN 32
|
|
|
|
static bool pcie_dbg_dumped_once = 0;
|
|
u32 i, pos, alloc_size, *ptr, *buf;
|
|
char *prefix;
|
|
|
|
if (pcie_dbg_dumped_once)
|
|
return;
|
|
|
|
/* Should be a multiple of 4 */
|
|
BUILD_BUG_ON(PCI_DUMP_SIZE > 4096 || PCI_DUMP_SIZE & 0x3);
|
|
BUILD_BUG_ON(PCI_MEM_DUMP_SIZE > 4096 || PCI_MEM_DUMP_SIZE & 0x3);
|
|
BUILD_BUG_ON(PCI_PARENT_DUMP_SIZE > 4096 || PCI_PARENT_DUMP_SIZE & 0x3);
|
|
|
|
/* Alloc a max size buffer */
|
|
alloc_size = PCI_ERR_ROOT_ERR_SRC + 4 + PREFIX_LEN;
|
|
alloc_size = max_t(u32, alloc_size, PCI_DUMP_SIZE + PREFIX_LEN);
|
|
alloc_size = max_t(u32, alloc_size, PCI_MEM_DUMP_SIZE + PREFIX_LEN);
|
|
alloc_size = max_t(u32, alloc_size, PCI_PARENT_DUMP_SIZE + PREFIX_LEN);
|
|
|
|
buf = kmalloc(alloc_size, GFP_ATOMIC);
|
|
if (!buf)
|
|
return;
|
|
prefix = (char *)buf + alloc_size - PREFIX_LEN;
|
|
|
|
IWL_ERR(trans, "iwlwifi transaction failed, dumping registers\n");
|
|
|
|
/* Print wifi device registers */
|
|
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
|
IWL_ERR(trans, "iwlwifi device config registers:\n");
|
|
for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++)
|
|
if (pci_read_config_dword(pdev, i, ptr))
|
|
goto err_read;
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
|
|
|
IWL_ERR(trans, "iwlwifi device memory mapped registers:\n");
|
|
for (i = 0, ptr = buf; i < PCI_MEM_DUMP_SIZE; i += 4, ptr++)
|
|
*ptr = iwl_read32(trans, i);
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
|
|
|
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
|
if (pos) {
|
|
IWL_ERR(trans, "iwlwifi device AER capability structure:\n");
|
|
for (i = 0, ptr = buf; i < PCI_ERR_ROOT_COMMAND; i += 4, ptr++)
|
|
if (pci_read_config_dword(pdev, pos + i, ptr))
|
|
goto err_read;
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
|
|
32, 4, buf, i, 0);
|
|
}
|
|
|
|
/* Print parent device registers next */
|
|
if (!pdev->bus->self)
|
|
goto out;
|
|
|
|
pdev = pdev->bus->self;
|
|
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
|
|
|
IWL_ERR(trans, "iwlwifi parent port (%s) config registers:\n",
|
|
pci_name(pdev));
|
|
for (i = 0, ptr = buf; i < PCI_PARENT_DUMP_SIZE; i += 4, ptr++)
|
|
if (pci_read_config_dword(pdev, i, ptr))
|
|
goto err_read;
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
|
|
|
/* Print root port AER registers */
|
|
pos = 0;
|
|
pdev = pcie_find_root_port(pdev);
|
|
if (pdev)
|
|
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
|
if (pos) {
|
|
IWL_ERR(trans, "iwlwifi root port (%s) AER cap structure:\n",
|
|
pci_name(pdev));
|
|
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
|
for (i = 0, ptr = buf; i <= PCI_ERR_ROOT_ERR_SRC; i += 4, ptr++)
|
|
if (pci_read_config_dword(pdev, pos + i, ptr))
|
|
goto err_read;
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32,
|
|
4, buf, i, 0);
|
|
}
|
|
goto out;
|
|
|
|
err_read:
|
|
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
|
IWL_ERR(trans, "Read failed at 0x%X\n", i);
|
|
out:
|
|
pcie_dbg_dumped_once = 1;
|
|
kfree(buf);
|
|
}
|