Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Debugfs interface
   4 *
   5 * Copyright (C) 2020, Intel Corporation
   6 * Authors: Gil Fine <gil.fine@intel.com>
   7 *	    Mika Westerberg <mika.westerberg@linux.intel.com>
   8 */
   9
  10#include <linux/debugfs.h>
  11#include <linux/pm_runtime.h>
  12#include <linux/uaccess.h>
  13
  14#include "tb.h"
  15#include "sb_regs.h"
  16
  17#define PORT_CAP_PCIE_LEN	1
  18#define PORT_CAP_POWER_LEN	2
  19#define PORT_CAP_LANE_LEN	3
  20#define PORT_CAP_USB3_LEN	5
  21#define PORT_CAP_DP_LEN		8
  22#define PORT_CAP_TMU_LEN	8
  23#define PORT_CAP_BASIC_LEN	9
  24#define PORT_CAP_USB4_LEN	20
  25
  26#define SWITCH_CAP_TMU_LEN	26
  27#define SWITCH_CAP_BASIC_LEN	27
  28
  29#define PATH_LEN		2
  30
  31#define COUNTER_SET_LEN		3
  32
  33#define DEBUGFS_ATTR(__space, __write)					\
  34static int __space ## _open(struct inode *inode, struct file *file)	\
  35{									\
  36	return single_open(file, __space ## _show, inode->i_private);	\
  37}									\
  38									\
  39static const struct file_operations __space ## _fops = {		\
  40	.owner = THIS_MODULE,						\
  41	.open = __space ## _open,					\
  42	.release = single_release,					\
  43	.read  = seq_read,						\
  44	.write = __write,						\
  45	.llseek = seq_lseek,						\
  46}
  47
  48#define DEBUGFS_ATTR_RO(__space)					\
  49	DEBUGFS_ATTR(__space, NULL)
  50
  51#define DEBUGFS_ATTR_RW(__space)					\
  52	DEBUGFS_ATTR(__space, __space ## _write)
  53
  54static struct dentry *tb_debugfs_root;
  55
  56static void *validate_and_copy_from_user(const void __user *user_buf,
  57					 size_t *count)
  58{
  59	size_t nbytes;
  60	void *buf;
  61
  62	if (!*count)
  63		return ERR_PTR(-EINVAL);
  64
  65	if (!access_ok(user_buf, *count))
  66		return ERR_PTR(-EFAULT);
  67
  68	buf = (void *)get_zeroed_page(GFP_KERNEL);
  69	if (!buf)
  70		return ERR_PTR(-ENOMEM);
  71
  72	nbytes = min_t(size_t, *count, PAGE_SIZE);
  73	if (copy_from_user(buf, user_buf, nbytes)) {
  74		free_page((unsigned long)buf);
  75		return ERR_PTR(-EFAULT);
  76	}
  77
  78	*count = nbytes;
  79	return buf;
  80}
  81
  82static bool parse_line(char **line, u32 *offs, u32 *val, int short_fmt_len,
  83		       int long_fmt_len)
  84{
  85	char *token;
  86	u32 v[5];
  87	int ret;
  88
  89	token = strsep(line, "\n");
  90	if (!token)
  91		return false;
  92
  93	/*
  94	 * For Adapter/Router configuration space:
  95	 * Short format is: offset value\n
  96	 *		    v[0]   v[1]
  97	 * Long format as produced from the read side:
  98	 * offset relative_offset cap_id vs_cap_id value\n
  99	 * v[0]   v[1]            v[2]   v[3]      v[4]
 100	 *
 101	 * For Counter configuration space:
 102	 * Short format is: offset\n
 103	 *		    v[0]
 104	 * Long format as produced from the read side:
 105	 * offset relative_offset counter_id value\n
 106	 * v[0]   v[1]            v[2]       v[3]
 107	 */
 108	ret = sscanf(token, "%i %i %i %i %i", &v[0], &v[1], &v[2], &v[3], &v[4]);
 109	/* In case of Counters, clear counter, "val" content is NA */
 110	if (ret == short_fmt_len) {
 111		*offs = v[0];
 112		*val = v[short_fmt_len - 1];
 113		return true;
 114	} else if (ret == long_fmt_len) {
 115		*offs = v[0];
 116		*val = v[long_fmt_len - 1];
 117		return true;
 118	}
 119
 120	return false;
 121}
 122
 123#if IS_ENABLED(CONFIG_USB4_DEBUGFS_WRITE)
 124static ssize_t regs_write(struct tb_switch *sw, struct tb_port *port,
 125			  const char __user *user_buf, size_t count,
 126			  loff_t *ppos)
 127{
 128	struct tb *tb = sw->tb;
 129	char *line, *buf;
 130	u32 val, offset;
 131	int ret = 0;
 132
 133	buf = validate_and_copy_from_user(user_buf, &count);
 134	if (IS_ERR(buf))
 135		return PTR_ERR(buf);
 136
 137	pm_runtime_get_sync(&sw->dev);
 138
 139	if (mutex_lock_interruptible(&tb->lock)) {
 140		ret = -ERESTARTSYS;
 141		goto out;
 142	}
 143
 144	/* User did hardware changes behind the driver's back */
 145	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 146
 147	line = buf;
 148	while (parse_line(&line, &offset, &val, 2, 5)) {
 149		if (port)
 150			ret = tb_port_write(port, &val, TB_CFG_PORT, offset, 1);
 151		else
 152			ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, offset, 1);
 153		if (ret)
 154			break;
 155	}
 156
 157	mutex_unlock(&tb->lock);
 158
 159out:
 160	pm_runtime_mark_last_busy(&sw->dev);
 161	pm_runtime_put_autosuspend(&sw->dev);
 162	free_page((unsigned long)buf);
 163
 164	return ret < 0 ? ret : count;
 165}
 166
 167static ssize_t port_regs_write(struct file *file, const char __user *user_buf,
 168			       size_t count, loff_t *ppos)
 169{
 170	struct seq_file *s = file->private_data;
 171	struct tb_port *port = s->private;
 172
 173	return regs_write(port->sw, port, user_buf, count, ppos);
 174}
 175
 176static ssize_t switch_regs_write(struct file *file, const char __user *user_buf,
 177				 size_t count, loff_t *ppos)
 178{
 179	struct seq_file *s = file->private_data;
 180	struct tb_switch *sw = s->private;
 181
 182	return regs_write(sw, NULL, user_buf, count, ppos);
 183}
 184#define DEBUGFS_MODE		0600
 185#else
 186#define port_regs_write		NULL
 187#define switch_regs_write	NULL
 188#define DEBUGFS_MODE		0400
 189#endif
 190
 191#if IS_ENABLED(CONFIG_USB4_DEBUGFS_MARGINING)
 192/**
 193 * struct tb_margining - Lane margining support
 194 * @caps: Port lane margining capabilities
 195 * @results: Last lane margining results
 196 * @lanes: %0, %1 or %7 (all)
 197 * @min_ber_level: Minimum supported BER level contour value
 198 * @max_ber_level: Maximum supported BER level contour value
 199 * @ber_level: Current BER level contour value
 200 * @voltage_steps: Number of mandatory voltage steps
 201 * @max_voltage_offset: Maximum mandatory voltage offset (in mV)
 202 * @time_steps: Number of time margin steps
 203 * @max_time_offset: Maximum time margin offset (in mUI)
 204 * @software: %true if software margining is used instead of hardware
 205 * @time: %true if time margining is used instead of voltage
 206 * @right_high: %false if left/low margin test is performed, %true if
 207 *		right/high
 208 */
 209struct tb_margining {
 210	u32 caps[2];
 211	u32 results[2];
 212	unsigned int lanes;
 213	unsigned int min_ber_level;
 214	unsigned int max_ber_level;
 215	unsigned int ber_level;
 216	unsigned int voltage_steps;
 217	unsigned int max_voltage_offset;
 218	unsigned int time_steps;
 219	unsigned int max_time_offset;
 220	bool software;
 221	bool time;
 222	bool right_high;
 223};
 224
 225static bool supports_software(const struct usb4_port *usb4)
 226{
 227	return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW;
 228}
 229
 230static bool supports_hardware(const struct usb4_port *usb4)
 231{
 232	return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW;
 233}
 234
 235static bool both_lanes(const struct usb4_port *usb4)
 236{
 237	return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES;
 238}
 239
 240static unsigned int independent_voltage_margins(const struct usb4_port *usb4)
 241{
 242	return (usb4->margining->caps[0] & USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK) >>
 243		USB4_MARGIN_CAP_0_VOLTAGE_INDP_SHIFT;
 244}
 245
 246static bool supports_time(const struct usb4_port *usb4)
 247{
 248	return usb4->margining->caps[0] & USB4_MARGIN_CAP_0_TIME;
 249}
 250
 251/* Only applicable if supports_time() returns true */
 252static unsigned int independent_time_margins(const struct usb4_port *usb4)
 253{
 254	return (usb4->margining->caps[1] & USB4_MARGIN_CAP_1_TIME_INDP_MASK) >>
 255		USB4_MARGIN_CAP_1_TIME_INDP_SHIFT;
 256}
 257
 258static ssize_t
 259margining_ber_level_write(struct file *file, const char __user *user_buf,
 260			   size_t count, loff_t *ppos)
 261{
 262	struct seq_file *s = file->private_data;
 263	struct tb_port *port = s->private;
 264	struct usb4_port *usb4 = port->usb4;
 265	struct tb *tb = port->sw->tb;
 266	unsigned int val;
 267	int ret = 0;
 268	char *buf;
 269
 270	if (mutex_lock_interruptible(&tb->lock))
 271		return -ERESTARTSYS;
 272
 273	if (usb4->margining->software) {
 274		ret = -EINVAL;
 275		goto out_unlock;
 276	}
 277
 278	buf = validate_and_copy_from_user(user_buf, &count);
 279	if (IS_ERR(buf)) {
 280		ret = PTR_ERR(buf);
 281		goto out_unlock;
 282	}
 283
 284	buf[count - 1] = '\0';
 285
 286	ret = kstrtouint(buf, 10, &val);
 287	if (ret)
 288		goto out_free;
 289
 290	if (val < usb4->margining->min_ber_level ||
 291	    val > usb4->margining->max_ber_level) {
 292		ret = -EINVAL;
 293		goto out_free;
 294	}
 295
 296	usb4->margining->ber_level = val;
 297
 298out_free:
 299	free_page((unsigned long)buf);
 300out_unlock:
 301	mutex_unlock(&tb->lock);
 302
 303	return ret < 0 ? ret : count;
 304}
 305
 306static void ber_level_show(struct seq_file *s, unsigned int val)
 307{
 308	if (val % 2)
 309		seq_printf(s, "3 * 1e%d (%u)\n", -12 + (val + 1) / 2, val);
 310	else
 311		seq_printf(s, "1e%d (%u)\n", -12 + val / 2, val);
 312}
 313
 314static int margining_ber_level_show(struct seq_file *s, void *not_used)
 315{
 316	struct tb_port *port = s->private;
 317	struct usb4_port *usb4 = port->usb4;
 318
 319	if (usb4->margining->software)
 320		return -EINVAL;
 321	ber_level_show(s, usb4->margining->ber_level);
 322	return 0;
 323}
 324DEBUGFS_ATTR_RW(margining_ber_level);
 325
 326static int margining_caps_show(struct seq_file *s, void *not_used)
 327{
 328	struct tb_port *port = s->private;
 329	struct usb4_port *usb4 = port->usb4;
 330	struct tb *tb = port->sw->tb;
 331	u32 cap0, cap1;
 332
 333	if (mutex_lock_interruptible(&tb->lock))
 334		return -ERESTARTSYS;
 335
 336	/* Dump the raw caps first */
 337	cap0 = usb4->margining->caps[0];
 338	seq_printf(s, "0x%08x\n", cap0);
 339	cap1 = usb4->margining->caps[1];
 340	seq_printf(s, "0x%08x\n", cap1);
 341
 342	seq_printf(s, "# software margining: %s\n",
 343		   supports_software(usb4) ? "yes" : "no");
 344	if (supports_hardware(usb4)) {
 345		seq_puts(s, "# hardware margining: yes\n");
 346		seq_puts(s, "# minimum BER level contour: ");
 347		ber_level_show(s, usb4->margining->min_ber_level);
 348		seq_puts(s, "# maximum BER level contour: ");
 349		ber_level_show(s, usb4->margining->max_ber_level);
 350	} else {
 351		seq_puts(s, "# hardware margining: no\n");
 352	}
 353
 354	seq_printf(s, "# both lanes simultaneously: %s\n",
 355		  both_lanes(usb4) ? "yes" : "no");
 356	seq_printf(s, "# voltage margin steps: %u\n",
 357		   usb4->margining->voltage_steps);
 358	seq_printf(s, "# maximum voltage offset: %u mV\n",
 359		   usb4->margining->max_voltage_offset);
 360
 361	switch (independent_voltage_margins(usb4)) {
 362	case USB4_MARGIN_CAP_0_VOLTAGE_MIN:
 363		seq_puts(s, "# returns minimum between high and low voltage margins\n");
 364		break;
 365	case USB4_MARGIN_CAP_0_VOLTAGE_HL:
 366		seq_puts(s, "# returns high or low voltage margin\n");
 367		break;
 368	case USB4_MARGIN_CAP_0_VOLTAGE_BOTH:
 369		seq_puts(s, "# returns both high and low margins\n");
 370		break;
 371	}
 372
 373	if (supports_time(usb4)) {
 374		seq_puts(s, "# time margining: yes\n");
 375		seq_printf(s, "# time margining is destructive: %s\n",
 376			   cap1 & USB4_MARGIN_CAP_1_TIME_DESTR ? "yes" : "no");
 377
 378		switch (independent_time_margins(usb4)) {
 379		case USB4_MARGIN_CAP_1_TIME_MIN:
 380			seq_puts(s, "# returns minimum between left and right time margins\n");
 381			break;
 382		case USB4_MARGIN_CAP_1_TIME_LR:
 383			seq_puts(s, "# returns left or right margin\n");
 384			break;
 385		case USB4_MARGIN_CAP_1_TIME_BOTH:
 386			seq_puts(s, "# returns both left and right margins\n");
 387			break;
 388		}
 389
 390		seq_printf(s, "# time margin steps: %u\n",
 391			   usb4->margining->time_steps);
 392		seq_printf(s, "# maximum time offset: %u mUI\n",
 393			   usb4->margining->max_time_offset);
 394	} else {
 395		seq_puts(s, "# time margining: no\n");
 396	}
 397
 398	mutex_unlock(&tb->lock);
 399	return 0;
 400}
 401DEBUGFS_ATTR_RO(margining_caps);
 402
 403static ssize_t
 404margining_lanes_write(struct file *file, const char __user *user_buf,
 405		      size_t count, loff_t *ppos)
 406{
 407	struct seq_file *s = file->private_data;
 408	struct tb_port *port = s->private;
 409	struct usb4_port *usb4 = port->usb4;
 410	struct tb *tb = port->sw->tb;
 411	int ret = 0;
 412	char *buf;
 413
 414	buf = validate_and_copy_from_user(user_buf, &count);
 415	if (IS_ERR(buf))
 416		return PTR_ERR(buf);
 417
 418	buf[count - 1] = '\0';
 419
 420	if (mutex_lock_interruptible(&tb->lock)) {
 421		ret = -ERESTARTSYS;
 422		goto out_free;
 423	}
 424
 425	if (!strcmp(buf, "0")) {
 426		usb4->margining->lanes = 0;
 427	} else if (!strcmp(buf, "1")) {
 428		usb4->margining->lanes = 1;
 429	} else if (!strcmp(buf, "all")) {
 430		/* Needs to be supported */
 431		if (both_lanes(usb4))
 432			usb4->margining->lanes = 7;
 433		else
 434			ret = -EINVAL;
 435	} else {
 436		ret = -EINVAL;
 437	}
 438
 439	mutex_unlock(&tb->lock);
 440
 441out_free:
 442	free_page((unsigned long)buf);
 443	return ret < 0 ? ret : count;
 444}
 445
 446static int margining_lanes_show(struct seq_file *s, void *not_used)
 447{
 448	struct tb_port *port = s->private;
 449	struct usb4_port *usb4 = port->usb4;
 450	struct tb *tb = port->sw->tb;
 451	unsigned int lanes;
 452
 453	if (mutex_lock_interruptible(&tb->lock))
 454		return -ERESTARTSYS;
 455
 456	lanes = usb4->margining->lanes;
 457	if (both_lanes(usb4)) {
 458		if (!lanes)
 459			seq_puts(s, "[0] 1 all\n");
 460		else if (lanes == 1)
 461			seq_puts(s, "0 [1] all\n");
 462		else
 463			seq_puts(s, "0 1 [all]\n");
 464	} else {
 465		if (!lanes)
 466			seq_puts(s, "[0] 1\n");
 467		else
 468			seq_puts(s, "0 [1]\n");
 469	}
 470
 471	mutex_unlock(&tb->lock);
 472	return 0;
 473}
 474DEBUGFS_ATTR_RW(margining_lanes);
 475
 476static ssize_t margining_mode_write(struct file *file,
 477				   const char __user *user_buf,
 478				   size_t count, loff_t *ppos)
 479{
 480	struct seq_file *s = file->private_data;
 481	struct tb_port *port = s->private;
 482	struct usb4_port *usb4 = port->usb4;
 483	struct tb *tb = port->sw->tb;
 484	int ret = 0;
 485	char *buf;
 486
 487	buf = validate_and_copy_from_user(user_buf, &count);
 488	if (IS_ERR(buf))
 489		return PTR_ERR(buf);
 490
 491	buf[count - 1] = '\0';
 492
 493	if (mutex_lock_interruptible(&tb->lock)) {
 494		ret = -ERESTARTSYS;
 495		goto out_free;
 496	}
 497
 498	if (!strcmp(buf, "software")) {
 499		if (supports_software(usb4))
 500			usb4->margining->software = true;
 501		else
 502			ret = -EINVAL;
 503	} else if (!strcmp(buf, "hardware")) {
 504		if (supports_hardware(usb4))
 505			usb4->margining->software = false;
 506		else
 507			ret = -EINVAL;
 508	} else {
 509		ret = -EINVAL;
 510	}
 511
 512	mutex_unlock(&tb->lock);
 513
 514out_free:
 515	free_page((unsigned long)buf);
 516	return ret ? ret : count;
 517}
 518
 519static int margining_mode_show(struct seq_file *s, void *not_used)
 520{
 521	const struct tb_port *port = s->private;
 522	const struct usb4_port *usb4 = port->usb4;
 523	struct tb *tb = port->sw->tb;
 524	const char *space = "";
 525
 526	if (mutex_lock_interruptible(&tb->lock))
 527		return -ERESTARTSYS;
 528
 529	if (supports_software(usb4)) {
 530		if (usb4->margining->software)
 531			seq_puts(s, "[software]");
 532		else
 533			seq_puts(s, "software");
 534		space = " ";
 535	}
 536	if (supports_hardware(usb4)) {
 537		if (usb4->margining->software)
 538			seq_printf(s, "%shardware", space);
 539		else
 540			seq_printf(s, "%s[hardware]", space);
 541	}
 542
 543	mutex_unlock(&tb->lock);
 544
 545	seq_puts(s, "\n");
 546	return 0;
 547}
 548DEBUGFS_ATTR_RW(margining_mode);
 549
 550static int margining_run_write(void *data, u64 val)
 551{
 552	struct tb_port *port = data;
 553	struct usb4_port *usb4 = port->usb4;
 554	struct tb_switch *sw = port->sw;
 555	struct tb_margining *margining;
 556	struct tb *tb = sw->tb;
 557	int ret;
 558
 559	if (val != 1)
 560		return -EINVAL;
 561
 562	pm_runtime_get_sync(&sw->dev);
 563
 564	if (mutex_lock_interruptible(&tb->lock)) {
 565		ret = -ERESTARTSYS;
 566		goto out_rpm_put;
 567	}
 568
 569	/*
 570	 * CL states may interfere with lane margining so inform the user know
 571	 * and bail out.
 572	 */
 573	if (tb_port_is_clx_enabled(port, TB_CL1 | TB_CL2)) {
 574		tb_port_warn(port,
 575			     "CL states are enabled, Disable them with clx=0 and re-connect\n");
 576		ret = -EINVAL;
 577		goto out_unlock;
 578	}
 579
 580	margining = usb4->margining;
 581
 582	if (margining->software) {
 583		tb_port_dbg(port, "running software %s lane margining for lanes %u\n",
 584			    margining->time ? "time" : "voltage", margining->lanes);
 585		ret = usb4_port_sw_margin(port, margining->lanes, margining->time,
 586					  margining->right_high,
 587					  USB4_MARGIN_SW_COUNTER_CLEAR);
 588		if (ret)
 589			goto out_unlock;
 590
 591		ret = usb4_port_sw_margin_errors(port, &margining->results[0]);
 592	} else {
 593		tb_port_dbg(port, "running hardware %s lane margining for lanes %u\n",
 594			    margining->time ? "time" : "voltage", margining->lanes);
 595		/* Clear the results */
 596		margining->results[0] = 0;
 597		margining->results[1] = 0;
 598		ret = usb4_port_hw_margin(port, margining->lanes,
 599					  margining->ber_level, margining->time,
 600					  margining->right_high, margining->results);
 601	}
 602
 603out_unlock:
 604	mutex_unlock(&tb->lock);
 605out_rpm_put:
 606	pm_runtime_mark_last_busy(&sw->dev);
 607	pm_runtime_put_autosuspend(&sw->dev);
 608
 609	return ret;
 610}
 611DEFINE_DEBUGFS_ATTRIBUTE(margining_run_fops, NULL, margining_run_write,
 612			 "%llu\n");
 613
 614static ssize_t margining_results_write(struct file *file,
 615				       const char __user *user_buf,
 616				       size_t count, loff_t *ppos)
 617{
 618	struct seq_file *s = file->private_data;
 619	struct tb_port *port = s->private;
 620	struct usb4_port *usb4 = port->usb4;
 621	struct tb *tb = port->sw->tb;
 622
 623	if (mutex_lock_interruptible(&tb->lock))
 624		return -ERESTARTSYS;
 625
 626	/* Just clear the results */
 627	usb4->margining->results[0] = 0;
 628	usb4->margining->results[1] = 0;
 629
 630	mutex_unlock(&tb->lock);
 631	return count;
 632}
 633
 634static void voltage_margin_show(struct seq_file *s,
 635				const struct tb_margining *margining, u8 val)
 636{
 637	unsigned int tmp, voltage;
 638
 639	tmp = val & USB4_MARGIN_HW_RES_1_MARGIN_MASK;
 640	voltage = tmp * margining->max_voltage_offset / margining->voltage_steps;
 641	seq_printf(s, "%u mV (%u)", voltage, tmp);
 642	if (val & USB4_MARGIN_HW_RES_1_EXCEEDS)
 643		seq_puts(s, " exceeds maximum");
 644	seq_puts(s, "\n");
 645}
 646
 647static void time_margin_show(struct seq_file *s,
 648			     const struct tb_margining *margining, u8 val)
 649{
 650	unsigned int tmp, interval;
 651
 652	tmp = val & USB4_MARGIN_HW_RES_1_MARGIN_MASK;
 653	interval = tmp * margining->max_time_offset / margining->time_steps;
 654	seq_printf(s, "%u mUI (%u)", interval, tmp);
 655	if (val & USB4_MARGIN_HW_RES_1_EXCEEDS)
 656		seq_puts(s, " exceeds maximum");
 657	seq_puts(s, "\n");
 658}
 659
 660static int margining_results_show(struct seq_file *s, void *not_used)
 661{
 662	struct tb_port *port = s->private;
 663	struct usb4_port *usb4 = port->usb4;
 664	struct tb_margining *margining;
 665	struct tb *tb = port->sw->tb;
 666
 667	if (mutex_lock_interruptible(&tb->lock))
 668		return -ERESTARTSYS;
 669
 670	margining = usb4->margining;
 671	/* Dump the raw results first */
 672	seq_printf(s, "0x%08x\n", margining->results[0]);
 673	/* Only the hardware margining has two result dwords */
 674	if (!margining->software) {
 675		unsigned int val;
 676
 677		seq_printf(s, "0x%08x\n", margining->results[1]);
 678
 679		if (margining->time) {
 680			if (!margining->lanes || margining->lanes == 7) {
 681				val = margining->results[1];
 682				seq_puts(s, "# lane 0 right time margin: ");
 683				time_margin_show(s, margining, val);
 684				val = margining->results[1] >>
 685					USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT;
 686				seq_puts(s, "# lane 0 left time margin: ");
 687				time_margin_show(s, margining, val);
 688			}
 689			if (margining->lanes == 1 || margining->lanes == 7) {
 690				val = margining->results[1] >>
 691					USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT;
 692				seq_puts(s, "# lane 1 right time margin: ");
 693				time_margin_show(s, margining, val);
 694				val = margining->results[1] >>
 695					USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT;
 696				seq_puts(s, "# lane 1 left time margin: ");
 697				time_margin_show(s, margining, val);
 698			}
 699		} else {
 700			if (!margining->lanes || margining->lanes == 7) {
 701				val = margining->results[1];
 702				seq_puts(s, "# lane 0 high voltage margin: ");
 703				voltage_margin_show(s, margining, val);
 704				val = margining->results[1] >>
 705					USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT;
 706				seq_puts(s, "# lane 0 low voltage margin: ");
 707				voltage_margin_show(s, margining, val);
 708			}
 709			if (margining->lanes == 1 || margining->lanes == 7) {
 710				val = margining->results[1] >>
 711					USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT;
 712				seq_puts(s, "# lane 1 high voltage margin: ");
 713				voltage_margin_show(s, margining, val);
 714				val = margining->results[1] >>
 715					USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT;
 716				seq_puts(s, "# lane 1 low voltage margin: ");
 717				voltage_margin_show(s, margining, val);
 718			}
 719		}
 720	}
 721
 722	mutex_unlock(&tb->lock);
 723	return 0;
 724}
 725DEBUGFS_ATTR_RW(margining_results);
 726
 727static ssize_t margining_test_write(struct file *file,
 728				    const char __user *user_buf,
 729				    size_t count, loff_t *ppos)
 730{
 731	struct seq_file *s = file->private_data;
 732	struct tb_port *port = s->private;
 733	struct usb4_port *usb4 = port->usb4;
 734	struct tb *tb = port->sw->tb;
 735	int ret = 0;
 736	char *buf;
 737
 738	buf = validate_and_copy_from_user(user_buf, &count);
 739	if (IS_ERR(buf))
 740		return PTR_ERR(buf);
 741
 742	buf[count - 1] = '\0';
 743
 744	if (mutex_lock_interruptible(&tb->lock)) {
 745		ret = -ERESTARTSYS;
 746		goto out_free;
 747	}
 748
 749	if (!strcmp(buf, "time") && supports_time(usb4))
 750		usb4->margining->time = true;
 751	else if (!strcmp(buf, "voltage"))
 752		usb4->margining->time = false;
 753	else
 754		ret = -EINVAL;
 755
 756	mutex_unlock(&tb->lock);
 757
 758out_free:
 759	free_page((unsigned long)buf);
 760	return ret ? ret : count;
 761}
 762
 763static int margining_test_show(struct seq_file *s, void *not_used)
 764{
 765	struct tb_port *port = s->private;
 766	struct usb4_port *usb4 = port->usb4;
 767	struct tb *tb = port->sw->tb;
 768
 769	if (mutex_lock_interruptible(&tb->lock))
 770		return -ERESTARTSYS;
 771
 772	if (supports_time(usb4)) {
 773		if (usb4->margining->time)
 774			seq_puts(s, "voltage [time]\n");
 775		else
 776			seq_puts(s, "[voltage] time\n");
 777	} else {
 778		seq_puts(s, "[voltage]\n");
 779	}
 780
 781	mutex_unlock(&tb->lock);
 782	return 0;
 783}
 784DEBUGFS_ATTR_RW(margining_test);
 785
 786static ssize_t margining_margin_write(struct file *file,
 787				    const char __user *user_buf,
 788				    size_t count, loff_t *ppos)
 789{
 790	struct seq_file *s = file->private_data;
 791	struct tb_port *port = s->private;
 792	struct usb4_port *usb4 = port->usb4;
 793	struct tb *tb = port->sw->tb;
 794	int ret = 0;
 795	char *buf;
 796
 797	buf = validate_and_copy_from_user(user_buf, &count);
 798	if (IS_ERR(buf))
 799		return PTR_ERR(buf);
 800
 801	buf[count - 1] = '\0';
 802
 803	if (mutex_lock_interruptible(&tb->lock)) {
 804		ret = -ERESTARTSYS;
 805		goto out_free;
 806	}
 807
 808	if (usb4->margining->time) {
 809		if (!strcmp(buf, "left"))
 810			usb4->margining->right_high = false;
 811		else if (!strcmp(buf, "right"))
 812			usb4->margining->right_high = true;
 813		else
 814			ret = -EINVAL;
 815	} else {
 816		if (!strcmp(buf, "low"))
 817			usb4->margining->right_high = false;
 818		else if (!strcmp(buf, "high"))
 819			usb4->margining->right_high = true;
 820		else
 821			ret = -EINVAL;
 822	}
 823
 824	mutex_unlock(&tb->lock);
 825
 826out_free:
 827	free_page((unsigned long)buf);
 828	return ret ? ret : count;
 829}
 830
 831static int margining_margin_show(struct seq_file *s, void *not_used)
 832{
 833	struct tb_port *port = s->private;
 834	struct usb4_port *usb4 = port->usb4;
 835	struct tb *tb = port->sw->tb;
 836
 837	if (mutex_lock_interruptible(&tb->lock))
 838		return -ERESTARTSYS;
 839
 840	if (usb4->margining->time) {
 841		if (usb4->margining->right_high)
 842			seq_puts(s, "left [right]\n");
 843		else
 844			seq_puts(s, "[left] right\n");
 845	} else {
 846		if (usb4->margining->right_high)
 847			seq_puts(s, "low [high]\n");
 848		else
 849			seq_puts(s, "[low] high\n");
 850	}
 851
 852	mutex_unlock(&tb->lock);
 853	return 0;
 854}
 855DEBUGFS_ATTR_RW(margining_margin);
 856
 857static void margining_port_init(struct tb_port *port)
 858{
 859	struct tb_margining *margining;
 860	struct dentry *dir, *parent;
 861	struct usb4_port *usb4;
 862	char dir_name[10];
 863	unsigned int val;
 864	int ret;
 865
 866	usb4 = port->usb4;
 867	if (!usb4)
 868		return;
 869
 870	snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
 871	parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
 872
 873	margining = kzalloc(sizeof(*margining), GFP_KERNEL);
 874	if (!margining)
 875		return;
 876
 877	ret = usb4_port_margining_caps(port, margining->caps);
 878	if (ret) {
 879		kfree(margining);
 880		return;
 881	}
 882
 883	usb4->margining = margining;
 884
 885	/* Set the initial mode */
 886	if (supports_software(usb4))
 887		margining->software = true;
 888
 889	val = (margining->caps[0] & USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK) >>
 890		USB4_MARGIN_CAP_0_VOLTAGE_STEPS_SHIFT;
 891	margining->voltage_steps = val;
 892	val = (margining->caps[0] & USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK) >>
 893		USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_SHIFT;
 894	margining->max_voltage_offset = 74 + val * 2;
 895
 896	if (supports_time(usb4)) {
 897		val = (margining->caps[1] & USB4_MARGIN_CAP_1_TIME_STEPS_MASK) >>
 898			USB4_MARGIN_CAP_1_TIME_STEPS_SHIFT;
 899		margining->time_steps = val;
 900		val = (margining->caps[1] & USB4_MARGIN_CAP_1_TIME_OFFSET_MASK) >>
 901			USB4_MARGIN_CAP_1_TIME_OFFSET_SHIFT;
 902		/*
 903		 * Store it as mUI (milli Unit Interval) because we want
 904		 * to keep it as integer.
 905		 */
 906		margining->max_time_offset = 200 + 10 * val;
 907	}
 908
 909	dir = debugfs_create_dir("margining", parent);
 910	if (supports_hardware(usb4)) {
 911		val = (margining->caps[1] & USB4_MARGIN_CAP_1_MIN_BER_MASK) >>
 912			USB4_MARGIN_CAP_1_MIN_BER_SHIFT;
 913		margining->min_ber_level = val;
 914		val = (margining->caps[1] & USB4_MARGIN_CAP_1_MAX_BER_MASK) >>
 915			USB4_MARGIN_CAP_1_MAX_BER_SHIFT;
 916		margining->max_ber_level = val;
 917
 918		/* Set the default to minimum */
 919		margining->ber_level = margining->min_ber_level;
 920
 921		debugfs_create_file("ber_level_contour", 0400, dir, port,
 922				    &margining_ber_level_fops);
 923	}
 924	debugfs_create_file("caps", 0400, dir, port, &margining_caps_fops);
 925	debugfs_create_file("lanes", 0600, dir, port, &margining_lanes_fops);
 926	debugfs_create_file("mode", 0600, dir, port, &margining_mode_fops);
 927	debugfs_create_file("run", 0600, dir, port, &margining_run_fops);
 928	debugfs_create_file("results", 0600, dir, port, &margining_results_fops);
 929	debugfs_create_file("test", 0600, dir, port, &margining_test_fops);
 930	if (independent_voltage_margins(usb4) ||
 931	    (supports_time(usb4) && independent_time_margins(usb4)))
 932		debugfs_create_file("margin", 0600, dir, port, &margining_margin_fops);
 933}
 934
 935static void margining_port_remove(struct tb_port *port)
 936{
 937	struct dentry *parent;
 938	char dir_name[10];
 939
 940	if (!port->usb4)
 941		return;
 942
 943	snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
 944	parent = debugfs_lookup(dir_name, port->sw->debugfs_dir);
 945	debugfs_remove_recursive(debugfs_lookup("margining", parent));
 946
 947	kfree(port->usb4->margining);
 948	port->usb4->margining = NULL;
 949}
 950
 951static void margining_switch_init(struct tb_switch *sw)
 952{
 953	struct tb_port *upstream, *downstream;
 954	struct tb_switch *parent_sw;
 955	u64 route = tb_route(sw);
 956
 957	if (!route)
 958		return;
 959
 960	upstream = tb_upstream_port(sw);
 961	parent_sw = tb_switch_parent(sw);
 962	downstream = tb_port_at(route, parent_sw);
 963
 964	margining_port_init(downstream);
 965	margining_port_init(upstream);
 966}
 967
 968static void margining_switch_remove(struct tb_switch *sw)
 969{
 970	struct tb_switch *parent_sw;
 971	struct tb_port *downstream;
 972	u64 route = tb_route(sw);
 973
 974	if (!route)
 975		return;
 976
 977	/*
 978	 * Upstream is removed with the router itself but we need to
 979	 * remove the downstream port margining directory.
 980	 */
 981	parent_sw = tb_switch_parent(sw);
 982	downstream = tb_port_at(route, parent_sw);
 983	margining_port_remove(downstream);
 984}
 985
 986static void margining_xdomain_init(struct tb_xdomain *xd)
 987{
 988	struct tb_switch *parent_sw;
 989	struct tb_port *downstream;
 990
 991	parent_sw = tb_xdomain_parent(xd);
 992	downstream = tb_port_at(xd->route, parent_sw);
 993
 994	margining_port_init(downstream);
 995}
 996
 997static void margining_xdomain_remove(struct tb_xdomain *xd)
 998{
 999	struct tb_switch *parent_sw;
1000	struct tb_port *downstream;
1001
1002	parent_sw = tb_xdomain_parent(xd);
1003	downstream = tb_port_at(xd->route, parent_sw);
1004	margining_port_remove(downstream);
1005}
1006#else
1007static inline void margining_switch_init(struct tb_switch *sw) { }
1008static inline void margining_switch_remove(struct tb_switch *sw) { }
1009static inline void margining_xdomain_init(struct tb_xdomain *xd) { }
1010static inline void margining_xdomain_remove(struct tb_xdomain *xd) { }
1011#endif
1012
1013static int port_clear_all_counters(struct tb_port *port)
1014{
1015	u32 *buf;
1016	int ret;
1017
1018	buf = kcalloc(COUNTER_SET_LEN * port->config.max_counters, sizeof(u32),
1019		      GFP_KERNEL);
1020	if (!buf)
1021		return -ENOMEM;
1022
1023	ret = tb_port_write(port, buf, TB_CFG_COUNTERS, 0,
1024			    COUNTER_SET_LEN * port->config.max_counters);
1025	kfree(buf);
1026
1027	return ret;
1028}
1029
1030static ssize_t counters_write(struct file *file, const char __user *user_buf,
1031			      size_t count, loff_t *ppos)
1032{
1033	struct seq_file *s = file->private_data;
1034	struct tb_port *port = s->private;
1035	struct tb_switch *sw = port->sw;
1036	struct tb *tb = port->sw->tb;
1037	char *buf;
1038	int ret;
1039
1040	buf = validate_and_copy_from_user(user_buf, &count);
1041	if (IS_ERR(buf))
1042		return PTR_ERR(buf);
1043
1044	pm_runtime_get_sync(&sw->dev);
1045
1046	if (mutex_lock_interruptible(&tb->lock)) {
1047		ret = -ERESTARTSYS;
1048		goto out;
1049	}
1050
1051	/* If written delimiter only, clear all counters in one shot */
1052	if (buf[0] == '\n') {
1053		ret = port_clear_all_counters(port);
1054	} else  {
1055		char *line = buf;
1056		u32 val, offset;
1057
1058		ret = -EINVAL;
1059		while (parse_line(&line, &offset, &val, 1, 4)) {
1060			ret = tb_port_write(port, &val, TB_CFG_COUNTERS,
1061					    offset, 1);
1062			if (ret)
1063				break;
1064		}
1065	}
1066
1067	mutex_unlock(&tb->lock);
1068
1069out:
1070	pm_runtime_mark_last_busy(&sw->dev);
1071	pm_runtime_put_autosuspend(&sw->dev);
1072	free_page((unsigned long)buf);
1073
1074	return ret < 0 ? ret : count;
1075}
1076
1077static void cap_show_by_dw(struct seq_file *s, struct tb_switch *sw,
1078			   struct tb_port *port, unsigned int cap,
1079			   unsigned int offset, u8 cap_id, u8 vsec_id,
1080			   int dwords)
1081{
1082	int i, ret;
1083	u32 data;
1084
1085	for (i = 0; i < dwords; i++) {
1086		if (port)
1087			ret = tb_port_read(port, &data, TB_CFG_PORT, cap + offset + i, 1);
1088		else
1089			ret = tb_sw_read(sw, &data, TB_CFG_SWITCH, cap + offset + i, 1);
1090		if (ret) {
1091			seq_printf(s, "0x%04x <not accessible>\n", cap + offset + i);
1092			continue;
1093		}
1094
1095		seq_printf(s, "0x%04x %4d 0x%02x 0x%02x 0x%08x\n", cap + offset + i,
1096			   offset + i, cap_id, vsec_id, data);
1097	}
1098}
1099
1100static void cap_show(struct seq_file *s, struct tb_switch *sw,
1101		     struct tb_port *port, unsigned int cap, u8 cap_id,
1102		     u8 vsec_id, int length)
1103{
1104	int ret, offset = 0;
1105
1106	while (length > 0) {
1107		int i, dwords = min(length, TB_MAX_CONFIG_RW_LENGTH);
1108		u32 data[TB_MAX_CONFIG_RW_LENGTH];
1109
1110		if (port)
1111			ret = tb_port_read(port, data, TB_CFG_PORT, cap + offset,
1112					   dwords);
1113		else
1114			ret = tb_sw_read(sw, data, TB_CFG_SWITCH, cap + offset, dwords);
1115		if (ret) {
1116			cap_show_by_dw(s, sw, port, cap, offset, cap_id, vsec_id, length);
1117			return;
1118		}
1119
1120		for (i = 0; i < dwords; i++) {
1121			seq_printf(s, "0x%04x %4d 0x%02x 0x%02x 0x%08x\n",
1122				   cap + offset + i, offset + i,
1123				   cap_id, vsec_id, data[i]);
1124		}
1125
1126		length -= dwords;
1127		offset += dwords;
1128	}
1129}
1130
1131static void port_cap_show(struct tb_port *port, struct seq_file *s,
1132			  unsigned int cap)
1133{
1134	struct tb_cap_any header;
1135	u8 vsec_id = 0;
1136	size_t length;
1137	int ret;
1138
1139	ret = tb_port_read(port, &header, TB_CFG_PORT, cap, 1);
1140	if (ret) {
1141		seq_printf(s, "0x%04x <capability read failed>\n", cap);
1142		return;
1143	}
1144
1145	switch (header.basic.cap) {
1146	case TB_PORT_CAP_PHY:
1147		length = PORT_CAP_LANE_LEN;
1148		break;
1149
1150	case TB_PORT_CAP_TIME1:
1151		length = PORT_CAP_TMU_LEN;
1152		break;
1153
1154	case TB_PORT_CAP_POWER:
1155		length = PORT_CAP_POWER_LEN;
1156		break;
1157
1158	case TB_PORT_CAP_ADAP:
1159		if (tb_port_is_pcie_down(port) || tb_port_is_pcie_up(port)) {
1160			length = PORT_CAP_PCIE_LEN;
1161		} else if (tb_port_is_dpin(port) || tb_port_is_dpout(port)) {
1162			length = PORT_CAP_DP_LEN;
1163		} else if (tb_port_is_usb3_down(port) ||
1164			   tb_port_is_usb3_up(port)) {
1165			length = PORT_CAP_USB3_LEN;
1166		} else {
1167			seq_printf(s, "0x%04x <unsupported capability 0x%02x>\n",
1168				   cap, header.basic.cap);
1169			return;
1170		}
1171		break;
1172
1173	case TB_PORT_CAP_VSE:
1174		if (!header.extended_short.length) {
1175			ret = tb_port_read(port, (u32 *)&header + 1, TB_CFG_PORT,
1176					   cap + 1, 1);
1177			if (ret) {
1178				seq_printf(s, "0x%04x <capability read failed>\n",
1179					   cap + 1);
1180				return;
1181			}
1182			length = header.extended_long.length;
1183			vsec_id = header.extended_short.vsec_id;
1184		} else {
1185			length = header.extended_short.length;
1186			vsec_id = header.extended_short.vsec_id;
1187		}
1188		break;
1189
1190	case TB_PORT_CAP_USB4:
1191		length = PORT_CAP_USB4_LEN;
1192		break;
1193
1194	default:
1195		seq_printf(s, "0x%04x <unsupported capability 0x%02x>\n",
1196			   cap, header.basic.cap);
1197		return;
1198	}
1199
1200	cap_show(s, NULL, port, cap, header.basic.cap, vsec_id, length);
1201}
1202
1203static void port_caps_show(struct tb_port *port, struct seq_file *s)
1204{
1205	int cap;
1206
1207	cap = tb_port_next_cap(port, 0);
1208	while (cap > 0) {
1209		port_cap_show(port, s, cap);
1210		cap = tb_port_next_cap(port, cap);
1211	}
1212}
1213
1214static int port_basic_regs_show(struct tb_port *port, struct seq_file *s)
1215{
1216	u32 data[PORT_CAP_BASIC_LEN];
1217	int ret, i;
1218
1219	ret = tb_port_read(port, data, TB_CFG_PORT, 0, ARRAY_SIZE(data));
1220	if (ret)
1221		return ret;
1222
1223	for (i = 0; i < ARRAY_SIZE(data); i++)
1224		seq_printf(s, "0x%04x %4d 0x00 0x00 0x%08x\n", i, i, data[i]);
1225
1226	return 0;
1227}
1228
1229static int port_regs_show(struct seq_file *s, void *not_used)
1230{
1231	struct tb_port *port = s->private;
1232	struct tb_switch *sw = port->sw;
1233	struct tb *tb = sw->tb;
1234	int ret;
1235
1236	pm_runtime_get_sync(&sw->dev);
1237
1238	if (mutex_lock_interruptible(&tb->lock)) {
1239		ret = -ERESTARTSYS;
1240		goto out_rpm_put;
1241	}
1242
1243	seq_puts(s, "# offset relative_offset cap_id vs_cap_id value\n");
1244
1245	ret = port_basic_regs_show(port, s);
1246	if (ret)
1247		goto out_unlock;
1248
1249	port_caps_show(port, s);
1250
1251out_unlock:
1252	mutex_unlock(&tb->lock);
1253out_rpm_put:
1254	pm_runtime_mark_last_busy(&sw->dev);
1255	pm_runtime_put_autosuspend(&sw->dev);
1256
1257	return ret;
1258}
1259DEBUGFS_ATTR_RW(port_regs);
1260
1261static void switch_cap_show(struct tb_switch *sw, struct seq_file *s,
1262			    unsigned int cap)
1263{
1264	struct tb_cap_any header;
1265	int ret, length;
1266	u8 vsec_id = 0;
1267
1268	ret = tb_sw_read(sw, &header, TB_CFG_SWITCH, cap, 1);
1269	if (ret) {
1270		seq_printf(s, "0x%04x <capability read failed>\n", cap);
1271		return;
1272	}
1273
1274	if (header.basic.cap == TB_SWITCH_CAP_VSE) {
1275		if (!header.extended_short.length) {
1276			ret = tb_sw_read(sw, (u32 *)&header + 1, TB_CFG_SWITCH,
1277					 cap + 1, 1);
1278			if (ret) {
1279				seq_printf(s, "0x%04x <capability read failed>\n",
1280					   cap + 1);
1281				return;
1282			}
1283			length = header.extended_long.length;
1284		} else {
1285			length = header.extended_short.length;
1286		}
1287		vsec_id = header.extended_short.vsec_id;
1288	} else {
1289		if (header.basic.cap == TB_SWITCH_CAP_TMU) {
1290			length = SWITCH_CAP_TMU_LEN;
1291		} else  {
1292			seq_printf(s, "0x%04x <unknown capability 0x%02x>\n",
1293				   cap, header.basic.cap);
1294			return;
1295		}
1296	}
1297
1298	cap_show(s, sw, NULL, cap, header.basic.cap, vsec_id, length);
1299}
1300
1301static void switch_caps_show(struct tb_switch *sw, struct seq_file *s)
1302{
1303	int cap;
1304
1305	cap = tb_switch_next_cap(sw, 0);
1306	while (cap > 0) {
1307		switch_cap_show(sw, s, cap);
1308		cap = tb_switch_next_cap(sw, cap);
1309	}
1310}
1311
1312static int switch_basic_regs_show(struct tb_switch *sw, struct seq_file *s)
1313{
1314	u32 data[SWITCH_CAP_BASIC_LEN];
1315	size_t dwords;
1316	int ret, i;
1317
1318	/* Only USB4 has the additional registers */
1319	if (tb_switch_is_usb4(sw))
1320		dwords = ARRAY_SIZE(data);
1321	else
1322		dwords = 7;
1323
1324	ret = tb_sw_read(sw, data, TB_CFG_SWITCH, 0, dwords);
1325	if (ret)
1326		return ret;
1327
1328	for (i = 0; i < dwords; i++)
1329		seq_printf(s, "0x%04x %4d 0x00 0x00 0x%08x\n", i, i, data[i]);
1330
1331	return 0;
1332}
1333
1334static int switch_regs_show(struct seq_file *s, void *not_used)
1335{
1336	struct tb_switch *sw = s->private;
1337	struct tb *tb = sw->tb;
1338	int ret;
1339
1340	pm_runtime_get_sync(&sw->dev);
1341
1342	if (mutex_lock_interruptible(&tb->lock)) {
1343		ret = -ERESTARTSYS;
1344		goto out_rpm_put;
1345	}
1346
1347	seq_puts(s, "# offset relative_offset cap_id vs_cap_id value\n");
1348
1349	ret = switch_basic_regs_show(sw, s);
1350	if (ret)
1351		goto out_unlock;
1352
1353	switch_caps_show(sw, s);
1354
1355out_unlock:
1356	mutex_unlock(&tb->lock);
1357out_rpm_put:
1358	pm_runtime_mark_last_busy(&sw->dev);
1359	pm_runtime_put_autosuspend(&sw->dev);
1360
1361	return ret;
1362}
1363DEBUGFS_ATTR_RW(switch_regs);
1364
1365static int path_show_one(struct tb_port *port, struct seq_file *s, int hopid)
1366{
1367	u32 data[PATH_LEN];
1368	int ret, i;
1369
1370	ret = tb_port_read(port, data, TB_CFG_HOPS, hopid * PATH_LEN,
1371			   ARRAY_SIZE(data));
1372	if (ret) {
1373		seq_printf(s, "0x%04x <not accessible>\n", hopid * PATH_LEN);
1374		return ret;
1375	}
1376
1377	for (i = 0; i < ARRAY_SIZE(data); i++) {
1378		seq_printf(s, "0x%04x %4d 0x%02x 0x%08x\n",
1379			   hopid * PATH_LEN + i, i, hopid, data[i]);
1380	}
1381
1382	return 0;
1383}
1384
1385static int path_show(struct seq_file *s, void *not_used)
1386{
1387	struct tb_port *port = s->private;
1388	struct tb_switch *sw = port->sw;
1389	struct tb *tb = sw->tb;
1390	int start, i, ret = 0;
1391
1392	pm_runtime_get_sync(&sw->dev);
1393
1394	if (mutex_lock_interruptible(&tb->lock)) {
1395		ret = -ERESTARTSYS;
1396		goto out_rpm_put;
1397	}
1398
1399	seq_puts(s, "# offset relative_offset in_hop_id value\n");
1400
1401	/* NHI and lane adapters have entry for path 0 */
1402	if (tb_port_is_null(port) || tb_port_is_nhi(port)) {
1403		ret = path_show_one(port, s, 0);
1404		if (ret)
1405			goto out_unlock;
1406	}
1407
1408	start = tb_port_is_nhi(port) ? 1 : TB_PATH_MIN_HOPID;
1409
1410	for (i = start; i <= port->config.max_in_hop_id; i++) {
1411		ret = path_show_one(port, s, i);
1412		if (ret)
1413			break;
1414	}
1415
1416out_unlock:
1417	mutex_unlock(&tb->lock);
1418out_rpm_put:
1419	pm_runtime_mark_last_busy(&sw->dev);
1420	pm_runtime_put_autosuspend(&sw->dev);
1421
1422	return ret;
1423}
1424DEBUGFS_ATTR_RO(path);
1425
1426static int counter_set_regs_show(struct tb_port *port, struct seq_file *s,
1427				 int counter)
1428{
1429	u32 data[COUNTER_SET_LEN];
1430	int ret, i;
1431
1432	ret = tb_port_read(port, data, TB_CFG_COUNTERS,
1433			   counter * COUNTER_SET_LEN, ARRAY_SIZE(data));
1434	if (ret) {
1435		seq_printf(s, "0x%04x <not accessible>\n",
1436			   counter * COUNTER_SET_LEN);
1437		return ret;
1438	}
1439
1440	for (i = 0; i < ARRAY_SIZE(data); i++) {
1441		seq_printf(s, "0x%04x %4d 0x%02x 0x%08x\n",
1442			   counter * COUNTER_SET_LEN + i, i, counter, data[i]);
1443	}
1444
1445	return 0;
1446}
1447
1448static int counters_show(struct seq_file *s, void *not_used)
1449{
1450	struct tb_port *port = s->private;
1451	struct tb_switch *sw = port->sw;
1452	struct tb *tb = sw->tb;
1453	int i, ret = 0;
1454
1455	pm_runtime_get_sync(&sw->dev);
1456
1457	if (mutex_lock_interruptible(&tb->lock)) {
1458		ret = -ERESTARTSYS;
1459		goto out;
1460	}
1461
1462	seq_puts(s, "# offset relative_offset counter_id value\n");
1463
1464	for (i = 0; i < port->config.max_counters; i++) {
1465		ret = counter_set_regs_show(port, s, i);
1466		if (ret)
1467			break;
1468	}
1469
1470	mutex_unlock(&tb->lock);
1471
1472out:
1473	pm_runtime_mark_last_busy(&sw->dev);
1474	pm_runtime_put_autosuspend(&sw->dev);
1475
1476	return ret;
1477}
1478DEBUGFS_ATTR_RW(counters);
1479
1480/**
1481 * tb_switch_debugfs_init() - Add debugfs entries for router
1482 * @sw: Pointer to the router
1483 *
1484 * Adds debugfs directories and files for given router.
1485 */
1486void tb_switch_debugfs_init(struct tb_switch *sw)
1487{
1488	struct dentry *debugfs_dir;
1489	struct tb_port *port;
1490
1491	debugfs_dir = debugfs_create_dir(dev_name(&sw->dev), tb_debugfs_root);
1492	sw->debugfs_dir = debugfs_dir;
1493	debugfs_create_file("regs", DEBUGFS_MODE, debugfs_dir, sw,
1494			    &switch_regs_fops);
1495
1496	tb_switch_for_each_port(sw, port) {
1497		struct dentry *debugfs_dir;
1498		char dir_name[10];
1499
1500		if (port->disabled)
1501			continue;
1502		if (port->config.type == TB_TYPE_INACTIVE)
1503			continue;
1504
1505		snprintf(dir_name, sizeof(dir_name), "port%d", port->port);
1506		debugfs_dir = debugfs_create_dir(dir_name, sw->debugfs_dir);
1507		debugfs_create_file("regs", DEBUGFS_MODE, debugfs_dir,
1508				    port, &port_regs_fops);
1509		debugfs_create_file("path", 0400, debugfs_dir, port,
1510				    &path_fops);
1511		if (port->config.counters_support)
1512			debugfs_create_file("counters", 0600, debugfs_dir, port,
1513					    &counters_fops);
1514	}
1515
1516	margining_switch_init(sw);
1517}
1518
1519/**
1520 * tb_switch_debugfs_remove() - Remove all router debugfs entries
1521 * @sw: Pointer to the router
1522 *
1523 * Removes all previously added debugfs entries under this router.
1524 */
1525void tb_switch_debugfs_remove(struct tb_switch *sw)
1526{
1527	margining_switch_remove(sw);
1528	debugfs_remove_recursive(sw->debugfs_dir);
1529}
1530
1531void tb_xdomain_debugfs_init(struct tb_xdomain *xd)
1532{
1533	margining_xdomain_init(xd);
1534}
1535
1536void tb_xdomain_debugfs_remove(struct tb_xdomain *xd)
1537{
1538	margining_xdomain_remove(xd);
1539}
1540
1541/**
1542 * tb_service_debugfs_init() - Add debugfs directory for service
1543 * @svc: Thunderbolt service pointer
1544 *
1545 * Adds debugfs directory for service.
1546 */
1547void tb_service_debugfs_init(struct tb_service *svc)
1548{
1549	svc->debugfs_dir = debugfs_create_dir(dev_name(&svc->dev),
1550					      tb_debugfs_root);
1551}
1552
1553/**
1554 * tb_service_debugfs_remove() - Remove service debugfs directory
1555 * @svc: Thunderbolt service pointer
1556 *
1557 * Removes the previously created debugfs directory for @svc.
1558 */
1559void tb_service_debugfs_remove(struct tb_service *svc)
1560{
1561	debugfs_remove_recursive(svc->debugfs_dir);
1562	svc->debugfs_dir = NULL;
1563}
1564
1565void tb_debugfs_init(void)
1566{
1567	tb_debugfs_root = debugfs_create_dir("thunderbolt", NULL);
1568}
1569
1570void tb_debugfs_exit(void)
1571{
1572	debugfs_remove_recursive(tb_debugfs_root);
1573}