Commit 1556ea91 authored by Huazhong Tan's avatar Huazhong Tan Committed by David S. Miller

net: hns3: refactor dump mac list of debugfs

Currently, the debugfs command for mac list info is implemented
by "echo xxxx > cmd", and record the information in dmesg. It's
unnecessary and heavy. To improve it, create two files "uc" and
"mc" under directory "mac_list" for it, and query mac list info
by "cat mac_list/uc" and "mac_list/mc", return the result to
userspace, rather than record in dmesg.

The display style is below:
$ cat mac_list/uc
UC MAC_LIST:
FUNC_ID  MAC_ADDR            STATE
pf       00:18:2d:00:00:71   ACTIVE

$ cat mac_list/mc
MC MAC_LIST:
FUNC_ID  MAC_ADDR            STATE
pf       01:80:c2:00:00:21   ACTIVE
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 77e91848
...@@ -257,6 +257,8 @@ enum hnae3_dbg_cmd { ...@@ -257,6 +257,8 @@ enum hnae3_dbg_cmd {
HNAE3_DBG_CMD_DEV_INFO, HNAE3_DBG_CMD_DEV_INFO,
HNAE3_DBG_CMD_TX_BD, HNAE3_DBG_CMD_TX_BD,
HNAE3_DBG_CMD_RX_BD, HNAE3_DBG_CMD_RX_BD,
HNAE3_DBG_CMD_MAC_UC,
HNAE3_DBG_CMD_MAC_MC,
HNAE3_DBG_CMD_UNKNOWN, HNAE3_DBG_CMD_UNKNOWN,
}; };
......
...@@ -20,6 +20,9 @@ static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = { ...@@ -20,6 +20,9 @@ static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = {
{ {
.name = "rx_bd_info" .name = "rx_bd_info"
}, },
{
.name = "mac_list"
},
/* keep common at the bottom and add new directory above */ /* keep common at the bottom and add new directory above */
{ {
.name = "common" .name = "common"
...@@ -73,6 +76,20 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { ...@@ -73,6 +76,20 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
.buf_len = HNS3_DBG_READ_LEN_4MB, .buf_len = HNS3_DBG_READ_LEN_4MB,
.init = hns3_dbg_bd_file_init, .init = hns3_dbg_bd_file_init,
}, },
{
.name = "uc",
.cmd = HNAE3_DBG_CMD_MAC_UC,
.dentry = HNS3_DBG_DENTRY_MAC,
.buf_len = HNS3_DBG_READ_LEN,
.init = hns3_dbg_common_file_init,
},
{
.name = "mc",
.cmd = HNAE3_DBG_CMD_MAC_MC,
.dentry = HNS3_DBG_DENTRY_MAC,
.buf_len = HNS3_DBG_READ_LEN,
.init = hns3_dbg_common_file_init,
},
}; };
static struct hns3_dbg_cap_info hns3_dbg_cap[] = { static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
...@@ -474,8 +491,6 @@ static void hns3_dbg_help(struct hnae3_handle *h) ...@@ -474,8 +491,6 @@ static void hns3_dbg_help(struct hnae3_handle *h)
dev_info(&h->pdev->dev, "dump mac tnl status\n"); dev_info(&h->pdev->dev, "dump mac tnl status\n");
dev_info(&h->pdev->dev, "dump loopback\n"); dev_info(&h->pdev->dev, "dump loopback\n");
dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n");
dev_info(&h->pdev->dev, "dump uc mac list <func id>\n");
dev_info(&h->pdev->dev, "dump mc mac list <func id>\n");
dev_info(&h->pdev->dev, "dump intr\n"); dev_info(&h->pdev->dev, "dump intr\n");
memset(printf_buf, 0, HNS3_DBG_BUF_LEN); memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
......
...@@ -27,6 +27,7 @@ enum hns3_dbg_dentry_type { ...@@ -27,6 +27,7 @@ enum hns3_dbg_dentry_type {
HNS3_DBG_DENTRY_TM, HNS3_DBG_DENTRY_TM,
HNS3_DBG_DENTRY_TX_BD, HNS3_DBG_DENTRY_TX_BD,
HNS3_DBG_DENTRY_RX_BD, HNS3_DBG_DENTRY_RX_BD,
HNS3_DBG_DENTRY_MAC,
HNS3_DBG_DENTRY_COMMON, HNS3_DBG_DENTRY_COMMON,
}; };
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include "hclge_tm.h" #include "hclge_tm.h"
#include "hnae3.h" #include "hnae3.h"
static const char * const hclge_mac_state_str[] = {
"TO_ADD", "TO_DEL", "ACTIVE"
};
static const struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = { static const struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = {
{ .reg_type = "bios common", { .reg_type = "bios common",
.dfx_msg = &hclge_dbg_bios_common_reg[0], .dfx_msg = &hclge_dbg_bios_common_reg[0],
...@@ -71,6 +75,35 @@ static const struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = { ...@@ -71,6 +75,35 @@ static const struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = {
.cmd = HCLGE_OPC_DFX_TQP_REG } }, .cmd = HCLGE_OPC_DFX_TQP_REG } },
}; };
static void hclge_dbg_fill_content(char *content, u16 len,
const struct hclge_dbg_item *items,
const char **result, u16 size)
{
char *pos = content;
u16 i;
memset(content, ' ', len);
for (i = 0; i < size; i++) {
if (result)
strncpy(pos, result[i], strlen(result[i]));
else
strncpy(pos, items[i].name, strlen(items[i].name));
pos += strlen(items[i].name) + items[i].interval;
}
*pos++ = '\n';
*pos++ = '\0';
}
static char *hclge_dbg_get_func_id_str(char *buf, u8 id)
{
if (id)
sprintf(buf, "vf%u", id - 1);
else
sprintf(buf, "pf");
return buf;
}
static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset) static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset)
{ {
struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT]; struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT];
...@@ -1693,45 +1726,65 @@ static void hclge_dbg_dump_qs_shaper(struct hclge_dev *hdev, ...@@ -1693,45 +1726,65 @@ static void hclge_dbg_dump_qs_shaper(struct hclge_dev *hdev,
hclge_dbg_dump_qs_shaper_single(hdev, qsid); hclge_dbg_dump_qs_shaper_single(hdev, qsid);
} }
static int hclge_dbg_dump_mac_list(struct hclge_dev *hdev, const char *cmd_buf, static const struct hclge_dbg_item mac_list_items[] = {
{ "FUNC_ID", 2 },
{ "MAC_ADDR", 12 },
{ "STATE", 2 },
};
static void hclge_dbg_dump_mac_list(struct hclge_dev *hdev, char *buf, int len,
bool is_unicast) bool is_unicast)
{ {
char data_str[ARRAY_SIZE(mac_list_items)][HCLGE_DBG_DATA_STR_LEN];
char content[HCLGE_DBG_INFO_LEN], str_id[HCLGE_DBG_ID_LEN];
char *result[ARRAY_SIZE(mac_list_items)];
struct hclge_mac_node *mac_node, *tmp; struct hclge_mac_node *mac_node, *tmp;
struct hclge_vport *vport; struct hclge_vport *vport;
struct list_head *list; struct list_head *list;
u32 func_id; u32 func_id;
int ret; int pos = 0;
int i;
ret = kstrtouint(cmd_buf, 0, &func_id); for (i = 0; i < ARRAY_SIZE(mac_list_items); i++)
if (ret < 0) { result[i] = &data_str[i][0];
dev_err(&hdev->pdev->dev,
"dump mac list: bad command string, ret = %d\n", ret);
return -EINVAL;
}
if (func_id >= hdev->num_alloc_vport) { pos += scnprintf(buf + pos, len - pos, "%s MAC_LIST:\n",
dev_err(&hdev->pdev->dev, is_unicast ? "UC" : "MC");
"function id(%u) is out of range(0-%u)\n", func_id, hclge_dbg_fill_content(content, sizeof(content), mac_list_items,
hdev->num_alloc_vport - 1); NULL, ARRAY_SIZE(mac_list_items));
return -EINVAL; pos += scnprintf(buf + pos, len - pos, "%s", content);
}
for (func_id = 0; func_id < hdev->num_alloc_vport; func_id++) {
vport = &hdev->vport[func_id]; vport = &hdev->vport[func_id];
list = is_unicast ? &vport->uc_mac_list : &vport->mc_mac_list; list = is_unicast ? &vport->uc_mac_list : &vport->mc_mac_list;
dev_info(&hdev->pdev->dev, "vport %u %s mac list:\n",
func_id, is_unicast ? "uc" : "mc");
dev_info(&hdev->pdev->dev, "mac address state\n");
spin_lock_bh(&vport->mac_list_lock); spin_lock_bh(&vport->mac_list_lock);
list_for_each_entry_safe(mac_node, tmp, list, node) { list_for_each_entry_safe(mac_node, tmp, list, node) {
dev_info(&hdev->pdev->dev, "%pM %d\n", i = 0;
mac_node->mac_addr, mac_node->state); result[i++] = hclge_dbg_get_func_id_str(str_id,
func_id);
sprintf(result[i++], "%pM", mac_node->mac_addr);
sprintf(result[i++], "%5s",
hclge_mac_state_str[mac_node->state]);
hclge_dbg_fill_content(content, sizeof(content),
mac_list_items,
(const char **)result,
ARRAY_SIZE(mac_list_items));
pos += scnprintf(buf + pos, len - pos, "%s", content);
} }
spin_unlock_bh(&vport->mac_list_lock); spin_unlock_bh(&vport->mac_list_lock);
}
}
static int hclge_dbg_dump_mac_uc(struct hclge_dev *hdev, char *buf, int len)
{
hclge_dbg_dump_mac_list(hdev, buf, len, true);
return 0;
}
static int hclge_dbg_dump_mac_mc(struct hclge_dev *hdev, char *buf, int len)
{
hclge_dbg_dump_mac_list(hdev, buf, len, false);
return 0; return 0;
} }
...@@ -1781,14 +1834,6 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) ...@@ -1781,14 +1834,6 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
} else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) { } else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) {
hclge_dbg_dump_qs_shaper(hdev, hclge_dbg_dump_qs_shaper(hdev,
&cmd_buf[sizeof("dump qs shaper")]); &cmd_buf[sizeof("dump qs shaper")]);
} else if (strncmp(cmd_buf, "dump uc mac list", 16) == 0) {
hclge_dbg_dump_mac_list(hdev,
&cmd_buf[sizeof("dump uc mac list")],
true);
} else if (strncmp(cmd_buf, "dump mc mac list", 16) == 0) {
hclge_dbg_dump_mac_list(hdev,
&cmd_buf[sizeof("dump mc mac list")],
false);
} else if (strncmp(cmd_buf, DUMP_INTERRUPT, } else if (strncmp(cmd_buf, DUMP_INTERRUPT,
strlen(DUMP_INTERRUPT)) == 0) { strlen(DUMP_INTERRUPT)) == 0) {
hclge_dbg_dump_interrupt(hdev); hclge_dbg_dump_interrupt(hdev);
...@@ -1813,6 +1858,14 @@ static const struct hclge_dbg_func hclge_dbg_cmd_func[] = { ...@@ -1813,6 +1858,14 @@ static const struct hclge_dbg_func hclge_dbg_cmd_func[] = {
.cmd = HNAE3_DBG_CMD_TM_QSET, .cmd = HNAE3_DBG_CMD_TM_QSET,
.dbg_dump = hclge_dbg_dump_tm_qset, .dbg_dump = hclge_dbg_dump_tm_qset,
}, },
{
.cmd = HNAE3_DBG_CMD_MAC_UC,
.dbg_dump = hclge_dbg_dump_mac_uc,
},
{
.cmd = HNAE3_DBG_CMD_MAC_MC,
.dbg_dump = hclge_dbg_dump_mac_mc,
},
}; };
int hclge_dbg_read_cmd(struct hnae3_handle *handle, enum hnae3_dbg_cmd cmd, int hclge_dbg_read_cmd(struct hnae3_handle *handle, enum hnae3_dbg_cmd cmd,
......
...@@ -728,4 +728,13 @@ static const struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = { ...@@ -728,4 +728,13 @@ static const struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = {
{true, "RCB_CFG_TX_RING_EBDNUM"}, {true, "RCB_CFG_TX_RING_EBDNUM"},
}; };
#define HCLGE_DBG_INFO_LEN 256
#define HCLGE_DBG_ID_LEN 16
#define HCLGE_DBG_ITEM_NAME_LEN 32
#define HCLGE_DBG_DATA_STR_LEN 32
struct hclge_dbg_item {
char name[HCLGE_DBG_ITEM_NAME_LEN];
u16 interval; /* blank numbers after the item */
};
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment