^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright IBM Corp. 2012,2015
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Jan Glauber <jang@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define KMSG_COMPONENT "zpci"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/pci_dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static struct dentry *debugfs_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) debug_info_t *pci_debug_msg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) EXPORT_SYMBOL_GPL(pci_debug_msg_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) debug_info_t *pci_debug_err_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) EXPORT_SYMBOL_GPL(pci_debug_err_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static char *pci_common_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) "Load operations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) "Store operations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) "Store block operations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) "Refresh operations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static char *pci_fmt0_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) "DMA read bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "DMA write bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static char *pci_fmt1_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "Received bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "Received packets",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "Transmitted bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "Transmitted packets",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static char *pci_fmt2_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) "Consumed work units",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) "Maximum work units",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static char *pci_fmt3_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "Transmitted bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static char *pci_sw_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "Allocated pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "Mapped pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "Unmapped pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void pci_fmb_show(struct seq_file *m, char *name[], int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) for (i = 0; i < length; i++, data++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) seq_printf(m, "%26s:\t%llu\n", name[i], *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void pci_sw_counter_show(struct seq_file *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct zpci_dev *zdev = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) atomic64_t *counter = &zdev->allocated_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) atomic64_read(counter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int pci_perf_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct zpci_dev *zdev = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!zdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mutex_lock(&zdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!zdev->fmb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mutex_unlock(&zdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) seq_puts(m, "FMB statistics disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pci_fmb_show(m, pci_common_names, ARRAY_SIZE(pci_common_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) &zdev->fmb->ld_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) switch (zdev->fmb->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!(zdev->fmb->fmt_ind & ZPCI_FMB_DMA_COUNTER_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) pci_fmb_show(m, pci_fmt0_names, ARRAY_SIZE(pci_fmt0_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) &zdev->fmb->fmt0.dma_rbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pci_fmb_show(m, pci_fmt1_names, ARRAY_SIZE(pci_fmt1_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) &zdev->fmb->fmt1.rx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pci_fmb_show(m, pci_fmt2_names, ARRAY_SIZE(pci_fmt2_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) &zdev->fmb->fmt2.consumed_work_units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pci_fmb_show(m, pci_fmt3_names, ARRAY_SIZE(pci_fmt3_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) &zdev->fmb->fmt3.tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) seq_puts(m, "Unknown format\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pci_sw_counter_show(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) mutex_unlock(&zdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) size_t count, loff_t *off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (!zdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rc = kstrtoul_from_user(ubuf, count, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mutex_lock(&zdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) rc = zpci_fmb_disable_device(zdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rc = zpci_fmb_enable_device(zdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mutex_unlock(&zdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return rc ? rc : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int pci_perf_seq_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return single_open(filp, pci_perf_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) file_inode(filp)->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static const struct file_operations debugfs_pci_perf_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .open = pci_perf_seq_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .write = pci_perf_seq_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) zdev->debugfs_dev, zdev, &debugfs_pci_perf_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) void zpci_debug_exit_device(struct zpci_dev *zdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) debugfs_remove_recursive(zdev->debugfs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int __init zpci_debug_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* event trace buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pci_debug_msg_id = debug_register("pci_msg", 8, 1, 8 * sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!pci_debug_msg_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) debug_set_level(pci_debug_msg_id, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* error log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!pci_debug_err_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) debug_set_level(pci_debug_err_id, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) debugfs_root = debugfs_create_dir("pci", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) void zpci_debug_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) debug_unregister(pci_debug_msg_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) debug_unregister(pci_debug_err_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) debugfs_remove(debugfs_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }