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