18c2ecf20Sopenharmony_ci/* Broadcom NetXtreme-C/E network driver.
28c2ecf20Sopenharmony_ci *
38c2ecf20Sopenharmony_ci * Copyright (c) 2017-2018 Broadcom Limited
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
68c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by
78c2ecf20Sopenharmony_ci * the Free Software Foundation.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/debugfs.h>
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/pci.h>
138c2ecf20Sopenharmony_ci#include "bnxt_hsi.h"
148c2ecf20Sopenharmony_ci#include <linux/dim.h>
158c2ecf20Sopenharmony_ci#include "bnxt.h"
168c2ecf20Sopenharmony_ci#include "bnxt_debugfs.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic struct dentry *bnxt_debug_mnt;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic ssize_t debugfs_dim_read(struct file *filep,
218c2ecf20Sopenharmony_ci				char __user *buffer,
228c2ecf20Sopenharmony_ci				size_t count, loff_t *ppos)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	struct dim *dim = filep->private_data;
258c2ecf20Sopenharmony_ci	int len;
268c2ecf20Sopenharmony_ci	char *buf;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	if (*ppos)
298c2ecf20Sopenharmony_ci		return 0;
308c2ecf20Sopenharmony_ci	if (!dim)
318c2ecf20Sopenharmony_ci		return -ENODEV;
328c2ecf20Sopenharmony_ci	buf = kasprintf(GFP_KERNEL,
338c2ecf20Sopenharmony_ci			"state = %d\n" \
348c2ecf20Sopenharmony_ci			"profile_ix = %d\n" \
358c2ecf20Sopenharmony_ci			"mode = %d\n" \
368c2ecf20Sopenharmony_ci			"tune_state = %d\n" \
378c2ecf20Sopenharmony_ci			"steps_right = %d\n" \
388c2ecf20Sopenharmony_ci			"steps_left = %d\n" \
398c2ecf20Sopenharmony_ci			"tired = %d\n",
408c2ecf20Sopenharmony_ci			dim->state,
418c2ecf20Sopenharmony_ci			dim->profile_ix,
428c2ecf20Sopenharmony_ci			dim->mode,
438c2ecf20Sopenharmony_ci			dim->tune_state,
448c2ecf20Sopenharmony_ci			dim->steps_right,
458c2ecf20Sopenharmony_ci			dim->steps_left,
468c2ecf20Sopenharmony_ci			dim->tired);
478c2ecf20Sopenharmony_ci	if (!buf)
488c2ecf20Sopenharmony_ci		return -ENOMEM;
498c2ecf20Sopenharmony_ci	if (count < strlen(buf)) {
508c2ecf20Sopenharmony_ci		kfree(buf);
518c2ecf20Sopenharmony_ci		return -ENOSPC;
528c2ecf20Sopenharmony_ci	}
538c2ecf20Sopenharmony_ci	len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
548c2ecf20Sopenharmony_ci	kfree(buf);
558c2ecf20Sopenharmony_ci	return len;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic const struct file_operations debugfs_dim_fops = {
598c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
608c2ecf20Sopenharmony_ci	.open = simple_open,
618c2ecf20Sopenharmony_ci	.read = debugfs_dim_read,
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic void debugfs_dim_ring_init(struct dim *dim, int ring_idx,
658c2ecf20Sopenharmony_ci				  struct dentry *dd)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	static char qname[16];
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	snprintf(qname, 10, "%d", ring_idx);
708c2ecf20Sopenharmony_ci	debugfs_create_file(qname, 0600, dd, dim, &debugfs_dim_fops);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_civoid bnxt_debug_dev_init(struct bnxt *bp)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	const char *pname = pci_name(bp->pdev);
768c2ecf20Sopenharmony_ci	struct dentry *dir;
778c2ecf20Sopenharmony_ci	int i;
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	bp->debugfs_pdev = debugfs_create_dir(pname, bnxt_debug_mnt);
808c2ecf20Sopenharmony_ci	dir = debugfs_create_dir("dim", bp->debugfs_pdev);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	/* create files for each rx ring */
838c2ecf20Sopenharmony_ci	for (i = 0; i < bp->cp_nr_rings; i++) {
848c2ecf20Sopenharmony_ci		struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci		if (cpr && bp->bnapi[i]->rx_ring)
878c2ecf20Sopenharmony_ci			debugfs_dim_ring_init(&cpr->dim, i, dir);
888c2ecf20Sopenharmony_ci	}
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_civoid bnxt_debug_dev_exit(struct bnxt *bp)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	if (bp) {
948c2ecf20Sopenharmony_ci		debugfs_remove_recursive(bp->debugfs_pdev);
958c2ecf20Sopenharmony_ci		bp->debugfs_pdev = NULL;
968c2ecf20Sopenharmony_ci	}
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_civoid bnxt_debug_init(void)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	bnxt_debug_mnt = debugfs_create_dir("bnxt_en", NULL);
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_civoid bnxt_debug_exit(void)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci	debugfs_remove_recursive(bnxt_debug_mnt);
1078c2ecf20Sopenharmony_ci}
108