162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is part of the Chelsio T4 Ethernet driver for Linux.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software is available to you under a choice of one of two
762306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the
1062306a36Sopenharmony_ci * OpenIB.org BSD license below:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
1362306a36Sopenharmony_ci *     without modification, are permitted provided that the following
1462306a36Sopenharmony_ci *     conditions are met:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *      - Redistributions of source code must retain the above
1762306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
1862306a36Sopenharmony_ci *        disclaimer.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
2162306a36Sopenharmony_ci *        copyright notice, this list of conditions and the following
2262306a36Sopenharmony_ci *        disclaimer in the documentation and/or other materials
2362306a36Sopenharmony_ci *        provided with the distribution.
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3262306a36Sopenharmony_ci * SOFTWARE.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include <linux/seq_file.h>
3662306a36Sopenharmony_ci#include <linux/debugfs.h>
3762306a36Sopenharmony_ci#include <linux/string_helpers.h>
3862306a36Sopenharmony_ci#include <linux/sort.h>
3962306a36Sopenharmony_ci#include <linux/ctype.h>
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#include "cxgb4.h"
4262306a36Sopenharmony_ci#include "t4_regs.h"
4362306a36Sopenharmony_ci#include "t4_values.h"
4462306a36Sopenharmony_ci#include "t4fw_api.h"
4562306a36Sopenharmony_ci#include "cxgb4_debugfs.h"
4662306a36Sopenharmony_ci#include "clip_tbl.h"
4762306a36Sopenharmony_ci#include "l2t.h"
4862306a36Sopenharmony_ci#include "cudbg_if.h"
4962306a36Sopenharmony_ci#include "cudbg_lib_common.h"
5062306a36Sopenharmony_ci#include "cudbg_entity.h"
5162306a36Sopenharmony_ci#include "cudbg_lib.h"
5262306a36Sopenharmony_ci#include "cxgb4_tc_mqprio.h"
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* generic seq_file support for showing a table of size rows x width. */
5562306a36Sopenharmony_cistatic void *seq_tab_get_idx(struct seq_tab *tb, loff_t pos)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	pos -= tb->skip_first;
5862306a36Sopenharmony_ci	return pos >= tb->rows ? NULL : &tb->data[pos * tb->width];
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic void *seq_tab_start(struct seq_file *seq, loff_t *pos)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	struct seq_tab *tb = seq->private;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (tb->skip_first && *pos == 0)
6662306a36Sopenharmony_ci		return SEQ_START_TOKEN;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	return seq_tab_get_idx(tb, *pos);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic void *seq_tab_next(struct seq_file *seq, void *v, loff_t *pos)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	v = seq_tab_get_idx(seq->private, *pos + 1);
7462306a36Sopenharmony_ci	++(*pos);
7562306a36Sopenharmony_ci	return v;
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic void seq_tab_stop(struct seq_file *seq, void *v)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic int seq_tab_show(struct seq_file *seq, void *v)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	const struct seq_tab *tb = seq->private;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return tb->show(seq, v, ((char *)v - tb->data) / tb->width);
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic const struct seq_operations seq_tab_ops = {
9062306a36Sopenharmony_ci	.start = seq_tab_start,
9162306a36Sopenharmony_ci	.next  = seq_tab_next,
9262306a36Sopenharmony_ci	.stop  = seq_tab_stop,
9362306a36Sopenharmony_ci	.show  = seq_tab_show
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistruct seq_tab *seq_open_tab(struct file *f, unsigned int rows,
9762306a36Sopenharmony_ci			     unsigned int width, unsigned int have_header,
9862306a36Sopenharmony_ci			     int (*show)(struct seq_file *seq, void *v, int i))
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	struct seq_tab *p;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	p = __seq_open_private(f, &seq_tab_ops, sizeof(*p) + rows * width);
10362306a36Sopenharmony_ci	if (p) {
10462306a36Sopenharmony_ci		p->show = show;
10562306a36Sopenharmony_ci		p->rows = rows;
10662306a36Sopenharmony_ci		p->width = width;
10762306a36Sopenharmony_ci		p->skip_first = have_header != 0;
10862306a36Sopenharmony_ci	}
10962306a36Sopenharmony_ci	return p;
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/* Trim the size of a seq_tab to the supplied number of rows.  The operation is
11362306a36Sopenharmony_ci * irreversible.
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_cistatic int seq_tab_trim(struct seq_tab *p, unsigned int new_rows)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	if (new_rows > p->rows)
11862306a36Sopenharmony_ci		return -EINVAL;
11962306a36Sopenharmony_ci	p->rows = new_rows;
12062306a36Sopenharmony_ci	return 0;
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistatic int cim_la_show(struct seq_file *seq, void *v, int idx)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN)
12662306a36Sopenharmony_ci		seq_puts(seq, "Status   Data      PC     LS0Stat  LS0Addr "
12762306a36Sopenharmony_ci			 "            LS0Data\n");
12862306a36Sopenharmony_ci	else {
12962306a36Sopenharmony_ci		const u32 *p = v;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		seq_printf(seq,
13262306a36Sopenharmony_ci			   "  %02x  %x%07x %x%07x %08x %08x %08x%08x%08x%08x\n",
13362306a36Sopenharmony_ci			   (p[0] >> 4) & 0xff, p[0] & 0xf, p[1] >> 4,
13462306a36Sopenharmony_ci			   p[1] & 0xf, p[2] >> 4, p[2] & 0xf, p[3], p[4], p[5],
13562306a36Sopenharmony_ci			   p[6], p[7]);
13662306a36Sopenharmony_ci	}
13762306a36Sopenharmony_ci	return 0;
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic int cim_la_show_3in1(struct seq_file *seq, void *v, int idx)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
14362306a36Sopenharmony_ci		seq_puts(seq, "Status   Data      PC\n");
14462306a36Sopenharmony_ci	} else {
14562306a36Sopenharmony_ci		const u32 *p = v;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %08x %08x\n", p[5] & 0xff, p[6],
14862306a36Sopenharmony_ci			   p[7]);
14962306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %02x%06x %02x%06x\n",
15062306a36Sopenharmony_ci			   (p[3] >> 8) & 0xff, p[3] & 0xff, p[4] >> 8,
15162306a36Sopenharmony_ci			   p[4] & 0xff, p[5] >> 8);
15262306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %x%07x %x%07x\n", (p[0] >> 4) & 0xff,
15362306a36Sopenharmony_ci			   p[0] & 0xf, p[1] >> 4, p[1] & 0xf, p[2] >> 4);
15462306a36Sopenharmony_ci	}
15562306a36Sopenharmony_ci	return 0;
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic int cim_la_show_t6(struct seq_file *seq, void *v, int idx)
15962306a36Sopenharmony_ci{
16062306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
16162306a36Sopenharmony_ci		seq_puts(seq, "Status   Inst    Data      PC     LS0Stat  "
16262306a36Sopenharmony_ci			 "LS0Addr  LS0Data  LS1Stat  LS1Addr  LS1Data\n");
16362306a36Sopenharmony_ci	} else {
16462306a36Sopenharmony_ci		const u32 *p = v;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %04x%04x %04x%04x %04x%04x %08x %08x %08x %08x %08x %08x\n",
16762306a36Sopenharmony_ci			   (p[9] >> 16) & 0xff,       /* Status */
16862306a36Sopenharmony_ci			   p[9] & 0xffff, p[8] >> 16, /* Inst */
16962306a36Sopenharmony_ci			   p[8] & 0xffff, p[7] >> 16, /* Data */
17062306a36Sopenharmony_ci			   p[7] & 0xffff, p[6] >> 16, /* PC */
17162306a36Sopenharmony_ci			   p[2], p[1], p[0],      /* LS0 Stat, Addr and Data */
17262306a36Sopenharmony_ci			   p[5], p[4], p[3]);     /* LS1 Stat, Addr and Data */
17362306a36Sopenharmony_ci	}
17462306a36Sopenharmony_ci	return 0;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic int cim_la_show_pc_t6(struct seq_file *seq, void *v, int idx)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
18062306a36Sopenharmony_ci		seq_puts(seq, "Status   Inst    Data      PC\n");
18162306a36Sopenharmony_ci	} else {
18262306a36Sopenharmony_ci		const u32 *p = v;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %08x %08x %08x\n",
18562306a36Sopenharmony_ci			   p[3] & 0xff, p[2], p[1], p[0]);
18662306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %02x%06x %02x%06x %02x%06x\n",
18762306a36Sopenharmony_ci			   (p[6] >> 8) & 0xff, p[6] & 0xff, p[5] >> 8,
18862306a36Sopenharmony_ci			   p[5] & 0xff, p[4] >> 8, p[4] & 0xff, p[3] >> 8);
18962306a36Sopenharmony_ci		seq_printf(seq, "  %02x   %04x%04x %04x%04x %04x%04x\n",
19062306a36Sopenharmony_ci			   (p[9] >> 16) & 0xff, p[9] & 0xffff, p[8] >> 16,
19162306a36Sopenharmony_ci			   p[8] & 0xffff, p[7] >> 16, p[7] & 0xffff,
19262306a36Sopenharmony_ci			   p[6] >> 16);
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci	return 0;
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic int cim_la_open(struct inode *inode, struct file *file)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	int ret;
20062306a36Sopenharmony_ci	unsigned int cfg;
20162306a36Sopenharmony_ci	struct seq_tab *p;
20262306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
20562306a36Sopenharmony_ci	if (ret)
20662306a36Sopenharmony_ci		return ret;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	if (is_t6(adap->params.chip)) {
20962306a36Sopenharmony_ci		/* +1 to account for integer division of CIMLA_SIZE/10 */
21062306a36Sopenharmony_ci		p = seq_open_tab(file, (adap->params.cim_la_size / 10) + 1,
21162306a36Sopenharmony_ci				 10 * sizeof(u32), 1,
21262306a36Sopenharmony_ci				 cfg & UPDBGLACAPTPCONLY_F ?
21362306a36Sopenharmony_ci					cim_la_show_pc_t6 : cim_la_show_t6);
21462306a36Sopenharmony_ci	} else {
21562306a36Sopenharmony_ci		p = seq_open_tab(file, adap->params.cim_la_size / 8,
21662306a36Sopenharmony_ci				 8 * sizeof(u32), 1,
21762306a36Sopenharmony_ci				 cfg & UPDBGLACAPTPCONLY_F ? cim_la_show_3in1 :
21862306a36Sopenharmony_ci							     cim_la_show);
21962306a36Sopenharmony_ci	}
22062306a36Sopenharmony_ci	if (!p)
22162306a36Sopenharmony_ci		return -ENOMEM;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	ret = t4_cim_read_la(adap, (u32 *)p->data, NULL);
22462306a36Sopenharmony_ci	if (ret)
22562306a36Sopenharmony_ci		seq_release_private(inode, file);
22662306a36Sopenharmony_ci	return ret;
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic const struct file_operations cim_la_fops = {
23062306a36Sopenharmony_ci	.owner   = THIS_MODULE,
23162306a36Sopenharmony_ci	.open    = cim_la_open,
23262306a36Sopenharmony_ci	.read    = seq_read,
23362306a36Sopenharmony_ci	.llseek  = seq_lseek,
23462306a36Sopenharmony_ci	.release = seq_release_private
23562306a36Sopenharmony_ci};
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_cistatic int cim_pif_la_show(struct seq_file *seq, void *v, int idx)
23862306a36Sopenharmony_ci{
23962306a36Sopenharmony_ci	const u32 *p = v;
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
24262306a36Sopenharmony_ci		seq_puts(seq, "Cntl ID DataBE   Addr                 Data\n");
24362306a36Sopenharmony_ci	} else if (idx < CIM_PIFLA_SIZE) {
24462306a36Sopenharmony_ci		seq_printf(seq, " %02x  %02x  %04x  %08x %08x%08x%08x%08x\n",
24562306a36Sopenharmony_ci			   (p[5] >> 22) & 0xff, (p[5] >> 16) & 0x3f,
24662306a36Sopenharmony_ci			   p[5] & 0xffff, p[4], p[3], p[2], p[1], p[0]);
24762306a36Sopenharmony_ci	} else {
24862306a36Sopenharmony_ci		if (idx == CIM_PIFLA_SIZE)
24962306a36Sopenharmony_ci			seq_puts(seq, "\nCntl ID               Data\n");
25062306a36Sopenharmony_ci		seq_printf(seq, " %02x  %02x %08x%08x%08x%08x\n",
25162306a36Sopenharmony_ci			   (p[4] >> 6) & 0xff, p[4] & 0x3f,
25262306a36Sopenharmony_ci			   p[3], p[2], p[1], p[0]);
25362306a36Sopenharmony_ci	}
25462306a36Sopenharmony_ci	return 0;
25562306a36Sopenharmony_ci}
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic int cim_pif_la_open(struct inode *inode, struct file *file)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	struct seq_tab *p;
26062306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	p = seq_open_tab(file, 2 * CIM_PIFLA_SIZE, 6 * sizeof(u32), 1,
26362306a36Sopenharmony_ci			 cim_pif_la_show);
26462306a36Sopenharmony_ci	if (!p)
26562306a36Sopenharmony_ci		return -ENOMEM;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	t4_cim_read_pif_la(adap, (u32 *)p->data,
26862306a36Sopenharmony_ci			   (u32 *)p->data + 6 * CIM_PIFLA_SIZE, NULL, NULL);
26962306a36Sopenharmony_ci	return 0;
27062306a36Sopenharmony_ci}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistatic const struct file_operations cim_pif_la_fops = {
27362306a36Sopenharmony_ci	.owner   = THIS_MODULE,
27462306a36Sopenharmony_ci	.open    = cim_pif_la_open,
27562306a36Sopenharmony_ci	.read    = seq_read,
27662306a36Sopenharmony_ci	.llseek  = seq_lseek,
27762306a36Sopenharmony_ci	.release = seq_release_private
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistatic int cim_ma_la_show(struct seq_file *seq, void *v, int idx)
28162306a36Sopenharmony_ci{
28262306a36Sopenharmony_ci	const u32 *p = v;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
28562306a36Sopenharmony_ci		seq_puts(seq, "\n");
28662306a36Sopenharmony_ci	} else if (idx < CIM_MALA_SIZE) {
28762306a36Sopenharmony_ci		seq_printf(seq, "%02x%08x%08x%08x%08x\n",
28862306a36Sopenharmony_ci			   p[4], p[3], p[2], p[1], p[0]);
28962306a36Sopenharmony_ci	} else {
29062306a36Sopenharmony_ci		if (idx == CIM_MALA_SIZE)
29162306a36Sopenharmony_ci			seq_puts(seq,
29262306a36Sopenharmony_ci				 "\nCnt ID Tag UE       Data       RDY VLD\n");
29362306a36Sopenharmony_ci		seq_printf(seq, "%3u %2u  %x   %u %08x%08x  %u   %u\n",
29462306a36Sopenharmony_ci			   (p[2] >> 10) & 0xff, (p[2] >> 7) & 7,
29562306a36Sopenharmony_ci			   (p[2] >> 3) & 0xf, (p[2] >> 2) & 1,
29662306a36Sopenharmony_ci			   (p[1] >> 2) | ((p[2] & 3) << 30),
29762306a36Sopenharmony_ci			   (p[0] >> 2) | ((p[1] & 3) << 30), (p[0] >> 1) & 1,
29862306a36Sopenharmony_ci			   p[0] & 1);
29962306a36Sopenharmony_ci	}
30062306a36Sopenharmony_ci	return 0;
30162306a36Sopenharmony_ci}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_cistatic int cim_ma_la_open(struct inode *inode, struct file *file)
30462306a36Sopenharmony_ci{
30562306a36Sopenharmony_ci	struct seq_tab *p;
30662306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	p = seq_open_tab(file, 2 * CIM_MALA_SIZE, 5 * sizeof(u32), 1,
30962306a36Sopenharmony_ci			 cim_ma_la_show);
31062306a36Sopenharmony_ci	if (!p)
31162306a36Sopenharmony_ci		return -ENOMEM;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	t4_cim_read_ma_la(adap, (u32 *)p->data,
31462306a36Sopenharmony_ci			  (u32 *)p->data + 5 * CIM_MALA_SIZE);
31562306a36Sopenharmony_ci	return 0;
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic const struct file_operations cim_ma_la_fops = {
31962306a36Sopenharmony_ci	.owner   = THIS_MODULE,
32062306a36Sopenharmony_ci	.open    = cim_ma_la_open,
32162306a36Sopenharmony_ci	.read    = seq_read,
32262306a36Sopenharmony_ci	.llseek  = seq_lseek,
32362306a36Sopenharmony_ci	.release = seq_release_private
32462306a36Sopenharmony_ci};
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic int cim_qcfg_show(struct seq_file *seq, void *v)
32762306a36Sopenharmony_ci{
32862306a36Sopenharmony_ci	static const char * const qname[] = {
32962306a36Sopenharmony_ci		"TP0", "TP1", "ULP", "SGE0", "SGE1", "NC-SI",
33062306a36Sopenharmony_ci		"ULP0", "ULP1", "ULP2", "ULP3", "SGE", "NC-SI",
33162306a36Sopenharmony_ci		"SGE0-RX", "SGE1-RX"
33262306a36Sopenharmony_ci	};
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	int i;
33562306a36Sopenharmony_ci	struct adapter *adap = seq->private;
33662306a36Sopenharmony_ci	u16 base[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
33762306a36Sopenharmony_ci	u16 size[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
33862306a36Sopenharmony_ci	u32 stat[(4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5))];
33962306a36Sopenharmony_ci	u16 thres[CIM_NUM_IBQ];
34062306a36Sopenharmony_ci	u32 obq_wr_t4[2 * CIM_NUM_OBQ], *wr;
34162306a36Sopenharmony_ci	u32 obq_wr_t5[2 * CIM_NUM_OBQ_T5];
34262306a36Sopenharmony_ci	u32 *p = stat;
34362306a36Sopenharmony_ci	int cim_num_obq = is_t4(adap->params.chip) ?
34462306a36Sopenharmony_ci				CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	i = t4_cim_read(adap, is_t4(adap->params.chip) ? UP_IBQ_0_RDADDR_A :
34762306a36Sopenharmony_ci			UP_IBQ_0_SHADOW_RDADDR_A,
34862306a36Sopenharmony_ci			ARRAY_SIZE(stat), stat);
34962306a36Sopenharmony_ci	if (!i) {
35062306a36Sopenharmony_ci		if (is_t4(adap->params.chip)) {
35162306a36Sopenharmony_ci			i = t4_cim_read(adap, UP_OBQ_0_REALADDR_A,
35262306a36Sopenharmony_ci					ARRAY_SIZE(obq_wr_t4), obq_wr_t4);
35362306a36Sopenharmony_ci			wr = obq_wr_t4;
35462306a36Sopenharmony_ci		} else {
35562306a36Sopenharmony_ci			i = t4_cim_read(adap, UP_OBQ_0_SHADOW_REALADDR_A,
35662306a36Sopenharmony_ci					ARRAY_SIZE(obq_wr_t5), obq_wr_t5);
35762306a36Sopenharmony_ci			wr = obq_wr_t5;
35862306a36Sopenharmony_ci		}
35962306a36Sopenharmony_ci	}
36062306a36Sopenharmony_ci	if (i)
36162306a36Sopenharmony_ci		return i;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	t4_read_cimq_cfg(adap, base, size, thres);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	seq_printf(seq,
36662306a36Sopenharmony_ci		   "  Queue  Base  Size Thres  RdPtr WrPtr  SOP  EOP Avail\n");
36762306a36Sopenharmony_ci	for (i = 0; i < CIM_NUM_IBQ; i++, p += 4)
36862306a36Sopenharmony_ci		seq_printf(seq, "%7s %5x %5u %5u %6x  %4x %4u %4u %5u\n",
36962306a36Sopenharmony_ci			   qname[i], base[i], size[i], thres[i],
37062306a36Sopenharmony_ci			   IBQRDADDR_G(p[0]), IBQWRADDR_G(p[1]),
37162306a36Sopenharmony_ci			   QUESOPCNT_G(p[3]), QUEEOPCNT_G(p[3]),
37262306a36Sopenharmony_ci			   QUEREMFLITS_G(p[2]) * 16);
37362306a36Sopenharmony_ci	for ( ; i < CIM_NUM_IBQ + cim_num_obq; i++, p += 4, wr += 2)
37462306a36Sopenharmony_ci		seq_printf(seq, "%7s %5x %5u %12x  %4x %4u %4u %5u\n",
37562306a36Sopenharmony_ci			   qname[i], base[i], size[i],
37662306a36Sopenharmony_ci			   QUERDADDR_G(p[0]) & 0x3fff, wr[0] - base[i],
37762306a36Sopenharmony_ci			   QUESOPCNT_G(p[3]), QUEEOPCNT_G(p[3]),
37862306a36Sopenharmony_ci			   QUEREMFLITS_G(p[2]) * 16);
37962306a36Sopenharmony_ci	return 0;
38062306a36Sopenharmony_ci}
38162306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(cim_qcfg);
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_cistatic int cimq_show(struct seq_file *seq, void *v, int idx)
38462306a36Sopenharmony_ci{
38562306a36Sopenharmony_ci	const u32 *p = v;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	seq_printf(seq, "%#06x: %08x %08x %08x %08x\n", idx * 16, p[0], p[1],
38862306a36Sopenharmony_ci		   p[2], p[3]);
38962306a36Sopenharmony_ci	return 0;
39062306a36Sopenharmony_ci}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic int cim_ibq_open(struct inode *inode, struct file *file)
39362306a36Sopenharmony_ci{
39462306a36Sopenharmony_ci	int ret;
39562306a36Sopenharmony_ci	struct seq_tab *p;
39662306a36Sopenharmony_ci	unsigned int qid = (uintptr_t)inode->i_private & 7;
39762306a36Sopenharmony_ci	struct adapter *adap = inode->i_private - qid;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	p = seq_open_tab(file, CIM_IBQ_SIZE, 4 * sizeof(u32), 0, cimq_show);
40062306a36Sopenharmony_ci	if (!p)
40162306a36Sopenharmony_ci		return -ENOMEM;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	ret = t4_read_cim_ibq(adap, qid, (u32 *)p->data, CIM_IBQ_SIZE * 4);
40462306a36Sopenharmony_ci	if (ret < 0)
40562306a36Sopenharmony_ci		seq_release_private(inode, file);
40662306a36Sopenharmony_ci	else
40762306a36Sopenharmony_ci		ret = 0;
40862306a36Sopenharmony_ci	return ret;
40962306a36Sopenharmony_ci}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_cistatic const struct file_operations cim_ibq_fops = {
41262306a36Sopenharmony_ci	.owner   = THIS_MODULE,
41362306a36Sopenharmony_ci	.open    = cim_ibq_open,
41462306a36Sopenharmony_ci	.read    = seq_read,
41562306a36Sopenharmony_ci	.llseek  = seq_lseek,
41662306a36Sopenharmony_ci	.release = seq_release_private
41762306a36Sopenharmony_ci};
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_cistatic int cim_obq_open(struct inode *inode, struct file *file)
42062306a36Sopenharmony_ci{
42162306a36Sopenharmony_ci	int ret;
42262306a36Sopenharmony_ci	struct seq_tab *p;
42362306a36Sopenharmony_ci	unsigned int qid = (uintptr_t)inode->i_private & 7;
42462306a36Sopenharmony_ci	struct adapter *adap = inode->i_private - qid;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	p = seq_open_tab(file, 6 * CIM_OBQ_SIZE, 4 * sizeof(u32), 0, cimq_show);
42762306a36Sopenharmony_ci	if (!p)
42862306a36Sopenharmony_ci		return -ENOMEM;
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	ret = t4_read_cim_obq(adap, qid, (u32 *)p->data, 6 * CIM_OBQ_SIZE * 4);
43162306a36Sopenharmony_ci	if (ret < 0) {
43262306a36Sopenharmony_ci		seq_release_private(inode, file);
43362306a36Sopenharmony_ci	} else {
43462306a36Sopenharmony_ci		seq_tab_trim(p, ret / 4);
43562306a36Sopenharmony_ci		ret = 0;
43662306a36Sopenharmony_ci	}
43762306a36Sopenharmony_ci	return ret;
43862306a36Sopenharmony_ci}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic const struct file_operations cim_obq_fops = {
44162306a36Sopenharmony_ci	.owner   = THIS_MODULE,
44262306a36Sopenharmony_ci	.open    = cim_obq_open,
44362306a36Sopenharmony_ci	.read    = seq_read,
44462306a36Sopenharmony_ci	.llseek  = seq_lseek,
44562306a36Sopenharmony_ci	.release = seq_release_private
44662306a36Sopenharmony_ci};
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_cistruct field_desc {
44962306a36Sopenharmony_ci	const char *name;
45062306a36Sopenharmony_ci	unsigned int start;
45162306a36Sopenharmony_ci	unsigned int width;
45262306a36Sopenharmony_ci};
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_cistatic void field_desc_show(struct seq_file *seq, u64 v,
45562306a36Sopenharmony_ci			    const struct field_desc *p)
45662306a36Sopenharmony_ci{
45762306a36Sopenharmony_ci	char buf[32];
45862306a36Sopenharmony_ci	int line_size = 0;
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	while (p->name) {
46162306a36Sopenharmony_ci		u64 mask = (1ULL << p->width) - 1;
46262306a36Sopenharmony_ci		int len = scnprintf(buf, sizeof(buf), "%s: %llu", p->name,
46362306a36Sopenharmony_ci				    ((unsigned long long)v >> p->start) & mask);
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci		if (line_size + len >= 79) {
46662306a36Sopenharmony_ci			line_size = 8;
46762306a36Sopenharmony_ci			seq_puts(seq, "\n        ");
46862306a36Sopenharmony_ci		}
46962306a36Sopenharmony_ci		seq_printf(seq, "%s ", buf);
47062306a36Sopenharmony_ci		line_size += len + 1;
47162306a36Sopenharmony_ci		p++;
47262306a36Sopenharmony_ci	}
47362306a36Sopenharmony_ci	seq_putc(seq, '\n');
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic struct field_desc tp_la0[] = {
47762306a36Sopenharmony_ci	{ "RcfOpCodeOut", 60, 4 },
47862306a36Sopenharmony_ci	{ "State", 56, 4 },
47962306a36Sopenharmony_ci	{ "WcfState", 52, 4 },
48062306a36Sopenharmony_ci	{ "RcfOpcSrcOut", 50, 2 },
48162306a36Sopenharmony_ci	{ "CRxError", 49, 1 },
48262306a36Sopenharmony_ci	{ "ERxError", 48, 1 },
48362306a36Sopenharmony_ci	{ "SanityFailed", 47, 1 },
48462306a36Sopenharmony_ci	{ "SpuriousMsg", 46, 1 },
48562306a36Sopenharmony_ci	{ "FlushInputMsg", 45, 1 },
48662306a36Sopenharmony_ci	{ "FlushInputCpl", 44, 1 },
48762306a36Sopenharmony_ci	{ "RssUpBit", 43, 1 },
48862306a36Sopenharmony_ci	{ "RssFilterHit", 42, 1 },
48962306a36Sopenharmony_ci	{ "Tid", 32, 10 },
49062306a36Sopenharmony_ci	{ "InitTcb", 31, 1 },
49162306a36Sopenharmony_ci	{ "LineNumber", 24, 7 },
49262306a36Sopenharmony_ci	{ "Emsg", 23, 1 },
49362306a36Sopenharmony_ci	{ "EdataOut", 22, 1 },
49462306a36Sopenharmony_ci	{ "Cmsg", 21, 1 },
49562306a36Sopenharmony_ci	{ "CdataOut", 20, 1 },
49662306a36Sopenharmony_ci	{ "EreadPdu", 19, 1 },
49762306a36Sopenharmony_ci	{ "CreadPdu", 18, 1 },
49862306a36Sopenharmony_ci	{ "TunnelPkt", 17, 1 },
49962306a36Sopenharmony_ci	{ "RcfPeerFin", 16, 1 },
50062306a36Sopenharmony_ci	{ "RcfReasonOut", 12, 4 },
50162306a36Sopenharmony_ci	{ "TxCchannel", 10, 2 },
50262306a36Sopenharmony_ci	{ "RcfTxChannel", 8, 2 },
50362306a36Sopenharmony_ci	{ "RxEchannel", 6, 2 },
50462306a36Sopenharmony_ci	{ "RcfRxChannel", 5, 1 },
50562306a36Sopenharmony_ci	{ "RcfDataOutSrdy", 4, 1 },
50662306a36Sopenharmony_ci	{ "RxDvld", 3, 1 },
50762306a36Sopenharmony_ci	{ "RxOoDvld", 2, 1 },
50862306a36Sopenharmony_ci	{ "RxCongestion", 1, 1 },
50962306a36Sopenharmony_ci	{ "TxCongestion", 0, 1 },
51062306a36Sopenharmony_ci	{ NULL }
51162306a36Sopenharmony_ci};
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_cistatic int tp_la_show(struct seq_file *seq, void *v, int idx)
51462306a36Sopenharmony_ci{
51562306a36Sopenharmony_ci	const u64 *p = v;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	field_desc_show(seq, *p, tp_la0);
51862306a36Sopenharmony_ci	return 0;
51962306a36Sopenharmony_ci}
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistatic int tp_la_show2(struct seq_file *seq, void *v, int idx)
52262306a36Sopenharmony_ci{
52362306a36Sopenharmony_ci	const u64 *p = v;
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	if (idx)
52662306a36Sopenharmony_ci		seq_putc(seq, '\n');
52762306a36Sopenharmony_ci	field_desc_show(seq, p[0], tp_la0);
52862306a36Sopenharmony_ci	if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL)
52962306a36Sopenharmony_ci		field_desc_show(seq, p[1], tp_la0);
53062306a36Sopenharmony_ci	return 0;
53162306a36Sopenharmony_ci}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_cistatic int tp_la_show3(struct seq_file *seq, void *v, int idx)
53462306a36Sopenharmony_ci{
53562306a36Sopenharmony_ci	static struct field_desc tp_la1[] = {
53662306a36Sopenharmony_ci		{ "CplCmdIn", 56, 8 },
53762306a36Sopenharmony_ci		{ "CplCmdOut", 48, 8 },
53862306a36Sopenharmony_ci		{ "ESynOut", 47, 1 },
53962306a36Sopenharmony_ci		{ "EAckOut", 46, 1 },
54062306a36Sopenharmony_ci		{ "EFinOut", 45, 1 },
54162306a36Sopenharmony_ci		{ "ERstOut", 44, 1 },
54262306a36Sopenharmony_ci		{ "SynIn", 43, 1 },
54362306a36Sopenharmony_ci		{ "AckIn", 42, 1 },
54462306a36Sopenharmony_ci		{ "FinIn", 41, 1 },
54562306a36Sopenharmony_ci		{ "RstIn", 40, 1 },
54662306a36Sopenharmony_ci		{ "DataIn", 39, 1 },
54762306a36Sopenharmony_ci		{ "DataInVld", 38, 1 },
54862306a36Sopenharmony_ci		{ "PadIn", 37, 1 },
54962306a36Sopenharmony_ci		{ "RxBufEmpty", 36, 1 },
55062306a36Sopenharmony_ci		{ "RxDdp", 35, 1 },
55162306a36Sopenharmony_ci		{ "RxFbCongestion", 34, 1 },
55262306a36Sopenharmony_ci		{ "TxFbCongestion", 33, 1 },
55362306a36Sopenharmony_ci		{ "TxPktSumSrdy", 32, 1 },
55462306a36Sopenharmony_ci		{ "RcfUlpType", 28, 4 },
55562306a36Sopenharmony_ci		{ "Eread", 27, 1 },
55662306a36Sopenharmony_ci		{ "Ebypass", 26, 1 },
55762306a36Sopenharmony_ci		{ "Esave", 25, 1 },
55862306a36Sopenharmony_ci		{ "Static0", 24, 1 },
55962306a36Sopenharmony_ci		{ "Cread", 23, 1 },
56062306a36Sopenharmony_ci		{ "Cbypass", 22, 1 },
56162306a36Sopenharmony_ci		{ "Csave", 21, 1 },
56262306a36Sopenharmony_ci		{ "CPktOut", 20, 1 },
56362306a36Sopenharmony_ci		{ "RxPagePoolFull", 18, 2 },
56462306a36Sopenharmony_ci		{ "RxLpbkPkt", 17, 1 },
56562306a36Sopenharmony_ci		{ "TxLpbkPkt", 16, 1 },
56662306a36Sopenharmony_ci		{ "RxVfValid", 15, 1 },
56762306a36Sopenharmony_ci		{ "SynLearned", 14, 1 },
56862306a36Sopenharmony_ci		{ "SetDelEntry", 13, 1 },
56962306a36Sopenharmony_ci		{ "SetInvEntry", 12, 1 },
57062306a36Sopenharmony_ci		{ "CpcmdDvld", 11, 1 },
57162306a36Sopenharmony_ci		{ "CpcmdSave", 10, 1 },
57262306a36Sopenharmony_ci		{ "RxPstructsFull", 8, 2 },
57362306a36Sopenharmony_ci		{ "EpcmdDvld", 7, 1 },
57462306a36Sopenharmony_ci		{ "EpcmdFlush", 6, 1 },
57562306a36Sopenharmony_ci		{ "EpcmdTrimPrefix", 5, 1 },
57662306a36Sopenharmony_ci		{ "EpcmdTrimPostfix", 4, 1 },
57762306a36Sopenharmony_ci		{ "ERssIp4Pkt", 3, 1 },
57862306a36Sopenharmony_ci		{ "ERssIp6Pkt", 2, 1 },
57962306a36Sopenharmony_ci		{ "ERssTcpUdpPkt", 1, 1 },
58062306a36Sopenharmony_ci		{ "ERssFceFipPkt", 0, 1 },
58162306a36Sopenharmony_ci		{ NULL }
58262306a36Sopenharmony_ci	};
58362306a36Sopenharmony_ci	static struct field_desc tp_la2[] = {
58462306a36Sopenharmony_ci		{ "CplCmdIn", 56, 8 },
58562306a36Sopenharmony_ci		{ "MpsVfVld", 55, 1 },
58662306a36Sopenharmony_ci		{ "MpsPf", 52, 3 },
58762306a36Sopenharmony_ci		{ "MpsVf", 44, 8 },
58862306a36Sopenharmony_ci		{ "SynIn", 43, 1 },
58962306a36Sopenharmony_ci		{ "AckIn", 42, 1 },
59062306a36Sopenharmony_ci		{ "FinIn", 41, 1 },
59162306a36Sopenharmony_ci		{ "RstIn", 40, 1 },
59262306a36Sopenharmony_ci		{ "DataIn", 39, 1 },
59362306a36Sopenharmony_ci		{ "DataInVld", 38, 1 },
59462306a36Sopenharmony_ci		{ "PadIn", 37, 1 },
59562306a36Sopenharmony_ci		{ "RxBufEmpty", 36, 1 },
59662306a36Sopenharmony_ci		{ "RxDdp", 35, 1 },
59762306a36Sopenharmony_ci		{ "RxFbCongestion", 34, 1 },
59862306a36Sopenharmony_ci		{ "TxFbCongestion", 33, 1 },
59962306a36Sopenharmony_ci		{ "TxPktSumSrdy", 32, 1 },
60062306a36Sopenharmony_ci		{ "RcfUlpType", 28, 4 },
60162306a36Sopenharmony_ci		{ "Eread", 27, 1 },
60262306a36Sopenharmony_ci		{ "Ebypass", 26, 1 },
60362306a36Sopenharmony_ci		{ "Esave", 25, 1 },
60462306a36Sopenharmony_ci		{ "Static0", 24, 1 },
60562306a36Sopenharmony_ci		{ "Cread", 23, 1 },
60662306a36Sopenharmony_ci		{ "Cbypass", 22, 1 },
60762306a36Sopenharmony_ci		{ "Csave", 21, 1 },
60862306a36Sopenharmony_ci		{ "CPktOut", 20, 1 },
60962306a36Sopenharmony_ci		{ "RxPagePoolFull", 18, 2 },
61062306a36Sopenharmony_ci		{ "RxLpbkPkt", 17, 1 },
61162306a36Sopenharmony_ci		{ "TxLpbkPkt", 16, 1 },
61262306a36Sopenharmony_ci		{ "RxVfValid", 15, 1 },
61362306a36Sopenharmony_ci		{ "SynLearned", 14, 1 },
61462306a36Sopenharmony_ci		{ "SetDelEntry", 13, 1 },
61562306a36Sopenharmony_ci		{ "SetInvEntry", 12, 1 },
61662306a36Sopenharmony_ci		{ "CpcmdDvld", 11, 1 },
61762306a36Sopenharmony_ci		{ "CpcmdSave", 10, 1 },
61862306a36Sopenharmony_ci		{ "RxPstructsFull", 8, 2 },
61962306a36Sopenharmony_ci		{ "EpcmdDvld", 7, 1 },
62062306a36Sopenharmony_ci		{ "EpcmdFlush", 6, 1 },
62162306a36Sopenharmony_ci		{ "EpcmdTrimPrefix", 5, 1 },
62262306a36Sopenharmony_ci		{ "EpcmdTrimPostfix", 4, 1 },
62362306a36Sopenharmony_ci		{ "ERssIp4Pkt", 3, 1 },
62462306a36Sopenharmony_ci		{ "ERssIp6Pkt", 2, 1 },
62562306a36Sopenharmony_ci		{ "ERssTcpUdpPkt", 1, 1 },
62662306a36Sopenharmony_ci		{ "ERssFceFipPkt", 0, 1 },
62762306a36Sopenharmony_ci		{ NULL }
62862306a36Sopenharmony_ci	};
62962306a36Sopenharmony_ci	const u64 *p = v;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	if (idx)
63262306a36Sopenharmony_ci		seq_putc(seq, '\n');
63362306a36Sopenharmony_ci	field_desc_show(seq, p[0], tp_la0);
63462306a36Sopenharmony_ci	if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL)
63562306a36Sopenharmony_ci		field_desc_show(seq, p[1], (p[0] & BIT(17)) ? tp_la2 : tp_la1);
63662306a36Sopenharmony_ci	return 0;
63762306a36Sopenharmony_ci}
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_cistatic int tp_la_open(struct inode *inode, struct file *file)
64062306a36Sopenharmony_ci{
64162306a36Sopenharmony_ci	struct seq_tab *p;
64262306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	switch (DBGLAMODE_G(t4_read_reg(adap, TP_DBG_LA_CONFIG_A))) {
64562306a36Sopenharmony_ci	case 2:
64662306a36Sopenharmony_ci		p = seq_open_tab(file, TPLA_SIZE / 2, 2 * sizeof(u64), 0,
64762306a36Sopenharmony_ci				 tp_la_show2);
64862306a36Sopenharmony_ci		break;
64962306a36Sopenharmony_ci	case 3:
65062306a36Sopenharmony_ci		p = seq_open_tab(file, TPLA_SIZE / 2, 2 * sizeof(u64), 0,
65162306a36Sopenharmony_ci				 tp_la_show3);
65262306a36Sopenharmony_ci		break;
65362306a36Sopenharmony_ci	default:
65462306a36Sopenharmony_ci		p = seq_open_tab(file, TPLA_SIZE, sizeof(u64), 0, tp_la_show);
65562306a36Sopenharmony_ci	}
65662306a36Sopenharmony_ci	if (!p)
65762306a36Sopenharmony_ci		return -ENOMEM;
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	t4_tp_read_la(adap, (u64 *)p->data, NULL);
66062306a36Sopenharmony_ci	return 0;
66162306a36Sopenharmony_ci}
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_cistatic ssize_t tp_la_write(struct file *file, const char __user *buf,
66462306a36Sopenharmony_ci			   size_t count, loff_t *pos)
66562306a36Sopenharmony_ci{
66662306a36Sopenharmony_ci	int err;
66762306a36Sopenharmony_ci	char s[32];
66862306a36Sopenharmony_ci	unsigned long val;
66962306a36Sopenharmony_ci	size_t size = min(sizeof(s) - 1, count);
67062306a36Sopenharmony_ci	struct adapter *adap = file_inode(file)->i_private;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	if (copy_from_user(s, buf, size))
67362306a36Sopenharmony_ci		return -EFAULT;
67462306a36Sopenharmony_ci	s[size] = '\0';
67562306a36Sopenharmony_ci	err = kstrtoul(s, 0, &val);
67662306a36Sopenharmony_ci	if (err)
67762306a36Sopenharmony_ci		return err;
67862306a36Sopenharmony_ci	if (val > 0xffff)
67962306a36Sopenharmony_ci		return -EINVAL;
68062306a36Sopenharmony_ci	adap->params.tp.la_mask = val << 16;
68162306a36Sopenharmony_ci	t4_set_reg_field(adap, TP_DBG_LA_CONFIG_A, 0xffff0000U,
68262306a36Sopenharmony_ci			 adap->params.tp.la_mask);
68362306a36Sopenharmony_ci	return count;
68462306a36Sopenharmony_ci}
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_cistatic const struct file_operations tp_la_fops = {
68762306a36Sopenharmony_ci	.owner   = THIS_MODULE,
68862306a36Sopenharmony_ci	.open    = tp_la_open,
68962306a36Sopenharmony_ci	.read    = seq_read,
69062306a36Sopenharmony_ci	.llseek  = seq_lseek,
69162306a36Sopenharmony_ci	.release = seq_release_private,
69262306a36Sopenharmony_ci	.write   = tp_la_write
69362306a36Sopenharmony_ci};
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_cistatic int ulprx_la_show(struct seq_file *seq, void *v, int idx)
69662306a36Sopenharmony_ci{
69762306a36Sopenharmony_ci	const u32 *p = v;
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN)
70062306a36Sopenharmony_ci		seq_puts(seq, "      Pcmd        Type   Message"
70162306a36Sopenharmony_ci			 "                Data\n");
70262306a36Sopenharmony_ci	else
70362306a36Sopenharmony_ci		seq_printf(seq, "%08x%08x  %4x  %08x  %08x%08x%08x%08x\n",
70462306a36Sopenharmony_ci			   p[1], p[0], p[2], p[3], p[7], p[6], p[5], p[4]);
70562306a36Sopenharmony_ci	return 0;
70662306a36Sopenharmony_ci}
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_cistatic int ulprx_la_open(struct inode *inode, struct file *file)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	struct seq_tab *p;
71162306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	p = seq_open_tab(file, ULPRX_LA_SIZE, 8 * sizeof(u32), 1,
71462306a36Sopenharmony_ci			 ulprx_la_show);
71562306a36Sopenharmony_ci	if (!p)
71662306a36Sopenharmony_ci		return -ENOMEM;
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	t4_ulprx_read_la(adap, (u32 *)p->data);
71962306a36Sopenharmony_ci	return 0;
72062306a36Sopenharmony_ci}
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_cistatic const struct file_operations ulprx_la_fops = {
72362306a36Sopenharmony_ci	.owner   = THIS_MODULE,
72462306a36Sopenharmony_ci	.open    = ulprx_la_open,
72562306a36Sopenharmony_ci	.read    = seq_read,
72662306a36Sopenharmony_ci	.llseek  = seq_lseek,
72762306a36Sopenharmony_ci	.release = seq_release_private
72862306a36Sopenharmony_ci};
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci/* Show the PM memory stats.  These stats include:
73162306a36Sopenharmony_ci *
73262306a36Sopenharmony_ci * TX:
73362306a36Sopenharmony_ci *   Read: memory read operation
73462306a36Sopenharmony_ci *   Write Bypass: cut-through
73562306a36Sopenharmony_ci *   Bypass + mem: cut-through and save copy
73662306a36Sopenharmony_ci *
73762306a36Sopenharmony_ci * RX:
73862306a36Sopenharmony_ci *   Read: memory read
73962306a36Sopenharmony_ci *   Write Bypass: cut-through
74062306a36Sopenharmony_ci *   Flush: payload trim or drop
74162306a36Sopenharmony_ci */
74262306a36Sopenharmony_cistatic int pm_stats_show(struct seq_file *seq, void *v)
74362306a36Sopenharmony_ci{
74462306a36Sopenharmony_ci	static const char * const tx_pm_stats[] = {
74562306a36Sopenharmony_ci		"Read:", "Write bypass:", "Write mem:", "Bypass + mem:"
74662306a36Sopenharmony_ci	};
74762306a36Sopenharmony_ci	static const char * const rx_pm_stats[] = {
74862306a36Sopenharmony_ci		"Read:", "Write bypass:", "Write mem:", "Flush:"
74962306a36Sopenharmony_ci	};
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	int i;
75262306a36Sopenharmony_ci	u32 tx_cnt[T6_PM_NSTATS], rx_cnt[T6_PM_NSTATS];
75362306a36Sopenharmony_ci	u64 tx_cyc[T6_PM_NSTATS], rx_cyc[T6_PM_NSTATS];
75462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	t4_pmtx_get_stats(adap, tx_cnt, tx_cyc);
75762306a36Sopenharmony_ci	t4_pmrx_get_stats(adap, rx_cnt, rx_cyc);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	seq_printf(seq, "%13s %10s  %20s\n", " ", "Tx pcmds", "Tx bytes");
76062306a36Sopenharmony_ci	for (i = 0; i < PM_NSTATS - 1; i++)
76162306a36Sopenharmony_ci		seq_printf(seq, "%-13s %10u  %20llu\n",
76262306a36Sopenharmony_ci			   tx_pm_stats[i], tx_cnt[i], tx_cyc[i]);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	seq_printf(seq, "%13s %10s  %20s\n", " ", "Rx pcmds", "Rx bytes");
76562306a36Sopenharmony_ci	for (i = 0; i < PM_NSTATS - 1; i++)
76662306a36Sopenharmony_ci		seq_printf(seq, "%-13s %10u  %20llu\n",
76762306a36Sopenharmony_ci			   rx_pm_stats[i], rx_cnt[i], rx_cyc[i]);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
77062306a36Sopenharmony_ci		/* In T5 the granularity of the total wait is too fine.
77162306a36Sopenharmony_ci		 * It is not useful as it reaches the max value too fast.
77262306a36Sopenharmony_ci		 * Hence display this Input FIFO wait for T6 onwards.
77362306a36Sopenharmony_ci		 */
77462306a36Sopenharmony_ci		seq_printf(seq, "%13s %10s  %20s\n",
77562306a36Sopenharmony_ci			   " ", "Total wait", "Total Occupancy");
77662306a36Sopenharmony_ci		seq_printf(seq, "Tx FIFO wait  %10u  %20llu\n",
77762306a36Sopenharmony_ci			   tx_cnt[i], tx_cyc[i]);
77862306a36Sopenharmony_ci		seq_printf(seq, "Rx FIFO wait  %10u  %20llu\n",
77962306a36Sopenharmony_ci			   rx_cnt[i], rx_cyc[i]);
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci		/* Skip index 6 as there is nothing useful ihere */
78262306a36Sopenharmony_ci		i += 2;
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci		/* At index 7, a new stat for read latency (count, total wait)
78562306a36Sopenharmony_ci		 * is added.
78662306a36Sopenharmony_ci		 */
78762306a36Sopenharmony_ci		seq_printf(seq, "%13s %10s  %20s\n",
78862306a36Sopenharmony_ci			   " ", "Reads", "Total wait");
78962306a36Sopenharmony_ci		seq_printf(seq, "Tx latency    %10u  %20llu\n",
79062306a36Sopenharmony_ci			   tx_cnt[i], tx_cyc[i]);
79162306a36Sopenharmony_ci		seq_printf(seq, "Rx latency    %10u  %20llu\n",
79262306a36Sopenharmony_ci			   rx_cnt[i], rx_cyc[i]);
79362306a36Sopenharmony_ci	}
79462306a36Sopenharmony_ci	return 0;
79562306a36Sopenharmony_ci}
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_cistatic int pm_stats_open(struct inode *inode, struct file *file)
79862306a36Sopenharmony_ci{
79962306a36Sopenharmony_ci	return single_open(file, pm_stats_show, inode->i_private);
80062306a36Sopenharmony_ci}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_cistatic ssize_t pm_stats_clear(struct file *file, const char __user *buf,
80362306a36Sopenharmony_ci			      size_t count, loff_t *pos)
80462306a36Sopenharmony_ci{
80562306a36Sopenharmony_ci	struct adapter *adap = file_inode(file)->i_private;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	t4_write_reg(adap, PM_RX_STAT_CONFIG_A, 0);
80862306a36Sopenharmony_ci	t4_write_reg(adap, PM_TX_STAT_CONFIG_A, 0);
80962306a36Sopenharmony_ci	return count;
81062306a36Sopenharmony_ci}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_cistatic const struct file_operations pm_stats_debugfs_fops = {
81362306a36Sopenharmony_ci	.owner   = THIS_MODULE,
81462306a36Sopenharmony_ci	.open    = pm_stats_open,
81562306a36Sopenharmony_ci	.read    = seq_read,
81662306a36Sopenharmony_ci	.llseek  = seq_lseek,
81762306a36Sopenharmony_ci	.release = single_release,
81862306a36Sopenharmony_ci	.write   = pm_stats_clear
81962306a36Sopenharmony_ci};
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_cistatic int tx_rate_show(struct seq_file *seq, void *v)
82262306a36Sopenharmony_ci{
82362306a36Sopenharmony_ci	u64 nrate[NCHAN], orate[NCHAN];
82462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	t4_get_chan_txrate(adap, nrate, orate);
82762306a36Sopenharmony_ci	if (adap->params.arch.nchan == NCHAN) {
82862306a36Sopenharmony_ci		seq_puts(seq, "              channel 0   channel 1   "
82962306a36Sopenharmony_ci			 "channel 2   channel 3\n");
83062306a36Sopenharmony_ci		seq_printf(seq, "NIC B/s:     %10llu  %10llu  %10llu  %10llu\n",
83162306a36Sopenharmony_ci			   (unsigned long long)nrate[0],
83262306a36Sopenharmony_ci			   (unsigned long long)nrate[1],
83362306a36Sopenharmony_ci			   (unsigned long long)nrate[2],
83462306a36Sopenharmony_ci			   (unsigned long long)nrate[3]);
83562306a36Sopenharmony_ci		seq_printf(seq, "Offload B/s: %10llu  %10llu  %10llu  %10llu\n",
83662306a36Sopenharmony_ci			   (unsigned long long)orate[0],
83762306a36Sopenharmony_ci			   (unsigned long long)orate[1],
83862306a36Sopenharmony_ci			   (unsigned long long)orate[2],
83962306a36Sopenharmony_ci			   (unsigned long long)orate[3]);
84062306a36Sopenharmony_ci	} else {
84162306a36Sopenharmony_ci		seq_puts(seq, "              channel 0   channel 1\n");
84262306a36Sopenharmony_ci		seq_printf(seq, "NIC B/s:     %10llu  %10llu\n",
84362306a36Sopenharmony_ci			   (unsigned long long)nrate[0],
84462306a36Sopenharmony_ci			   (unsigned long long)nrate[1]);
84562306a36Sopenharmony_ci		seq_printf(seq, "Offload B/s: %10llu  %10llu\n",
84662306a36Sopenharmony_ci			   (unsigned long long)orate[0],
84762306a36Sopenharmony_ci			   (unsigned long long)orate[1]);
84862306a36Sopenharmony_ci	}
84962306a36Sopenharmony_ci	return 0;
85062306a36Sopenharmony_ci}
85162306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(tx_rate);
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_cistatic int cctrl_tbl_show(struct seq_file *seq, void *v)
85462306a36Sopenharmony_ci{
85562306a36Sopenharmony_ci	static const char * const dec_fac[] = {
85662306a36Sopenharmony_ci		"0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875",
85762306a36Sopenharmony_ci		"0.9375" };
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	int i;
86062306a36Sopenharmony_ci	u16 (*incr)[NCCTRL_WIN];
86162306a36Sopenharmony_ci	struct adapter *adap = seq->private;
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	incr = kmalloc_array(NMTUS, sizeof(*incr), GFP_KERNEL);
86462306a36Sopenharmony_ci	if (!incr)
86562306a36Sopenharmony_ci		return -ENOMEM;
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	t4_read_cong_tbl(adap, incr);
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	for (i = 0; i < NCCTRL_WIN; ++i) {
87062306a36Sopenharmony_ci		seq_printf(seq, "%2d: %4u %4u %4u %4u %4u %4u %4u %4u\n", i,
87162306a36Sopenharmony_ci			   incr[0][i], incr[1][i], incr[2][i], incr[3][i],
87262306a36Sopenharmony_ci			   incr[4][i], incr[5][i], incr[6][i], incr[7][i]);
87362306a36Sopenharmony_ci		seq_printf(seq, "%8u %4u %4u %4u %4u %4u %4u %4u %5u %s\n",
87462306a36Sopenharmony_ci			   incr[8][i], incr[9][i], incr[10][i], incr[11][i],
87562306a36Sopenharmony_ci			   incr[12][i], incr[13][i], incr[14][i], incr[15][i],
87662306a36Sopenharmony_ci			   adap->params.a_wnd[i],
87762306a36Sopenharmony_ci			   dec_fac[adap->params.b_wnd[i]]);
87862306a36Sopenharmony_ci	}
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	kfree(incr);
88162306a36Sopenharmony_ci	return 0;
88262306a36Sopenharmony_ci}
88362306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(cctrl_tbl);
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci/* Format a value in a unit that differs from the value's native unit by the
88662306a36Sopenharmony_ci * given factor.
88762306a36Sopenharmony_ci */
88862306a36Sopenharmony_cistatic char *unit_conv(char *buf, size_t len, unsigned int val,
88962306a36Sopenharmony_ci		       unsigned int factor)
89062306a36Sopenharmony_ci{
89162306a36Sopenharmony_ci	unsigned int rem = val % factor;
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci	if (rem == 0) {
89462306a36Sopenharmony_ci		snprintf(buf, len, "%u", val / factor);
89562306a36Sopenharmony_ci	} else {
89662306a36Sopenharmony_ci		while (rem % 10 == 0)
89762306a36Sopenharmony_ci			rem /= 10;
89862306a36Sopenharmony_ci		snprintf(buf, len, "%u.%u", val / factor, rem);
89962306a36Sopenharmony_ci	}
90062306a36Sopenharmony_ci	return buf;
90162306a36Sopenharmony_ci}
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_cistatic int clk_show(struct seq_file *seq, void *v)
90462306a36Sopenharmony_ci{
90562306a36Sopenharmony_ci	char buf[32];
90662306a36Sopenharmony_ci	struct adapter *adap = seq->private;
90762306a36Sopenharmony_ci	unsigned int cclk_ps = 1000000000 / adap->params.vpd.cclk;  /* in ps */
90862306a36Sopenharmony_ci	u32 res = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
90962306a36Sopenharmony_ci	unsigned int tre = TIMERRESOLUTION_G(res);
91062306a36Sopenharmony_ci	unsigned int dack_re = DELAYEDACKRESOLUTION_G(res);
91162306a36Sopenharmony_ci	unsigned long long tp_tick_us = (cclk_ps << tre) / 1000000; /* in us */
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	seq_printf(seq, "Core clock period: %s ns\n",
91462306a36Sopenharmony_ci		   unit_conv(buf, sizeof(buf), cclk_ps, 1000));
91562306a36Sopenharmony_ci	seq_printf(seq, "TP timer tick: %s us\n",
91662306a36Sopenharmony_ci		   unit_conv(buf, sizeof(buf), (cclk_ps << tre), 1000000));
91762306a36Sopenharmony_ci	seq_printf(seq, "TCP timestamp tick: %s us\n",
91862306a36Sopenharmony_ci		   unit_conv(buf, sizeof(buf),
91962306a36Sopenharmony_ci			     (cclk_ps << TIMESTAMPRESOLUTION_G(res)), 1000000));
92062306a36Sopenharmony_ci	seq_printf(seq, "DACK tick: %s us\n",
92162306a36Sopenharmony_ci		   unit_conv(buf, sizeof(buf), (cclk_ps << dack_re), 1000000));
92262306a36Sopenharmony_ci	seq_printf(seq, "DACK timer: %u us\n",
92362306a36Sopenharmony_ci		   ((cclk_ps << dack_re) / 1000000) *
92462306a36Sopenharmony_ci		   t4_read_reg(adap, TP_DACK_TIMER_A));
92562306a36Sopenharmony_ci	seq_printf(seq, "Retransmit min: %llu us\n",
92662306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_RXT_MIN_A));
92762306a36Sopenharmony_ci	seq_printf(seq, "Retransmit max: %llu us\n",
92862306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_RXT_MAX_A));
92962306a36Sopenharmony_ci	seq_printf(seq, "Persist timer min: %llu us\n",
93062306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_PERS_MIN_A));
93162306a36Sopenharmony_ci	seq_printf(seq, "Persist timer max: %llu us\n",
93262306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_PERS_MAX_A));
93362306a36Sopenharmony_ci	seq_printf(seq, "Keepalive idle timer: %llu us\n",
93462306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_KEEP_IDLE_A));
93562306a36Sopenharmony_ci	seq_printf(seq, "Keepalive interval: %llu us\n",
93662306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_KEEP_INTVL_A));
93762306a36Sopenharmony_ci	seq_printf(seq, "Initial SRTT: %llu us\n",
93862306a36Sopenharmony_ci		   tp_tick_us * INITSRTT_G(t4_read_reg(adap, TP_INIT_SRTT_A)));
93962306a36Sopenharmony_ci	seq_printf(seq, "FINWAIT2 timer: %llu us\n",
94062306a36Sopenharmony_ci		   tp_tick_us * t4_read_reg(adap, TP_FINWAIT2_TIMER_A));
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci	return 0;
94362306a36Sopenharmony_ci}
94462306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(clk);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci/* Firmware Device Log dump. */
94762306a36Sopenharmony_cistatic const char * const devlog_level_strings[] = {
94862306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_EMERG]		= "EMERG",
94962306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_CRIT]		= "CRIT",
95062306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_ERR]		= "ERR",
95162306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_NOTICE]	= "NOTICE",
95262306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_INFO]		= "INFO",
95362306a36Sopenharmony_ci	[FW_DEVLOG_LEVEL_DEBUG]		= "DEBUG"
95462306a36Sopenharmony_ci};
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_cistatic const char * const devlog_facility_strings[] = {
95762306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_CORE]	= "CORE",
95862306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_CF]         = "CF",
95962306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_SCHED]	= "SCHED",
96062306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_TIMER]	= "TIMER",
96162306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_RES]	= "RES",
96262306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_HW]		= "HW",
96362306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_FLR]	= "FLR",
96462306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_DMAQ]	= "DMAQ",
96562306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_PHY]	= "PHY",
96662306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_MAC]	= "MAC",
96762306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_PORT]	= "PORT",
96862306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_VI]		= "VI",
96962306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_FILTER]	= "FILTER",
97062306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_ACL]	= "ACL",
97162306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_TM]		= "TM",
97262306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_QFC]	= "QFC",
97362306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_DCB]	= "DCB",
97462306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_ETH]	= "ETH",
97562306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_OFLD]	= "OFLD",
97662306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_RI]		= "RI",
97762306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_ISCSI]	= "ISCSI",
97862306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_FCOE]	= "FCOE",
97962306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_FOISCSI]	= "FOISCSI",
98062306a36Sopenharmony_ci	[FW_DEVLOG_FACILITY_FOFCOE]	= "FOFCOE"
98162306a36Sopenharmony_ci};
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci/* Information gathered by Device Log Open routine for the display routine.
98462306a36Sopenharmony_ci */
98562306a36Sopenharmony_cistruct devlog_info {
98662306a36Sopenharmony_ci	unsigned int nentries;		/* number of entries in log[] */
98762306a36Sopenharmony_ci	unsigned int first;		/* first [temporal] entry in log[] */
98862306a36Sopenharmony_ci	struct fw_devlog_e log[];	/* Firmware Device Log */
98962306a36Sopenharmony_ci};
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci/* Dump a Firmaware Device Log entry.
99262306a36Sopenharmony_ci */
99362306a36Sopenharmony_cistatic int devlog_show(struct seq_file *seq, void *v)
99462306a36Sopenharmony_ci{
99562306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN)
99662306a36Sopenharmony_ci		seq_printf(seq, "%10s  %15s  %8s  %8s  %s\n",
99762306a36Sopenharmony_ci			   "Seq#", "Tstamp", "Level", "Facility", "Message");
99862306a36Sopenharmony_ci	else {
99962306a36Sopenharmony_ci		struct devlog_info *dinfo = seq->private;
100062306a36Sopenharmony_ci		int fidx = (uintptr_t)v - 2;
100162306a36Sopenharmony_ci		unsigned long index;
100262306a36Sopenharmony_ci		struct fw_devlog_e *e;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci		/* Get a pointer to the log entry to display.  Skip unused log
100562306a36Sopenharmony_ci		 * entries.
100662306a36Sopenharmony_ci		 */
100762306a36Sopenharmony_ci		index = dinfo->first + fidx;
100862306a36Sopenharmony_ci		if (index >= dinfo->nentries)
100962306a36Sopenharmony_ci			index -= dinfo->nentries;
101062306a36Sopenharmony_ci		e = &dinfo->log[index];
101162306a36Sopenharmony_ci		if (e->timestamp == 0)
101262306a36Sopenharmony_ci			return 0;
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci		/* Print the message.  This depends on the firmware using
101562306a36Sopenharmony_ci		 * exactly the same formating strings as the kernel so we may
101662306a36Sopenharmony_ci		 * eventually have to put a format interpreter in here ...
101762306a36Sopenharmony_ci		 */
101862306a36Sopenharmony_ci		seq_printf(seq, "%10d  %15llu  %8s  %8s  ",
101962306a36Sopenharmony_ci			   be32_to_cpu(e->seqno),
102062306a36Sopenharmony_ci			   be64_to_cpu(e->timestamp),
102162306a36Sopenharmony_ci			   (e->level < ARRAY_SIZE(devlog_level_strings)
102262306a36Sopenharmony_ci			    ? devlog_level_strings[e->level]
102362306a36Sopenharmony_ci			    : "UNKNOWN"),
102462306a36Sopenharmony_ci			   (e->facility < ARRAY_SIZE(devlog_facility_strings)
102562306a36Sopenharmony_ci			    ? devlog_facility_strings[e->facility]
102662306a36Sopenharmony_ci			    : "UNKNOWN"));
102762306a36Sopenharmony_ci		seq_printf(seq, e->fmt,
102862306a36Sopenharmony_ci			   be32_to_cpu(e->params[0]),
102962306a36Sopenharmony_ci			   be32_to_cpu(e->params[1]),
103062306a36Sopenharmony_ci			   be32_to_cpu(e->params[2]),
103162306a36Sopenharmony_ci			   be32_to_cpu(e->params[3]),
103262306a36Sopenharmony_ci			   be32_to_cpu(e->params[4]),
103362306a36Sopenharmony_ci			   be32_to_cpu(e->params[5]),
103462306a36Sopenharmony_ci			   be32_to_cpu(e->params[6]),
103562306a36Sopenharmony_ci			   be32_to_cpu(e->params[7]));
103662306a36Sopenharmony_ci	}
103762306a36Sopenharmony_ci	return 0;
103862306a36Sopenharmony_ci}
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci/* Sequential File Operations for Device Log.
104162306a36Sopenharmony_ci */
104262306a36Sopenharmony_cistatic inline void *devlog_get_idx(struct devlog_info *dinfo, loff_t pos)
104362306a36Sopenharmony_ci{
104462306a36Sopenharmony_ci	if (pos > dinfo->nentries)
104562306a36Sopenharmony_ci		return NULL;
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	return (void *)(uintptr_t)(pos + 1);
104862306a36Sopenharmony_ci}
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_cistatic void *devlog_start(struct seq_file *seq, loff_t *pos)
105162306a36Sopenharmony_ci{
105262306a36Sopenharmony_ci	struct devlog_info *dinfo = seq->private;
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	return (*pos
105562306a36Sopenharmony_ci		? devlog_get_idx(dinfo, *pos)
105662306a36Sopenharmony_ci		: SEQ_START_TOKEN);
105762306a36Sopenharmony_ci}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_cistatic void *devlog_next(struct seq_file *seq, void *v, loff_t *pos)
106062306a36Sopenharmony_ci{
106162306a36Sopenharmony_ci	struct devlog_info *dinfo = seq->private;
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci	(*pos)++;
106462306a36Sopenharmony_ci	return devlog_get_idx(dinfo, *pos);
106562306a36Sopenharmony_ci}
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_cistatic void devlog_stop(struct seq_file *seq, void *v)
106862306a36Sopenharmony_ci{
106962306a36Sopenharmony_ci}
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_cistatic const struct seq_operations devlog_seq_ops = {
107262306a36Sopenharmony_ci	.start = devlog_start,
107362306a36Sopenharmony_ci	.next  = devlog_next,
107462306a36Sopenharmony_ci	.stop  = devlog_stop,
107562306a36Sopenharmony_ci	.show  = devlog_show
107662306a36Sopenharmony_ci};
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci/* Set up for reading the firmware's device log.  We read the entire log here
107962306a36Sopenharmony_ci * and then display it incrementally in devlog_show().
108062306a36Sopenharmony_ci */
108162306a36Sopenharmony_cistatic int devlog_open(struct inode *inode, struct file *file)
108262306a36Sopenharmony_ci{
108362306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
108462306a36Sopenharmony_ci	struct devlog_params *dparams = &adap->params.devlog;
108562306a36Sopenharmony_ci	struct devlog_info *dinfo;
108662306a36Sopenharmony_ci	unsigned int index;
108762306a36Sopenharmony_ci	u32 fseqno;
108862306a36Sopenharmony_ci	int ret;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	/* If we don't know where the log is we can't do anything.
109162306a36Sopenharmony_ci	 */
109262306a36Sopenharmony_ci	if (dparams->start == 0)
109362306a36Sopenharmony_ci		return -ENXIO;
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci	/* Allocate the space to read in the firmware's device log and set up
109662306a36Sopenharmony_ci	 * for the iterated call to our display function.
109762306a36Sopenharmony_ci	 */
109862306a36Sopenharmony_ci	dinfo = __seq_open_private(file, &devlog_seq_ops,
109962306a36Sopenharmony_ci				   sizeof(*dinfo) + dparams->size);
110062306a36Sopenharmony_ci	if (!dinfo)
110162306a36Sopenharmony_ci		return -ENOMEM;
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	/* Record the basic log buffer information and read in the raw log.
110462306a36Sopenharmony_ci	 */
110562306a36Sopenharmony_ci	dinfo->nentries = (dparams->size / sizeof(struct fw_devlog_e));
110662306a36Sopenharmony_ci	dinfo->first = 0;
110762306a36Sopenharmony_ci	spin_lock(&adap->win0_lock);
110862306a36Sopenharmony_ci	ret = t4_memory_rw(adap, adap->params.drv_memwin, dparams->memtype,
110962306a36Sopenharmony_ci			   dparams->start, dparams->size, (__be32 *)dinfo->log,
111062306a36Sopenharmony_ci			   T4_MEMORY_READ);
111162306a36Sopenharmony_ci	spin_unlock(&adap->win0_lock);
111262306a36Sopenharmony_ci	if (ret) {
111362306a36Sopenharmony_ci		seq_release_private(inode, file);
111462306a36Sopenharmony_ci		return ret;
111562306a36Sopenharmony_ci	}
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci	/* Find the earliest (lowest Sequence Number) log entry in the
111862306a36Sopenharmony_ci	 * circular Device Log.
111962306a36Sopenharmony_ci	 */
112062306a36Sopenharmony_ci	for (fseqno = ~((u32)0), index = 0; index < dinfo->nentries; index++) {
112162306a36Sopenharmony_ci		struct fw_devlog_e *e = &dinfo->log[index];
112262306a36Sopenharmony_ci		__u32 seqno;
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci		if (e->timestamp == 0)
112562306a36Sopenharmony_ci			continue;
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci		seqno = be32_to_cpu(e->seqno);
112862306a36Sopenharmony_ci		if (seqno < fseqno) {
112962306a36Sopenharmony_ci			fseqno = seqno;
113062306a36Sopenharmony_ci			dinfo->first = index;
113162306a36Sopenharmony_ci		}
113262306a36Sopenharmony_ci	}
113362306a36Sopenharmony_ci	return 0;
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_cistatic const struct file_operations devlog_fops = {
113762306a36Sopenharmony_ci	.owner   = THIS_MODULE,
113862306a36Sopenharmony_ci	.open    = devlog_open,
113962306a36Sopenharmony_ci	.read    = seq_read,
114062306a36Sopenharmony_ci	.llseek  = seq_lseek,
114162306a36Sopenharmony_ci	.release = seq_release_private
114262306a36Sopenharmony_ci};
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci/* Show Firmware Mailbox Command/Reply Log
114562306a36Sopenharmony_ci *
114662306a36Sopenharmony_ci * Note that we don't do any locking when dumping the Firmware Mailbox Log so
114762306a36Sopenharmony_ci * it's possible that we can catch things during a log update and therefore
114862306a36Sopenharmony_ci * see partially corrupted log entries.  But it's probably Good Enough(tm).
114962306a36Sopenharmony_ci * If we ever decide that we want to make sure that we're dumping a coherent
115062306a36Sopenharmony_ci * log, we'd need to perform locking in the mailbox logging and in
115162306a36Sopenharmony_ci * mboxlog_open() where we'd need to grab the entire mailbox log in one go
115262306a36Sopenharmony_ci * like we do for the Firmware Device Log.
115362306a36Sopenharmony_ci */
115462306a36Sopenharmony_cistatic int mboxlog_show(struct seq_file *seq, void *v)
115562306a36Sopenharmony_ci{
115662306a36Sopenharmony_ci	struct adapter *adapter = seq->private;
115762306a36Sopenharmony_ci	struct mbox_cmd_log *log = adapter->mbox_log;
115862306a36Sopenharmony_ci	struct mbox_cmd *entry;
115962306a36Sopenharmony_ci	int entry_idx, i;
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
116262306a36Sopenharmony_ci		seq_printf(seq,
116362306a36Sopenharmony_ci			   "%10s  %15s  %5s  %5s  %s\n",
116462306a36Sopenharmony_ci			   "Seq#", "Tstamp", "Atime", "Etime",
116562306a36Sopenharmony_ci			   "Command/Reply");
116662306a36Sopenharmony_ci		return 0;
116762306a36Sopenharmony_ci	}
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	entry_idx = log->cursor + ((uintptr_t)v - 2);
117062306a36Sopenharmony_ci	if (entry_idx >= log->size)
117162306a36Sopenharmony_ci		entry_idx -= log->size;
117262306a36Sopenharmony_ci	entry = mbox_cmd_log_entry(log, entry_idx);
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	/* skip over unused entries */
117562306a36Sopenharmony_ci	if (entry->timestamp == 0)
117662306a36Sopenharmony_ci		return 0;
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	seq_printf(seq, "%10u  %15llu  %5d  %5d",
117962306a36Sopenharmony_ci		   entry->seqno, entry->timestamp,
118062306a36Sopenharmony_ci		   entry->access, entry->execute);
118162306a36Sopenharmony_ci	for (i = 0; i < MBOX_LEN / 8; i++) {
118262306a36Sopenharmony_ci		u64 flit = entry->cmd[i];
118362306a36Sopenharmony_ci		u32 hi = (u32)(flit >> 32);
118462306a36Sopenharmony_ci		u32 lo = (u32)flit;
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci		seq_printf(seq, "  %08x %08x", hi, lo);
118762306a36Sopenharmony_ci	}
118862306a36Sopenharmony_ci	seq_puts(seq, "\n");
118962306a36Sopenharmony_ci	return 0;
119062306a36Sopenharmony_ci}
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_cistatic inline void *mboxlog_get_idx(struct seq_file *seq, loff_t pos)
119362306a36Sopenharmony_ci{
119462306a36Sopenharmony_ci	struct adapter *adapter = seq->private;
119562306a36Sopenharmony_ci	struct mbox_cmd_log *log = adapter->mbox_log;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	return ((pos <= log->size) ? (void *)(uintptr_t)(pos + 1) : NULL);
119862306a36Sopenharmony_ci}
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_cistatic void *mboxlog_start(struct seq_file *seq, loff_t *pos)
120162306a36Sopenharmony_ci{
120262306a36Sopenharmony_ci	return *pos ? mboxlog_get_idx(seq, *pos) : SEQ_START_TOKEN;
120362306a36Sopenharmony_ci}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_cistatic void *mboxlog_next(struct seq_file *seq, void *v, loff_t *pos)
120662306a36Sopenharmony_ci{
120762306a36Sopenharmony_ci	++*pos;
120862306a36Sopenharmony_ci	return mboxlog_get_idx(seq, *pos);
120962306a36Sopenharmony_ci}
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_cistatic void mboxlog_stop(struct seq_file *seq, void *v)
121262306a36Sopenharmony_ci{
121362306a36Sopenharmony_ci}
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_cistatic const struct seq_operations mboxlog_seq_ops = {
121662306a36Sopenharmony_ci	.start = mboxlog_start,
121762306a36Sopenharmony_ci	.next  = mboxlog_next,
121862306a36Sopenharmony_ci	.stop  = mboxlog_stop,
121962306a36Sopenharmony_ci	.show  = mboxlog_show
122062306a36Sopenharmony_ci};
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_cistatic int mboxlog_open(struct inode *inode, struct file *file)
122362306a36Sopenharmony_ci{
122462306a36Sopenharmony_ci	int res = seq_open(file, &mboxlog_seq_ops);
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	if (!res) {
122762306a36Sopenharmony_ci		struct seq_file *seq = file->private_data;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci		seq->private = inode->i_private;
123062306a36Sopenharmony_ci	}
123162306a36Sopenharmony_ci	return res;
123262306a36Sopenharmony_ci}
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_cistatic const struct file_operations mboxlog_fops = {
123562306a36Sopenharmony_ci	.owner   = THIS_MODULE,
123662306a36Sopenharmony_ci	.open    = mboxlog_open,
123762306a36Sopenharmony_ci	.read    = seq_read,
123862306a36Sopenharmony_ci	.llseek  = seq_lseek,
123962306a36Sopenharmony_ci	.release = seq_release,
124062306a36Sopenharmony_ci};
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_cistatic int mbox_show(struct seq_file *seq, void *v)
124362306a36Sopenharmony_ci{
124462306a36Sopenharmony_ci	static const char * const owner[] = { "none", "FW", "driver",
124562306a36Sopenharmony_ci					      "unknown", "<unread>" };
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	int i;
124862306a36Sopenharmony_ci	unsigned int mbox = (uintptr_t)seq->private & 7;
124962306a36Sopenharmony_ci	struct adapter *adap = seq->private - mbox;
125062306a36Sopenharmony_ci	void __iomem *addr = adap->regs + PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	/* For T4 we don't have a shadow copy of the Mailbox Control register.
125362306a36Sopenharmony_ci	 * And since reading that real register causes a side effect of
125462306a36Sopenharmony_ci	 * granting ownership, we're best of simply not reading it at all.
125562306a36Sopenharmony_ci	 */
125662306a36Sopenharmony_ci	if (is_t4(adap->params.chip)) {
125762306a36Sopenharmony_ci		i = 4; /* index of "<unread>" */
125862306a36Sopenharmony_ci	} else {
125962306a36Sopenharmony_ci		unsigned int ctrl_reg = CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A;
126062306a36Sopenharmony_ci		void __iomem *ctrl = adap->regs + PF_REG(mbox, ctrl_reg);
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci		i = MBOWNER_G(readl(ctrl));
126362306a36Sopenharmony_ci	}
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	seq_printf(seq, "mailbox owned by %s\n\n", owner[i]);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	for (i = 0; i < MBOX_LEN; i += 8)
126862306a36Sopenharmony_ci		seq_printf(seq, "%016llx\n",
126962306a36Sopenharmony_ci			   (unsigned long long)readq(addr + i));
127062306a36Sopenharmony_ci	return 0;
127162306a36Sopenharmony_ci}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_cistatic int mbox_open(struct inode *inode, struct file *file)
127462306a36Sopenharmony_ci{
127562306a36Sopenharmony_ci	return single_open(file, mbox_show, inode->i_private);
127662306a36Sopenharmony_ci}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_cistatic ssize_t mbox_write(struct file *file, const char __user *buf,
127962306a36Sopenharmony_ci			  size_t count, loff_t *pos)
128062306a36Sopenharmony_ci{
128162306a36Sopenharmony_ci	int i;
128262306a36Sopenharmony_ci	char c = '\n', s[256];
128362306a36Sopenharmony_ci	unsigned long long data[8];
128462306a36Sopenharmony_ci	const struct inode *ino;
128562306a36Sopenharmony_ci	unsigned int mbox;
128662306a36Sopenharmony_ci	struct adapter *adap;
128762306a36Sopenharmony_ci	void __iomem *addr;
128862306a36Sopenharmony_ci	void __iomem *ctrl;
128962306a36Sopenharmony_ci
129062306a36Sopenharmony_ci	if (count > sizeof(s) - 1 || !count)
129162306a36Sopenharmony_ci		return -EINVAL;
129262306a36Sopenharmony_ci	if (copy_from_user(s, buf, count))
129362306a36Sopenharmony_ci		return -EFAULT;
129462306a36Sopenharmony_ci	s[count] = '\0';
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	if (sscanf(s, "%llx %llx %llx %llx %llx %llx %llx %llx%c", &data[0],
129762306a36Sopenharmony_ci		   &data[1], &data[2], &data[3], &data[4], &data[5], &data[6],
129862306a36Sopenharmony_ci		   &data[7], &c) < 8 || c != '\n')
129962306a36Sopenharmony_ci		return -EINVAL;
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci	ino = file_inode(file);
130262306a36Sopenharmony_ci	mbox = (uintptr_t)ino->i_private & 7;
130362306a36Sopenharmony_ci	adap = ino->i_private - mbox;
130462306a36Sopenharmony_ci	addr = adap->regs + PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
130562306a36Sopenharmony_ci	ctrl = addr + MBOX_LEN;
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	if (MBOWNER_G(readl(ctrl)) != X_MBOWNER_PL)
130862306a36Sopenharmony_ci		return -EBUSY;
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	for (i = 0; i < 8; i++)
131162306a36Sopenharmony_ci		writeq(data[i], addr + 8 * i);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	writel(MBMSGVALID_F | MBOWNER_V(X_MBOWNER_FW), ctrl);
131462306a36Sopenharmony_ci	return count;
131562306a36Sopenharmony_ci}
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_cistatic const struct file_operations mbox_debugfs_fops = {
131862306a36Sopenharmony_ci	.owner   = THIS_MODULE,
131962306a36Sopenharmony_ci	.open    = mbox_open,
132062306a36Sopenharmony_ci	.read    = seq_read,
132162306a36Sopenharmony_ci	.llseek  = seq_lseek,
132262306a36Sopenharmony_ci	.release = single_release,
132362306a36Sopenharmony_ci	.write   = mbox_write
132462306a36Sopenharmony_ci};
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_cistatic int mps_trc_show(struct seq_file *seq, void *v)
132762306a36Sopenharmony_ci{
132862306a36Sopenharmony_ci	int enabled, i;
132962306a36Sopenharmony_ci	struct trace_params tp;
133062306a36Sopenharmony_ci	unsigned int trcidx = (uintptr_t)seq->private & 3;
133162306a36Sopenharmony_ci	struct adapter *adap = seq->private - trcidx;
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	t4_get_trace_filter(adap, &tp, trcidx, &enabled);
133462306a36Sopenharmony_ci	if (!enabled) {
133562306a36Sopenharmony_ci		seq_puts(seq, "tracer is disabled\n");
133662306a36Sopenharmony_ci		return 0;
133762306a36Sopenharmony_ci	}
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	if (tp.skip_ofst * 8 >= TRACE_LEN) {
134062306a36Sopenharmony_ci		dev_err(adap->pdev_dev, "illegal trace pattern skip offset\n");
134162306a36Sopenharmony_ci		return -EINVAL;
134262306a36Sopenharmony_ci	}
134362306a36Sopenharmony_ci	if (tp.port < 8) {
134462306a36Sopenharmony_ci		i = adap->chan_map[tp.port & 3];
134562306a36Sopenharmony_ci		if (i >= MAX_NPORTS) {
134662306a36Sopenharmony_ci			dev_err(adap->pdev_dev, "tracer %u is assigned "
134762306a36Sopenharmony_ci				"to non-existing port\n", trcidx);
134862306a36Sopenharmony_ci			return -EINVAL;
134962306a36Sopenharmony_ci		}
135062306a36Sopenharmony_ci		seq_printf(seq, "tracer is capturing %s %s, ",
135162306a36Sopenharmony_ci			   adap->port[i]->name, tp.port < 4 ? "Rx" : "Tx");
135262306a36Sopenharmony_ci	} else
135362306a36Sopenharmony_ci		seq_printf(seq, "tracer is capturing loopback %d, ",
135462306a36Sopenharmony_ci			   tp.port - 8);
135562306a36Sopenharmony_ci	seq_printf(seq, "snap length: %u, min length: %u\n", tp.snap_len,
135662306a36Sopenharmony_ci		   tp.min_len);
135762306a36Sopenharmony_ci	seq_printf(seq, "packets captured %smatch filter\n",
135862306a36Sopenharmony_ci		   tp.invert ? "do not " : "");
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	if (tp.skip_ofst) {
136162306a36Sopenharmony_ci		seq_puts(seq, "filter pattern: ");
136262306a36Sopenharmony_ci		for (i = 0; i < tp.skip_ofst * 2; i += 2)
136362306a36Sopenharmony_ci			seq_printf(seq, "%08x%08x", tp.data[i], tp.data[i + 1]);
136462306a36Sopenharmony_ci		seq_putc(seq, '/');
136562306a36Sopenharmony_ci		for (i = 0; i < tp.skip_ofst * 2; i += 2)
136662306a36Sopenharmony_ci			seq_printf(seq, "%08x%08x", tp.mask[i], tp.mask[i + 1]);
136762306a36Sopenharmony_ci		seq_puts(seq, "@0\n");
136862306a36Sopenharmony_ci	}
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	seq_puts(seq, "filter pattern: ");
137162306a36Sopenharmony_ci	for (i = tp.skip_ofst * 2; i < TRACE_LEN / 4; i += 2)
137262306a36Sopenharmony_ci		seq_printf(seq, "%08x%08x", tp.data[i], tp.data[i + 1]);
137362306a36Sopenharmony_ci	seq_putc(seq, '/');
137462306a36Sopenharmony_ci	for (i = tp.skip_ofst * 2; i < TRACE_LEN / 4; i += 2)
137562306a36Sopenharmony_ci		seq_printf(seq, "%08x%08x", tp.mask[i], tp.mask[i + 1]);
137662306a36Sopenharmony_ci	seq_printf(seq, "@%u\n", (tp.skip_ofst + tp.skip_len) * 8);
137762306a36Sopenharmony_ci	return 0;
137862306a36Sopenharmony_ci}
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_cistatic int mps_trc_open(struct inode *inode, struct file *file)
138162306a36Sopenharmony_ci{
138262306a36Sopenharmony_ci	return single_open(file, mps_trc_show, inode->i_private);
138362306a36Sopenharmony_ci}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_cistatic unsigned int xdigit2int(unsigned char c)
138662306a36Sopenharmony_ci{
138762306a36Sopenharmony_ci	return isdigit(c) ? c - '0' : tolower(c) - 'a' + 10;
138862306a36Sopenharmony_ci}
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci#define TRC_PORT_NONE 0xff
139162306a36Sopenharmony_ci#define TRC_RSS_ENABLE 0x33
139262306a36Sopenharmony_ci#define TRC_RSS_DISABLE 0x13
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci/* Set an MPS trace filter.  Syntax is:
139562306a36Sopenharmony_ci *
139662306a36Sopenharmony_ci * disable
139762306a36Sopenharmony_ci *
139862306a36Sopenharmony_ci * to disable tracing, or
139962306a36Sopenharmony_ci *
140062306a36Sopenharmony_ci * interface qid=<qid no> [snaplen=<val>] [minlen=<val>] [not] [<pattern>]...
140162306a36Sopenharmony_ci *
140262306a36Sopenharmony_ci * where interface is one of rxN, txN, or loopbackN, N = 0..3, qid can be one
140362306a36Sopenharmony_ci * of the NIC's response qid obtained from sge_qinfo and pattern has the form
140462306a36Sopenharmony_ci *
140562306a36Sopenharmony_ci * <pattern data>[/<pattern mask>][@<anchor>]
140662306a36Sopenharmony_ci *
140762306a36Sopenharmony_ci * Up to 2 filter patterns can be specified.  If 2 are supplied the first one
140862306a36Sopenharmony_ci * must be anchored at 0.  An omitted mask is taken as a mask of 1s, an omitted
140962306a36Sopenharmony_ci * anchor is taken as 0.
141062306a36Sopenharmony_ci */
141162306a36Sopenharmony_cistatic ssize_t mps_trc_write(struct file *file, const char __user *buf,
141262306a36Sopenharmony_ci			     size_t count, loff_t *pos)
141362306a36Sopenharmony_ci{
141462306a36Sopenharmony_ci	int i, enable, ret;
141562306a36Sopenharmony_ci	u32 *data, *mask;
141662306a36Sopenharmony_ci	struct trace_params tp;
141762306a36Sopenharmony_ci	const struct inode *ino;
141862306a36Sopenharmony_ci	unsigned int trcidx;
141962306a36Sopenharmony_ci	char *s, *p, *word, *end;
142062306a36Sopenharmony_ci	struct adapter *adap;
142162306a36Sopenharmony_ci	u32 j;
142262306a36Sopenharmony_ci
142362306a36Sopenharmony_ci	ino = file_inode(file);
142462306a36Sopenharmony_ci	trcidx = (uintptr_t)ino->i_private & 3;
142562306a36Sopenharmony_ci	adap = ino->i_private - trcidx;
142662306a36Sopenharmony_ci
142762306a36Sopenharmony_ci	/* Don't accept input more than 1K, can't be anything valid except lots
142862306a36Sopenharmony_ci	 * of whitespace.  Well, use less.
142962306a36Sopenharmony_ci	 */
143062306a36Sopenharmony_ci	if (count > 1024)
143162306a36Sopenharmony_ci		return -EFBIG;
143262306a36Sopenharmony_ci	p = s = kzalloc(count + 1, GFP_USER);
143362306a36Sopenharmony_ci	if (!s)
143462306a36Sopenharmony_ci		return -ENOMEM;
143562306a36Sopenharmony_ci	if (copy_from_user(s, buf, count)) {
143662306a36Sopenharmony_ci		count = -EFAULT;
143762306a36Sopenharmony_ci		goto out;
143862306a36Sopenharmony_ci	}
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	if (s[count - 1] == '\n')
144162306a36Sopenharmony_ci		s[count - 1] = '\0';
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci	enable = strcmp("disable", s) != 0;
144462306a36Sopenharmony_ci	if (!enable)
144562306a36Sopenharmony_ci		goto apply;
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ci	/* enable or disable trace multi rss filter */
144862306a36Sopenharmony_ci	if (adap->trace_rss)
144962306a36Sopenharmony_ci		t4_write_reg(adap, MPS_TRC_CFG_A, TRC_RSS_ENABLE);
145062306a36Sopenharmony_ci	else
145162306a36Sopenharmony_ci		t4_write_reg(adap, MPS_TRC_CFG_A, TRC_RSS_DISABLE);
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	memset(&tp, 0, sizeof(tp));
145462306a36Sopenharmony_ci	tp.port = TRC_PORT_NONE;
145562306a36Sopenharmony_ci	i = 0;	/* counts pattern nibbles */
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	while (p) {
145862306a36Sopenharmony_ci		while (isspace(*p))
145962306a36Sopenharmony_ci			p++;
146062306a36Sopenharmony_ci		word = strsep(&p, " ");
146162306a36Sopenharmony_ci		if (!*word)
146262306a36Sopenharmony_ci			break;
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci		if (!strncmp(word, "qid=", 4)) {
146562306a36Sopenharmony_ci			end = (char *)word + 4;
146662306a36Sopenharmony_ci			ret = kstrtouint(end, 10, &j);
146762306a36Sopenharmony_ci			if (ret)
146862306a36Sopenharmony_ci				goto out;
146962306a36Sopenharmony_ci			if (!adap->trace_rss) {
147062306a36Sopenharmony_ci				t4_write_reg(adap, MPS_T5_TRC_RSS_CONTROL_A, j);
147162306a36Sopenharmony_ci				continue;
147262306a36Sopenharmony_ci			}
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci			switch (trcidx) {
147562306a36Sopenharmony_ci			case 0:
147662306a36Sopenharmony_ci				t4_write_reg(adap, MPS_TRC_RSS_CONTROL_A, j);
147762306a36Sopenharmony_ci				break;
147862306a36Sopenharmony_ci			case 1:
147962306a36Sopenharmony_ci				t4_write_reg(adap,
148062306a36Sopenharmony_ci					     MPS_TRC_FILTER1_RSS_CONTROL_A, j);
148162306a36Sopenharmony_ci				break;
148262306a36Sopenharmony_ci			case 2:
148362306a36Sopenharmony_ci				t4_write_reg(adap,
148462306a36Sopenharmony_ci					     MPS_TRC_FILTER2_RSS_CONTROL_A, j);
148562306a36Sopenharmony_ci				break;
148662306a36Sopenharmony_ci			case 3:
148762306a36Sopenharmony_ci				t4_write_reg(adap,
148862306a36Sopenharmony_ci					     MPS_TRC_FILTER3_RSS_CONTROL_A, j);
148962306a36Sopenharmony_ci				break;
149062306a36Sopenharmony_ci			}
149162306a36Sopenharmony_ci			continue;
149262306a36Sopenharmony_ci		}
149362306a36Sopenharmony_ci		if (!strncmp(word, "snaplen=", 8)) {
149462306a36Sopenharmony_ci			end = (char *)word + 8;
149562306a36Sopenharmony_ci			ret = kstrtouint(end, 10, &j);
149662306a36Sopenharmony_ci			if (ret || j > 9600) {
149762306a36Sopenharmony_ciinval:				count = -EINVAL;
149862306a36Sopenharmony_ci				goto out;
149962306a36Sopenharmony_ci			}
150062306a36Sopenharmony_ci			tp.snap_len = j;
150162306a36Sopenharmony_ci			continue;
150262306a36Sopenharmony_ci		}
150362306a36Sopenharmony_ci		if (!strncmp(word, "minlen=", 7)) {
150462306a36Sopenharmony_ci			end = (char *)word + 7;
150562306a36Sopenharmony_ci			ret = kstrtouint(end, 10, &j);
150662306a36Sopenharmony_ci			if (ret || j > TFMINPKTSIZE_M)
150762306a36Sopenharmony_ci				goto inval;
150862306a36Sopenharmony_ci			tp.min_len = j;
150962306a36Sopenharmony_ci			continue;
151062306a36Sopenharmony_ci		}
151162306a36Sopenharmony_ci		if (!strcmp(word, "not")) {
151262306a36Sopenharmony_ci			tp.invert = !tp.invert;
151362306a36Sopenharmony_ci			continue;
151462306a36Sopenharmony_ci		}
151562306a36Sopenharmony_ci		if (!strncmp(word, "loopback", 8) && tp.port == TRC_PORT_NONE) {
151662306a36Sopenharmony_ci			if (word[8] < '0' || word[8] > '3' || word[9])
151762306a36Sopenharmony_ci				goto inval;
151862306a36Sopenharmony_ci			tp.port = word[8] - '0' + 8;
151962306a36Sopenharmony_ci			continue;
152062306a36Sopenharmony_ci		}
152162306a36Sopenharmony_ci		if (!strncmp(word, "tx", 2) && tp.port == TRC_PORT_NONE) {
152262306a36Sopenharmony_ci			if (word[2] < '0' || word[2] > '3' || word[3])
152362306a36Sopenharmony_ci				goto inval;
152462306a36Sopenharmony_ci			tp.port = word[2] - '0' + 4;
152562306a36Sopenharmony_ci			if (adap->chan_map[tp.port & 3] >= MAX_NPORTS)
152662306a36Sopenharmony_ci				goto inval;
152762306a36Sopenharmony_ci			continue;
152862306a36Sopenharmony_ci		}
152962306a36Sopenharmony_ci		if (!strncmp(word, "rx", 2) && tp.port == TRC_PORT_NONE) {
153062306a36Sopenharmony_ci			if (word[2] < '0' || word[2] > '3' || word[3])
153162306a36Sopenharmony_ci				goto inval;
153262306a36Sopenharmony_ci			tp.port = word[2] - '0';
153362306a36Sopenharmony_ci			if (adap->chan_map[tp.port] >= MAX_NPORTS)
153462306a36Sopenharmony_ci				goto inval;
153562306a36Sopenharmony_ci			continue;
153662306a36Sopenharmony_ci		}
153762306a36Sopenharmony_ci		if (!isxdigit(*word))
153862306a36Sopenharmony_ci			goto inval;
153962306a36Sopenharmony_ci
154062306a36Sopenharmony_ci		/* we have found a trace pattern */
154162306a36Sopenharmony_ci		if (i) {                            /* split pattern */
154262306a36Sopenharmony_ci			if (tp.skip_len)            /* too many splits */
154362306a36Sopenharmony_ci				goto inval;
154462306a36Sopenharmony_ci			tp.skip_ofst = i / 16;
154562306a36Sopenharmony_ci		}
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ci		data = &tp.data[i / 8];
154862306a36Sopenharmony_ci		mask = &tp.mask[i / 8];
154962306a36Sopenharmony_ci		j = i;
155062306a36Sopenharmony_ci
155162306a36Sopenharmony_ci		while (isxdigit(*word)) {
155262306a36Sopenharmony_ci			if (i >= TRACE_LEN * 2) {
155362306a36Sopenharmony_ci				count = -EFBIG;
155462306a36Sopenharmony_ci				goto out;
155562306a36Sopenharmony_ci			}
155662306a36Sopenharmony_ci			*data = (*data << 4) + xdigit2int(*word++);
155762306a36Sopenharmony_ci			if (++i % 8 == 0)
155862306a36Sopenharmony_ci				data++;
155962306a36Sopenharmony_ci		}
156062306a36Sopenharmony_ci		if (*word == '/') {
156162306a36Sopenharmony_ci			word++;
156262306a36Sopenharmony_ci			while (isxdigit(*word)) {
156362306a36Sopenharmony_ci				if (j >= i)         /* mask longer than data */
156462306a36Sopenharmony_ci					goto inval;
156562306a36Sopenharmony_ci				*mask = (*mask << 4) + xdigit2int(*word++);
156662306a36Sopenharmony_ci				if (++j % 8 == 0)
156762306a36Sopenharmony_ci					mask++;
156862306a36Sopenharmony_ci			}
156962306a36Sopenharmony_ci			if (i != j)                 /* mask shorter than data */
157062306a36Sopenharmony_ci				goto inval;
157162306a36Sopenharmony_ci		} else {                            /* no mask, use all 1s */
157262306a36Sopenharmony_ci			for ( ; i - j >= 8; j += 8)
157362306a36Sopenharmony_ci				*mask++ = 0xffffffff;
157462306a36Sopenharmony_ci			if (i % 8)
157562306a36Sopenharmony_ci				*mask = (1 << (i % 8) * 4) - 1;
157662306a36Sopenharmony_ci		}
157762306a36Sopenharmony_ci		if (*word == '@') {
157862306a36Sopenharmony_ci			end = (char *)word + 1;
157962306a36Sopenharmony_ci			ret = kstrtouint(end, 10, &j);
158062306a36Sopenharmony_ci			if (*end && *end != '\n')
158162306a36Sopenharmony_ci				goto inval;
158262306a36Sopenharmony_ci			if (j & 7)          /* doesn't start at multiple of 8 */
158362306a36Sopenharmony_ci				goto inval;
158462306a36Sopenharmony_ci			j /= 8;
158562306a36Sopenharmony_ci			if (j < tp.skip_ofst)     /* overlaps earlier pattern */
158662306a36Sopenharmony_ci				goto inval;
158762306a36Sopenharmony_ci			if (j - tp.skip_ofst > 31)            /* skip too big */
158862306a36Sopenharmony_ci				goto inval;
158962306a36Sopenharmony_ci			tp.skip_len = j - tp.skip_ofst;
159062306a36Sopenharmony_ci		}
159162306a36Sopenharmony_ci		if (i % 8) {
159262306a36Sopenharmony_ci			*data <<= (8 - i % 8) * 4;
159362306a36Sopenharmony_ci			*mask <<= (8 - i % 8) * 4;
159462306a36Sopenharmony_ci			i = (i + 15) & ~15;         /* 8-byte align */
159562306a36Sopenharmony_ci		}
159662306a36Sopenharmony_ci	}
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	if (tp.port == TRC_PORT_NONE)
159962306a36Sopenharmony_ci		goto inval;
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ciapply:
160262306a36Sopenharmony_ci	i = t4_set_trace_filter(adap, &tp, trcidx, enable);
160362306a36Sopenharmony_ci	if (i)
160462306a36Sopenharmony_ci		count = i;
160562306a36Sopenharmony_ciout:
160662306a36Sopenharmony_ci	kfree(s);
160762306a36Sopenharmony_ci	return count;
160862306a36Sopenharmony_ci}
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_cistatic const struct file_operations mps_trc_debugfs_fops = {
161162306a36Sopenharmony_ci	.owner   = THIS_MODULE,
161262306a36Sopenharmony_ci	.open    = mps_trc_open,
161362306a36Sopenharmony_ci	.read    = seq_read,
161462306a36Sopenharmony_ci	.llseek  = seq_lseek,
161562306a36Sopenharmony_ci	.release = single_release,
161662306a36Sopenharmony_ci	.write   = mps_trc_write
161762306a36Sopenharmony_ci};
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_cistatic ssize_t flash_read(struct file *file, char __user *buf, size_t count,
162062306a36Sopenharmony_ci			  loff_t *ppos)
162162306a36Sopenharmony_ci{
162262306a36Sopenharmony_ci	loff_t pos = *ppos;
162362306a36Sopenharmony_ci	loff_t avail = file_inode(file)->i_size;
162462306a36Sopenharmony_ci	struct adapter *adap = file->private_data;
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci	if (pos < 0)
162762306a36Sopenharmony_ci		return -EINVAL;
162862306a36Sopenharmony_ci	if (pos >= avail)
162962306a36Sopenharmony_ci		return 0;
163062306a36Sopenharmony_ci	if (count > avail - pos)
163162306a36Sopenharmony_ci		count = avail - pos;
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci	while (count) {
163462306a36Sopenharmony_ci		size_t len;
163562306a36Sopenharmony_ci		int ret, ofst;
163662306a36Sopenharmony_ci		u8 data[256];
163762306a36Sopenharmony_ci
163862306a36Sopenharmony_ci		ofst = pos & 3;
163962306a36Sopenharmony_ci		len = min(count + ofst, sizeof(data));
164062306a36Sopenharmony_ci		ret = t4_read_flash(adap, pos - ofst, (len + 3) / 4,
164162306a36Sopenharmony_ci				    (u32 *)data, 1);
164262306a36Sopenharmony_ci		if (ret)
164362306a36Sopenharmony_ci			return ret;
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci		len -= ofst;
164662306a36Sopenharmony_ci		if (copy_to_user(buf, data + ofst, len))
164762306a36Sopenharmony_ci			return -EFAULT;
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci		buf += len;
165062306a36Sopenharmony_ci		pos += len;
165162306a36Sopenharmony_ci		count -= len;
165262306a36Sopenharmony_ci	}
165362306a36Sopenharmony_ci	count = pos - *ppos;
165462306a36Sopenharmony_ci	*ppos = pos;
165562306a36Sopenharmony_ci	return count;
165662306a36Sopenharmony_ci}
165762306a36Sopenharmony_ci
165862306a36Sopenharmony_cistatic const struct file_operations flash_debugfs_fops = {
165962306a36Sopenharmony_ci	.owner   = THIS_MODULE,
166062306a36Sopenharmony_ci	.open    = mem_open,
166162306a36Sopenharmony_ci	.read    = flash_read,
166262306a36Sopenharmony_ci	.llseek  = default_llseek,
166362306a36Sopenharmony_ci};
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_cistatic inline void tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
166662306a36Sopenharmony_ci{
166762306a36Sopenharmony_ci	*mask = x | y;
166862306a36Sopenharmony_ci	y = (__force u64)cpu_to_be64(y);
166962306a36Sopenharmony_ci	memcpy(addr, (char *)&y + 2, ETH_ALEN);
167062306a36Sopenharmony_ci}
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_cistatic int mps_tcam_show(struct seq_file *seq, void *v)
167362306a36Sopenharmony_ci{
167462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
167562306a36Sopenharmony_ci	unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
167662306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
167762306a36Sopenharmony_ci		if (chip_ver > CHELSIO_T5) {
167862306a36Sopenharmony_ci			seq_puts(seq, "Idx  Ethernet address     Mask     "
167962306a36Sopenharmony_ci				 "  VNI   Mask   IVLAN Vld "
168062306a36Sopenharmony_ci				 "DIP_Hit   Lookup  Port "
168162306a36Sopenharmony_ci				 "Vld Ports PF  VF                           "
168262306a36Sopenharmony_ci				 "Replication                                "
168362306a36Sopenharmony_ci				 "    P0 P1 P2 P3  ML\n");
168462306a36Sopenharmony_ci		} else {
168562306a36Sopenharmony_ci			if (adap->params.arch.mps_rplc_size > 128)
168662306a36Sopenharmony_ci				seq_puts(seq, "Idx  Ethernet address     Mask     "
168762306a36Sopenharmony_ci					 "Vld Ports PF  VF                           "
168862306a36Sopenharmony_ci					 "Replication                                "
168962306a36Sopenharmony_ci					 "    P0 P1 P2 P3  ML\n");
169062306a36Sopenharmony_ci			else
169162306a36Sopenharmony_ci				seq_puts(seq, "Idx  Ethernet address     Mask     "
169262306a36Sopenharmony_ci					 "Vld Ports PF  VF              Replication"
169362306a36Sopenharmony_ci					 "	         P0 P1 P2 P3  ML\n");
169462306a36Sopenharmony_ci		}
169562306a36Sopenharmony_ci	} else {
169662306a36Sopenharmony_ci		u64 mask;
169762306a36Sopenharmony_ci		u8 addr[ETH_ALEN];
169862306a36Sopenharmony_ci		bool replicate, dip_hit = false, vlan_vld = false;
169962306a36Sopenharmony_ci		unsigned int idx = (uintptr_t)v - 2;
170062306a36Sopenharmony_ci		u64 tcamy, tcamx, val;
170162306a36Sopenharmony_ci		u32 cls_lo, cls_hi, ctl, data2, vnix = 0, vniy = 0;
170262306a36Sopenharmony_ci		u32 rplc[8] = {0};
170362306a36Sopenharmony_ci		u8 lookup_type = 0, port_num = 0;
170462306a36Sopenharmony_ci		u16 ivlan = 0;
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci		if (chip_ver > CHELSIO_T5) {
170762306a36Sopenharmony_ci			/* CtlCmdType - 0: Read, 1: Write
170862306a36Sopenharmony_ci			 * CtlTcamSel - 0: TCAM0, 1: TCAM1
170962306a36Sopenharmony_ci			 * CtlXYBitSel- 0: Y bit, 1: X bit
171062306a36Sopenharmony_ci			 */
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_ci			/* Read tcamy */
171362306a36Sopenharmony_ci			ctl = CTLCMDTYPE_V(0) | CTLXYBITSEL_V(0);
171462306a36Sopenharmony_ci			if (idx < 256)
171562306a36Sopenharmony_ci				ctl |= CTLTCAMINDEX_V(idx) | CTLTCAMSEL_V(0);
171662306a36Sopenharmony_ci			else
171762306a36Sopenharmony_ci				ctl |= CTLTCAMINDEX_V(idx - 256) |
171862306a36Sopenharmony_ci				       CTLTCAMSEL_V(1);
171962306a36Sopenharmony_ci			t4_write_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
172062306a36Sopenharmony_ci			val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A);
172162306a36Sopenharmony_ci			tcamy = DMACH_G(val) << 32;
172262306a36Sopenharmony_ci			tcamy |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A);
172362306a36Sopenharmony_ci			data2 = t4_read_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A);
172462306a36Sopenharmony_ci			lookup_type = DATALKPTYPE_G(data2);
172562306a36Sopenharmony_ci			/* 0 - Outer header, 1 - Inner header
172662306a36Sopenharmony_ci			 * [71:48] bit locations are overloaded for
172762306a36Sopenharmony_ci			 * outer vs. inner lookup types.
172862306a36Sopenharmony_ci			 */
172962306a36Sopenharmony_ci			if (lookup_type && (lookup_type != DATALKPTYPE_M)) {
173062306a36Sopenharmony_ci				/* Inner header VNI */
173162306a36Sopenharmony_ci				vniy = (data2 & DATAVIDH2_F) |
173262306a36Sopenharmony_ci				       (DATAVIDH1_G(data2) << 16) | VIDL_G(val);
173362306a36Sopenharmony_ci				dip_hit = data2 & DATADIPHIT_F;
173462306a36Sopenharmony_ci			} else {
173562306a36Sopenharmony_ci				vlan_vld = data2 & DATAVIDH2_F;
173662306a36Sopenharmony_ci				ivlan = VIDL_G(val);
173762306a36Sopenharmony_ci			}
173862306a36Sopenharmony_ci			port_num = DATAPORTNUM_G(data2);
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci			/* Read tcamx. Change the control param */
174162306a36Sopenharmony_ci			vnix = 0;
174262306a36Sopenharmony_ci			ctl |= CTLXYBITSEL_V(1);
174362306a36Sopenharmony_ci			t4_write_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A, ctl);
174462306a36Sopenharmony_ci			val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A);
174562306a36Sopenharmony_ci			tcamx = DMACH_G(val) << 32;
174662306a36Sopenharmony_ci			tcamx |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A);
174762306a36Sopenharmony_ci			data2 = t4_read_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A);
174862306a36Sopenharmony_ci			if (lookup_type && (lookup_type != DATALKPTYPE_M)) {
174962306a36Sopenharmony_ci				/* Inner header VNI mask */
175062306a36Sopenharmony_ci				vnix = (data2 & DATAVIDH2_F) |
175162306a36Sopenharmony_ci				       (DATAVIDH1_G(data2) << 16) | VIDL_G(val);
175262306a36Sopenharmony_ci			}
175362306a36Sopenharmony_ci		} else {
175462306a36Sopenharmony_ci			tcamy = t4_read_reg64(adap, MPS_CLS_TCAM_Y_L(idx));
175562306a36Sopenharmony_ci			tcamx = t4_read_reg64(adap, MPS_CLS_TCAM_X_L(idx));
175662306a36Sopenharmony_ci		}
175762306a36Sopenharmony_ci
175862306a36Sopenharmony_ci		cls_lo = t4_read_reg(adap, MPS_CLS_SRAM_L(idx));
175962306a36Sopenharmony_ci		cls_hi = t4_read_reg(adap, MPS_CLS_SRAM_H(idx));
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci		if (tcamx & tcamy) {
176262306a36Sopenharmony_ci			seq_printf(seq, "%3u         -\n", idx);
176362306a36Sopenharmony_ci			goto out;
176462306a36Sopenharmony_ci		}
176562306a36Sopenharmony_ci
176662306a36Sopenharmony_ci		rplc[0] = rplc[1] = rplc[2] = rplc[3] = 0;
176762306a36Sopenharmony_ci		if (chip_ver > CHELSIO_T5)
176862306a36Sopenharmony_ci			replicate = (cls_lo & T6_REPLICATE_F);
176962306a36Sopenharmony_ci		else
177062306a36Sopenharmony_ci			replicate = (cls_lo & REPLICATE_F);
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci		if (replicate) {
177362306a36Sopenharmony_ci			struct fw_ldst_cmd ldst_cmd;
177462306a36Sopenharmony_ci			int ret;
177562306a36Sopenharmony_ci			struct fw_ldst_mps_rplc mps_rplc;
177662306a36Sopenharmony_ci			u32 ldst_addrspc;
177762306a36Sopenharmony_ci
177862306a36Sopenharmony_ci			memset(&ldst_cmd, 0, sizeof(ldst_cmd));
177962306a36Sopenharmony_ci			ldst_addrspc =
178062306a36Sopenharmony_ci				FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MPS);
178162306a36Sopenharmony_ci			ldst_cmd.op_to_addrspace =
178262306a36Sopenharmony_ci				htonl(FW_CMD_OP_V(FW_LDST_CMD) |
178362306a36Sopenharmony_ci				      FW_CMD_REQUEST_F |
178462306a36Sopenharmony_ci				      FW_CMD_READ_F |
178562306a36Sopenharmony_ci				      ldst_addrspc);
178662306a36Sopenharmony_ci			ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
178762306a36Sopenharmony_ci			ldst_cmd.u.mps.rplc.fid_idx =
178862306a36Sopenharmony_ci				htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
178962306a36Sopenharmony_ci				      FW_LDST_CMD_IDX_V(idx));
179062306a36Sopenharmony_ci			ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd,
179162306a36Sopenharmony_ci					 sizeof(ldst_cmd), &ldst_cmd);
179262306a36Sopenharmony_ci			if (ret)
179362306a36Sopenharmony_ci				dev_warn(adap->pdev_dev, "Can't read MPS "
179462306a36Sopenharmony_ci					 "replication map for idx %d: %d\n",
179562306a36Sopenharmony_ci					 idx, -ret);
179662306a36Sopenharmony_ci			else {
179762306a36Sopenharmony_ci				mps_rplc = ldst_cmd.u.mps.rplc;
179862306a36Sopenharmony_ci				rplc[0] = ntohl(mps_rplc.rplc31_0);
179962306a36Sopenharmony_ci				rplc[1] = ntohl(mps_rplc.rplc63_32);
180062306a36Sopenharmony_ci				rplc[2] = ntohl(mps_rplc.rplc95_64);
180162306a36Sopenharmony_ci				rplc[3] = ntohl(mps_rplc.rplc127_96);
180262306a36Sopenharmony_ci				if (adap->params.arch.mps_rplc_size > 128) {
180362306a36Sopenharmony_ci					rplc[4] = ntohl(mps_rplc.rplc159_128);
180462306a36Sopenharmony_ci					rplc[5] = ntohl(mps_rplc.rplc191_160);
180562306a36Sopenharmony_ci					rplc[6] = ntohl(mps_rplc.rplc223_192);
180662306a36Sopenharmony_ci					rplc[7] = ntohl(mps_rplc.rplc255_224);
180762306a36Sopenharmony_ci				}
180862306a36Sopenharmony_ci			}
180962306a36Sopenharmony_ci		}
181062306a36Sopenharmony_ci
181162306a36Sopenharmony_ci		tcamxy2valmask(tcamx, tcamy, addr, &mask);
181262306a36Sopenharmony_ci		if (chip_ver > CHELSIO_T5) {
181362306a36Sopenharmony_ci			/* Inner header lookup */
181462306a36Sopenharmony_ci			if (lookup_type && (lookup_type != DATALKPTYPE_M)) {
181562306a36Sopenharmony_ci				seq_printf(seq,
181662306a36Sopenharmony_ci					   "%3u %pM %012llx %06x %06x    -    -   %3c      'I'  %4x   %3c   %#x%4u%4d",
181762306a36Sopenharmony_ci					   idx, addr,
181862306a36Sopenharmony_ci					   (unsigned long long)mask,
181962306a36Sopenharmony_ci					   vniy, (vnix | vniy),
182062306a36Sopenharmony_ci					   dip_hit ? 'Y' : 'N',
182162306a36Sopenharmony_ci					   port_num,
182262306a36Sopenharmony_ci					   (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N',
182362306a36Sopenharmony_ci					   PORTMAP_G(cls_hi),
182462306a36Sopenharmony_ci					   T6_PF_G(cls_lo),
182562306a36Sopenharmony_ci					   (cls_lo & T6_VF_VALID_F) ?
182662306a36Sopenharmony_ci					   T6_VF_G(cls_lo) : -1);
182762306a36Sopenharmony_ci			} else {
182862306a36Sopenharmony_ci				seq_printf(seq,
182962306a36Sopenharmony_ci					   "%3u %pM %012llx    -       -   ",
183062306a36Sopenharmony_ci					   idx, addr,
183162306a36Sopenharmony_ci					   (unsigned long long)mask);
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci				if (vlan_vld)
183462306a36Sopenharmony_ci					seq_printf(seq, "%4u   Y     ", ivlan);
183562306a36Sopenharmony_ci				else
183662306a36Sopenharmony_ci					seq_puts(seq, "  -    N     ");
183762306a36Sopenharmony_ci
183862306a36Sopenharmony_ci				seq_printf(seq,
183962306a36Sopenharmony_ci					   "-      %3c  %4x   %3c   %#x%4u%4d",
184062306a36Sopenharmony_ci					   lookup_type ? 'I' : 'O', port_num,
184162306a36Sopenharmony_ci					   (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N',
184262306a36Sopenharmony_ci					   PORTMAP_G(cls_hi),
184362306a36Sopenharmony_ci					   T6_PF_G(cls_lo),
184462306a36Sopenharmony_ci					   (cls_lo & T6_VF_VALID_F) ?
184562306a36Sopenharmony_ci					   T6_VF_G(cls_lo) : -1);
184662306a36Sopenharmony_ci			}
184762306a36Sopenharmony_ci		} else
184862306a36Sopenharmony_ci			seq_printf(seq, "%3u %pM %012llx%3c   %#x%4u%4d",
184962306a36Sopenharmony_ci				   idx, addr, (unsigned long long)mask,
185062306a36Sopenharmony_ci				   (cls_lo & SRAM_VLD_F) ? 'Y' : 'N',
185162306a36Sopenharmony_ci				   PORTMAP_G(cls_hi),
185262306a36Sopenharmony_ci				   PF_G(cls_lo),
185362306a36Sopenharmony_ci				   (cls_lo & VF_VALID_F) ? VF_G(cls_lo) : -1);
185462306a36Sopenharmony_ci
185562306a36Sopenharmony_ci		if (replicate) {
185662306a36Sopenharmony_ci			if (adap->params.arch.mps_rplc_size > 128)
185762306a36Sopenharmony_ci				seq_printf(seq, " %08x %08x %08x %08x "
185862306a36Sopenharmony_ci					   "%08x %08x %08x %08x",
185962306a36Sopenharmony_ci					   rplc[7], rplc[6], rplc[5], rplc[4],
186062306a36Sopenharmony_ci					   rplc[3], rplc[2], rplc[1], rplc[0]);
186162306a36Sopenharmony_ci			else
186262306a36Sopenharmony_ci				seq_printf(seq, " %08x %08x %08x %08x",
186362306a36Sopenharmony_ci					   rplc[3], rplc[2], rplc[1], rplc[0]);
186462306a36Sopenharmony_ci		} else {
186562306a36Sopenharmony_ci			if (adap->params.arch.mps_rplc_size > 128)
186662306a36Sopenharmony_ci				seq_printf(seq, "%72c", ' ');
186762306a36Sopenharmony_ci			else
186862306a36Sopenharmony_ci				seq_printf(seq, "%36c", ' ');
186962306a36Sopenharmony_ci		}
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci		if (chip_ver > CHELSIO_T5)
187262306a36Sopenharmony_ci			seq_printf(seq, "%4u%3u%3u%3u %#x\n",
187362306a36Sopenharmony_ci				   T6_SRAM_PRIO0_G(cls_lo),
187462306a36Sopenharmony_ci				   T6_SRAM_PRIO1_G(cls_lo),
187562306a36Sopenharmony_ci				   T6_SRAM_PRIO2_G(cls_lo),
187662306a36Sopenharmony_ci				   T6_SRAM_PRIO3_G(cls_lo),
187762306a36Sopenharmony_ci				   (cls_lo >> T6_MULTILISTEN0_S) & 0xf);
187862306a36Sopenharmony_ci		else
187962306a36Sopenharmony_ci			seq_printf(seq, "%4u%3u%3u%3u %#x\n",
188062306a36Sopenharmony_ci				   SRAM_PRIO0_G(cls_lo), SRAM_PRIO1_G(cls_lo),
188162306a36Sopenharmony_ci				   SRAM_PRIO2_G(cls_lo), SRAM_PRIO3_G(cls_lo),
188262306a36Sopenharmony_ci				   (cls_lo >> MULTILISTEN0_S) & 0xf);
188362306a36Sopenharmony_ci	}
188462306a36Sopenharmony_ciout:	return 0;
188562306a36Sopenharmony_ci}
188662306a36Sopenharmony_ci
188762306a36Sopenharmony_cistatic inline void *mps_tcam_get_idx(struct seq_file *seq, loff_t pos)
188862306a36Sopenharmony_ci{
188962306a36Sopenharmony_ci	struct adapter *adap = seq->private;
189062306a36Sopenharmony_ci	int max_mac_addr = is_t4(adap->params.chip) ?
189162306a36Sopenharmony_ci				NUM_MPS_CLS_SRAM_L_INSTANCES :
189262306a36Sopenharmony_ci				NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
189362306a36Sopenharmony_ci	return ((pos <= max_mac_addr) ? (void *)(uintptr_t)(pos + 1) : NULL);
189462306a36Sopenharmony_ci}
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_cistatic void *mps_tcam_start(struct seq_file *seq, loff_t *pos)
189762306a36Sopenharmony_ci{
189862306a36Sopenharmony_ci	return *pos ? mps_tcam_get_idx(seq, *pos) : SEQ_START_TOKEN;
189962306a36Sopenharmony_ci}
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_cistatic void *mps_tcam_next(struct seq_file *seq, void *v, loff_t *pos)
190262306a36Sopenharmony_ci{
190362306a36Sopenharmony_ci	++*pos;
190462306a36Sopenharmony_ci	return mps_tcam_get_idx(seq, *pos);
190562306a36Sopenharmony_ci}
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_cistatic void mps_tcam_stop(struct seq_file *seq, void *v)
190862306a36Sopenharmony_ci{
190962306a36Sopenharmony_ci}
191062306a36Sopenharmony_ci
191162306a36Sopenharmony_cistatic const struct seq_operations mps_tcam_seq_ops = {
191262306a36Sopenharmony_ci	.start = mps_tcam_start,
191362306a36Sopenharmony_ci	.next  = mps_tcam_next,
191462306a36Sopenharmony_ci	.stop  = mps_tcam_stop,
191562306a36Sopenharmony_ci	.show  = mps_tcam_show
191662306a36Sopenharmony_ci};
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_cistatic int mps_tcam_open(struct inode *inode, struct file *file)
191962306a36Sopenharmony_ci{
192062306a36Sopenharmony_ci	int res = seq_open(file, &mps_tcam_seq_ops);
192162306a36Sopenharmony_ci
192262306a36Sopenharmony_ci	if (!res) {
192362306a36Sopenharmony_ci		struct seq_file *seq = file->private_data;
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci		seq->private = inode->i_private;
192662306a36Sopenharmony_ci	}
192762306a36Sopenharmony_ci	return res;
192862306a36Sopenharmony_ci}
192962306a36Sopenharmony_ci
193062306a36Sopenharmony_cistatic const struct file_operations mps_tcam_debugfs_fops = {
193162306a36Sopenharmony_ci	.owner   = THIS_MODULE,
193262306a36Sopenharmony_ci	.open    = mps_tcam_open,
193362306a36Sopenharmony_ci	.read    = seq_read,
193462306a36Sopenharmony_ci	.llseek  = seq_lseek,
193562306a36Sopenharmony_ci	.release = seq_release,
193662306a36Sopenharmony_ci};
193762306a36Sopenharmony_ci
193862306a36Sopenharmony_ci/* Display various sensor information.
193962306a36Sopenharmony_ci */
194062306a36Sopenharmony_cistatic int sensors_show(struct seq_file *seq, void *v)
194162306a36Sopenharmony_ci{
194262306a36Sopenharmony_ci	struct adapter *adap = seq->private;
194362306a36Sopenharmony_ci	u32 param[7], val[7];
194462306a36Sopenharmony_ci	int ret;
194562306a36Sopenharmony_ci
194662306a36Sopenharmony_ci	/* Note that if the sensors haven't been initialized and turned on
194762306a36Sopenharmony_ci	 * we'll get values of 0, so treat those as "<unknown>" ...
194862306a36Sopenharmony_ci	 */
194962306a36Sopenharmony_ci	param[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
195062306a36Sopenharmony_ci		    FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) |
195162306a36Sopenharmony_ci		    FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_TMP));
195262306a36Sopenharmony_ci	param[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
195362306a36Sopenharmony_ci		    FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) |
195462306a36Sopenharmony_ci		    FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_VDD));
195562306a36Sopenharmony_ci	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
195662306a36Sopenharmony_ci			      param, val);
195762306a36Sopenharmony_ci
195862306a36Sopenharmony_ci	if (ret < 0 || val[0] == 0)
195962306a36Sopenharmony_ci		seq_puts(seq, "Temperature: <unknown>\n");
196062306a36Sopenharmony_ci	else
196162306a36Sopenharmony_ci		seq_printf(seq, "Temperature: %dC\n", val[0]);
196262306a36Sopenharmony_ci
196362306a36Sopenharmony_ci	if (ret < 0 || val[1] == 0)
196462306a36Sopenharmony_ci		seq_puts(seq, "Core VDD:    <unknown>\n");
196562306a36Sopenharmony_ci	else
196662306a36Sopenharmony_ci		seq_printf(seq, "Core VDD:    %dmV\n", val[1]);
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci	return 0;
196962306a36Sopenharmony_ci}
197062306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(sensors);
197162306a36Sopenharmony_ci
197262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
197362306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(clip_tbl);
197462306a36Sopenharmony_ci#endif
197562306a36Sopenharmony_ci
197662306a36Sopenharmony_ci/*RSS Table.
197762306a36Sopenharmony_ci */
197862306a36Sopenharmony_ci
197962306a36Sopenharmony_cistatic int rss_show(struct seq_file *seq, void *v, int idx)
198062306a36Sopenharmony_ci{
198162306a36Sopenharmony_ci	u16 *entry = v;
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_ci	seq_printf(seq, "%4d:  %4u  %4u  %4u  %4u  %4u  %4u  %4u  %4u\n",
198462306a36Sopenharmony_ci		   idx * 8, entry[0], entry[1], entry[2], entry[3], entry[4],
198562306a36Sopenharmony_ci		   entry[5], entry[6], entry[7]);
198662306a36Sopenharmony_ci	return 0;
198762306a36Sopenharmony_ci}
198862306a36Sopenharmony_ci
198962306a36Sopenharmony_cistatic int rss_open(struct inode *inode, struct file *file)
199062306a36Sopenharmony_ci{
199162306a36Sopenharmony_ci	struct adapter *adap = inode->i_private;
199262306a36Sopenharmony_ci	int ret, nentries;
199362306a36Sopenharmony_ci	struct seq_tab *p;
199462306a36Sopenharmony_ci
199562306a36Sopenharmony_ci	nentries = t4_chip_rss_size(adap);
199662306a36Sopenharmony_ci	p = seq_open_tab(file, nentries / 8, 8 * sizeof(u16), 0, rss_show);
199762306a36Sopenharmony_ci	if (!p)
199862306a36Sopenharmony_ci		return -ENOMEM;
199962306a36Sopenharmony_ci
200062306a36Sopenharmony_ci	ret = t4_read_rss(adap, (u16 *)p->data);
200162306a36Sopenharmony_ci	if (ret)
200262306a36Sopenharmony_ci		seq_release_private(inode, file);
200362306a36Sopenharmony_ci
200462306a36Sopenharmony_ci	return ret;
200562306a36Sopenharmony_ci}
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_cistatic const struct file_operations rss_debugfs_fops = {
200862306a36Sopenharmony_ci	.owner   = THIS_MODULE,
200962306a36Sopenharmony_ci	.open    = rss_open,
201062306a36Sopenharmony_ci	.read    = seq_read,
201162306a36Sopenharmony_ci	.llseek  = seq_lseek,
201262306a36Sopenharmony_ci	.release = seq_release_private
201362306a36Sopenharmony_ci};
201462306a36Sopenharmony_ci
201562306a36Sopenharmony_ci/* RSS Configuration.
201662306a36Sopenharmony_ci */
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_ci/* Small utility function to return the strings "yes" or "no" if the supplied
201962306a36Sopenharmony_ci * argument is non-zero.
202062306a36Sopenharmony_ci */
202162306a36Sopenharmony_cistatic const char *yesno(int x)
202262306a36Sopenharmony_ci{
202362306a36Sopenharmony_ci	static const char *yes = "yes";
202462306a36Sopenharmony_ci	static const char *no = "no";
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	return x ? yes : no;
202762306a36Sopenharmony_ci}
202862306a36Sopenharmony_ci
202962306a36Sopenharmony_cistatic int rss_config_show(struct seq_file *seq, void *v)
203062306a36Sopenharmony_ci{
203162306a36Sopenharmony_ci	struct adapter *adapter = seq->private;
203262306a36Sopenharmony_ci	static const char * const keymode[] = {
203362306a36Sopenharmony_ci		"global",
203462306a36Sopenharmony_ci		"global and per-VF scramble",
203562306a36Sopenharmony_ci		"per-PF and per-VF scramble",
203662306a36Sopenharmony_ci		"per-VF and per-VF scramble",
203762306a36Sopenharmony_ci	};
203862306a36Sopenharmony_ci	u32 rssconf;
203962306a36Sopenharmony_ci
204062306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_A);
204162306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG: %#x\n", rssconf);
204262306a36Sopenharmony_ci	seq_printf(seq, "  Tnl4TupEnIpv6: %3s\n", yesno(rssconf &
204362306a36Sopenharmony_ci							TNL4TUPENIPV6_F));
204462306a36Sopenharmony_ci	seq_printf(seq, "  Tnl2TupEnIpv6: %3s\n", yesno(rssconf &
204562306a36Sopenharmony_ci							TNL2TUPENIPV6_F));
204662306a36Sopenharmony_ci	seq_printf(seq, "  Tnl4TupEnIpv4: %3s\n", yesno(rssconf &
204762306a36Sopenharmony_ci							TNL4TUPENIPV4_F));
204862306a36Sopenharmony_ci	seq_printf(seq, "  Tnl2TupEnIpv4: %3s\n", yesno(rssconf &
204962306a36Sopenharmony_ci							TNL2TUPENIPV4_F));
205062306a36Sopenharmony_ci	seq_printf(seq, "  TnlTcpSel:     %3s\n", yesno(rssconf & TNLTCPSEL_F));
205162306a36Sopenharmony_ci	seq_printf(seq, "  TnlIp6Sel:     %3s\n", yesno(rssconf & TNLIP6SEL_F));
205262306a36Sopenharmony_ci	seq_printf(seq, "  TnlVrtSel:     %3s\n", yesno(rssconf & TNLVRTSEL_F));
205362306a36Sopenharmony_ci	seq_printf(seq, "  TnlMapEn:      %3s\n", yesno(rssconf & TNLMAPEN_F));
205462306a36Sopenharmony_ci	seq_printf(seq, "  OfdHashSave:   %3s\n", yesno(rssconf &
205562306a36Sopenharmony_ci							OFDHASHSAVE_F));
205662306a36Sopenharmony_ci	seq_printf(seq, "  OfdVrtSel:     %3s\n", yesno(rssconf & OFDVRTSEL_F));
205762306a36Sopenharmony_ci	seq_printf(seq, "  OfdMapEn:      %3s\n", yesno(rssconf & OFDMAPEN_F));
205862306a36Sopenharmony_ci	seq_printf(seq, "  OfdLkpEn:      %3s\n", yesno(rssconf & OFDLKPEN_F));
205962306a36Sopenharmony_ci	seq_printf(seq, "  Syn4TupEnIpv6: %3s\n", yesno(rssconf &
206062306a36Sopenharmony_ci							SYN4TUPENIPV6_F));
206162306a36Sopenharmony_ci	seq_printf(seq, "  Syn2TupEnIpv6: %3s\n", yesno(rssconf &
206262306a36Sopenharmony_ci							SYN2TUPENIPV6_F));
206362306a36Sopenharmony_ci	seq_printf(seq, "  Syn4TupEnIpv4: %3s\n", yesno(rssconf &
206462306a36Sopenharmony_ci							SYN4TUPENIPV4_F));
206562306a36Sopenharmony_ci	seq_printf(seq, "  Syn2TupEnIpv4: %3s\n", yesno(rssconf &
206662306a36Sopenharmony_ci							SYN2TUPENIPV4_F));
206762306a36Sopenharmony_ci	seq_printf(seq, "  Syn4TupEnIpv6: %3s\n", yesno(rssconf &
206862306a36Sopenharmony_ci							SYN4TUPENIPV6_F));
206962306a36Sopenharmony_ci	seq_printf(seq, "  SynIp6Sel:     %3s\n", yesno(rssconf & SYNIP6SEL_F));
207062306a36Sopenharmony_ci	seq_printf(seq, "  SynVrt6Sel:    %3s\n", yesno(rssconf & SYNVRTSEL_F));
207162306a36Sopenharmony_ci	seq_printf(seq, "  SynMapEn:      %3s\n", yesno(rssconf & SYNMAPEN_F));
207262306a36Sopenharmony_ci	seq_printf(seq, "  SynLkpEn:      %3s\n", yesno(rssconf & SYNLKPEN_F));
207362306a36Sopenharmony_ci	seq_printf(seq, "  ChnEn:         %3s\n", yesno(rssconf &
207462306a36Sopenharmony_ci							CHANNELENABLE_F));
207562306a36Sopenharmony_ci	seq_printf(seq, "  PrtEn:         %3s\n", yesno(rssconf &
207662306a36Sopenharmony_ci							PORTENABLE_F));
207762306a36Sopenharmony_ci	seq_printf(seq, "  TnlAllLkp:     %3s\n", yesno(rssconf &
207862306a36Sopenharmony_ci							TNLALLLOOKUP_F));
207962306a36Sopenharmony_ci	seq_printf(seq, "  VrtEn:         %3s\n", yesno(rssconf &
208062306a36Sopenharmony_ci							VIRTENABLE_F));
208162306a36Sopenharmony_ci	seq_printf(seq, "  CngEn:         %3s\n", yesno(rssconf &
208262306a36Sopenharmony_ci							CONGESTIONENABLE_F));
208362306a36Sopenharmony_ci	seq_printf(seq, "  HashToeplitz:  %3s\n", yesno(rssconf &
208462306a36Sopenharmony_ci							HASHTOEPLITZ_F));
208562306a36Sopenharmony_ci	seq_printf(seq, "  Udp4En:        %3s\n", yesno(rssconf & UDPENABLE_F));
208662306a36Sopenharmony_ci	seq_printf(seq, "  Disable:       %3s\n", yesno(rssconf & DISABLE_F));
208762306a36Sopenharmony_ci
208862306a36Sopenharmony_ci	seq_puts(seq, "\n");
208962306a36Sopenharmony_ci
209062306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_TNL_A);
209162306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG_TNL: %#x\n", rssconf);
209262306a36Sopenharmony_ci	seq_printf(seq, "  MaskSize:      %3d\n", MASKSIZE_G(rssconf));
209362306a36Sopenharmony_ci	seq_printf(seq, "  MaskFilter:    %3d\n", MASKFILTER_G(rssconf));
209462306a36Sopenharmony_ci	if (CHELSIO_CHIP_VERSION(adapter->params.chip) > CHELSIO_T5) {
209562306a36Sopenharmony_ci		seq_printf(seq, "  HashAll:     %3s\n",
209662306a36Sopenharmony_ci			   yesno(rssconf & HASHALL_F));
209762306a36Sopenharmony_ci		seq_printf(seq, "  HashEth:     %3s\n",
209862306a36Sopenharmony_ci			   yesno(rssconf & HASHETH_F));
209962306a36Sopenharmony_ci	}
210062306a36Sopenharmony_ci	seq_printf(seq, "  UseWireCh:     %3s\n", yesno(rssconf & USEWIRECH_F));
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_ci	seq_puts(seq, "\n");
210362306a36Sopenharmony_ci
210462306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_OFD_A);
210562306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG_OFD: %#x\n", rssconf);
210662306a36Sopenharmony_ci	seq_printf(seq, "  MaskSize:      %3d\n", MASKSIZE_G(rssconf));
210762306a36Sopenharmony_ci	seq_printf(seq, "  RRCplMapEn:    %3s\n", yesno(rssconf &
210862306a36Sopenharmony_ci							RRCPLMAPEN_F));
210962306a36Sopenharmony_ci	seq_printf(seq, "  RRCplQueWidth: %3d\n", RRCPLQUEWIDTH_G(rssconf));
211062306a36Sopenharmony_ci
211162306a36Sopenharmony_ci	seq_puts(seq, "\n");
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_SYN_A);
211462306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG_SYN: %#x\n", rssconf);
211562306a36Sopenharmony_ci	seq_printf(seq, "  MaskSize:      %3d\n", MASKSIZE_G(rssconf));
211662306a36Sopenharmony_ci	seq_printf(seq, "  UseWireCh:     %3s\n", yesno(rssconf & USEWIRECH_F));
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci	seq_puts(seq, "\n");
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_VRT_A);
212162306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG_VRT: %#x\n", rssconf);
212262306a36Sopenharmony_ci	if (CHELSIO_CHIP_VERSION(adapter->params.chip) > CHELSIO_T5) {
212362306a36Sopenharmony_ci		seq_printf(seq, "  KeyWrAddrX:     %3d\n",
212462306a36Sopenharmony_ci			   KEYWRADDRX_G(rssconf));
212562306a36Sopenharmony_ci		seq_printf(seq, "  KeyExtend:      %3s\n",
212662306a36Sopenharmony_ci			   yesno(rssconf & KEYEXTEND_F));
212762306a36Sopenharmony_ci	}
212862306a36Sopenharmony_ci	seq_printf(seq, "  VfRdRg:        %3s\n", yesno(rssconf & VFRDRG_F));
212962306a36Sopenharmony_ci	seq_printf(seq, "  VfRdEn:        %3s\n", yesno(rssconf & VFRDEN_F));
213062306a36Sopenharmony_ci	seq_printf(seq, "  VfPerrEn:      %3s\n", yesno(rssconf & VFPERREN_F));
213162306a36Sopenharmony_ci	seq_printf(seq, "  KeyPerrEn:     %3s\n", yesno(rssconf & KEYPERREN_F));
213262306a36Sopenharmony_ci	seq_printf(seq, "  DisVfVlan:     %3s\n", yesno(rssconf &
213362306a36Sopenharmony_ci							DISABLEVLAN_F));
213462306a36Sopenharmony_ci	seq_printf(seq, "  EnUpSwt:       %3s\n", yesno(rssconf & ENABLEUP0_F));
213562306a36Sopenharmony_ci	seq_printf(seq, "  HashDelay:     %3d\n", HASHDELAY_G(rssconf));
213662306a36Sopenharmony_ci	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
213762306a36Sopenharmony_ci		seq_printf(seq, "  VfWrAddr:      %3d\n", VFWRADDR_G(rssconf));
213862306a36Sopenharmony_ci	else
213962306a36Sopenharmony_ci		seq_printf(seq, "  VfWrAddr:      %3d\n",
214062306a36Sopenharmony_ci			   T6_VFWRADDR_G(rssconf));
214162306a36Sopenharmony_ci	seq_printf(seq, "  KeyMode:       %s\n", keymode[KEYMODE_G(rssconf)]);
214262306a36Sopenharmony_ci	seq_printf(seq, "  VfWrEn:        %3s\n", yesno(rssconf & VFWREN_F));
214362306a36Sopenharmony_ci	seq_printf(seq, "  KeyWrEn:       %3s\n", yesno(rssconf & KEYWREN_F));
214462306a36Sopenharmony_ci	seq_printf(seq, "  KeyWrAddr:     %3d\n", KEYWRADDR_G(rssconf));
214562306a36Sopenharmony_ci
214662306a36Sopenharmony_ci	seq_puts(seq, "\n");
214762306a36Sopenharmony_ci
214862306a36Sopenharmony_ci	rssconf = t4_read_reg(adapter, TP_RSS_CONFIG_CNG_A);
214962306a36Sopenharmony_ci	seq_printf(seq, "TP_RSS_CONFIG_CNG: %#x\n", rssconf);
215062306a36Sopenharmony_ci	seq_printf(seq, "  ChnCount3:     %3s\n", yesno(rssconf & CHNCOUNT3_F));
215162306a36Sopenharmony_ci	seq_printf(seq, "  ChnCount2:     %3s\n", yesno(rssconf & CHNCOUNT2_F));
215262306a36Sopenharmony_ci	seq_printf(seq, "  ChnCount1:     %3s\n", yesno(rssconf & CHNCOUNT1_F));
215362306a36Sopenharmony_ci	seq_printf(seq, "  ChnCount0:     %3s\n", yesno(rssconf & CHNCOUNT0_F));
215462306a36Sopenharmony_ci	seq_printf(seq, "  ChnUndFlow3:   %3s\n", yesno(rssconf &
215562306a36Sopenharmony_ci							CHNUNDFLOW3_F));
215662306a36Sopenharmony_ci	seq_printf(seq, "  ChnUndFlow2:   %3s\n", yesno(rssconf &
215762306a36Sopenharmony_ci							CHNUNDFLOW2_F));
215862306a36Sopenharmony_ci	seq_printf(seq, "  ChnUndFlow1:   %3s\n", yesno(rssconf &
215962306a36Sopenharmony_ci							CHNUNDFLOW1_F));
216062306a36Sopenharmony_ci	seq_printf(seq, "  ChnUndFlow0:   %3s\n", yesno(rssconf &
216162306a36Sopenharmony_ci							CHNUNDFLOW0_F));
216262306a36Sopenharmony_ci	seq_printf(seq, "  RstChn3:       %3s\n", yesno(rssconf & RSTCHN3_F));
216362306a36Sopenharmony_ci	seq_printf(seq, "  RstChn2:       %3s\n", yesno(rssconf & RSTCHN2_F));
216462306a36Sopenharmony_ci	seq_printf(seq, "  RstChn1:       %3s\n", yesno(rssconf & RSTCHN1_F));
216562306a36Sopenharmony_ci	seq_printf(seq, "  RstChn0:       %3s\n", yesno(rssconf & RSTCHN0_F));
216662306a36Sopenharmony_ci	seq_printf(seq, "  UpdVld:        %3s\n", yesno(rssconf & UPDVLD_F));
216762306a36Sopenharmony_ci	seq_printf(seq, "  Xoff:          %3s\n", yesno(rssconf & XOFF_F));
216862306a36Sopenharmony_ci	seq_printf(seq, "  UpdChn3:       %3s\n", yesno(rssconf & UPDCHN3_F));
216962306a36Sopenharmony_ci	seq_printf(seq, "  UpdChn2:       %3s\n", yesno(rssconf & UPDCHN2_F));
217062306a36Sopenharmony_ci	seq_printf(seq, "  UpdChn1:       %3s\n", yesno(rssconf & UPDCHN1_F));
217162306a36Sopenharmony_ci	seq_printf(seq, "  UpdChn0:       %3s\n", yesno(rssconf & UPDCHN0_F));
217262306a36Sopenharmony_ci	seq_printf(seq, "  Queue:         %3d\n", QUEUE_G(rssconf));
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci	return 0;
217562306a36Sopenharmony_ci}
217662306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(rss_config);
217762306a36Sopenharmony_ci
217862306a36Sopenharmony_ci/* RSS Secret Key.
217962306a36Sopenharmony_ci */
218062306a36Sopenharmony_ci
218162306a36Sopenharmony_cistatic int rss_key_show(struct seq_file *seq, void *v)
218262306a36Sopenharmony_ci{
218362306a36Sopenharmony_ci	u32 key[10];
218462306a36Sopenharmony_ci
218562306a36Sopenharmony_ci	t4_read_rss_key(seq->private, key, true);
218662306a36Sopenharmony_ci	seq_printf(seq, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x\n",
218762306a36Sopenharmony_ci		   key[9], key[8], key[7], key[6], key[5], key[4], key[3],
218862306a36Sopenharmony_ci		   key[2], key[1], key[0]);
218962306a36Sopenharmony_ci	return 0;
219062306a36Sopenharmony_ci}
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_cistatic int rss_key_open(struct inode *inode, struct file *file)
219362306a36Sopenharmony_ci{
219462306a36Sopenharmony_ci	return single_open(file, rss_key_show, inode->i_private);
219562306a36Sopenharmony_ci}
219662306a36Sopenharmony_ci
219762306a36Sopenharmony_cistatic ssize_t rss_key_write(struct file *file, const char __user *buf,
219862306a36Sopenharmony_ci			     size_t count, loff_t *pos)
219962306a36Sopenharmony_ci{
220062306a36Sopenharmony_ci	int i, j;
220162306a36Sopenharmony_ci	u32 key[10];
220262306a36Sopenharmony_ci	char s[100], *p;
220362306a36Sopenharmony_ci	struct adapter *adap = file_inode(file)->i_private;
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	if (count > sizeof(s) - 1)
220662306a36Sopenharmony_ci		return -EINVAL;
220762306a36Sopenharmony_ci	if (copy_from_user(s, buf, count))
220862306a36Sopenharmony_ci		return -EFAULT;
220962306a36Sopenharmony_ci	for (i = count; i > 0 && isspace(s[i - 1]); i--)
221062306a36Sopenharmony_ci		;
221162306a36Sopenharmony_ci	s[i] = '\0';
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	for (p = s, i = 9; i >= 0; i--) {
221462306a36Sopenharmony_ci		key[i] = 0;
221562306a36Sopenharmony_ci		for (j = 0; j < 8; j++, p++) {
221662306a36Sopenharmony_ci			if (!isxdigit(*p))
221762306a36Sopenharmony_ci				return -EINVAL;
221862306a36Sopenharmony_ci			key[i] = (key[i] << 4) | hex2val(*p);
221962306a36Sopenharmony_ci		}
222062306a36Sopenharmony_ci	}
222162306a36Sopenharmony_ci
222262306a36Sopenharmony_ci	t4_write_rss_key(adap, key, -1, true);
222362306a36Sopenharmony_ci	return count;
222462306a36Sopenharmony_ci}
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_cistatic const struct file_operations rss_key_debugfs_fops = {
222762306a36Sopenharmony_ci	.owner   = THIS_MODULE,
222862306a36Sopenharmony_ci	.open    = rss_key_open,
222962306a36Sopenharmony_ci	.read    = seq_read,
223062306a36Sopenharmony_ci	.llseek  = seq_lseek,
223162306a36Sopenharmony_ci	.release = single_release,
223262306a36Sopenharmony_ci	.write   = rss_key_write
223362306a36Sopenharmony_ci};
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci/* PF RSS Configuration.
223662306a36Sopenharmony_ci */
223762306a36Sopenharmony_ci
223862306a36Sopenharmony_cistruct rss_pf_conf {
223962306a36Sopenharmony_ci	u32 rss_pf_map;
224062306a36Sopenharmony_ci	u32 rss_pf_mask;
224162306a36Sopenharmony_ci	u32 rss_pf_config;
224262306a36Sopenharmony_ci};
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_cistatic int rss_pf_config_show(struct seq_file *seq, void *v, int idx)
224562306a36Sopenharmony_ci{
224662306a36Sopenharmony_ci	struct rss_pf_conf *pfconf;
224762306a36Sopenharmony_ci
224862306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
224962306a36Sopenharmony_ci		/* use the 0th entry to dump the PF Map Index Size */
225062306a36Sopenharmony_ci		pfconf = seq->private + offsetof(struct seq_tab, data);
225162306a36Sopenharmony_ci		seq_printf(seq, "PF Map Index Size = %d\n\n",
225262306a36Sopenharmony_ci			   LKPIDXSIZE_G(pfconf->rss_pf_map));
225362306a36Sopenharmony_ci
225462306a36Sopenharmony_ci		seq_puts(seq, "     RSS              PF   VF    Hash Tuple Enable         Default\n");
225562306a36Sopenharmony_ci		seq_puts(seq, "     Enable       IPF Mask Mask  IPv6      IPv4      UDP   Queue\n");
225662306a36Sopenharmony_ci		seq_puts(seq, " PF  Map Chn Prt  Map Size Size  Four Two  Four Two  Four  Ch1  Ch0\n");
225762306a36Sopenharmony_ci	} else {
225862306a36Sopenharmony_ci		#define G_PFnLKPIDX(map, n) \
225962306a36Sopenharmony_ci			(((map) >> PF1LKPIDX_S*(n)) & PF0LKPIDX_M)
226062306a36Sopenharmony_ci		#define G_PFnMSKSIZE(mask, n) \
226162306a36Sopenharmony_ci			(((mask) >> PF1MSKSIZE_S*(n)) & PF1MSKSIZE_M)
226262306a36Sopenharmony_ci
226362306a36Sopenharmony_ci		pfconf = v;
226462306a36Sopenharmony_ci		seq_printf(seq, "%3d  %3s %3s %3s  %3d  %3d  %3d   %3s %3s   %3s %3s   %3s  %3d  %3d\n",
226562306a36Sopenharmony_ci			   idx,
226662306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & MAPENABLE_F),
226762306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & CHNENABLE_F),
226862306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & PRTENABLE_F),
226962306a36Sopenharmony_ci			   G_PFnLKPIDX(pfconf->rss_pf_map, idx),
227062306a36Sopenharmony_ci			   G_PFnMSKSIZE(pfconf->rss_pf_mask, idx),
227162306a36Sopenharmony_ci			   IVFWIDTH_G(pfconf->rss_pf_config),
227262306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & IP6FOURTUPEN_F),
227362306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & IP6TWOTUPEN_F),
227462306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & IP4FOURTUPEN_F),
227562306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & IP4TWOTUPEN_F),
227662306a36Sopenharmony_ci			   yesno(pfconf->rss_pf_config & UDPFOURTUPEN_F),
227762306a36Sopenharmony_ci			   CH1DEFAULTQUEUE_G(pfconf->rss_pf_config),
227862306a36Sopenharmony_ci			   CH0DEFAULTQUEUE_G(pfconf->rss_pf_config));
227962306a36Sopenharmony_ci
228062306a36Sopenharmony_ci		#undef G_PFnLKPIDX
228162306a36Sopenharmony_ci		#undef G_PFnMSKSIZE
228262306a36Sopenharmony_ci	}
228362306a36Sopenharmony_ci	return 0;
228462306a36Sopenharmony_ci}
228562306a36Sopenharmony_ci
228662306a36Sopenharmony_cistatic int rss_pf_config_open(struct inode *inode, struct file *file)
228762306a36Sopenharmony_ci{
228862306a36Sopenharmony_ci	struct adapter *adapter = inode->i_private;
228962306a36Sopenharmony_ci	struct seq_tab *p;
229062306a36Sopenharmony_ci	u32 rss_pf_map, rss_pf_mask;
229162306a36Sopenharmony_ci	struct rss_pf_conf *pfconf;
229262306a36Sopenharmony_ci	int pf;
229362306a36Sopenharmony_ci
229462306a36Sopenharmony_ci	p = seq_open_tab(file, 8, sizeof(*pfconf), 1, rss_pf_config_show);
229562306a36Sopenharmony_ci	if (!p)
229662306a36Sopenharmony_ci		return -ENOMEM;
229762306a36Sopenharmony_ci
229862306a36Sopenharmony_ci	pfconf = (struct rss_pf_conf *)p->data;
229962306a36Sopenharmony_ci	rss_pf_map = t4_read_rss_pf_map(adapter, true);
230062306a36Sopenharmony_ci	rss_pf_mask = t4_read_rss_pf_mask(adapter, true);
230162306a36Sopenharmony_ci	for (pf = 0; pf < 8; pf++) {
230262306a36Sopenharmony_ci		pfconf[pf].rss_pf_map = rss_pf_map;
230362306a36Sopenharmony_ci		pfconf[pf].rss_pf_mask = rss_pf_mask;
230462306a36Sopenharmony_ci		t4_read_rss_pf_config(adapter, pf, &pfconf[pf].rss_pf_config,
230562306a36Sopenharmony_ci				      true);
230662306a36Sopenharmony_ci	}
230762306a36Sopenharmony_ci	return 0;
230862306a36Sopenharmony_ci}
230962306a36Sopenharmony_ci
231062306a36Sopenharmony_cistatic const struct file_operations rss_pf_config_debugfs_fops = {
231162306a36Sopenharmony_ci	.owner   = THIS_MODULE,
231262306a36Sopenharmony_ci	.open    = rss_pf_config_open,
231362306a36Sopenharmony_ci	.read    = seq_read,
231462306a36Sopenharmony_ci	.llseek  = seq_lseek,
231562306a36Sopenharmony_ci	.release = seq_release_private
231662306a36Sopenharmony_ci};
231762306a36Sopenharmony_ci
231862306a36Sopenharmony_ci/* VF RSS Configuration.
231962306a36Sopenharmony_ci */
232062306a36Sopenharmony_ci
232162306a36Sopenharmony_cistruct rss_vf_conf {
232262306a36Sopenharmony_ci	u32 rss_vf_vfl;
232362306a36Sopenharmony_ci	u32 rss_vf_vfh;
232462306a36Sopenharmony_ci};
232562306a36Sopenharmony_ci
232662306a36Sopenharmony_cistatic int rss_vf_config_show(struct seq_file *seq, void *v, int idx)
232762306a36Sopenharmony_ci{
232862306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
232962306a36Sopenharmony_ci		seq_puts(seq, "     RSS                     Hash Tuple Enable\n");
233062306a36Sopenharmony_ci		seq_puts(seq, "     Enable   IVF  Dis  Enb  IPv6      IPv4      UDP    Def  Secret Key\n");
233162306a36Sopenharmony_ci		seq_puts(seq, " VF  Chn Prt  Map  VLAN  uP  Four Two  Four Two  Four   Que  Idx       Hash\n");
233262306a36Sopenharmony_ci	} else {
233362306a36Sopenharmony_ci		struct rss_vf_conf *vfconf = v;
233462306a36Sopenharmony_ci
233562306a36Sopenharmony_ci		seq_printf(seq, "%3d  %3s %3s  %3d   %3s %3s   %3s %3s   %3s  %3s   %3s  %4d  %3d %#10x\n",
233662306a36Sopenharmony_ci			   idx,
233762306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFCHNEN_F),
233862306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFPRTEN_F),
233962306a36Sopenharmony_ci			   VFLKPIDX_G(vfconf->rss_vf_vfh),
234062306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFVLNEX_F),
234162306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFUPEN_F),
234262306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFIP4FOURTUPEN_F),
234362306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFIP6TWOTUPEN_F),
234462306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFIP4FOURTUPEN_F),
234562306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & VFIP4TWOTUPEN_F),
234662306a36Sopenharmony_ci			   yesno(vfconf->rss_vf_vfh & ENABLEUDPHASH_F),
234762306a36Sopenharmony_ci			   DEFAULTQUEUE_G(vfconf->rss_vf_vfh),
234862306a36Sopenharmony_ci			   KEYINDEX_G(vfconf->rss_vf_vfh),
234962306a36Sopenharmony_ci			   vfconf->rss_vf_vfl);
235062306a36Sopenharmony_ci	}
235162306a36Sopenharmony_ci	return 0;
235262306a36Sopenharmony_ci}
235362306a36Sopenharmony_ci
235462306a36Sopenharmony_cistatic int rss_vf_config_open(struct inode *inode, struct file *file)
235562306a36Sopenharmony_ci{
235662306a36Sopenharmony_ci	struct adapter *adapter = inode->i_private;
235762306a36Sopenharmony_ci	struct seq_tab *p;
235862306a36Sopenharmony_ci	struct rss_vf_conf *vfconf;
235962306a36Sopenharmony_ci	int vf, vfcount = adapter->params.arch.vfcount;
236062306a36Sopenharmony_ci
236162306a36Sopenharmony_ci	p = seq_open_tab(file, vfcount, sizeof(*vfconf), 1, rss_vf_config_show);
236262306a36Sopenharmony_ci	if (!p)
236362306a36Sopenharmony_ci		return -ENOMEM;
236462306a36Sopenharmony_ci
236562306a36Sopenharmony_ci	vfconf = (struct rss_vf_conf *)p->data;
236662306a36Sopenharmony_ci	for (vf = 0; vf < vfcount; vf++) {
236762306a36Sopenharmony_ci		t4_read_rss_vf_config(adapter, vf, &vfconf[vf].rss_vf_vfl,
236862306a36Sopenharmony_ci				      &vfconf[vf].rss_vf_vfh, true);
236962306a36Sopenharmony_ci	}
237062306a36Sopenharmony_ci	return 0;
237162306a36Sopenharmony_ci}
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_cistatic const struct file_operations rss_vf_config_debugfs_fops = {
237462306a36Sopenharmony_ci	.owner   = THIS_MODULE,
237562306a36Sopenharmony_ci	.open    = rss_vf_config_open,
237662306a36Sopenharmony_ci	.read    = seq_read,
237762306a36Sopenharmony_ci	.llseek  = seq_lseek,
237862306a36Sopenharmony_ci	.release = seq_release_private
237962306a36Sopenharmony_ci};
238062306a36Sopenharmony_ci
238162306a36Sopenharmony_ci#ifdef CONFIG_CHELSIO_T4_DCB
238262306a36Sopenharmony_ci
238362306a36Sopenharmony_ci/* Data Center Briging information for each port.
238462306a36Sopenharmony_ci */
238562306a36Sopenharmony_cistatic int dcb_info_show(struct seq_file *seq, void *v)
238662306a36Sopenharmony_ci{
238762306a36Sopenharmony_ci	struct adapter *adap = seq->private;
238862306a36Sopenharmony_ci
238962306a36Sopenharmony_ci	if (v == SEQ_START_TOKEN) {
239062306a36Sopenharmony_ci		seq_puts(seq, "Data Center Bridging Information\n");
239162306a36Sopenharmony_ci	} else {
239262306a36Sopenharmony_ci		int port = (uintptr_t)v - 2;
239362306a36Sopenharmony_ci		struct net_device *dev = adap->port[port];
239462306a36Sopenharmony_ci		struct port_info *pi = netdev2pinfo(dev);
239562306a36Sopenharmony_ci		struct port_dcb_info *dcb = &pi->dcb;
239662306a36Sopenharmony_ci
239762306a36Sopenharmony_ci		seq_puts(seq, "\n");
239862306a36Sopenharmony_ci		seq_printf(seq, "Port: %d (DCB negotiated: %s)\n",
239962306a36Sopenharmony_ci			   port,
240062306a36Sopenharmony_ci			   cxgb4_dcb_enabled(dev) ? "yes" : "no");
240162306a36Sopenharmony_ci
240262306a36Sopenharmony_ci		if (cxgb4_dcb_enabled(dev))
240362306a36Sopenharmony_ci			seq_printf(seq, "[ DCBx Version %s ]\n",
240462306a36Sopenharmony_ci				   dcb_ver_array[dcb->dcb_version]);
240562306a36Sopenharmony_ci
240662306a36Sopenharmony_ci		if (dcb->msgs) {
240762306a36Sopenharmony_ci			int i;
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci			seq_puts(seq, "\n  Index\t\t\t  :\t");
241062306a36Sopenharmony_ci			for (i = 0; i < 8; i++)
241162306a36Sopenharmony_ci				seq_printf(seq, " %3d", i);
241262306a36Sopenharmony_ci			seq_puts(seq, "\n\n");
241362306a36Sopenharmony_ci		}
241462306a36Sopenharmony_ci
241562306a36Sopenharmony_ci		if (dcb->msgs & CXGB4_DCB_FW_PGID) {
241662306a36Sopenharmony_ci			int prio, pgid;
241762306a36Sopenharmony_ci
241862306a36Sopenharmony_ci			seq_puts(seq, "  Priority Group IDs\t  :\t");
241962306a36Sopenharmony_ci			for (prio = 0; prio < 8; prio++) {
242062306a36Sopenharmony_ci				pgid = (dcb->pgid >> 4 * (7 - prio)) & 0xf;
242162306a36Sopenharmony_ci				seq_printf(seq, " %3d", pgid);
242262306a36Sopenharmony_ci			}
242362306a36Sopenharmony_ci			seq_puts(seq, "\n");
242462306a36Sopenharmony_ci		}
242562306a36Sopenharmony_ci
242662306a36Sopenharmony_ci		if (dcb->msgs & CXGB4_DCB_FW_PGRATE) {
242762306a36Sopenharmony_ci			int pg;
242862306a36Sopenharmony_ci
242962306a36Sopenharmony_ci			seq_puts(seq, "  Priority Group BW(%)\t  :\t");
243062306a36Sopenharmony_ci			for (pg = 0; pg < 8; pg++)
243162306a36Sopenharmony_ci				seq_printf(seq, " %3d", dcb->pgrate[pg]);
243262306a36Sopenharmony_ci			seq_puts(seq, "\n");
243362306a36Sopenharmony_ci
243462306a36Sopenharmony_ci			if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
243562306a36Sopenharmony_ci				seq_puts(seq, "  TSA Algorithm\t\t  :\t");
243662306a36Sopenharmony_ci				for (pg = 0; pg < 8; pg++)
243762306a36Sopenharmony_ci					seq_printf(seq, " %3d", dcb->tsa[pg]);
243862306a36Sopenharmony_ci				seq_puts(seq, "\n");
243962306a36Sopenharmony_ci			}
244062306a36Sopenharmony_ci
244162306a36Sopenharmony_ci			seq_printf(seq, "  Max PG Traffic Classes  [%3d  ]\n",
244262306a36Sopenharmony_ci				   dcb->pg_num_tcs_supported);
244362306a36Sopenharmony_ci
244462306a36Sopenharmony_ci			seq_puts(seq, "\n");
244562306a36Sopenharmony_ci		}
244662306a36Sopenharmony_ci
244762306a36Sopenharmony_ci		if (dcb->msgs & CXGB4_DCB_FW_PRIORATE) {
244862306a36Sopenharmony_ci			int prio;
244962306a36Sopenharmony_ci
245062306a36Sopenharmony_ci			seq_puts(seq, "  Priority Rate\t:\t");
245162306a36Sopenharmony_ci			for (prio = 0; prio < 8; prio++)
245262306a36Sopenharmony_ci				seq_printf(seq, " %3d", dcb->priorate[prio]);
245362306a36Sopenharmony_ci			seq_puts(seq, "\n");
245462306a36Sopenharmony_ci		}
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci		if (dcb->msgs & CXGB4_DCB_FW_PFC) {
245762306a36Sopenharmony_ci			int prio;
245862306a36Sopenharmony_ci
245962306a36Sopenharmony_ci			seq_puts(seq, "  Priority Flow Control   :\t");
246062306a36Sopenharmony_ci			for (prio = 0; prio < 8; prio++) {
246162306a36Sopenharmony_ci				int pfcen = (dcb->pfcen >> 1 * (7 - prio))
246262306a36Sopenharmony_ci					    & 0x1;
246362306a36Sopenharmony_ci				seq_printf(seq, " %3d", pfcen);
246462306a36Sopenharmony_ci			}
246562306a36Sopenharmony_ci			seq_puts(seq, "\n");
246662306a36Sopenharmony_ci
246762306a36Sopenharmony_ci			seq_printf(seq, "  Max PFC Traffic Classes [%3d  ]\n",
246862306a36Sopenharmony_ci				   dcb->pfc_num_tcs_supported);
246962306a36Sopenharmony_ci
247062306a36Sopenharmony_ci			seq_puts(seq, "\n");
247162306a36Sopenharmony_ci		}
247262306a36Sopenharmony_ci
247362306a36Sopenharmony_ci		if (dcb->msgs & CXGB4_DCB_FW_APP_ID) {
247462306a36Sopenharmony_ci			int app, napps;
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_ci			seq_puts(seq, "  Application Information:\n");
247762306a36Sopenharmony_ci			seq_puts(seq, "  App    Priority    Selection         Protocol\n");
247862306a36Sopenharmony_ci			seq_puts(seq, "  Index  Map         Field             ID\n");
247962306a36Sopenharmony_ci			for (app = 0, napps = 0;
248062306a36Sopenharmony_ci			     app < CXGB4_MAX_DCBX_APP_SUPPORTED; app++) {
248162306a36Sopenharmony_ci				struct app_priority *ap;
248262306a36Sopenharmony_ci				static const char * const sel_names[] = {
248362306a36Sopenharmony_ci					"Ethertype",
248462306a36Sopenharmony_ci					"Socket TCP",
248562306a36Sopenharmony_ci					"Socket UDP",
248662306a36Sopenharmony_ci					"Socket All",
248762306a36Sopenharmony_ci				};
248862306a36Sopenharmony_ci				const char *sel_name;
248962306a36Sopenharmony_ci
249062306a36Sopenharmony_ci				ap = &dcb->app_priority[app];
249162306a36Sopenharmony_ci				/* skip empty slots */
249262306a36Sopenharmony_ci				if (ap->protocolid == 0)
249362306a36Sopenharmony_ci					continue;
249462306a36Sopenharmony_ci				napps++;
249562306a36Sopenharmony_ci
249662306a36Sopenharmony_ci				if (ap->sel_field < ARRAY_SIZE(sel_names))
249762306a36Sopenharmony_ci					sel_name = sel_names[ap->sel_field];
249862306a36Sopenharmony_ci				else
249962306a36Sopenharmony_ci					sel_name = "UNKNOWN";
250062306a36Sopenharmony_ci
250162306a36Sopenharmony_ci				seq_printf(seq, "  %3d    %#04x        %-10s (%d)    %#06x (%d)\n",
250262306a36Sopenharmony_ci					   app,
250362306a36Sopenharmony_ci					   ap->user_prio_map,
250462306a36Sopenharmony_ci					   sel_name, ap->sel_field,
250562306a36Sopenharmony_ci					   ap->protocolid, ap->protocolid);
250662306a36Sopenharmony_ci			}
250762306a36Sopenharmony_ci			if (napps == 0)
250862306a36Sopenharmony_ci				seq_puts(seq, "    --- None ---\n");
250962306a36Sopenharmony_ci		}
251062306a36Sopenharmony_ci	}
251162306a36Sopenharmony_ci	return 0;
251262306a36Sopenharmony_ci}
251362306a36Sopenharmony_ci
251462306a36Sopenharmony_cistatic inline void *dcb_info_get_idx(struct adapter *adap, loff_t pos)
251562306a36Sopenharmony_ci{
251662306a36Sopenharmony_ci	return (pos <= adap->params.nports
251762306a36Sopenharmony_ci		? (void *)((uintptr_t)pos + 1)
251862306a36Sopenharmony_ci		: NULL);
251962306a36Sopenharmony_ci}
252062306a36Sopenharmony_ci
252162306a36Sopenharmony_cistatic void *dcb_info_start(struct seq_file *seq, loff_t *pos)
252262306a36Sopenharmony_ci{
252362306a36Sopenharmony_ci	struct adapter *adap = seq->private;
252462306a36Sopenharmony_ci
252562306a36Sopenharmony_ci	return (*pos
252662306a36Sopenharmony_ci		? dcb_info_get_idx(adap, *pos)
252762306a36Sopenharmony_ci		: SEQ_START_TOKEN);
252862306a36Sopenharmony_ci}
252962306a36Sopenharmony_ci
253062306a36Sopenharmony_cistatic void dcb_info_stop(struct seq_file *seq, void *v)
253162306a36Sopenharmony_ci{
253262306a36Sopenharmony_ci}
253362306a36Sopenharmony_ci
253462306a36Sopenharmony_cistatic void *dcb_info_next(struct seq_file *seq, void *v, loff_t *pos)
253562306a36Sopenharmony_ci{
253662306a36Sopenharmony_ci	struct adapter *adap = seq->private;
253762306a36Sopenharmony_ci
253862306a36Sopenharmony_ci	(*pos)++;
253962306a36Sopenharmony_ci	return dcb_info_get_idx(adap, *pos);
254062306a36Sopenharmony_ci}
254162306a36Sopenharmony_ci
254262306a36Sopenharmony_cistatic const struct seq_operations dcb_info_seq_ops = {
254362306a36Sopenharmony_ci	.start = dcb_info_start,
254462306a36Sopenharmony_ci	.next  = dcb_info_next,
254562306a36Sopenharmony_ci	.stop  = dcb_info_stop,
254662306a36Sopenharmony_ci	.show  = dcb_info_show
254762306a36Sopenharmony_ci};
254862306a36Sopenharmony_ci
254962306a36Sopenharmony_cistatic int dcb_info_open(struct inode *inode, struct file *file)
255062306a36Sopenharmony_ci{
255162306a36Sopenharmony_ci	int res = seq_open(file, &dcb_info_seq_ops);
255262306a36Sopenharmony_ci
255362306a36Sopenharmony_ci	if (!res) {
255462306a36Sopenharmony_ci		struct seq_file *seq = file->private_data;
255562306a36Sopenharmony_ci
255662306a36Sopenharmony_ci		seq->private = inode->i_private;
255762306a36Sopenharmony_ci	}
255862306a36Sopenharmony_ci	return res;
255962306a36Sopenharmony_ci}
256062306a36Sopenharmony_ci
256162306a36Sopenharmony_cistatic const struct file_operations dcb_info_debugfs_fops = {
256262306a36Sopenharmony_ci	.owner   = THIS_MODULE,
256362306a36Sopenharmony_ci	.open    = dcb_info_open,
256462306a36Sopenharmony_ci	.read    = seq_read,
256562306a36Sopenharmony_ci	.llseek  = seq_lseek,
256662306a36Sopenharmony_ci	.release = seq_release,
256762306a36Sopenharmony_ci};
256862306a36Sopenharmony_ci#endif /* CONFIG_CHELSIO_T4_DCB */
256962306a36Sopenharmony_ci
257062306a36Sopenharmony_cistatic int resources_show(struct seq_file *seq, void *v)
257162306a36Sopenharmony_ci{
257262306a36Sopenharmony_ci	struct adapter *adapter = seq->private;
257362306a36Sopenharmony_ci	struct pf_resources *pfres = &adapter->params.pfres;
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci	#define S(desc, fmt, var) \
257662306a36Sopenharmony_ci		seq_printf(seq, "%-60s " fmt "\n", \
257762306a36Sopenharmony_ci			   desc " (" #var "):", pfres->var)
257862306a36Sopenharmony_ci
257962306a36Sopenharmony_ci	S("Virtual Interfaces", "%d", nvi);
258062306a36Sopenharmony_ci	S("Egress Queues", "%d", neq);
258162306a36Sopenharmony_ci	S("Ethernet Control", "%d", nethctrl);
258262306a36Sopenharmony_ci	S("Ingress Queues/w Free Lists/Interrupts", "%d", niqflint);
258362306a36Sopenharmony_ci	S("Ingress Queues", "%d", niq);
258462306a36Sopenharmony_ci	S("Traffic Class", "%d", tc);
258562306a36Sopenharmony_ci	S("Port Access Rights Mask", "%#x", pmask);
258662306a36Sopenharmony_ci	S("MAC Address Filters", "%d", nexactf);
258762306a36Sopenharmony_ci	S("Firmware Command Read Capabilities", "%#x", r_caps);
258862306a36Sopenharmony_ci	S("Firmware Command Write/Execute Capabilities", "%#x", wx_caps);
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci	#undef S
259162306a36Sopenharmony_ci
259262306a36Sopenharmony_ci	return 0;
259362306a36Sopenharmony_ci}
259462306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(resources);
259562306a36Sopenharmony_ci
259662306a36Sopenharmony_ci/**
259762306a36Sopenharmony_ci * ethqset2pinfo - return port_info of an Ethernet Queue Set
259862306a36Sopenharmony_ci * @adap: the adapter
259962306a36Sopenharmony_ci * @qset: Ethernet Queue Set
260062306a36Sopenharmony_ci */
260162306a36Sopenharmony_cistatic inline struct port_info *ethqset2pinfo(struct adapter *adap, int qset)
260262306a36Sopenharmony_ci{
260362306a36Sopenharmony_ci	int pidx;
260462306a36Sopenharmony_ci
260562306a36Sopenharmony_ci	for_each_port(adap, pidx) {
260662306a36Sopenharmony_ci		struct port_info *pi = adap2pinfo(adap, pidx);
260762306a36Sopenharmony_ci
260862306a36Sopenharmony_ci		if (qset >= pi->first_qset &&
260962306a36Sopenharmony_ci		    qset < pi->first_qset + pi->nqsets)
261062306a36Sopenharmony_ci			return pi;
261162306a36Sopenharmony_ci	}
261262306a36Sopenharmony_ci
261362306a36Sopenharmony_ci	/* should never happen! */
261462306a36Sopenharmony_ci	BUG();
261562306a36Sopenharmony_ci	return NULL;
261662306a36Sopenharmony_ci}
261762306a36Sopenharmony_ci
261862306a36Sopenharmony_cistatic int sge_qinfo_uld_txq_entries(const struct adapter *adap, int uld)
261962306a36Sopenharmony_ci{
262062306a36Sopenharmony_ci	const struct sge_uld_txq_info *utxq_info = adap->sge.uld_txq_info[uld];
262162306a36Sopenharmony_ci
262262306a36Sopenharmony_ci	if (!utxq_info)
262362306a36Sopenharmony_ci		return 0;
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	return DIV_ROUND_UP(utxq_info->ntxq, 4);
262662306a36Sopenharmony_ci}
262762306a36Sopenharmony_ci
262862306a36Sopenharmony_cistatic int sge_qinfo_uld_rspq_entries(const struct adapter *adap, int uld,
262962306a36Sopenharmony_ci				      bool ciq)
263062306a36Sopenharmony_ci{
263162306a36Sopenharmony_ci	const struct sge_uld_rxq_info *urxq_info = adap->sge.uld_rxq_info[uld];
263262306a36Sopenharmony_ci
263362306a36Sopenharmony_ci	if (!urxq_info)
263462306a36Sopenharmony_ci		return 0;
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	return ciq ? DIV_ROUND_UP(urxq_info->nciq, 4) :
263762306a36Sopenharmony_ci		     DIV_ROUND_UP(urxq_info->nrxq, 4);
263862306a36Sopenharmony_ci}
263962306a36Sopenharmony_ci
264062306a36Sopenharmony_cistatic int sge_qinfo_uld_rxq_entries(const struct adapter *adap, int uld)
264162306a36Sopenharmony_ci{
264262306a36Sopenharmony_ci	return sge_qinfo_uld_rspq_entries(adap, uld, false);
264362306a36Sopenharmony_ci}
264462306a36Sopenharmony_ci
264562306a36Sopenharmony_cistatic int sge_qinfo_uld_ciq_entries(const struct adapter *adap, int uld)
264662306a36Sopenharmony_ci{
264762306a36Sopenharmony_ci	return sge_qinfo_uld_rspq_entries(adap, uld, true);
264862306a36Sopenharmony_ci}
264962306a36Sopenharmony_ci
265062306a36Sopenharmony_cistatic int sge_qinfo_show(struct seq_file *seq, void *v)
265162306a36Sopenharmony_ci{
265262306a36Sopenharmony_ci	int eth_entries, ctrl_entries, eohw_entries = 0, eosw_entries = 0;
265362306a36Sopenharmony_ci	int uld_rxq_entries[CXGB4_ULD_MAX] = { 0 };
265462306a36Sopenharmony_ci	int uld_ciq_entries[CXGB4_ULD_MAX] = { 0 };
265562306a36Sopenharmony_ci	int uld_txq_entries[CXGB4_TX_MAX] = { 0 };
265662306a36Sopenharmony_ci	const struct sge_uld_txq_info *utxq_info;
265762306a36Sopenharmony_ci	const struct sge_uld_rxq_info *urxq_info;
265862306a36Sopenharmony_ci	struct cxgb4_tc_port_mqprio *port_mqprio;
265962306a36Sopenharmony_ci	struct adapter *adap = seq->private;
266062306a36Sopenharmony_ci	int i, j, n, r = (uintptr_t)v - 1;
266162306a36Sopenharmony_ci	struct sge *s = &adap->sge;
266262306a36Sopenharmony_ci
266362306a36Sopenharmony_ci	eth_entries = DIV_ROUND_UP(adap->sge.ethqsets, 4);
266462306a36Sopenharmony_ci	ctrl_entries = DIV_ROUND_UP(MAX_CTRL_QUEUES, 4);
266562306a36Sopenharmony_ci
266662306a36Sopenharmony_ci	if (r)
266762306a36Sopenharmony_ci		seq_putc(seq, '\n');
266862306a36Sopenharmony_ci
266962306a36Sopenharmony_ci#define S3(fmt_spec, s, v) \
267062306a36Sopenharmony_cido { \
267162306a36Sopenharmony_ci	seq_printf(seq, "%-12s", s); \
267262306a36Sopenharmony_ci	for (i = 0; i < n; ++i) \
267362306a36Sopenharmony_ci		seq_printf(seq, " %16" fmt_spec, v); \
267462306a36Sopenharmony_ci	seq_putc(seq, '\n'); \
267562306a36Sopenharmony_ci} while (0)
267662306a36Sopenharmony_ci#define S(s, v) S3("s", s, v)
267762306a36Sopenharmony_ci#define T3(fmt_spec, s, v) S3(fmt_spec, s, tx[i].v)
267862306a36Sopenharmony_ci#define T(s, v) S3("u", s, tx[i].v)
267962306a36Sopenharmony_ci#define TL(s, v) T3("lu", s, v)
268062306a36Sopenharmony_ci#define R3(fmt_spec, s, v) S3(fmt_spec, s, rx[i].v)
268162306a36Sopenharmony_ci#define R(s, v) S3("u", s, rx[i].v)
268262306a36Sopenharmony_ci#define RL(s, v) R3("lu", s, v)
268362306a36Sopenharmony_ci
268462306a36Sopenharmony_ci	if (r < eth_entries) {
268562306a36Sopenharmony_ci		int base_qset = r * 4;
268662306a36Sopenharmony_ci		const struct sge_eth_rxq *rx = &s->ethrxq[base_qset];
268762306a36Sopenharmony_ci		const struct sge_eth_txq *tx = &s->ethtxq[base_qset];
268862306a36Sopenharmony_ci
268962306a36Sopenharmony_ci		n = min(4, s->ethqsets - 4 * r);
269062306a36Sopenharmony_ci
269162306a36Sopenharmony_ci		S("QType:", "Ethernet");
269262306a36Sopenharmony_ci		S("Interface:",
269362306a36Sopenharmony_ci		  rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
269462306a36Sopenharmony_ci		T("TxQ ID:", q.cntxt_id);
269562306a36Sopenharmony_ci		T("TxQ size:", q.size);
269662306a36Sopenharmony_ci		T("TxQ inuse:", q.in_use);
269762306a36Sopenharmony_ci		T("TxQ CIDX:", q.cidx);
269862306a36Sopenharmony_ci		T("TxQ PIDX:", q.pidx);
269962306a36Sopenharmony_ci#ifdef CONFIG_CHELSIO_T4_DCB
270062306a36Sopenharmony_ci		T("DCB Prio:", dcb_prio);
270162306a36Sopenharmony_ci		S3("u", "DCB PGID:",
270262306a36Sopenharmony_ci		   (ethqset2pinfo(adap, base_qset + i)->dcb.pgid >>
270362306a36Sopenharmony_ci		    4*(7-tx[i].dcb_prio)) & 0xf);
270462306a36Sopenharmony_ci		S3("u", "DCB PFC:",
270562306a36Sopenharmony_ci		   (ethqset2pinfo(adap, base_qset + i)->dcb.pfcen >>
270662306a36Sopenharmony_ci		    1*(7-tx[i].dcb_prio)) & 0x1);
270762306a36Sopenharmony_ci#endif
270862306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
270962306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
271062306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
271162306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
271262306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
271362306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
271462306a36Sopenharmony_ci		S3("u", "Intr pktcnt:", s->counter_val[rx[i].rspq.pktcnt_idx]);
271562306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
271662306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
271762306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
271862306a36Sopenharmony_ci		R("FL avail:", fl.avail);
271962306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
272062306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
272162306a36Sopenharmony_ci		RL("RxPackets:", stats.pkts);
272262306a36Sopenharmony_ci		RL("RxCSO:", stats.rx_cso);
272362306a36Sopenharmony_ci		RL("VLANxtract:", stats.vlan_ex);
272462306a36Sopenharmony_ci		RL("LROmerged:", stats.lro_merged);
272562306a36Sopenharmony_ci		RL("LROpackets:", stats.lro_pkts);
272662306a36Sopenharmony_ci		RL("RxDrops:", stats.rx_drops);
272762306a36Sopenharmony_ci		RL("RxBadPkts:", stats.bad_rx_pkts);
272862306a36Sopenharmony_ci		TL("TSO:", tso);
272962306a36Sopenharmony_ci		TL("USO:", uso);
273062306a36Sopenharmony_ci		TL("TxCSO:", tx_cso);
273162306a36Sopenharmony_ci		TL("VLANins:", vlan_ins);
273262306a36Sopenharmony_ci		TL("TxQFull:", q.stops);
273362306a36Sopenharmony_ci		TL("TxQRestarts:", q.restarts);
273462306a36Sopenharmony_ci		TL("TxMapErr:", mapping_err);
273562306a36Sopenharmony_ci		RL("FLAllocErr:", fl.alloc_failed);
273662306a36Sopenharmony_ci		RL("FLLrgAlcErr:", fl.large_alloc_failed);
273762306a36Sopenharmony_ci		RL("FLMapErr:", fl.mapping_err);
273862306a36Sopenharmony_ci		RL("FLLow:", fl.low);
273962306a36Sopenharmony_ci		RL("FLStarving:", fl.starving);
274062306a36Sopenharmony_ci
274162306a36Sopenharmony_ci		goto out;
274262306a36Sopenharmony_ci	}
274362306a36Sopenharmony_ci
274462306a36Sopenharmony_ci	r -= eth_entries;
274562306a36Sopenharmony_ci	for_each_port(adap, j) {
274662306a36Sopenharmony_ci		struct port_info *pi = adap2pinfo(adap, j);
274762306a36Sopenharmony_ci		const struct sge_eth_rxq *rx;
274862306a36Sopenharmony_ci
274962306a36Sopenharmony_ci		mutex_lock(&pi->vi_mirror_mutex);
275062306a36Sopenharmony_ci		if (!pi->vi_mirror_count) {
275162306a36Sopenharmony_ci			mutex_unlock(&pi->vi_mirror_mutex);
275262306a36Sopenharmony_ci			continue;
275362306a36Sopenharmony_ci		}
275462306a36Sopenharmony_ci
275562306a36Sopenharmony_ci		if (r >= DIV_ROUND_UP(pi->nmirrorqsets, 4)) {
275662306a36Sopenharmony_ci			r -= DIV_ROUND_UP(pi->nmirrorqsets, 4);
275762306a36Sopenharmony_ci			mutex_unlock(&pi->vi_mirror_mutex);
275862306a36Sopenharmony_ci			continue;
275962306a36Sopenharmony_ci		}
276062306a36Sopenharmony_ci
276162306a36Sopenharmony_ci		rx = &s->mirror_rxq[j][r * 4];
276262306a36Sopenharmony_ci		n = min(4, pi->nmirrorqsets - 4 * r);
276362306a36Sopenharmony_ci
276462306a36Sopenharmony_ci		S("QType:", "Mirror-Rxq");
276562306a36Sopenharmony_ci		S("Interface:",
276662306a36Sopenharmony_ci		  rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
276762306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
276862306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
276962306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
277062306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
277162306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
277262306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
277362306a36Sopenharmony_ci		S3("u", "Intr pktcnt:", s->counter_val[rx[i].rspq.pktcnt_idx]);
277462306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
277562306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
277662306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
277762306a36Sopenharmony_ci		R("FL avail:", fl.avail);
277862306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
277962306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
278062306a36Sopenharmony_ci		RL("RxPackets:", stats.pkts);
278162306a36Sopenharmony_ci		RL("RxCSO:", stats.rx_cso);
278262306a36Sopenharmony_ci		RL("VLANxtract:", stats.vlan_ex);
278362306a36Sopenharmony_ci		RL("LROmerged:", stats.lro_merged);
278462306a36Sopenharmony_ci		RL("LROpackets:", stats.lro_pkts);
278562306a36Sopenharmony_ci		RL("RxDrops:", stats.rx_drops);
278662306a36Sopenharmony_ci		RL("RxBadPkts:", stats.bad_rx_pkts);
278762306a36Sopenharmony_ci		RL("FLAllocErr:", fl.alloc_failed);
278862306a36Sopenharmony_ci		RL("FLLrgAlcErr:", fl.large_alloc_failed);
278962306a36Sopenharmony_ci		RL("FLMapErr:", fl.mapping_err);
279062306a36Sopenharmony_ci		RL("FLLow:", fl.low);
279162306a36Sopenharmony_ci		RL("FLStarving:", fl.starving);
279262306a36Sopenharmony_ci
279362306a36Sopenharmony_ci		mutex_unlock(&pi->vi_mirror_mutex);
279462306a36Sopenharmony_ci		goto out;
279562306a36Sopenharmony_ci	}
279662306a36Sopenharmony_ci
279762306a36Sopenharmony_ci	if (!adap->tc_mqprio)
279862306a36Sopenharmony_ci		goto skip_mqprio;
279962306a36Sopenharmony_ci
280062306a36Sopenharmony_ci	mutex_lock(&adap->tc_mqprio->mqprio_mutex);
280162306a36Sopenharmony_ci	if (!refcount_read(&adap->tc_mqprio->refcnt)) {
280262306a36Sopenharmony_ci		mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
280362306a36Sopenharmony_ci		goto skip_mqprio;
280462306a36Sopenharmony_ci	}
280562306a36Sopenharmony_ci
280662306a36Sopenharmony_ci	eohw_entries = DIV_ROUND_UP(adap->sge.eoqsets, 4);
280762306a36Sopenharmony_ci	if (r < eohw_entries) {
280862306a36Sopenharmony_ci		int base_qset = r * 4;
280962306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx = &s->eohw_rxq[base_qset];
281062306a36Sopenharmony_ci		const struct sge_eohw_txq *tx = &s->eohw_txq[base_qset];
281162306a36Sopenharmony_ci
281262306a36Sopenharmony_ci		n = min(4, s->eoqsets - 4 * r);
281362306a36Sopenharmony_ci
281462306a36Sopenharmony_ci		S("QType:", "ETHOFLD");
281562306a36Sopenharmony_ci		S("Interface:",
281662306a36Sopenharmony_ci		  rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
281762306a36Sopenharmony_ci		T("TxQ ID:", q.cntxt_id);
281862306a36Sopenharmony_ci		T("TxQ size:", q.size);
281962306a36Sopenharmony_ci		T("TxQ inuse:", q.in_use);
282062306a36Sopenharmony_ci		T("TxQ CIDX:", q.cidx);
282162306a36Sopenharmony_ci		T("TxQ PIDX:", q.pidx);
282262306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
282362306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
282462306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
282562306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
282662306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
282762306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
282862306a36Sopenharmony_ci		S3("u", "Intr pktcnt:", s->counter_val[rx[i].rspq.pktcnt_idx]);
282962306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
283062306a36Sopenharmony_ci		S3("u", "FL size:", rx->fl.size ? rx->fl.size - 8 : 0);
283162306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
283262306a36Sopenharmony_ci		R("FL avail:", fl.avail);
283362306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
283462306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
283562306a36Sopenharmony_ci		RL("RxPackets:", stats.pkts);
283662306a36Sopenharmony_ci		RL("RxImm:", stats.imm);
283762306a36Sopenharmony_ci		RL("RxAN", stats.an);
283862306a36Sopenharmony_ci		RL("RxNoMem", stats.nomem);
283962306a36Sopenharmony_ci		TL("TSO:", tso);
284062306a36Sopenharmony_ci		TL("USO:", uso);
284162306a36Sopenharmony_ci		TL("TxCSO:", tx_cso);
284262306a36Sopenharmony_ci		TL("VLANins:", vlan_ins);
284362306a36Sopenharmony_ci		TL("TxQFull:", q.stops);
284462306a36Sopenharmony_ci		TL("TxQRestarts:", q.restarts);
284562306a36Sopenharmony_ci		TL("TxMapErr:", mapping_err);
284662306a36Sopenharmony_ci		RL("FLAllocErr:", fl.alloc_failed);
284762306a36Sopenharmony_ci		RL("FLLrgAlcErr:", fl.large_alloc_failed);
284862306a36Sopenharmony_ci		RL("FLMapErr:", fl.mapping_err);
284962306a36Sopenharmony_ci		RL("FLLow:", fl.low);
285062306a36Sopenharmony_ci		RL("FLStarving:", fl.starving);
285162306a36Sopenharmony_ci
285262306a36Sopenharmony_ci		mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
285362306a36Sopenharmony_ci		goto out;
285462306a36Sopenharmony_ci	}
285562306a36Sopenharmony_ci
285662306a36Sopenharmony_ci	r -= eohw_entries;
285762306a36Sopenharmony_ci	for (j = 0; j < adap->params.nports; j++) {
285862306a36Sopenharmony_ci		int entries;
285962306a36Sopenharmony_ci		u8 tc;
286062306a36Sopenharmony_ci
286162306a36Sopenharmony_ci		port_mqprio = &adap->tc_mqprio->port_mqprio[j];
286262306a36Sopenharmony_ci		entries = 0;
286362306a36Sopenharmony_ci		for (tc = 0; tc < port_mqprio->mqprio.qopt.num_tc; tc++)
286462306a36Sopenharmony_ci			entries += port_mqprio->mqprio.qopt.count[tc];
286562306a36Sopenharmony_ci
286662306a36Sopenharmony_ci		if (!entries)
286762306a36Sopenharmony_ci			continue;
286862306a36Sopenharmony_ci
286962306a36Sopenharmony_ci		eosw_entries = DIV_ROUND_UP(entries, 4);
287062306a36Sopenharmony_ci		if (r < eosw_entries) {
287162306a36Sopenharmony_ci			const struct sge_eosw_txq *tx;
287262306a36Sopenharmony_ci
287362306a36Sopenharmony_ci			n = min(4, entries - 4 * r);
287462306a36Sopenharmony_ci			tx = &port_mqprio->eosw_txq[4 * r];
287562306a36Sopenharmony_ci
287662306a36Sopenharmony_ci			S("QType:", "EOSW-TXQ");
287762306a36Sopenharmony_ci			S("Interface:",
287862306a36Sopenharmony_ci			  adap->port[j] ? adap->port[j]->name : "N/A");
287962306a36Sopenharmony_ci			T("EOTID:", hwtid);
288062306a36Sopenharmony_ci			T("HWQID:", hwqid);
288162306a36Sopenharmony_ci			T("State:", state);
288262306a36Sopenharmony_ci			T("Size:", ndesc);
288362306a36Sopenharmony_ci			T("In-Use:", inuse);
288462306a36Sopenharmony_ci			T("Credits:", cred);
288562306a36Sopenharmony_ci			T("Compl:", ncompl);
288662306a36Sopenharmony_ci			T("Last-Compl:", last_compl);
288762306a36Sopenharmony_ci			T("PIDX:", pidx);
288862306a36Sopenharmony_ci			T("Last-PIDX:", last_pidx);
288962306a36Sopenharmony_ci			T("CIDX:", cidx);
289062306a36Sopenharmony_ci			T("Last-CIDX:", last_cidx);
289162306a36Sopenharmony_ci			T("FLOWC-IDX:", flowc_idx);
289262306a36Sopenharmony_ci
289362306a36Sopenharmony_ci			mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
289462306a36Sopenharmony_ci			goto out;
289562306a36Sopenharmony_ci		}
289662306a36Sopenharmony_ci
289762306a36Sopenharmony_ci		r -= eosw_entries;
289862306a36Sopenharmony_ci	}
289962306a36Sopenharmony_ci	mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
290062306a36Sopenharmony_ci
290162306a36Sopenharmony_ciskip_mqprio:
290262306a36Sopenharmony_ci	if (!is_uld(adap))
290362306a36Sopenharmony_ci		goto skip_uld;
290462306a36Sopenharmony_ci
290562306a36Sopenharmony_ci	mutex_lock(&uld_mutex);
290662306a36Sopenharmony_ci	if (s->uld_txq_info)
290762306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(uld_txq_entries); i++)
290862306a36Sopenharmony_ci			uld_txq_entries[i] = sge_qinfo_uld_txq_entries(adap, i);
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ci	if (s->uld_rxq_info) {
291162306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(uld_rxq_entries); i++) {
291262306a36Sopenharmony_ci			uld_rxq_entries[i] = sge_qinfo_uld_rxq_entries(adap, i);
291362306a36Sopenharmony_ci			uld_ciq_entries[i] = sge_qinfo_uld_ciq_entries(adap, i);
291462306a36Sopenharmony_ci		}
291562306a36Sopenharmony_ci	}
291662306a36Sopenharmony_ci
291762306a36Sopenharmony_ci	if (r < uld_txq_entries[CXGB4_TX_OFLD]) {
291862306a36Sopenharmony_ci		const struct sge_uld_txq *tx;
291962306a36Sopenharmony_ci
292062306a36Sopenharmony_ci		utxq_info = s->uld_txq_info[CXGB4_TX_OFLD];
292162306a36Sopenharmony_ci		tx = &utxq_info->uldtxq[r * 4];
292262306a36Sopenharmony_ci		n = min(4, utxq_info->ntxq - 4 * r);
292362306a36Sopenharmony_ci
292462306a36Sopenharmony_ci		S("QType:", "OFLD-TXQ");
292562306a36Sopenharmony_ci		T("TxQ ID:", q.cntxt_id);
292662306a36Sopenharmony_ci		T("TxQ size:", q.size);
292762306a36Sopenharmony_ci		T("TxQ inuse:", q.in_use);
292862306a36Sopenharmony_ci		T("TxQ CIDX:", q.cidx);
292962306a36Sopenharmony_ci		T("TxQ PIDX:", q.pidx);
293062306a36Sopenharmony_ci
293162306a36Sopenharmony_ci		goto unlock;
293262306a36Sopenharmony_ci	}
293362306a36Sopenharmony_ci
293462306a36Sopenharmony_ci	r -= uld_txq_entries[CXGB4_TX_OFLD];
293562306a36Sopenharmony_ci	if (r < uld_rxq_entries[CXGB4_ULD_RDMA]) {
293662306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
293762306a36Sopenharmony_ci
293862306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_RDMA];
293962306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[r * 4];
294062306a36Sopenharmony_ci		n = min(4, urxq_info->nrxq - 4 * r);
294162306a36Sopenharmony_ci
294262306a36Sopenharmony_ci		S("QType:", "RDMA-CPL");
294362306a36Sopenharmony_ci		S("Interface:",
294462306a36Sopenharmony_ci		  rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
294562306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
294662306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
294762306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
294862306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
294962306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
295062306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
295162306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
295262306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
295362306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
295462306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
295562306a36Sopenharmony_ci		R("FL avail:", fl.avail);
295662306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
295762306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
295862306a36Sopenharmony_ci
295962306a36Sopenharmony_ci		goto unlock;
296062306a36Sopenharmony_ci	}
296162306a36Sopenharmony_ci
296262306a36Sopenharmony_ci	r -= uld_rxq_entries[CXGB4_ULD_RDMA];
296362306a36Sopenharmony_ci	if (r < uld_ciq_entries[CXGB4_ULD_RDMA]) {
296462306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
296562306a36Sopenharmony_ci		int ciq_idx = 0;
296662306a36Sopenharmony_ci
296762306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_RDMA];
296862306a36Sopenharmony_ci		ciq_idx = urxq_info->nrxq + (r * 4);
296962306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[ciq_idx];
297062306a36Sopenharmony_ci		n = min(4, urxq_info->nciq - 4 * r);
297162306a36Sopenharmony_ci
297262306a36Sopenharmony_ci		S("QType:", "RDMA-CIQ");
297362306a36Sopenharmony_ci		S("Interface:",
297462306a36Sopenharmony_ci		  rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
297562306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
297662306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
297762306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
297862306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
297962306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
298062306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
298162306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
298262306a36Sopenharmony_ci
298362306a36Sopenharmony_ci		goto unlock;
298462306a36Sopenharmony_ci	}
298562306a36Sopenharmony_ci
298662306a36Sopenharmony_ci	r -= uld_ciq_entries[CXGB4_ULD_RDMA];
298762306a36Sopenharmony_ci	if (r < uld_rxq_entries[CXGB4_ULD_ISCSI]) {
298862306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
298962306a36Sopenharmony_ci
299062306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_ISCSI];
299162306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[r * 4];
299262306a36Sopenharmony_ci		n = min(4, urxq_info->nrxq - 4 * r);
299362306a36Sopenharmony_ci
299462306a36Sopenharmony_ci		S("QType:", "iSCSI");
299562306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
299662306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
299762306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
299862306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
299962306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
300062306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
300162306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
300262306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
300362306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
300462306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
300562306a36Sopenharmony_ci		R("FL avail:", fl.avail);
300662306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
300762306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
300862306a36Sopenharmony_ci
300962306a36Sopenharmony_ci		goto unlock;
301062306a36Sopenharmony_ci	}
301162306a36Sopenharmony_ci
301262306a36Sopenharmony_ci	r -= uld_rxq_entries[CXGB4_ULD_ISCSI];
301362306a36Sopenharmony_ci	if (r < uld_rxq_entries[CXGB4_ULD_ISCSIT]) {
301462306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
301562306a36Sopenharmony_ci
301662306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_ISCSIT];
301762306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[r * 4];
301862306a36Sopenharmony_ci		n = min(4, urxq_info->nrxq - 4 * r);
301962306a36Sopenharmony_ci
302062306a36Sopenharmony_ci		S("QType:", "iSCSIT");
302162306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
302262306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
302362306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
302462306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
302562306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
302662306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
302762306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
302862306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
302962306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
303062306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
303162306a36Sopenharmony_ci		R("FL avail:", fl.avail);
303262306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
303362306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
303462306a36Sopenharmony_ci
303562306a36Sopenharmony_ci		goto unlock;
303662306a36Sopenharmony_ci	}
303762306a36Sopenharmony_ci
303862306a36Sopenharmony_ci	r -= uld_rxq_entries[CXGB4_ULD_ISCSIT];
303962306a36Sopenharmony_ci	if (r < uld_rxq_entries[CXGB4_ULD_TLS]) {
304062306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
304162306a36Sopenharmony_ci
304262306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_TLS];
304362306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[r * 4];
304462306a36Sopenharmony_ci		n = min(4, urxq_info->nrxq - 4 * r);
304562306a36Sopenharmony_ci
304662306a36Sopenharmony_ci		S("QType:", "TLS");
304762306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
304862306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
304962306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
305062306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
305162306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
305262306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
305362306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
305462306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
305562306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
305662306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
305762306a36Sopenharmony_ci		R("FL avail:", fl.avail);
305862306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
305962306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
306062306a36Sopenharmony_ci
306162306a36Sopenharmony_ci		goto unlock;
306262306a36Sopenharmony_ci	}
306362306a36Sopenharmony_ci
306462306a36Sopenharmony_ci	r -= uld_rxq_entries[CXGB4_ULD_TLS];
306562306a36Sopenharmony_ci	if (r < uld_txq_entries[CXGB4_TX_CRYPTO]) {
306662306a36Sopenharmony_ci		const struct sge_ofld_rxq *rx;
306762306a36Sopenharmony_ci		const struct sge_uld_txq *tx;
306862306a36Sopenharmony_ci
306962306a36Sopenharmony_ci		utxq_info = s->uld_txq_info[CXGB4_TX_CRYPTO];
307062306a36Sopenharmony_ci		urxq_info = s->uld_rxq_info[CXGB4_ULD_CRYPTO];
307162306a36Sopenharmony_ci		tx = &utxq_info->uldtxq[r * 4];
307262306a36Sopenharmony_ci		rx = &urxq_info->uldrxq[r * 4];
307362306a36Sopenharmony_ci		n = min(4, utxq_info->ntxq - 4 * r);
307462306a36Sopenharmony_ci
307562306a36Sopenharmony_ci		S("QType:", "Crypto");
307662306a36Sopenharmony_ci		T("TxQ ID:", q.cntxt_id);
307762306a36Sopenharmony_ci		T("TxQ size:", q.size);
307862306a36Sopenharmony_ci		T("TxQ inuse:", q.in_use);
307962306a36Sopenharmony_ci		T("TxQ CIDX:", q.cidx);
308062306a36Sopenharmony_ci		T("TxQ PIDX:", q.pidx);
308162306a36Sopenharmony_ci		R("RspQ ID:", rspq.abs_id);
308262306a36Sopenharmony_ci		R("RspQ size:", rspq.size);
308362306a36Sopenharmony_ci		R("RspQE size:", rspq.iqe_len);
308462306a36Sopenharmony_ci		R("RspQ CIDX:", rspq.cidx);
308562306a36Sopenharmony_ci		R("RspQ Gen:", rspq.gen);
308662306a36Sopenharmony_ci		S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
308762306a36Sopenharmony_ci		S3("u", "Intr pktcnt:",	s->counter_val[rx[i].rspq.pktcnt_idx]);
308862306a36Sopenharmony_ci		R("FL ID:", fl.cntxt_id);
308962306a36Sopenharmony_ci		R("FL size:", fl.size - 8);
309062306a36Sopenharmony_ci		R("FL pend:", fl.pend_cred);
309162306a36Sopenharmony_ci		R("FL avail:", fl.avail);
309262306a36Sopenharmony_ci		R("FL PIDX:", fl.pidx);
309362306a36Sopenharmony_ci		R("FL CIDX:", fl.cidx);
309462306a36Sopenharmony_ci
309562306a36Sopenharmony_ci		goto unlock;
309662306a36Sopenharmony_ci	}
309762306a36Sopenharmony_ci
309862306a36Sopenharmony_ci	r -= uld_txq_entries[CXGB4_TX_CRYPTO];
309962306a36Sopenharmony_ci	mutex_unlock(&uld_mutex);
310062306a36Sopenharmony_ci
310162306a36Sopenharmony_ciskip_uld:
310262306a36Sopenharmony_ci	if (r < ctrl_entries) {
310362306a36Sopenharmony_ci		const struct sge_ctrl_txq *tx = &s->ctrlq[r * 4];
310462306a36Sopenharmony_ci
310562306a36Sopenharmony_ci		n = min(4, adap->params.nports - 4 * r);
310662306a36Sopenharmony_ci
310762306a36Sopenharmony_ci		S("QType:", "Control");
310862306a36Sopenharmony_ci		T("TxQ ID:", q.cntxt_id);
310962306a36Sopenharmony_ci		T("TxQ size:", q.size);
311062306a36Sopenharmony_ci		T("TxQ inuse:", q.in_use);
311162306a36Sopenharmony_ci		T("TxQ CIDX:", q.cidx);
311262306a36Sopenharmony_ci		T("TxQ PIDX:", q.pidx);
311362306a36Sopenharmony_ci		TL("TxQFull:", q.stops);
311462306a36Sopenharmony_ci		TL("TxQRestarts:", q.restarts);
311562306a36Sopenharmony_ci
311662306a36Sopenharmony_ci		goto out;
311762306a36Sopenharmony_ci	}
311862306a36Sopenharmony_ci
311962306a36Sopenharmony_ci	r -= ctrl_entries;
312062306a36Sopenharmony_ci	if (r < 1) {
312162306a36Sopenharmony_ci		const struct sge_rspq *evtq = &s->fw_evtq;
312262306a36Sopenharmony_ci
312362306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16s\n", "QType:", "FW event queue");
312462306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "RspQ ID:", evtq->abs_id);
312562306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "RspQ size:", evtq->size);
312662306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "RspQE size:", evtq->iqe_len);
312762306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "RspQ CIDX:", evtq->cidx);
312862306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "RspQ Gen:", evtq->gen);
312962306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "Intr delay:",
313062306a36Sopenharmony_ci			   qtimer_val(adap, evtq));
313162306a36Sopenharmony_ci		seq_printf(seq, "%-12s %16u\n", "Intr pktcnt:",
313262306a36Sopenharmony_ci			   s->counter_val[evtq->pktcnt_idx]);
313362306a36Sopenharmony_ci
313462306a36Sopenharmony_ci		goto out;
313562306a36Sopenharmony_ci	}
313662306a36Sopenharmony_ci
313762306a36Sopenharmony_ci#undef R
313862306a36Sopenharmony_ci#undef RL
313962306a36Sopenharmony_ci#undef T
314062306a36Sopenharmony_ci#undef TL
314162306a36Sopenharmony_ci#undef S
314262306a36Sopenharmony_ci#undef R3
314362306a36Sopenharmony_ci#undef T3
314462306a36Sopenharmony_ci#undef S3
314562306a36Sopenharmony_ciout:
314662306a36Sopenharmony_ci	return 0;
314762306a36Sopenharmony_ci
314862306a36Sopenharmony_ciunlock:
314962306a36Sopenharmony_ci	mutex_unlock(&uld_mutex);
315062306a36Sopenharmony_ci	return 0;
315162306a36Sopenharmony_ci}
315262306a36Sopenharmony_ci
315362306a36Sopenharmony_cistatic int sge_queue_entries(struct adapter *adap)
315462306a36Sopenharmony_ci{
315562306a36Sopenharmony_ci	int i, tot_uld_entries = 0, eohw_entries = 0, eosw_entries = 0;
315662306a36Sopenharmony_ci	int mirror_rxq_entries = 0;
315762306a36Sopenharmony_ci
315862306a36Sopenharmony_ci	if (adap->tc_mqprio) {
315962306a36Sopenharmony_ci		struct cxgb4_tc_port_mqprio *port_mqprio;
316062306a36Sopenharmony_ci		u8 tc;
316162306a36Sopenharmony_ci
316262306a36Sopenharmony_ci		mutex_lock(&adap->tc_mqprio->mqprio_mutex);
316362306a36Sopenharmony_ci		if (adap->sge.eohw_txq)
316462306a36Sopenharmony_ci			eohw_entries = DIV_ROUND_UP(adap->sge.eoqsets, 4);
316562306a36Sopenharmony_ci
316662306a36Sopenharmony_ci		for (i = 0; i < adap->params.nports; i++) {
316762306a36Sopenharmony_ci			u32 entries = 0;
316862306a36Sopenharmony_ci
316962306a36Sopenharmony_ci			port_mqprio = &adap->tc_mqprio->port_mqprio[i];
317062306a36Sopenharmony_ci			for (tc = 0; tc < port_mqprio->mqprio.qopt.num_tc; tc++)
317162306a36Sopenharmony_ci				entries += port_mqprio->mqprio.qopt.count[tc];
317262306a36Sopenharmony_ci
317362306a36Sopenharmony_ci			if (entries)
317462306a36Sopenharmony_ci				eosw_entries += DIV_ROUND_UP(entries, 4);
317562306a36Sopenharmony_ci		}
317662306a36Sopenharmony_ci		mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
317762306a36Sopenharmony_ci	}
317862306a36Sopenharmony_ci
317962306a36Sopenharmony_ci	for_each_port(adap, i) {
318062306a36Sopenharmony_ci		struct port_info *pi = adap2pinfo(adap, i);
318162306a36Sopenharmony_ci
318262306a36Sopenharmony_ci		mutex_lock(&pi->vi_mirror_mutex);
318362306a36Sopenharmony_ci		if (pi->vi_mirror_count)
318462306a36Sopenharmony_ci			mirror_rxq_entries += DIV_ROUND_UP(pi->nmirrorqsets, 4);
318562306a36Sopenharmony_ci		mutex_unlock(&pi->vi_mirror_mutex);
318662306a36Sopenharmony_ci	}
318762306a36Sopenharmony_ci
318862306a36Sopenharmony_ci	if (!is_uld(adap))
318962306a36Sopenharmony_ci		goto lld_only;
319062306a36Sopenharmony_ci
319162306a36Sopenharmony_ci	mutex_lock(&uld_mutex);
319262306a36Sopenharmony_ci	for (i = 0; i < CXGB4_TX_MAX; i++)
319362306a36Sopenharmony_ci		tot_uld_entries += sge_qinfo_uld_txq_entries(adap, i);
319462306a36Sopenharmony_ci
319562306a36Sopenharmony_ci	for (i = 0; i < CXGB4_ULD_MAX; i++) {
319662306a36Sopenharmony_ci		tot_uld_entries += sge_qinfo_uld_rxq_entries(adap, i);
319762306a36Sopenharmony_ci		tot_uld_entries += sge_qinfo_uld_ciq_entries(adap, i);
319862306a36Sopenharmony_ci	}
319962306a36Sopenharmony_ci	mutex_unlock(&uld_mutex);
320062306a36Sopenharmony_ci
320162306a36Sopenharmony_cilld_only:
320262306a36Sopenharmony_ci	return DIV_ROUND_UP(adap->sge.ethqsets, 4) + mirror_rxq_entries +
320362306a36Sopenharmony_ci	       eohw_entries + eosw_entries + tot_uld_entries +
320462306a36Sopenharmony_ci	       DIV_ROUND_UP(MAX_CTRL_QUEUES, 4) + 1;
320562306a36Sopenharmony_ci}
320662306a36Sopenharmony_ci
320762306a36Sopenharmony_cistatic void *sge_queue_start(struct seq_file *seq, loff_t *pos)
320862306a36Sopenharmony_ci{
320962306a36Sopenharmony_ci	int entries = sge_queue_entries(seq->private);
321062306a36Sopenharmony_ci
321162306a36Sopenharmony_ci	return *pos < entries ? (void *)((uintptr_t)*pos + 1) : NULL;
321262306a36Sopenharmony_ci}
321362306a36Sopenharmony_ci
321462306a36Sopenharmony_cistatic void sge_queue_stop(struct seq_file *seq, void *v)
321562306a36Sopenharmony_ci{
321662306a36Sopenharmony_ci}
321762306a36Sopenharmony_ci
321862306a36Sopenharmony_cistatic void *sge_queue_next(struct seq_file *seq, void *v, loff_t *pos)
321962306a36Sopenharmony_ci{
322062306a36Sopenharmony_ci	int entries = sge_queue_entries(seq->private);
322162306a36Sopenharmony_ci
322262306a36Sopenharmony_ci	++*pos;
322362306a36Sopenharmony_ci	return *pos < entries ? (void *)((uintptr_t)*pos + 1) : NULL;
322462306a36Sopenharmony_ci}
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_cistatic const struct seq_operations sge_qinfo_seq_ops = {
322762306a36Sopenharmony_ci	.start = sge_queue_start,
322862306a36Sopenharmony_ci	.next  = sge_queue_next,
322962306a36Sopenharmony_ci	.stop  = sge_queue_stop,
323062306a36Sopenharmony_ci	.show  = sge_qinfo_show
323162306a36Sopenharmony_ci};
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_cistatic int sge_qinfo_open(struct inode *inode, struct file *file)
323462306a36Sopenharmony_ci{
323562306a36Sopenharmony_ci	int res = seq_open(file, &sge_qinfo_seq_ops);
323662306a36Sopenharmony_ci
323762306a36Sopenharmony_ci	if (!res) {
323862306a36Sopenharmony_ci		struct seq_file *seq = file->private_data;
323962306a36Sopenharmony_ci
324062306a36Sopenharmony_ci		seq->private = inode->i_private;
324162306a36Sopenharmony_ci	}
324262306a36Sopenharmony_ci	return res;
324362306a36Sopenharmony_ci}
324462306a36Sopenharmony_ci
324562306a36Sopenharmony_cistatic const struct file_operations sge_qinfo_debugfs_fops = {
324662306a36Sopenharmony_ci	.owner   = THIS_MODULE,
324762306a36Sopenharmony_ci	.open    = sge_qinfo_open,
324862306a36Sopenharmony_ci	.read    = seq_read,
324962306a36Sopenharmony_ci	.llseek  = seq_lseek,
325062306a36Sopenharmony_ci	.release = seq_release,
325162306a36Sopenharmony_ci};
325262306a36Sopenharmony_ci
325362306a36Sopenharmony_ciint mem_open(struct inode *inode, struct file *file)
325462306a36Sopenharmony_ci{
325562306a36Sopenharmony_ci	unsigned int mem;
325662306a36Sopenharmony_ci	struct adapter *adap;
325762306a36Sopenharmony_ci
325862306a36Sopenharmony_ci	file->private_data = inode->i_private;
325962306a36Sopenharmony_ci
326062306a36Sopenharmony_ci	mem = (uintptr_t)file->private_data & 0x7;
326162306a36Sopenharmony_ci	adap = file->private_data - mem;
326262306a36Sopenharmony_ci
326362306a36Sopenharmony_ci	(void)t4_fwcache(adap, FW_PARAM_DEV_FWCACHE_FLUSH);
326462306a36Sopenharmony_ci
326562306a36Sopenharmony_ci	return 0;
326662306a36Sopenharmony_ci}
326762306a36Sopenharmony_ci
326862306a36Sopenharmony_cistatic ssize_t mem_read(struct file *file, char __user *buf, size_t count,
326962306a36Sopenharmony_ci			loff_t *ppos)
327062306a36Sopenharmony_ci{
327162306a36Sopenharmony_ci	loff_t pos = *ppos;
327262306a36Sopenharmony_ci	loff_t avail = file_inode(file)->i_size;
327362306a36Sopenharmony_ci	unsigned int mem = (uintptr_t)file->private_data & 0x7;
327462306a36Sopenharmony_ci	struct adapter *adap = file->private_data - mem;
327562306a36Sopenharmony_ci	__be32 *data;
327662306a36Sopenharmony_ci	int ret;
327762306a36Sopenharmony_ci
327862306a36Sopenharmony_ci	if (pos < 0)
327962306a36Sopenharmony_ci		return -EINVAL;
328062306a36Sopenharmony_ci	if (pos >= avail)
328162306a36Sopenharmony_ci		return 0;
328262306a36Sopenharmony_ci	if (count > avail - pos)
328362306a36Sopenharmony_ci		count = avail - pos;
328462306a36Sopenharmony_ci
328562306a36Sopenharmony_ci	data = kvzalloc(count, GFP_KERNEL);
328662306a36Sopenharmony_ci	if (!data)
328762306a36Sopenharmony_ci		return -ENOMEM;
328862306a36Sopenharmony_ci
328962306a36Sopenharmony_ci	spin_lock(&adap->win0_lock);
329062306a36Sopenharmony_ci	ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ);
329162306a36Sopenharmony_ci	spin_unlock(&adap->win0_lock);
329262306a36Sopenharmony_ci	if (ret) {
329362306a36Sopenharmony_ci		kvfree(data);
329462306a36Sopenharmony_ci		return ret;
329562306a36Sopenharmony_ci	}
329662306a36Sopenharmony_ci	ret = copy_to_user(buf, data, count);
329762306a36Sopenharmony_ci
329862306a36Sopenharmony_ci	kvfree(data);
329962306a36Sopenharmony_ci	if (ret)
330062306a36Sopenharmony_ci		return -EFAULT;
330162306a36Sopenharmony_ci
330262306a36Sopenharmony_ci	*ppos = pos + count;
330362306a36Sopenharmony_ci	return count;
330462306a36Sopenharmony_ci}
330562306a36Sopenharmony_cistatic const struct file_operations mem_debugfs_fops = {
330662306a36Sopenharmony_ci	.owner   = THIS_MODULE,
330762306a36Sopenharmony_ci	.open    = simple_open,
330862306a36Sopenharmony_ci	.read    = mem_read,
330962306a36Sopenharmony_ci	.llseek  = default_llseek,
331062306a36Sopenharmony_ci};
331162306a36Sopenharmony_ci
331262306a36Sopenharmony_cistatic int tid_info_show(struct seq_file *seq, void *v)
331362306a36Sopenharmony_ci{
331462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
331562306a36Sopenharmony_ci	const struct tid_info *t;
331662306a36Sopenharmony_ci	enum chip_type chip;
331762306a36Sopenharmony_ci
331862306a36Sopenharmony_ci	t = &adap->tids;
331962306a36Sopenharmony_ci	chip = CHELSIO_CHIP_VERSION(adap->params.chip);
332062306a36Sopenharmony_ci	if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) {
332162306a36Sopenharmony_ci		unsigned int sb;
332262306a36Sopenharmony_ci		seq_printf(seq, "Connections in use: %u\n",
332362306a36Sopenharmony_ci			   atomic_read(&t->conns_in_use));
332462306a36Sopenharmony_ci
332562306a36Sopenharmony_ci		if (chip <= CHELSIO_T5)
332662306a36Sopenharmony_ci			sb = t4_read_reg(adap, LE_DB_SERVER_INDEX_A) / 4;
332762306a36Sopenharmony_ci		else
332862306a36Sopenharmony_ci			sb = t4_read_reg(adap, LE_DB_SRVR_START_INDEX_A);
332962306a36Sopenharmony_ci
333062306a36Sopenharmony_ci		if (sb) {
333162306a36Sopenharmony_ci			seq_printf(seq, "TID range: %u..%u/%u..%u", t->tid_base,
333262306a36Sopenharmony_ci				   sb - 1, adap->tids.hash_base,
333362306a36Sopenharmony_ci				   t->tid_base + t->ntids - 1);
333462306a36Sopenharmony_ci			seq_printf(seq, ", in use: %u/%u\n",
333562306a36Sopenharmony_ci				   atomic_read(&t->tids_in_use),
333662306a36Sopenharmony_ci				   atomic_read(&t->hash_tids_in_use));
333762306a36Sopenharmony_ci		} else if (adap->flags & CXGB4_FW_OFLD_CONN) {
333862306a36Sopenharmony_ci			seq_printf(seq, "TID range: %u..%u/%u..%u",
333962306a36Sopenharmony_ci				   t->aftid_base,
334062306a36Sopenharmony_ci				   t->aftid_end,
334162306a36Sopenharmony_ci				   adap->tids.hash_base,
334262306a36Sopenharmony_ci				   t->tid_base + t->ntids - 1);
334362306a36Sopenharmony_ci			seq_printf(seq, ", in use: %u/%u\n",
334462306a36Sopenharmony_ci				   atomic_read(&t->tids_in_use),
334562306a36Sopenharmony_ci				   atomic_read(&t->hash_tids_in_use));
334662306a36Sopenharmony_ci		} else {
334762306a36Sopenharmony_ci			seq_printf(seq, "TID range: %u..%u",
334862306a36Sopenharmony_ci				   adap->tids.hash_base,
334962306a36Sopenharmony_ci				   t->tid_base + t->ntids - 1);
335062306a36Sopenharmony_ci			seq_printf(seq, ", in use: %u\n",
335162306a36Sopenharmony_ci				   atomic_read(&t->hash_tids_in_use));
335262306a36Sopenharmony_ci		}
335362306a36Sopenharmony_ci	} else if (t->ntids) {
335462306a36Sopenharmony_ci		seq_printf(seq, "Connections in use: %u\n",
335562306a36Sopenharmony_ci			   atomic_read(&t->conns_in_use));
335662306a36Sopenharmony_ci
335762306a36Sopenharmony_ci		seq_printf(seq, "TID range: %u..%u", t->tid_base,
335862306a36Sopenharmony_ci			   t->tid_base + t->ntids - 1);
335962306a36Sopenharmony_ci		seq_printf(seq, ", in use: %u\n",
336062306a36Sopenharmony_ci			   atomic_read(&t->tids_in_use));
336162306a36Sopenharmony_ci	}
336262306a36Sopenharmony_ci
336362306a36Sopenharmony_ci	if (t->nstids)
336462306a36Sopenharmony_ci		seq_printf(seq, "STID range: %u..%u, in use-IPv4/IPv6: %u/%u\n",
336562306a36Sopenharmony_ci			   (!t->stid_base &&
336662306a36Sopenharmony_ci			   (chip <= CHELSIO_T5)) ?
336762306a36Sopenharmony_ci			   t->stid_base + 1 : t->stid_base,
336862306a36Sopenharmony_ci			   t->stid_base + t->nstids - 1,
336962306a36Sopenharmony_ci			   t->stids_in_use - t->v6_stids_in_use,
337062306a36Sopenharmony_ci			   t->v6_stids_in_use);
337162306a36Sopenharmony_ci
337262306a36Sopenharmony_ci	if (t->natids)
337362306a36Sopenharmony_ci		seq_printf(seq, "ATID range: 0..%u, in use: %u\n",
337462306a36Sopenharmony_ci			   t->natids - 1, t->atids_in_use);
337562306a36Sopenharmony_ci	seq_printf(seq, "FTID range: %u..%u\n", t->ftid_base,
337662306a36Sopenharmony_ci		   t->ftid_base + t->nftids - 1);
337762306a36Sopenharmony_ci	if (t->nsftids)
337862306a36Sopenharmony_ci		seq_printf(seq, "SFTID range: %u..%u in use: %u\n",
337962306a36Sopenharmony_ci			   t->sftid_base, t->sftid_base + t->nsftids - 2,
338062306a36Sopenharmony_ci			   t->sftids_in_use);
338162306a36Sopenharmony_ci	if (t->nhpftids)
338262306a36Sopenharmony_ci		seq_printf(seq, "HPFTID range: %u..%u\n", t->hpftid_base,
338362306a36Sopenharmony_ci			   t->hpftid_base + t->nhpftids - 1);
338462306a36Sopenharmony_ci	if (t->neotids)
338562306a36Sopenharmony_ci		seq_printf(seq, "EOTID range: %u..%u, in use: %u\n",
338662306a36Sopenharmony_ci			   t->eotid_base, t->eotid_base + t->neotids - 1,
338762306a36Sopenharmony_ci			   atomic_read(&t->eotids_in_use));
338862306a36Sopenharmony_ci	if (t->ntids)
338962306a36Sopenharmony_ci		seq_printf(seq, "HW TID usage: %u IP users, %u IPv6 users\n",
339062306a36Sopenharmony_ci			   t4_read_reg(adap, LE_DB_ACT_CNT_IPV4_A),
339162306a36Sopenharmony_ci			   t4_read_reg(adap, LE_DB_ACT_CNT_IPV6_A));
339262306a36Sopenharmony_ci	return 0;
339362306a36Sopenharmony_ci}
339462306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(tid_info);
339562306a36Sopenharmony_ci
339662306a36Sopenharmony_cistatic void add_debugfs_mem(struct adapter *adap, const char *name,
339762306a36Sopenharmony_ci			    unsigned int idx, unsigned int size_mb)
339862306a36Sopenharmony_ci{
339962306a36Sopenharmony_ci	debugfs_create_file_size(name, 0400, adap->debugfs_root,
340062306a36Sopenharmony_ci				 (void *)adap + idx, &mem_debugfs_fops,
340162306a36Sopenharmony_ci				 size_mb << 20);
340262306a36Sopenharmony_ci}
340362306a36Sopenharmony_ci
340462306a36Sopenharmony_cistatic ssize_t blocked_fl_read(struct file *filp, char __user *ubuf,
340562306a36Sopenharmony_ci			       size_t count, loff_t *ppos)
340662306a36Sopenharmony_ci{
340762306a36Sopenharmony_ci	int len;
340862306a36Sopenharmony_ci	const struct adapter *adap = filp->private_data;
340962306a36Sopenharmony_ci	char *buf;
341062306a36Sopenharmony_ci	ssize_t size = (adap->sge.egr_sz + 3) / 4 +
341162306a36Sopenharmony_ci			adap->sge.egr_sz / 32 + 2; /* includes ,/\n/\0 */
341262306a36Sopenharmony_ci
341362306a36Sopenharmony_ci	buf = kzalloc(size, GFP_KERNEL);
341462306a36Sopenharmony_ci	if (!buf)
341562306a36Sopenharmony_ci		return -ENOMEM;
341662306a36Sopenharmony_ci
341762306a36Sopenharmony_ci	len = snprintf(buf, size - 1, "%*pb\n",
341862306a36Sopenharmony_ci		       adap->sge.egr_sz, adap->sge.blocked_fl);
341962306a36Sopenharmony_ci	len += sprintf(buf + len, "\n");
342062306a36Sopenharmony_ci	size = simple_read_from_buffer(ubuf, count, ppos, buf, len);
342162306a36Sopenharmony_ci	kfree(buf);
342262306a36Sopenharmony_ci	return size;
342362306a36Sopenharmony_ci}
342462306a36Sopenharmony_ci
342562306a36Sopenharmony_cistatic ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf,
342662306a36Sopenharmony_ci				size_t count, loff_t *ppos)
342762306a36Sopenharmony_ci{
342862306a36Sopenharmony_ci	int err;
342962306a36Sopenharmony_ci	unsigned long *t;
343062306a36Sopenharmony_ci	struct adapter *adap = filp->private_data;
343162306a36Sopenharmony_ci
343262306a36Sopenharmony_ci	t = bitmap_zalloc(adap->sge.egr_sz, GFP_KERNEL);
343362306a36Sopenharmony_ci	if (!t)
343462306a36Sopenharmony_ci		return -ENOMEM;
343562306a36Sopenharmony_ci
343662306a36Sopenharmony_ci	err = bitmap_parse_user(ubuf, count, t, adap->sge.egr_sz);
343762306a36Sopenharmony_ci	if (err) {
343862306a36Sopenharmony_ci		bitmap_free(t);
343962306a36Sopenharmony_ci		return err;
344062306a36Sopenharmony_ci	}
344162306a36Sopenharmony_ci
344262306a36Sopenharmony_ci	bitmap_copy(adap->sge.blocked_fl, t, adap->sge.egr_sz);
344362306a36Sopenharmony_ci	bitmap_free(t);
344462306a36Sopenharmony_ci	return count;
344562306a36Sopenharmony_ci}
344662306a36Sopenharmony_ci
344762306a36Sopenharmony_cistatic const struct file_operations blocked_fl_fops = {
344862306a36Sopenharmony_ci	.owner   = THIS_MODULE,
344962306a36Sopenharmony_ci	.open    = simple_open,
345062306a36Sopenharmony_ci	.read    = blocked_fl_read,
345162306a36Sopenharmony_ci	.write   = blocked_fl_write,
345262306a36Sopenharmony_ci	.llseek  = generic_file_llseek,
345362306a36Sopenharmony_ci};
345462306a36Sopenharmony_ci
345562306a36Sopenharmony_cistatic void mem_region_show(struct seq_file *seq, const char *name,
345662306a36Sopenharmony_ci			    unsigned int from, unsigned int to)
345762306a36Sopenharmony_ci{
345862306a36Sopenharmony_ci	char buf[40];
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci	string_get_size((u64)to - from + 1, 1, STRING_UNITS_2, buf,
346162306a36Sopenharmony_ci			sizeof(buf));
346262306a36Sopenharmony_ci	seq_printf(seq, "%-15s %#x-%#x [%s]\n", name, from, to, buf);
346362306a36Sopenharmony_ci}
346462306a36Sopenharmony_ci
346562306a36Sopenharmony_cistatic int meminfo_show(struct seq_file *seq, void *v)
346662306a36Sopenharmony_ci{
346762306a36Sopenharmony_ci	static const char * const memory[] = { "EDC0:", "EDC1:", "MC:",
346862306a36Sopenharmony_ci					       "MC0:", "MC1:", "HMA:"};
346962306a36Sopenharmony_ci	struct adapter *adap = seq->private;
347062306a36Sopenharmony_ci	struct cudbg_meminfo meminfo;
347162306a36Sopenharmony_ci	int i, rc;
347262306a36Sopenharmony_ci
347362306a36Sopenharmony_ci	memset(&meminfo, 0, sizeof(struct cudbg_meminfo));
347462306a36Sopenharmony_ci	rc = cudbg_fill_meminfo(adap, &meminfo);
347562306a36Sopenharmony_ci	if (rc)
347662306a36Sopenharmony_ci		return -ENXIO;
347762306a36Sopenharmony_ci
347862306a36Sopenharmony_ci	for (i = 0; i < meminfo.avail_c; i++)
347962306a36Sopenharmony_ci		mem_region_show(seq, memory[meminfo.avail[i].idx],
348062306a36Sopenharmony_ci				meminfo.avail[i].base,
348162306a36Sopenharmony_ci				meminfo.avail[i].limit - 1);
348262306a36Sopenharmony_ci
348362306a36Sopenharmony_ci	seq_putc(seq, '\n');
348462306a36Sopenharmony_ci	for (i = 0; i < meminfo.mem_c; i++) {
348562306a36Sopenharmony_ci		if (meminfo.mem[i].idx >= ARRAY_SIZE(cudbg_region))
348662306a36Sopenharmony_ci			continue;                        /* skip holes */
348762306a36Sopenharmony_ci		if (!meminfo.mem[i].limit)
348862306a36Sopenharmony_ci			meminfo.mem[i].limit =
348962306a36Sopenharmony_ci				i < meminfo.mem_c - 1 ?
349062306a36Sopenharmony_ci				meminfo.mem[i + 1].base - 1 : ~0;
349162306a36Sopenharmony_ci		mem_region_show(seq, cudbg_region[meminfo.mem[i].idx],
349262306a36Sopenharmony_ci				meminfo.mem[i].base, meminfo.mem[i].limit);
349362306a36Sopenharmony_ci	}
349462306a36Sopenharmony_ci
349562306a36Sopenharmony_ci	seq_putc(seq, '\n');
349662306a36Sopenharmony_ci	mem_region_show(seq, "uP RAM:", meminfo.up_ram_lo, meminfo.up_ram_hi);
349762306a36Sopenharmony_ci	mem_region_show(seq, "uP Extmem2:", meminfo.up_extmem2_lo,
349862306a36Sopenharmony_ci			meminfo.up_extmem2_hi);
349962306a36Sopenharmony_ci
350062306a36Sopenharmony_ci	seq_printf(seq, "\n%u Rx pages (%u free) of size %uKiB for %u channels\n",
350162306a36Sopenharmony_ci		   meminfo.rx_pages_data[0], meminfo.free_rx_cnt,
350262306a36Sopenharmony_ci		   meminfo.rx_pages_data[1], meminfo.rx_pages_data[2]);
350362306a36Sopenharmony_ci
350462306a36Sopenharmony_ci	seq_printf(seq, "%u Tx pages (%u free) of size %u%ciB for %u channels\n",
350562306a36Sopenharmony_ci		   meminfo.tx_pages_data[0], meminfo.free_tx_cnt,
350662306a36Sopenharmony_ci		   meminfo.tx_pages_data[1], meminfo.tx_pages_data[2],
350762306a36Sopenharmony_ci		   meminfo.tx_pages_data[3]);
350862306a36Sopenharmony_ci
350962306a36Sopenharmony_ci	seq_printf(seq, "%u p-structs (%u free)\n\n",
351062306a36Sopenharmony_ci		   meminfo.p_structs, meminfo.p_structs_free_cnt);
351162306a36Sopenharmony_ci
351262306a36Sopenharmony_ci	for (i = 0; i < 4; i++)
351362306a36Sopenharmony_ci		/* For T6 these are MAC buffer groups */
351462306a36Sopenharmony_ci		seq_printf(seq, "Port %d using %u pages out of %u allocated\n",
351562306a36Sopenharmony_ci			   i, meminfo.port_used[i], meminfo.port_alloc[i]);
351662306a36Sopenharmony_ci
351762306a36Sopenharmony_ci	for (i = 0; i < adap->params.arch.nchan; i++)
351862306a36Sopenharmony_ci		/* For T6 these are MAC buffer groups */
351962306a36Sopenharmony_ci		seq_printf(seq,
352062306a36Sopenharmony_ci			   "Loopback %d using %u pages out of %u allocated\n",
352162306a36Sopenharmony_ci			   i, meminfo.loopback_used[i],
352262306a36Sopenharmony_ci			   meminfo.loopback_alloc[i]);
352362306a36Sopenharmony_ci
352462306a36Sopenharmony_ci	return 0;
352562306a36Sopenharmony_ci}
352662306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(meminfo);
352762306a36Sopenharmony_ci
352862306a36Sopenharmony_cistatic int chcr_stats_show(struct seq_file *seq, void *v)
352962306a36Sopenharmony_ci{
353062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
353162306a36Sopenharmony_ci	struct ch_ktls_port_stats_debug *ktls_port;
353262306a36Sopenharmony_ci	int i = 0;
353362306a36Sopenharmony_ci#endif
353462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
353562306a36Sopenharmony_ci
353662306a36Sopenharmony_ci	seq_puts(seq, "Chelsio Crypto Accelerator Stats \n");
353762306a36Sopenharmony_ci	seq_printf(seq, "Cipher Ops: %10u \n",
353862306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.cipher_rqst));
353962306a36Sopenharmony_ci	seq_printf(seq, "Digest Ops: %10u \n",
354062306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.digest_rqst));
354162306a36Sopenharmony_ci	seq_printf(seq, "Aead Ops: %10u \n",
354262306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.aead_rqst));
354362306a36Sopenharmony_ci	seq_printf(seq, "Completion: %10u \n",
354462306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.complete));
354562306a36Sopenharmony_ci	seq_printf(seq, "Error: %10u \n",
354662306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.error));
354762306a36Sopenharmony_ci	seq_printf(seq, "Fallback: %10u \n",
354862306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.fallback));
354962306a36Sopenharmony_ci	seq_printf(seq, "TLS PDU Tx: %10u\n",
355062306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.tls_pdu_tx));
355162306a36Sopenharmony_ci	seq_printf(seq, "TLS PDU Rx: %10u\n",
355262306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.tls_pdu_rx));
355362306a36Sopenharmony_ci	seq_printf(seq, "TLS Keys (DDR) Count: %10u\n",
355462306a36Sopenharmony_ci		   atomic_read(&adap->chcr_stats.tls_key));
355562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
355662306a36Sopenharmony_ci	seq_puts(seq, "\nChelsio Inline IPsec Crypto Accelerator Stats\n");
355762306a36Sopenharmony_ci	seq_printf(seq, "IPSec PDU: %10u\n",
355862306a36Sopenharmony_ci		   atomic_read(&adap->ch_ipsec_stats.ipsec_cnt));
355962306a36Sopenharmony_ci#endif
356062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
356162306a36Sopenharmony_ci	seq_puts(seq, "\nChelsio KTLS Crypto Accelerator Stats\n");
356262306a36Sopenharmony_ci	seq_printf(seq, "Tx TLS offload refcount:          %20u\n",
356362306a36Sopenharmony_ci		   refcount_read(&adap->chcr_ktls.ktls_refcount));
356462306a36Sopenharmony_ci	seq_printf(seq, "Tx records send:                  %20llu\n",
356562306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_send_records));
356662306a36Sopenharmony_ci	seq_printf(seq, "Tx partial start of records:      %20llu\n",
356762306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_start_pkts));
356862306a36Sopenharmony_ci	seq_printf(seq, "Tx partial middle of records:     %20llu\n",
356962306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_middle_pkts));
357062306a36Sopenharmony_ci	seq_printf(seq, "Tx partial end of record:         %20llu\n",
357162306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_end_pkts));
357262306a36Sopenharmony_ci	seq_printf(seq, "Tx complete records:              %20llu\n",
357362306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_complete_pkts));
357462306a36Sopenharmony_ci	seq_printf(seq, "TX trim pkts :                    %20llu\n",
357562306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_trimmed_pkts));
357662306a36Sopenharmony_ci	seq_printf(seq, "TX sw fallback :                  %20llu\n",
357762306a36Sopenharmony_ci		   atomic64_read(&adap->ch_ktls_stats.ktls_tx_fallback));
357862306a36Sopenharmony_ci	while (i < MAX_NPORTS) {
357962306a36Sopenharmony_ci		ktls_port = &adap->ch_ktls_stats.ktls_port[i];
358062306a36Sopenharmony_ci		seq_printf(seq, "Port %d\n", i);
358162306a36Sopenharmony_ci		seq_printf(seq, "Tx connection created:            %20llu\n",
358262306a36Sopenharmony_ci			   atomic64_read(&ktls_port->ktls_tx_connection_open));
358362306a36Sopenharmony_ci		seq_printf(seq, "Tx connection failed:             %20llu\n",
358462306a36Sopenharmony_ci			   atomic64_read(&ktls_port->ktls_tx_connection_fail));
358562306a36Sopenharmony_ci		seq_printf(seq, "Tx connection closed:             %20llu\n",
358662306a36Sopenharmony_ci			   atomic64_read(&ktls_port->ktls_tx_connection_close));
358762306a36Sopenharmony_ci		i++;
358862306a36Sopenharmony_ci	}
358962306a36Sopenharmony_ci#endif
359062306a36Sopenharmony_ci	return 0;
359162306a36Sopenharmony_ci}
359262306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(chcr_stats);
359362306a36Sopenharmony_ci
359462306a36Sopenharmony_ci#define PRINT_ADAP_STATS(string, value) \
359562306a36Sopenharmony_ci	seq_printf(seq, "%-25s %-20llu\n", (string), \
359662306a36Sopenharmony_ci		   (unsigned long long)(value))
359762306a36Sopenharmony_ci
359862306a36Sopenharmony_ci#define PRINT_CH_STATS(string, value) \
359962306a36Sopenharmony_cido { \
360062306a36Sopenharmony_ci	seq_printf(seq, "%-25s ", (string)); \
360162306a36Sopenharmony_ci	for (i = 0; i < adap->params.arch.nchan; i++) \
360262306a36Sopenharmony_ci		seq_printf(seq, "%-20llu ", \
360362306a36Sopenharmony_ci			   (unsigned long long)stats.value[i]); \
360462306a36Sopenharmony_ci	seq_printf(seq, "\n"); \
360562306a36Sopenharmony_ci} while (0)
360662306a36Sopenharmony_ci
360762306a36Sopenharmony_ci#define PRINT_CH_STATS2(string, value) \
360862306a36Sopenharmony_cido { \
360962306a36Sopenharmony_ci	seq_printf(seq, "%-25s ", (string)); \
361062306a36Sopenharmony_ci	for (i = 0; i < adap->params.arch.nchan; i++) \
361162306a36Sopenharmony_ci		seq_printf(seq, "%-20llu ", \
361262306a36Sopenharmony_ci			   (unsigned long long)stats[i].value); \
361362306a36Sopenharmony_ci	seq_printf(seq, "\n"); \
361462306a36Sopenharmony_ci} while (0)
361562306a36Sopenharmony_ci
361662306a36Sopenharmony_cistatic void show_tcp_stats(struct seq_file *seq)
361762306a36Sopenharmony_ci{
361862306a36Sopenharmony_ci	struct adapter *adap = seq->private;
361962306a36Sopenharmony_ci	struct tp_tcp_stats v4, v6;
362062306a36Sopenharmony_ci
362162306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
362262306a36Sopenharmony_ci	t4_tp_get_tcp_stats(adap, &v4, &v6, false);
362362306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
362462306a36Sopenharmony_ci
362562306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv4_out_rsts:", v4.tcp_out_rsts);
362662306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv4_in_segs:", v4.tcp_in_segs);
362762306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv4_out_segs:", v4.tcp_out_segs);
362862306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv4_retrans_segs:", v4.tcp_retrans_segs);
362962306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv6_out_rsts:", v6.tcp_out_rsts);
363062306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv6_in_segs:", v6.tcp_in_segs);
363162306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv6_out_segs:", v6.tcp_out_segs);
363262306a36Sopenharmony_ci	PRINT_ADAP_STATS("tcp_ipv6_retrans_segs:", v6.tcp_retrans_segs);
363362306a36Sopenharmony_ci}
363462306a36Sopenharmony_ci
363562306a36Sopenharmony_cistatic void show_ddp_stats(struct seq_file *seq)
363662306a36Sopenharmony_ci{
363762306a36Sopenharmony_ci	struct adapter *adap = seq->private;
363862306a36Sopenharmony_ci	struct tp_usm_stats stats;
363962306a36Sopenharmony_ci
364062306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
364162306a36Sopenharmony_ci	t4_get_usm_stats(adap, &stats, false);
364262306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
364362306a36Sopenharmony_ci
364462306a36Sopenharmony_ci	PRINT_ADAP_STATS("usm_ddp_frames:", stats.frames);
364562306a36Sopenharmony_ci	PRINT_ADAP_STATS("usm_ddp_octets:", stats.octets);
364662306a36Sopenharmony_ci	PRINT_ADAP_STATS("usm_ddp_drops:", stats.drops);
364762306a36Sopenharmony_ci}
364862306a36Sopenharmony_ci
364962306a36Sopenharmony_cistatic void show_rdma_stats(struct seq_file *seq)
365062306a36Sopenharmony_ci{
365162306a36Sopenharmony_ci	struct adapter *adap = seq->private;
365262306a36Sopenharmony_ci	struct tp_rdma_stats stats;
365362306a36Sopenharmony_ci
365462306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
365562306a36Sopenharmony_ci	t4_tp_get_rdma_stats(adap, &stats, false);
365662306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
365762306a36Sopenharmony_ci
365862306a36Sopenharmony_ci	PRINT_ADAP_STATS("rdma_no_rqe_mod_defer:", stats.rqe_dfr_mod);
365962306a36Sopenharmony_ci	PRINT_ADAP_STATS("rdma_no_rqe_pkt_defer:", stats.rqe_dfr_pkt);
366062306a36Sopenharmony_ci}
366162306a36Sopenharmony_ci
366262306a36Sopenharmony_cistatic void show_tp_err_adapter_stats(struct seq_file *seq)
366362306a36Sopenharmony_ci{
366462306a36Sopenharmony_ci	struct adapter *adap = seq->private;
366562306a36Sopenharmony_ci	struct tp_err_stats stats;
366662306a36Sopenharmony_ci
366762306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
366862306a36Sopenharmony_ci	t4_tp_get_err_stats(adap, &stats, false);
366962306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
367062306a36Sopenharmony_ci
367162306a36Sopenharmony_ci	PRINT_ADAP_STATS("tp_err_ofld_no_neigh:", stats.ofld_no_neigh);
367262306a36Sopenharmony_ci	PRINT_ADAP_STATS("tp_err_ofld_cong_defer:", stats.ofld_cong_defer);
367362306a36Sopenharmony_ci}
367462306a36Sopenharmony_ci
367562306a36Sopenharmony_cistatic void show_cpl_stats(struct seq_file *seq)
367662306a36Sopenharmony_ci{
367762306a36Sopenharmony_ci	struct adapter *adap = seq->private;
367862306a36Sopenharmony_ci	struct tp_cpl_stats stats;
367962306a36Sopenharmony_ci	u8 i;
368062306a36Sopenharmony_ci
368162306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
368262306a36Sopenharmony_ci	t4_tp_get_cpl_stats(adap, &stats, false);
368362306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
368462306a36Sopenharmony_ci
368562306a36Sopenharmony_ci	PRINT_CH_STATS("tp_cpl_requests:", req);
368662306a36Sopenharmony_ci	PRINT_CH_STATS("tp_cpl_responses:", rsp);
368762306a36Sopenharmony_ci}
368862306a36Sopenharmony_ci
368962306a36Sopenharmony_cistatic void show_tp_err_channel_stats(struct seq_file *seq)
369062306a36Sopenharmony_ci{
369162306a36Sopenharmony_ci	struct adapter *adap = seq->private;
369262306a36Sopenharmony_ci	struct tp_err_stats stats;
369362306a36Sopenharmony_ci	u8 i;
369462306a36Sopenharmony_ci
369562306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
369662306a36Sopenharmony_ci	t4_tp_get_err_stats(adap, &stats, false);
369762306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
369862306a36Sopenharmony_ci
369962306a36Sopenharmony_ci	PRINT_CH_STATS("tp_mac_in_errs:", mac_in_errs);
370062306a36Sopenharmony_ci	PRINT_CH_STATS("tp_hdr_in_errs:", hdr_in_errs);
370162306a36Sopenharmony_ci	PRINT_CH_STATS("tp_tcp_in_errs:", tcp_in_errs);
370262306a36Sopenharmony_ci	PRINT_CH_STATS("tp_tcp6_in_errs:", tcp6_in_errs);
370362306a36Sopenharmony_ci	PRINT_CH_STATS("tp_tnl_cong_drops:", tnl_cong_drops);
370462306a36Sopenharmony_ci	PRINT_CH_STATS("tp_tnl_tx_drops:", tnl_tx_drops);
370562306a36Sopenharmony_ci	PRINT_CH_STATS("tp_ofld_vlan_drops:", ofld_vlan_drops);
370662306a36Sopenharmony_ci	PRINT_CH_STATS("tp_ofld_chan_drops:", ofld_chan_drops);
370762306a36Sopenharmony_ci}
370862306a36Sopenharmony_ci
370962306a36Sopenharmony_cistatic void show_fcoe_stats(struct seq_file *seq)
371062306a36Sopenharmony_ci{
371162306a36Sopenharmony_ci	struct adapter *adap = seq->private;
371262306a36Sopenharmony_ci	struct tp_fcoe_stats stats[NCHAN];
371362306a36Sopenharmony_ci	u8 i;
371462306a36Sopenharmony_ci
371562306a36Sopenharmony_ci	spin_lock(&adap->stats_lock);
371662306a36Sopenharmony_ci	for (i = 0; i < adap->params.arch.nchan; i++)
371762306a36Sopenharmony_ci		t4_get_fcoe_stats(adap, i, &stats[i], false);
371862306a36Sopenharmony_ci	spin_unlock(&adap->stats_lock);
371962306a36Sopenharmony_ci
372062306a36Sopenharmony_ci	PRINT_CH_STATS2("fcoe_octets_ddp", octets_ddp);
372162306a36Sopenharmony_ci	PRINT_CH_STATS2("fcoe_frames_ddp", frames_ddp);
372262306a36Sopenharmony_ci	PRINT_CH_STATS2("fcoe_frames_drop", frames_drop);
372362306a36Sopenharmony_ci}
372462306a36Sopenharmony_ci
372562306a36Sopenharmony_ci#undef PRINT_CH_STATS2
372662306a36Sopenharmony_ci#undef PRINT_CH_STATS
372762306a36Sopenharmony_ci#undef PRINT_ADAP_STATS
372862306a36Sopenharmony_ci
372962306a36Sopenharmony_cistatic int tp_stats_show(struct seq_file *seq, void *v)
373062306a36Sopenharmony_ci{
373162306a36Sopenharmony_ci	struct adapter *adap = seq->private;
373262306a36Sopenharmony_ci
373362306a36Sopenharmony_ci	seq_puts(seq, "\n--------Adapter Stats--------\n");
373462306a36Sopenharmony_ci	show_tcp_stats(seq);
373562306a36Sopenharmony_ci	show_ddp_stats(seq);
373662306a36Sopenharmony_ci	show_rdma_stats(seq);
373762306a36Sopenharmony_ci	show_tp_err_adapter_stats(seq);
373862306a36Sopenharmony_ci
373962306a36Sopenharmony_ci	seq_puts(seq, "\n-------- Channel Stats --------\n");
374062306a36Sopenharmony_ci	if (adap->params.arch.nchan == NCHAN)
374162306a36Sopenharmony_ci		seq_printf(seq, "%-25s %-20s %-20s %-20s %-20s\n",
374262306a36Sopenharmony_ci			   " ", "channel 0", "channel 1",
374362306a36Sopenharmony_ci			   "channel 2", "channel 3");
374462306a36Sopenharmony_ci	else
374562306a36Sopenharmony_ci		seq_printf(seq, "%-25s %-20s %-20s\n",
374662306a36Sopenharmony_ci			   " ", "channel 0", "channel 1");
374762306a36Sopenharmony_ci	show_cpl_stats(seq);
374862306a36Sopenharmony_ci	show_tp_err_channel_stats(seq);
374962306a36Sopenharmony_ci	show_fcoe_stats(seq);
375062306a36Sopenharmony_ci
375162306a36Sopenharmony_ci	return 0;
375262306a36Sopenharmony_ci}
375362306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(tp_stats);
375462306a36Sopenharmony_ci
375562306a36Sopenharmony_ci/* Add an array of Debug FS files.
375662306a36Sopenharmony_ci */
375762306a36Sopenharmony_civoid add_debugfs_files(struct adapter *adap,
375862306a36Sopenharmony_ci		       struct t4_debugfs_entry *files,
375962306a36Sopenharmony_ci		       unsigned int nfiles)
376062306a36Sopenharmony_ci{
376162306a36Sopenharmony_ci	int i;
376262306a36Sopenharmony_ci
376362306a36Sopenharmony_ci	/* debugfs support is best effort */
376462306a36Sopenharmony_ci	for (i = 0; i < nfiles; i++)
376562306a36Sopenharmony_ci		debugfs_create_file(files[i].name, files[i].mode,
376662306a36Sopenharmony_ci				    adap->debugfs_root,
376762306a36Sopenharmony_ci				    (void *)adap + files[i].data,
376862306a36Sopenharmony_ci				    files[i].ops);
376962306a36Sopenharmony_ci}
377062306a36Sopenharmony_ci
377162306a36Sopenharmony_ciint t4_setup_debugfs(struct adapter *adap)
377262306a36Sopenharmony_ci{
377362306a36Sopenharmony_ci	int i;
377462306a36Sopenharmony_ci	u32 size = 0;
377562306a36Sopenharmony_ci
377662306a36Sopenharmony_ci	static struct t4_debugfs_entry t4_debugfs_files[] = {
377762306a36Sopenharmony_ci		{ "cim_la", &cim_la_fops, 0400, 0 },
377862306a36Sopenharmony_ci		{ "cim_pif_la", &cim_pif_la_fops, 0400, 0 },
377962306a36Sopenharmony_ci		{ "cim_ma_la", &cim_ma_la_fops, 0400, 0 },
378062306a36Sopenharmony_ci		{ "cim_qcfg", &cim_qcfg_fops, 0400, 0 },
378162306a36Sopenharmony_ci		{ "clk", &clk_fops, 0400, 0 },
378262306a36Sopenharmony_ci		{ "devlog", &devlog_fops, 0400, 0 },
378362306a36Sopenharmony_ci		{ "mboxlog", &mboxlog_fops, 0400, 0 },
378462306a36Sopenharmony_ci		{ "mbox0", &mbox_debugfs_fops, 0600, 0 },
378562306a36Sopenharmony_ci		{ "mbox1", &mbox_debugfs_fops, 0600, 1 },
378662306a36Sopenharmony_ci		{ "mbox2", &mbox_debugfs_fops, 0600, 2 },
378762306a36Sopenharmony_ci		{ "mbox3", &mbox_debugfs_fops, 0600, 3 },
378862306a36Sopenharmony_ci		{ "mbox4", &mbox_debugfs_fops, 0600, 4 },
378962306a36Sopenharmony_ci		{ "mbox5", &mbox_debugfs_fops, 0600, 5 },
379062306a36Sopenharmony_ci		{ "mbox6", &mbox_debugfs_fops, 0600, 6 },
379162306a36Sopenharmony_ci		{ "mbox7", &mbox_debugfs_fops, 0600, 7 },
379262306a36Sopenharmony_ci		{ "trace0", &mps_trc_debugfs_fops, 0600, 0 },
379362306a36Sopenharmony_ci		{ "trace1", &mps_trc_debugfs_fops, 0600, 1 },
379462306a36Sopenharmony_ci		{ "trace2", &mps_trc_debugfs_fops, 0600, 2 },
379562306a36Sopenharmony_ci		{ "trace3", &mps_trc_debugfs_fops, 0600, 3 },
379662306a36Sopenharmony_ci		{ "l2t", &t4_l2t_fops, 0400, 0},
379762306a36Sopenharmony_ci		{ "mps_tcam", &mps_tcam_debugfs_fops, 0400, 0 },
379862306a36Sopenharmony_ci		{ "rss", &rss_debugfs_fops, 0400, 0 },
379962306a36Sopenharmony_ci		{ "rss_config", &rss_config_fops, 0400, 0 },
380062306a36Sopenharmony_ci		{ "rss_key", &rss_key_debugfs_fops, 0400, 0 },
380162306a36Sopenharmony_ci		{ "rss_pf_config", &rss_pf_config_debugfs_fops, 0400, 0 },
380262306a36Sopenharmony_ci		{ "rss_vf_config", &rss_vf_config_debugfs_fops, 0400, 0 },
380362306a36Sopenharmony_ci		{ "resources", &resources_fops, 0400, 0 },
380462306a36Sopenharmony_ci#ifdef CONFIG_CHELSIO_T4_DCB
380562306a36Sopenharmony_ci		{ "dcb_info", &dcb_info_debugfs_fops, 0400, 0 },
380662306a36Sopenharmony_ci#endif
380762306a36Sopenharmony_ci		{ "sge_qinfo", &sge_qinfo_debugfs_fops, 0400, 0 },
380862306a36Sopenharmony_ci		{ "ibq_tp0",  &cim_ibq_fops, 0400, 0 },
380962306a36Sopenharmony_ci		{ "ibq_tp1",  &cim_ibq_fops, 0400, 1 },
381062306a36Sopenharmony_ci		{ "ibq_ulp",  &cim_ibq_fops, 0400, 2 },
381162306a36Sopenharmony_ci		{ "ibq_sge0", &cim_ibq_fops, 0400, 3 },
381262306a36Sopenharmony_ci		{ "ibq_sge1", &cim_ibq_fops, 0400, 4 },
381362306a36Sopenharmony_ci		{ "ibq_ncsi", &cim_ibq_fops, 0400, 5 },
381462306a36Sopenharmony_ci		{ "obq_ulp0", &cim_obq_fops, 0400, 0 },
381562306a36Sopenharmony_ci		{ "obq_ulp1", &cim_obq_fops, 0400, 1 },
381662306a36Sopenharmony_ci		{ "obq_ulp2", &cim_obq_fops, 0400, 2 },
381762306a36Sopenharmony_ci		{ "obq_ulp3", &cim_obq_fops, 0400, 3 },
381862306a36Sopenharmony_ci		{ "obq_sge",  &cim_obq_fops, 0400, 4 },
381962306a36Sopenharmony_ci		{ "obq_ncsi", &cim_obq_fops, 0400, 5 },
382062306a36Sopenharmony_ci		{ "tp_la", &tp_la_fops, 0400, 0 },
382162306a36Sopenharmony_ci		{ "ulprx_la", &ulprx_la_fops, 0400, 0 },
382262306a36Sopenharmony_ci		{ "sensors", &sensors_fops, 0400, 0 },
382362306a36Sopenharmony_ci		{ "pm_stats", &pm_stats_debugfs_fops, 0400, 0 },
382462306a36Sopenharmony_ci		{ "tx_rate", &tx_rate_fops, 0400, 0 },
382562306a36Sopenharmony_ci		{ "cctrl", &cctrl_tbl_fops, 0400, 0 },
382662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
382762306a36Sopenharmony_ci		{ "clip_tbl", &clip_tbl_fops, 0400, 0 },
382862306a36Sopenharmony_ci#endif
382962306a36Sopenharmony_ci		{ "tids", &tid_info_fops, 0400, 0},
383062306a36Sopenharmony_ci		{ "blocked_fl", &blocked_fl_fops, 0600, 0 },
383162306a36Sopenharmony_ci		{ "meminfo", &meminfo_fops, 0400, 0 },
383262306a36Sopenharmony_ci		{ "crypto", &chcr_stats_fops, 0400, 0 },
383362306a36Sopenharmony_ci		{ "tp_stats", &tp_stats_fops, 0400, 0 },
383462306a36Sopenharmony_ci	};
383562306a36Sopenharmony_ci
383662306a36Sopenharmony_ci	/* Debug FS nodes common to all T5 and later adapters.
383762306a36Sopenharmony_ci	 */
383862306a36Sopenharmony_ci	static struct t4_debugfs_entry t5_debugfs_files[] = {
383962306a36Sopenharmony_ci		{ "obq_sge_rx_q0", &cim_obq_fops, 0400, 6 },
384062306a36Sopenharmony_ci		{ "obq_sge_rx_q1", &cim_obq_fops, 0400, 7 },
384162306a36Sopenharmony_ci	};
384262306a36Sopenharmony_ci
384362306a36Sopenharmony_ci	add_debugfs_files(adap,
384462306a36Sopenharmony_ci			  t4_debugfs_files,
384562306a36Sopenharmony_ci			  ARRAY_SIZE(t4_debugfs_files));
384662306a36Sopenharmony_ci	if (!is_t4(adap->params.chip))
384762306a36Sopenharmony_ci		add_debugfs_files(adap,
384862306a36Sopenharmony_ci				  t5_debugfs_files,
384962306a36Sopenharmony_ci				  ARRAY_SIZE(t5_debugfs_files));
385062306a36Sopenharmony_ci
385162306a36Sopenharmony_ci	i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
385262306a36Sopenharmony_ci	if (i & EDRAM0_ENABLE_F) {
385362306a36Sopenharmony_ci		size = t4_read_reg(adap, MA_EDRAM0_BAR_A);
385462306a36Sopenharmony_ci		add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM0_SIZE_G(size));
385562306a36Sopenharmony_ci	}
385662306a36Sopenharmony_ci	if (i & EDRAM1_ENABLE_F) {
385762306a36Sopenharmony_ci		size = t4_read_reg(adap, MA_EDRAM1_BAR_A);
385862306a36Sopenharmony_ci		add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM1_SIZE_G(size));
385962306a36Sopenharmony_ci	}
386062306a36Sopenharmony_ci	if (is_t5(adap->params.chip)) {
386162306a36Sopenharmony_ci		if (i & EXT_MEM0_ENABLE_F) {
386262306a36Sopenharmony_ci			size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
386362306a36Sopenharmony_ci			add_debugfs_mem(adap, "mc0", MEM_MC0,
386462306a36Sopenharmony_ci					EXT_MEM0_SIZE_G(size));
386562306a36Sopenharmony_ci		}
386662306a36Sopenharmony_ci		if (i & EXT_MEM1_ENABLE_F) {
386762306a36Sopenharmony_ci			size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
386862306a36Sopenharmony_ci			add_debugfs_mem(adap, "mc1", MEM_MC1,
386962306a36Sopenharmony_ci					EXT_MEM1_SIZE_G(size));
387062306a36Sopenharmony_ci		}
387162306a36Sopenharmony_ci	} else {
387262306a36Sopenharmony_ci		if (i & EXT_MEM_ENABLE_F) {
387362306a36Sopenharmony_ci			size = t4_read_reg(adap, MA_EXT_MEMORY_BAR_A);
387462306a36Sopenharmony_ci			add_debugfs_mem(adap, "mc", MEM_MC,
387562306a36Sopenharmony_ci					EXT_MEM_SIZE_G(size));
387662306a36Sopenharmony_ci		}
387762306a36Sopenharmony_ci
387862306a36Sopenharmony_ci		if (i & HMA_MUX_F) {
387962306a36Sopenharmony_ci			size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
388062306a36Sopenharmony_ci			add_debugfs_mem(adap, "hma", MEM_HMA,
388162306a36Sopenharmony_ci					EXT_MEM1_SIZE_G(size));
388262306a36Sopenharmony_ci		}
388362306a36Sopenharmony_ci	}
388462306a36Sopenharmony_ci
388562306a36Sopenharmony_ci	debugfs_create_file_size("flash", 0400, adap->debugfs_root, adap,
388662306a36Sopenharmony_ci				 &flash_debugfs_fops, adap->params.sf_size);
388762306a36Sopenharmony_ci	debugfs_create_bool("use_backdoor", 0600,
388862306a36Sopenharmony_ci			    adap->debugfs_root, &adap->use_bd);
388962306a36Sopenharmony_ci	debugfs_create_bool("trace_rss", 0600,
389062306a36Sopenharmony_ci			    adap->debugfs_root, &adap->trace_rss);
389162306a36Sopenharmony_ci
389262306a36Sopenharmony_ci	return 0;
389362306a36Sopenharmony_ci}
3894