1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Huawei HiNIC PCI Express Linux driver
3 * Copyright(c) 2017 Huawei Technologies Co., Ltd
6 #include <linux/debugfs.h>
7 #include <linux/device.h>
9 #include "hinic_debugfs.h"
11 static struct dentry
*hinic_dbgfs_root
;
21 static char *sq_fields
[] = {"glb_sq_id", "sq_pi", "sq_ci", "sq_fi", "sq_msix_entry"};
23 static u64
hinic_dbg_get_sq_info(struct hinic_dev
*nic_dev
, struct hinic_sq
*sq
, int idx
)
25 struct hinic_wq
*wq
= sq
->wq
;
29 return nic_dev
->hwdev
->func_to_io
.global_qpn
+ sq
->qid
;
31 return atomic_read(&wq
->prod_idx
) & wq
->mask
;
33 return atomic_read(&wq
->cons_idx
) & wq
->mask
;
35 return be16_to_cpu(*(__be16
*)(sq
->hw_ci_addr
)) & wq
->mask
;
37 return sq
->msix_entry
;
51 static char *rq_fields
[] = {"glb_rq_id", "rq_hw_pi", "rq_sw_ci", "rq_sw_pi", "rq_msix_entry"};
53 static u64
hinic_dbg_get_rq_info(struct hinic_dev
*nic_dev
, struct hinic_rq
*rq
, int idx
)
55 struct hinic_wq
*wq
= rq
->wq
;
59 return nic_dev
->hwdev
->func_to_io
.global_qpn
+ rq
->qid
;
61 return be16_to_cpu(*(__be16
*)(rq
->pi_virt_addr
)) & wq
->mask
;
63 return atomic_read(&wq
->cons_idx
) & wq
->mask
;
65 return atomic_read(&wq
->prod_idx
) & wq
->mask
;
67 return rq
->msix_entry
;
81 static char *func_table_fields
[] = {"valid", "rx_mode", "mtu", "rq_depth", "cfg_q_num"};
83 static int hinic_dbg_get_func_table(struct hinic_dev
*nic_dev
, int idx
)
85 struct tag_sml_funcfg_tbl
*funcfg_table_elem
;
86 struct hinic_cmd_lt_rd
*read_data
;
87 u16 out_size
= sizeof(*read_data
);
90 read_data
= kzalloc(sizeof(*read_data
), GFP_KERNEL
);
94 read_data
->node
= TBL_ID_FUNC_CFG_SM_NODE
;
95 read_data
->inst
= TBL_ID_FUNC_CFG_SM_INST
;
96 read_data
->entry_size
= HINIC_FUNCTION_CONFIGURE_TABLE_SIZE
;
97 read_data
->lt_index
= HINIC_HWIF_FUNC_IDX(nic_dev
->hwdev
->hwif
);
98 read_data
->len
= HINIC_FUNCTION_CONFIGURE_TABLE_SIZE
;
100 err
= hinic_port_msg_cmd(nic_dev
->hwdev
, HINIC_PORT_CMD_RD_LINE_TBL
, read_data
,
101 sizeof(*read_data
), read_data
, &out_size
);
102 if (err
|| out_size
!= sizeof(*read_data
) || read_data
->status
) {
103 netif_err(nic_dev
, drv
, nic_dev
->netdev
,
104 "Failed to get func table, err: %d, status: 0x%x, out size: 0x%x\n",
105 err
, read_data
->status
, out_size
);
110 funcfg_table_elem
= (struct tag_sml_funcfg_tbl
*)read_data
->data
;
114 return funcfg_table_elem
->dw0
.bs
.valid
;
116 return funcfg_table_elem
->dw0
.bs
.nic_rx_mode
;
118 return funcfg_table_elem
->dw1
.bs
.mtu
;
120 return funcfg_table_elem
->dw13
.bs
.cfg_rq_depth
;
122 return funcfg_table_elem
->dw13
.bs
.cfg_q_num
;
130 static ssize_t
hinic_dbg_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
133 struct hinic_debug_priv
*dbg
;
139 desc
= filp
->private_data
;
140 dbg
= container_of(desc
, struct hinic_debug_priv
, field_id
[*desc
]);
143 case HINIC_DBG_SQ_INFO
:
144 out
= hinic_dbg_get_sq_info(dbg
->dev
, dbg
->object
, *desc
);
147 case HINIC_DBG_RQ_INFO
:
148 out
= hinic_dbg_get_rq_info(dbg
->dev
, dbg
->object
, *desc
);
151 case HINIC_DBG_FUNC_TABLE
:
152 out
= hinic_dbg_get_func_table(dbg
->dev
, *desc
);
156 netif_warn(dbg
->dev
, drv
, dbg
->dev
->netdev
, "Invalid hinic debug cmd: %d\n",
161 ret
= snprintf(ret_buf
, sizeof(ret_buf
), "0x%llx\n", out
);
163 return simple_read_from_buffer(buffer
, count
, ppos
, ret_buf
, ret
);
166 static const struct file_operations hinic_dbg_cmd_fops
= {
167 .owner
= THIS_MODULE
,
169 .read
= hinic_dbg_cmd_read
,
172 static int create_dbg_files(struct hinic_dev
*dev
, enum hinic_dbg_type type
, void *data
,
173 struct dentry
*root
, struct hinic_debug_priv
**dbg
, char **field
,
176 struct hinic_debug_priv
*tmp
;
179 tmp
= kzalloc(sizeof(*tmp
), GFP_KERNEL
);
188 for (i
= 0; i
< nfile
; i
++) {
189 tmp
->field_id
[i
] = i
;
190 debugfs_create_file(field
[i
], 0400, root
, &tmp
->field_id
[i
], &hinic_dbg_cmd_fops
);
198 static void rem_dbg_files(struct hinic_debug_priv
*dbg
)
200 if (dbg
->type
!= HINIC_DBG_FUNC_TABLE
)
201 debugfs_remove_recursive(dbg
->root
);
206 int hinic_sq_debug_add(struct hinic_dev
*dev
, u16 sq_id
)
212 sq
= dev
->txqs
[sq_id
].sq
;
214 sprintf(sub_dir
, "0x%x", sq_id
);
216 root
= debugfs_create_dir(sub_dir
, dev
->sq_dbgfs
);
218 return create_dbg_files(dev
, HINIC_DBG_SQ_INFO
, sq
, root
, &sq
->dbg
, sq_fields
,
219 ARRAY_SIZE(sq_fields
));
222 void hinic_sq_debug_rem(struct hinic_sq
*sq
)
225 rem_dbg_files(sq
->dbg
);
228 int hinic_rq_debug_add(struct hinic_dev
*dev
, u16 rq_id
)
234 rq
= dev
->rxqs
[rq_id
].rq
;
236 sprintf(sub_dir
, "0x%x", rq_id
);
238 root
= debugfs_create_dir(sub_dir
, dev
->rq_dbgfs
);
240 return create_dbg_files(dev
, HINIC_DBG_RQ_INFO
, rq
, root
, &rq
->dbg
, rq_fields
,
241 ARRAY_SIZE(rq_fields
));
244 void hinic_rq_debug_rem(struct hinic_rq
*rq
)
247 rem_dbg_files(rq
->dbg
);
250 int hinic_func_table_debug_add(struct hinic_dev
*dev
)
252 if (HINIC_IS_VF(dev
->hwdev
->hwif
))
255 return create_dbg_files(dev
, HINIC_DBG_FUNC_TABLE
, dev
, dev
->func_tbl_dbgfs
, &dev
->dbg
,
256 func_table_fields
, ARRAY_SIZE(func_table_fields
));
259 void hinic_func_table_debug_rem(struct hinic_dev
*dev
)
261 if (!HINIC_IS_VF(dev
->hwdev
->hwif
) && dev
->dbg
)
262 rem_dbg_files(dev
->dbg
);
265 void hinic_sq_dbgfs_init(struct hinic_dev
*nic_dev
)
267 nic_dev
->sq_dbgfs
= debugfs_create_dir("SQs", nic_dev
->dbgfs_root
);
270 void hinic_sq_dbgfs_uninit(struct hinic_dev
*nic_dev
)
272 debugfs_remove_recursive(nic_dev
->sq_dbgfs
);
275 void hinic_rq_dbgfs_init(struct hinic_dev
*nic_dev
)
277 nic_dev
->rq_dbgfs
= debugfs_create_dir("RQs", nic_dev
->dbgfs_root
);
280 void hinic_rq_dbgfs_uninit(struct hinic_dev
*nic_dev
)
282 debugfs_remove_recursive(nic_dev
->rq_dbgfs
);
285 void hinic_func_tbl_dbgfs_init(struct hinic_dev
*nic_dev
)
287 if (!HINIC_IS_VF(nic_dev
->hwdev
->hwif
))
288 nic_dev
->func_tbl_dbgfs
= debugfs_create_dir("func_table", nic_dev
->dbgfs_root
);
291 void hinic_func_tbl_dbgfs_uninit(struct hinic_dev
*nic_dev
)
293 if (!HINIC_IS_VF(nic_dev
->hwdev
->hwif
))
294 debugfs_remove_recursive(nic_dev
->func_tbl_dbgfs
);
297 void hinic_dbg_init(struct hinic_dev
*nic_dev
)
299 nic_dev
->dbgfs_root
= debugfs_create_dir(pci_name(nic_dev
->hwdev
->hwif
->pdev
),
303 void hinic_dbg_uninit(struct hinic_dev
*nic_dev
)
305 debugfs_remove_recursive(nic_dev
->dbgfs_root
);
306 nic_dev
->dbgfs_root
= NULL
;
309 void hinic_dbg_register_debugfs(const char *debugfs_dir_name
)
311 hinic_dbgfs_root
= debugfs_create_dir(debugfs_dir_name
, NULL
);
314 void hinic_dbg_unregister_debugfs(void)
316 debugfs_remove_recursive(hinic_dbgfs_root
);
317 hinic_dbgfs_root
= NULL
;