Loading drivers/net/ethernet/huawei/hinic/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -4,4 +4,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ hinic_hw_io.o hinic_hw_qp.o hinic_hw_cmdq.o hinic_hw_wq.o \ hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o \ hinic_common.o hinic_ethtool.o hinic_devlink.o hinic_hw_mbox.o hinic_sriov.o hinic_common.o hinic_ethtool.o hinic_devlink.o hinic_hw_mbox.o \ hinic_sriov.o hinic_debugfs.o drivers/net/ethernet/huawei/hinic/hinic_debugfs.c 0 → 100644 +318 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #include <linux/debugfs.h> #include <linux/device.h> #include "hinic_debugfs.h" static struct dentry *hinic_dbgfs_root; enum sq_dbg_info { GLB_SQ_ID, SQ_PI, SQ_CI, SQ_FI, SQ_MSIX_ENTRY, }; static char *sq_fields[] = {"glb_sq_id", "sq_pi", "sq_ci", "sq_fi", "sq_msix_entry"}; static u64 hinic_dbg_get_sq_info(struct hinic_dev *nic_dev, struct hinic_sq *sq, int idx) { struct hinic_wq *wq = sq->wq; switch (idx) { case GLB_SQ_ID: return nic_dev->hwdev->func_to_io.global_qpn + sq->qid; case SQ_PI: return atomic_read(&wq->prod_idx) & wq->mask; case SQ_CI: return atomic_read(&wq->cons_idx) & wq->mask; case SQ_FI: return be16_to_cpu(*(__be16 *)(sq->hw_ci_addr)) & wq->mask; case SQ_MSIX_ENTRY: return sq->msix_entry; } return 0; } enum rq_dbg_info { GLB_RQ_ID, RQ_HW_PI, RQ_SW_CI, RQ_SW_PI, RQ_MSIX_ENTRY, }; static char *rq_fields[] = {"glb_rq_id", "rq_hw_pi", "rq_sw_ci", "rq_sw_pi", "rq_msix_entry"}; static u64 hinic_dbg_get_rq_info(struct hinic_dev *nic_dev, struct hinic_rq *rq, int idx) { struct hinic_wq *wq = rq->wq; switch (idx) { case GLB_RQ_ID: return nic_dev->hwdev->func_to_io.global_qpn + rq->qid; case RQ_HW_PI: return be16_to_cpu(*(__be16 *)(rq->pi_virt_addr)) & wq->mask; case RQ_SW_CI: return atomic_read(&wq->cons_idx) & wq->mask; case RQ_SW_PI: return atomic_read(&wq->prod_idx) & wq->mask; case RQ_MSIX_ENTRY: return rq->msix_entry; } return 0; } enum func_tbl_info { VALID, RX_MODE, MTU, RQ_DEPTH, QUEUE_NUM, }; static char *func_table_fields[] = {"valid", "rx_mode", "mtu", "rq_depth", "cfg_q_num"}; static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx) { struct tag_sml_funcfg_tbl *funcfg_table_elem; struct hinic_cmd_lt_rd *read_data; u16 out_size = sizeof(*read_data); int err; read_data = kzalloc(sizeof(*read_data), GFP_KERNEL); if (!read_data) return ~0; read_data->node = TBL_ID_FUNC_CFG_SM_NODE; read_data->inst = TBL_ID_FUNC_CFG_SM_INST; read_data->entry_size = HINIC_FUNCTION_CONFIGURE_TABLE_SIZE; read_data->lt_index = HINIC_HWIF_FUNC_IDX(nic_dev->hwdev->hwif); read_data->len = HINIC_FUNCTION_CONFIGURE_TABLE_SIZE; err = hinic_port_msg_cmd(nic_dev->hwdev, HINIC_PORT_CMD_RD_LINE_TBL, read_data, sizeof(*read_data), read_data, &out_size); if (err || out_size != sizeof(*read_data) || read_data->status) { netif_err(nic_dev, drv, nic_dev->netdev, "Failed to get func table, err: %d, status: 0x%x, out size: 0x%x\n", err, read_data->status, out_size); kfree(read_data); return ~0; } funcfg_table_elem = (struct tag_sml_funcfg_tbl *)read_data->data; switch (idx) { case VALID: return funcfg_table_elem->dw0.bs.valid; case RX_MODE: return funcfg_table_elem->dw0.bs.nic_rx_mode; case MTU: return funcfg_table_elem->dw1.bs.mtu; case RQ_DEPTH: return funcfg_table_elem->dw13.bs.cfg_rq_depth; case QUEUE_NUM: return funcfg_table_elem->dw13.bs.cfg_q_num; } kfree(read_data); return ~0; } static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { struct hinic_debug_priv *dbg; char ret_buf[20]; int *desc; u64 out; int ret; desc = filp->private_data; dbg = container_of(desc, struct hinic_debug_priv, field_id[*desc]); switch (dbg->type) { case HINIC_DBG_SQ_INFO: out = hinic_dbg_get_sq_info(dbg->dev, dbg->object, *desc); break; case HINIC_DBG_RQ_INFO: out = hinic_dbg_get_rq_info(dbg->dev, dbg->object, *desc); break; case HINIC_DBG_FUNC_TABLE: out = hinic_dbg_get_func_table(dbg->dev, *desc); break; default: netif_warn(dbg->dev, drv, dbg->dev->netdev, "Invalid hinic debug cmd: %d\n", dbg->type); return -EINVAL; } ret = snprintf(ret_buf, sizeof(ret_buf), "0x%llx\n", out); return simple_read_from_buffer(buffer, count, ppos, ret_buf, ret); } static const struct file_operations hinic_dbg_cmd_fops = { .owner = THIS_MODULE, .open = simple_open, .read = hinic_dbg_cmd_read, }; static int create_dbg_files(struct hinic_dev *dev, enum hinic_dbg_type type, void *data, struct dentry *root, struct hinic_debug_priv **dbg, char **field, int nfile) { struct hinic_debug_priv *tmp; int i; tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); if (!tmp) return -ENOMEM; tmp->dev = dev; tmp->object = data; tmp->type = type; tmp->root = root; for (i = 0; i < nfile; i++) { tmp->field_id[i] = i; debugfs_create_file(field[i], 0400, root, &tmp->field_id[i], &hinic_dbg_cmd_fops); } *dbg = tmp; return 0; } static void rem_dbg_files(struct hinic_debug_priv *dbg) { if (dbg->type != HINIC_DBG_FUNC_TABLE) debugfs_remove_recursive(dbg->root); kfree(dbg); } int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id) { struct hinic_sq *sq; struct dentry *root; char sub_dir[16]; sq = dev->txqs[sq_id].sq; sprintf(sub_dir, "0x%x", sq_id); root = debugfs_create_dir(sub_dir, dev->sq_dbgfs); return create_dbg_files(dev, HINIC_DBG_SQ_INFO, sq, root, &sq->dbg, sq_fields, ARRAY_SIZE(sq_fields)); } void hinic_sq_debug_rem(struct hinic_sq *sq) { if (sq->dbg) rem_dbg_files(sq->dbg); } int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id) { struct hinic_rq *rq; struct dentry *root; char sub_dir[16]; rq = dev->rxqs[rq_id].rq; sprintf(sub_dir, "0x%x", rq_id); root = debugfs_create_dir(sub_dir, dev->rq_dbgfs); return create_dbg_files(dev, HINIC_DBG_RQ_INFO, rq, root, &rq->dbg, rq_fields, ARRAY_SIZE(rq_fields)); } void hinic_rq_debug_rem(struct hinic_rq *rq) { if (rq->dbg) rem_dbg_files(rq->dbg); } int hinic_func_table_debug_add(struct hinic_dev *dev) { if (HINIC_IS_VF(dev->hwdev->hwif)) return 0; return create_dbg_files(dev, HINIC_DBG_FUNC_TABLE, dev, dev->func_tbl_dbgfs, &dev->dbg, func_table_fields, ARRAY_SIZE(func_table_fields)); } void hinic_func_table_debug_rem(struct hinic_dev *dev) { if (!HINIC_IS_VF(dev->hwdev->hwif) && dev->dbg) rem_dbg_files(dev->dbg); } void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev) { nic_dev->sq_dbgfs = debugfs_create_dir("SQs", nic_dev->dbgfs_root); } void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->sq_dbgfs); } void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev) { nic_dev->rq_dbgfs = debugfs_create_dir("RQs", nic_dev->dbgfs_root); } void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->rq_dbgfs); } void hinic_func_tbl_dbgfs_init(struct hinic_dev *nic_dev) { if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) nic_dev->func_tbl_dbgfs = debugfs_create_dir("func_table", nic_dev->dbgfs_root); } void hinic_func_tbl_dbgfs_uninit(struct hinic_dev *nic_dev) { if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) debugfs_remove_recursive(nic_dev->func_tbl_dbgfs); } void hinic_dbg_init(struct hinic_dev *nic_dev) { nic_dev->dbgfs_root = debugfs_create_dir(pci_name(nic_dev->hwdev->hwif->pdev), hinic_dbgfs_root); } void hinic_dbg_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->dbgfs_root); nic_dev->dbgfs_root = NULL; } void hinic_dbg_register_debugfs(const char *debugfs_dir_name) { hinic_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); } void hinic_dbg_unregister_debugfs(void) { debugfs_remove_recursive(hinic_dbgfs_root); hinic_dbgfs_root = NULL; } drivers/net/ethernet/huawei/hinic/hinic_debugfs.h 0 → 100644 +114 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #ifndef HINIC_DEBUGFS_H #define HINIC_DEBUGFS_H #include "hinic_dev.h" #define TBL_ID_FUNC_CFG_SM_NODE 11 #define TBL_ID_FUNC_CFG_SM_INST 1 #define HINIC_FUNCTION_CONFIGURE_TABLE_SIZE 64 #define HINIC_FUNCTION_CONFIGURE_TABLE 1 struct hinic_cmd_lt_rd { u8 status; u8 version; u8 rsvd0[6]; unsigned char node; unsigned char inst; unsigned char entry_size; unsigned char rsvd; unsigned int lt_index; unsigned int offset; unsigned int len; unsigned char data[100]; }; struct tag_sml_funcfg_tbl { union { struct { u32 rsvd0 :8; u32 nic_rx_mode :5; u32 rsvd1 :18; u32 valid :1; } bs; u32 value; } dw0; union { struct { u32 vlan_id :12; u32 vlan_mode :3; u32 fast_recycled_mode :1; u32 mtu :16; } bs; u32 value; } dw1; u32 dw2; u32 dw3; u32 dw4; u32 dw5; u32 dw6; u32 dw7; u32 dw8; u32 dw9; u32 dw10; u32 dw11; u32 dw12; union { struct { u32 rsvd2 :15; u32 cfg_q_num :9; u32 cfg_rq_depth :6; u32 vhd_type :2; } bs; u32 value; } dw13; u32 dw14; u32 dw15; }; int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id); void hinic_sq_debug_rem(struct hinic_sq *sq); int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id); void hinic_rq_debug_rem(struct hinic_rq *rq); int hinic_func_table_debug_add(struct hinic_dev *dev); void hinic_func_table_debug_rem(struct hinic_dev *dev); void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev); void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev); void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_func_tbl_dbgfs_init(struct hinic_dev *nic_dev); void hinic_func_tbl_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_dbg_init(struct hinic_dev *nic_dev); void hinic_dbg_uninit(struct hinic_dev *nic_dev); void hinic_dbg_register_debugfs(const char *debugfs_dir_name); void hinic_dbg_unregister_debugfs(void); #endif drivers/net/ethernet/huawei/hinic/hinic_dev.h +20 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,20 @@ struct hinic_intr_coal_info { u8 resend_timer_cfg; }; enum hinic_dbg_type { HINIC_DBG_SQ_INFO, HINIC_DBG_RQ_INFO, HINIC_DBG_FUNC_TABLE, }; struct hinic_debug_priv { struct hinic_dev *dev; void *object; enum hinic_dbg_type type; struct dentry *root; int field_id[64]; }; struct hinic_dev { struct net_device *netdev; struct hinic_hwdev *hwdev; Loading Loading @@ -97,6 +111,12 @@ struct hinic_dev { int lb_test_rx_idx; int lb_pkt_len; u8 *lb_test_rx_buf; struct dentry *dbgfs_root; struct dentry *sq_dbgfs; struct dentry *rq_dbgfs; struct dentry *func_tbl_dbgfs; struct hinic_debug_priv *dbg; struct devlink *devlink; bool cable_unplugged; bool module_unrecognized; Loading drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +1 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth) func_to_io->hwdev = hwdev; func_to_io->sq_depth = sq_depth; func_to_io->rq_depth = rq_depth; func_to_io->global_qpn = base_qpn; err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, ceq_msix_entries); Loading Loading
drivers/net/ethernet/huawei/hinic/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -4,4 +4,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ hinic_hw_io.o hinic_hw_qp.o hinic_hw_cmdq.o hinic_hw_wq.o \ hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o \ hinic_common.o hinic_ethtool.o hinic_devlink.o hinic_hw_mbox.o hinic_sriov.o hinic_common.o hinic_ethtool.o hinic_devlink.o hinic_hw_mbox.o \ hinic_sriov.o hinic_debugfs.o
drivers/net/ethernet/huawei/hinic/hinic_debugfs.c 0 → 100644 +318 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #include <linux/debugfs.h> #include <linux/device.h> #include "hinic_debugfs.h" static struct dentry *hinic_dbgfs_root; enum sq_dbg_info { GLB_SQ_ID, SQ_PI, SQ_CI, SQ_FI, SQ_MSIX_ENTRY, }; static char *sq_fields[] = {"glb_sq_id", "sq_pi", "sq_ci", "sq_fi", "sq_msix_entry"}; static u64 hinic_dbg_get_sq_info(struct hinic_dev *nic_dev, struct hinic_sq *sq, int idx) { struct hinic_wq *wq = sq->wq; switch (idx) { case GLB_SQ_ID: return nic_dev->hwdev->func_to_io.global_qpn + sq->qid; case SQ_PI: return atomic_read(&wq->prod_idx) & wq->mask; case SQ_CI: return atomic_read(&wq->cons_idx) & wq->mask; case SQ_FI: return be16_to_cpu(*(__be16 *)(sq->hw_ci_addr)) & wq->mask; case SQ_MSIX_ENTRY: return sq->msix_entry; } return 0; } enum rq_dbg_info { GLB_RQ_ID, RQ_HW_PI, RQ_SW_CI, RQ_SW_PI, RQ_MSIX_ENTRY, }; static char *rq_fields[] = {"glb_rq_id", "rq_hw_pi", "rq_sw_ci", "rq_sw_pi", "rq_msix_entry"}; static u64 hinic_dbg_get_rq_info(struct hinic_dev *nic_dev, struct hinic_rq *rq, int idx) { struct hinic_wq *wq = rq->wq; switch (idx) { case GLB_RQ_ID: return nic_dev->hwdev->func_to_io.global_qpn + rq->qid; case RQ_HW_PI: return be16_to_cpu(*(__be16 *)(rq->pi_virt_addr)) & wq->mask; case RQ_SW_CI: return atomic_read(&wq->cons_idx) & wq->mask; case RQ_SW_PI: return atomic_read(&wq->prod_idx) & wq->mask; case RQ_MSIX_ENTRY: return rq->msix_entry; } return 0; } enum func_tbl_info { VALID, RX_MODE, MTU, RQ_DEPTH, QUEUE_NUM, }; static char *func_table_fields[] = {"valid", "rx_mode", "mtu", "rq_depth", "cfg_q_num"}; static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx) { struct tag_sml_funcfg_tbl *funcfg_table_elem; struct hinic_cmd_lt_rd *read_data; u16 out_size = sizeof(*read_data); int err; read_data = kzalloc(sizeof(*read_data), GFP_KERNEL); if (!read_data) return ~0; read_data->node = TBL_ID_FUNC_CFG_SM_NODE; read_data->inst = TBL_ID_FUNC_CFG_SM_INST; read_data->entry_size = HINIC_FUNCTION_CONFIGURE_TABLE_SIZE; read_data->lt_index = HINIC_HWIF_FUNC_IDX(nic_dev->hwdev->hwif); read_data->len = HINIC_FUNCTION_CONFIGURE_TABLE_SIZE; err = hinic_port_msg_cmd(nic_dev->hwdev, HINIC_PORT_CMD_RD_LINE_TBL, read_data, sizeof(*read_data), read_data, &out_size); if (err || out_size != sizeof(*read_data) || read_data->status) { netif_err(nic_dev, drv, nic_dev->netdev, "Failed to get func table, err: %d, status: 0x%x, out size: 0x%x\n", err, read_data->status, out_size); kfree(read_data); return ~0; } funcfg_table_elem = (struct tag_sml_funcfg_tbl *)read_data->data; switch (idx) { case VALID: return funcfg_table_elem->dw0.bs.valid; case RX_MODE: return funcfg_table_elem->dw0.bs.nic_rx_mode; case MTU: return funcfg_table_elem->dw1.bs.mtu; case RQ_DEPTH: return funcfg_table_elem->dw13.bs.cfg_rq_depth; case QUEUE_NUM: return funcfg_table_elem->dw13.bs.cfg_q_num; } kfree(read_data); return ~0; } static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { struct hinic_debug_priv *dbg; char ret_buf[20]; int *desc; u64 out; int ret; desc = filp->private_data; dbg = container_of(desc, struct hinic_debug_priv, field_id[*desc]); switch (dbg->type) { case HINIC_DBG_SQ_INFO: out = hinic_dbg_get_sq_info(dbg->dev, dbg->object, *desc); break; case HINIC_DBG_RQ_INFO: out = hinic_dbg_get_rq_info(dbg->dev, dbg->object, *desc); break; case HINIC_DBG_FUNC_TABLE: out = hinic_dbg_get_func_table(dbg->dev, *desc); break; default: netif_warn(dbg->dev, drv, dbg->dev->netdev, "Invalid hinic debug cmd: %d\n", dbg->type); return -EINVAL; } ret = snprintf(ret_buf, sizeof(ret_buf), "0x%llx\n", out); return simple_read_from_buffer(buffer, count, ppos, ret_buf, ret); } static const struct file_operations hinic_dbg_cmd_fops = { .owner = THIS_MODULE, .open = simple_open, .read = hinic_dbg_cmd_read, }; static int create_dbg_files(struct hinic_dev *dev, enum hinic_dbg_type type, void *data, struct dentry *root, struct hinic_debug_priv **dbg, char **field, int nfile) { struct hinic_debug_priv *tmp; int i; tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); if (!tmp) return -ENOMEM; tmp->dev = dev; tmp->object = data; tmp->type = type; tmp->root = root; for (i = 0; i < nfile; i++) { tmp->field_id[i] = i; debugfs_create_file(field[i], 0400, root, &tmp->field_id[i], &hinic_dbg_cmd_fops); } *dbg = tmp; return 0; } static void rem_dbg_files(struct hinic_debug_priv *dbg) { if (dbg->type != HINIC_DBG_FUNC_TABLE) debugfs_remove_recursive(dbg->root); kfree(dbg); } int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id) { struct hinic_sq *sq; struct dentry *root; char sub_dir[16]; sq = dev->txqs[sq_id].sq; sprintf(sub_dir, "0x%x", sq_id); root = debugfs_create_dir(sub_dir, dev->sq_dbgfs); return create_dbg_files(dev, HINIC_DBG_SQ_INFO, sq, root, &sq->dbg, sq_fields, ARRAY_SIZE(sq_fields)); } void hinic_sq_debug_rem(struct hinic_sq *sq) { if (sq->dbg) rem_dbg_files(sq->dbg); } int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id) { struct hinic_rq *rq; struct dentry *root; char sub_dir[16]; rq = dev->rxqs[rq_id].rq; sprintf(sub_dir, "0x%x", rq_id); root = debugfs_create_dir(sub_dir, dev->rq_dbgfs); return create_dbg_files(dev, HINIC_DBG_RQ_INFO, rq, root, &rq->dbg, rq_fields, ARRAY_SIZE(rq_fields)); } void hinic_rq_debug_rem(struct hinic_rq *rq) { if (rq->dbg) rem_dbg_files(rq->dbg); } int hinic_func_table_debug_add(struct hinic_dev *dev) { if (HINIC_IS_VF(dev->hwdev->hwif)) return 0; return create_dbg_files(dev, HINIC_DBG_FUNC_TABLE, dev, dev->func_tbl_dbgfs, &dev->dbg, func_table_fields, ARRAY_SIZE(func_table_fields)); } void hinic_func_table_debug_rem(struct hinic_dev *dev) { if (!HINIC_IS_VF(dev->hwdev->hwif) && dev->dbg) rem_dbg_files(dev->dbg); } void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev) { nic_dev->sq_dbgfs = debugfs_create_dir("SQs", nic_dev->dbgfs_root); } void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->sq_dbgfs); } void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev) { nic_dev->rq_dbgfs = debugfs_create_dir("RQs", nic_dev->dbgfs_root); } void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->rq_dbgfs); } void hinic_func_tbl_dbgfs_init(struct hinic_dev *nic_dev) { if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) nic_dev->func_tbl_dbgfs = debugfs_create_dir("func_table", nic_dev->dbgfs_root); } void hinic_func_tbl_dbgfs_uninit(struct hinic_dev *nic_dev) { if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) debugfs_remove_recursive(nic_dev->func_tbl_dbgfs); } void hinic_dbg_init(struct hinic_dev *nic_dev) { nic_dev->dbgfs_root = debugfs_create_dir(pci_name(nic_dev->hwdev->hwif->pdev), hinic_dbgfs_root); } void hinic_dbg_uninit(struct hinic_dev *nic_dev) { debugfs_remove_recursive(nic_dev->dbgfs_root); nic_dev->dbgfs_root = NULL; } void hinic_dbg_register_debugfs(const char *debugfs_dir_name) { hinic_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL); } void hinic_dbg_unregister_debugfs(void) { debugfs_remove_recursive(hinic_dbgfs_root); hinic_dbgfs_root = NULL; }
drivers/net/ethernet/huawei/hinic/hinic_debugfs.h 0 → 100644 +114 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #ifndef HINIC_DEBUGFS_H #define HINIC_DEBUGFS_H #include "hinic_dev.h" #define TBL_ID_FUNC_CFG_SM_NODE 11 #define TBL_ID_FUNC_CFG_SM_INST 1 #define HINIC_FUNCTION_CONFIGURE_TABLE_SIZE 64 #define HINIC_FUNCTION_CONFIGURE_TABLE 1 struct hinic_cmd_lt_rd { u8 status; u8 version; u8 rsvd0[6]; unsigned char node; unsigned char inst; unsigned char entry_size; unsigned char rsvd; unsigned int lt_index; unsigned int offset; unsigned int len; unsigned char data[100]; }; struct tag_sml_funcfg_tbl { union { struct { u32 rsvd0 :8; u32 nic_rx_mode :5; u32 rsvd1 :18; u32 valid :1; } bs; u32 value; } dw0; union { struct { u32 vlan_id :12; u32 vlan_mode :3; u32 fast_recycled_mode :1; u32 mtu :16; } bs; u32 value; } dw1; u32 dw2; u32 dw3; u32 dw4; u32 dw5; u32 dw6; u32 dw7; u32 dw8; u32 dw9; u32 dw10; u32 dw11; u32 dw12; union { struct { u32 rsvd2 :15; u32 cfg_q_num :9; u32 cfg_rq_depth :6; u32 vhd_type :2; } bs; u32 value; } dw13; u32 dw14; u32 dw15; }; int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id); void hinic_sq_debug_rem(struct hinic_sq *sq); int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id); void hinic_rq_debug_rem(struct hinic_rq *rq); int hinic_func_table_debug_add(struct hinic_dev *dev); void hinic_func_table_debug_rem(struct hinic_dev *dev); void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev); void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev); void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_func_tbl_dbgfs_init(struct hinic_dev *nic_dev); void hinic_func_tbl_dbgfs_uninit(struct hinic_dev *nic_dev); void hinic_dbg_init(struct hinic_dev *nic_dev); void hinic_dbg_uninit(struct hinic_dev *nic_dev); void hinic_dbg_register_debugfs(const char *debugfs_dir_name); void hinic_dbg_unregister_debugfs(void); #endif
drivers/net/ethernet/huawei/hinic/hinic_dev.h +20 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,20 @@ struct hinic_intr_coal_info { u8 resend_timer_cfg; }; enum hinic_dbg_type { HINIC_DBG_SQ_INFO, HINIC_DBG_RQ_INFO, HINIC_DBG_FUNC_TABLE, }; struct hinic_debug_priv { struct hinic_dev *dev; void *object; enum hinic_dbg_type type; struct dentry *root; int field_id[64]; }; struct hinic_dev { struct net_device *netdev; struct hinic_hwdev *hwdev; Loading Loading @@ -97,6 +111,12 @@ struct hinic_dev { int lb_test_rx_idx; int lb_pkt_len; u8 *lb_test_rx_buf; struct dentry *dbgfs_root; struct dentry *sq_dbgfs; struct dentry *rq_dbgfs; struct dentry *func_tbl_dbgfs; struct hinic_debug_priv *dbg; struct devlink *devlink; bool cable_unplugged; bool module_unrecognized; Loading
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +1 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth) func_to_io->hwdev = hwdev; func_to_io->sq_depth = sq_depth; func_to_io->rq_depth = rq_depth; func_to_io->global_qpn = base_qpn; err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, ceq_msix_entries); Loading