net: hns3: add support for get_regs
This patch adds get_regs support for ethtool cmd. Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b2d3bcfa26
commit
77b3411011
|
@ -356,7 +356,8 @@ struct hnae3_ae_ops {
|
||||||
u32 stringset, u8 *data);
|
u32 stringset, u8 *data);
|
||||||
int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
|
int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
|
||||||
|
|
||||||
void (*get_regs)(struct hnae3_handle *handle, void *data);
|
void (*get_regs)(struct hnae3_handle *handle, u32 *version,
|
||||||
|
void *data);
|
||||||
int (*get_regs_len)(struct hnae3_handle *handle);
|
int (*get_regs_len)(struct hnae3_handle *handle);
|
||||||
|
|
||||||
u32 (*get_rss_key_size)(struct hnae3_handle *handle);
|
u32 (*get_rss_key_size)(struct hnae3_handle *handle);
|
||||||
|
|
|
@ -1063,6 +1063,27 @@ static int hns3_set_coalesce(struct net_device *netdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hns3_get_regs_len(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||||
|
|
||||||
|
if (!h->ae_algo->ops->get_regs_len)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return h->ae_algo->ops->get_regs_len(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hns3_get_regs(struct net_device *netdev,
|
||||||
|
struct ethtool_regs *cmd, void *data)
|
||||||
|
{
|
||||||
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||||
|
|
||||||
|
if (!h->ae_algo->ops->get_regs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
h->ae_algo->ops->get_regs(h, &cmd->version, data);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops hns3vf_ethtool_ops = {
|
static const struct ethtool_ops hns3vf_ethtool_ops = {
|
||||||
.get_drvinfo = hns3_get_drvinfo,
|
.get_drvinfo = hns3_get_drvinfo,
|
||||||
.get_ringparam = hns3_get_ringparam,
|
.get_ringparam = hns3_get_ringparam,
|
||||||
|
@ -1103,6 +1124,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
|
||||||
.set_channels = hns3_set_channels,
|
.set_channels = hns3_set_channels,
|
||||||
.get_coalesce = hns3_get_coalesce,
|
.get_coalesce = hns3_get_coalesce,
|
||||||
.set_coalesce = hns3_set_coalesce,
|
.set_coalesce = hns3_set_coalesce,
|
||||||
|
.get_regs_len = hns3_get_regs_len,
|
||||||
|
.get_regs = hns3_get_regs,
|
||||||
};
|
};
|
||||||
|
|
||||||
void hns3_ethtool_set_ops(struct net_device *netdev)
|
void hns3_ethtool_set_ops(struct net_device *netdev)
|
||||||
|
|
|
@ -102,6 +102,10 @@ enum hclge_opcode_type {
|
||||||
HCLGE_OPC_STATS_64_BIT = 0x0030,
|
HCLGE_OPC_STATS_64_BIT = 0x0030,
|
||||||
HCLGE_OPC_STATS_32_BIT = 0x0031,
|
HCLGE_OPC_STATS_32_BIT = 0x0031,
|
||||||
HCLGE_OPC_STATS_MAC = 0x0032,
|
HCLGE_OPC_STATS_MAC = 0x0032,
|
||||||
|
|
||||||
|
HCLGE_OPC_QUERY_REG_NUM = 0x0040,
|
||||||
|
HCLGE_OPC_QUERY_32_BIT_REG = 0x0041,
|
||||||
|
HCLGE_OPC_QUERY_64_BIT_REG = 0x0042,
|
||||||
/* Device management command */
|
/* Device management command */
|
||||||
|
|
||||||
/* MAC commond */
|
/* MAC commond */
|
||||||
|
|
|
@ -5544,6 +5544,180 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit,
|
||||||
|
u32 *regs_num_64_bit)
|
||||||
|
{
|
||||||
|
struct hclge_desc desc;
|
||||||
|
u32 total_num;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true);
|
||||||
|
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Query register number cmd failed, ret = %d.\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*regs_num_32_bit = le32_to_cpu(desc.data[0]);
|
||||||
|
*regs_num_64_bit = le32_to_cpu(desc.data[1]);
|
||||||
|
|
||||||
|
total_num = *regs_num_32_bit + *regs_num_64_bit;
|
||||||
|
if (!total_num)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
#define HCLGE_32_BIT_REG_RTN_DATANUM 8
|
||||||
|
|
||||||
|
struct hclge_desc *desc;
|
||||||
|
u32 *reg_val = data;
|
||||||
|
__le32 *desc_data;
|
||||||
|
int cmd_num;
|
||||||
|
int i, k, n;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (regs_num == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cmd_num = DIV_ROUND_UP(regs_num + 2, HCLGE_32_BIT_REG_RTN_DATANUM);
|
||||||
|
desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
|
||||||
|
if (!desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true);
|
||||||
|
ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Query 32 bit register cmd failed, ret = %d.\n", ret);
|
||||||
|
kfree(desc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cmd_num; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
desc_data = (__le32 *)(&desc[i].data[0]);
|
||||||
|
n = HCLGE_32_BIT_REG_RTN_DATANUM - 2;
|
||||||
|
} else {
|
||||||
|
desc_data = (__le32 *)(&desc[i]);
|
||||||
|
n = HCLGE_32_BIT_REG_RTN_DATANUM;
|
||||||
|
}
|
||||||
|
for (k = 0; k < n; k++) {
|
||||||
|
*reg_val++ = le32_to_cpu(*desc_data++);
|
||||||
|
|
||||||
|
regs_num--;
|
||||||
|
if (!regs_num)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(desc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
#define HCLGE_64_BIT_REG_RTN_DATANUM 4
|
||||||
|
|
||||||
|
struct hclge_desc *desc;
|
||||||
|
u64 *reg_val = data;
|
||||||
|
__le64 *desc_data;
|
||||||
|
int cmd_num;
|
||||||
|
int i, k, n;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (regs_num == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cmd_num = DIV_ROUND_UP(regs_num + 1, HCLGE_64_BIT_REG_RTN_DATANUM);
|
||||||
|
desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
|
||||||
|
if (!desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true);
|
||||||
|
ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Query 64 bit register cmd failed, ret = %d.\n", ret);
|
||||||
|
kfree(desc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cmd_num; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
desc_data = (__le64 *)(&desc[i].data[0]);
|
||||||
|
n = HCLGE_64_BIT_REG_RTN_DATANUM - 1;
|
||||||
|
} else {
|
||||||
|
desc_data = (__le64 *)(&desc[i]);
|
||||||
|
n = HCLGE_64_BIT_REG_RTN_DATANUM;
|
||||||
|
}
|
||||||
|
for (k = 0; k < n; k++) {
|
||||||
|
*reg_val++ = le64_to_cpu(*desc_data++);
|
||||||
|
|
||||||
|
regs_num--;
|
||||||
|
if (!regs_num)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(desc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hclge_get_regs_len(struct hnae3_handle *handle)
|
||||||
|
{
|
||||||
|
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||||
|
struct hclge_dev *hdev = vport->back;
|
||||||
|
u32 regs_num_32_bit, regs_num_64_bit;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Get register number failed, ret = %d.\n", ret);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return regs_num_32_bit * sizeof(u32) + regs_num_64_bit * sizeof(u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||||
|
struct hclge_dev *hdev = vport->back;
|
||||||
|
u32 regs_num_32_bit, regs_num_64_bit;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*version = hdev->fw_version;
|
||||||
|
|
||||||
|
ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Get register number failed, ret = %d.\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, data);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Get 32 bit register failed, ret = %d.\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (u32 *)data + regs_num_32_bit;
|
||||||
|
ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit,
|
||||||
|
data);
|
||||||
|
if (ret)
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"Get 64 bit register failed, ret = %d.\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct hnae3_ae_ops hclge_ops = {
|
static const struct hnae3_ae_ops hclge_ops = {
|
||||||
.init_ae_dev = hclge_init_ae_dev,
|
.init_ae_dev = hclge_init_ae_dev,
|
||||||
.uninit_ae_dev = hclge_uninit_ae_dev,
|
.uninit_ae_dev = hclge_uninit_ae_dev,
|
||||||
|
@ -5595,6 +5769,8 @@ static const struct hnae3_ae_ops hclge_ops = {
|
||||||
.set_channels = hclge_set_channels,
|
.set_channels = hclge_set_channels,
|
||||||
.get_channels = hclge_get_channels,
|
.get_channels = hclge_get_channels,
|
||||||
.get_flowctrl_adv = hclge_get_flowctrl_adv,
|
.get_flowctrl_adv = hclge_get_flowctrl_adv,
|
||||||
|
.get_regs_len = hclge_get_regs_len,
|
||||||
|
.get_regs = hclge_get_regs,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hnae3_ae_algo ae_algo = {
|
static struct hnae3_ae_algo ae_algo = {
|
||||||
|
|
Loading…
Reference in New Issue