Merge branch 'hns3-next'

Huazhong Tan says:

====================
code optimizations & bugfixes for HNS3 driver

This patch-set includes code optimizations and bugfixes for the HNS3
ethernet controller driver.

[patch 1/12] fixes a compile warning reported by kbuild test robot.

[patch 2/12] fixes HNS3_RXD_GRO_SIZE_M macro definition error.

[patch 3/12] adds a debugfs command to dump firmware information.

[patch 4/12 - 10/12] adds some code optimizaions and cleanups for
reset and driver unloading.

[patch 11/12 - 12/12] adds two bugfixes.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-05-28 17:39:01 -07:00
commit 602e0f295a
12 changed files with 213 additions and 80 deletions

View File

@ -252,6 +252,7 @@ static void hns3_dbg_help(struct hnae3_handle *h)
dev_info(&h->pdev->dev, "dump qos buf cfg\n");
dev_info(&h->pdev->dev, "dump mng tbl\n");
dev_info(&h->pdev->dev, "dump reset info\n");
dev_info(&h->pdev->dev, "dump m7 info\n");
dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n");
dev_info(&h->pdev->dev, "dump mac tnl status\n");

View File

@ -3901,6 +3901,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
hns3_client_stop(handle);
hns3_uninit_phy(netdev);
if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
netdev_warn(netdev, "already uninitialized\n");
goto out_netdev_free;
@ -3910,8 +3912,6 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
hns3_force_clear_all_rx_ring(handle);
hns3_uninit_phy(netdev);
hns3_nic_uninit_vector_data(priv);
ret = hns3_nic_dealloc_vector_data(priv);

View File

@ -145,7 +145,7 @@ enum hns3_nic_state {
#define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S)
#define HNS3_RXD_LKBK_B 15
#define HNS3_RXD_GRO_SIZE_S 16
#define HNS3_RXD_GRO_SIZE_M (0x3ff << HNS3_RXD_GRO_SIZE_S)
#define HNS3_RXD_GRO_SIZE_M (0x3fff << HNS3_RXD_GRO_SIZE_S)
#define HNS3_TXD_L3T_S 0
#define HNS3_TXD_L3T_M (0x3 << HNS3_TXD_L3T_S)

View File

@ -110,8 +110,7 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
upper_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG,
(ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S) |
HCLGE_NIC_CMQ_ENABLE);
ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
} else {
@ -120,8 +119,7 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
hclge_write_dev(hw, HCLGE_NIC_CRQ_BASEADDR_H_REG,
upper_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CRQ_DEPTH_REG,
(ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S) |
HCLGE_NIC_CMQ_ENABLE);
ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
hclge_write_dev(hw, HCLGE_NIC_CRQ_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_TAIL_REG, 0);
}

View File

@ -243,6 +243,9 @@ enum hclge_opcode_type {
/* NCL config command */
HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011,
/* M7 stats command */
HCLGE_OPC_M7_STATS_BD = 0x7012,
HCLGE_OPC_M7_STATS_INFO = 0x7013,
/* SFP command */
HCLGE_OPC_GET_SFP_INFO = 0x7104,
@ -970,6 +973,11 @@ struct hclge_fd_ad_config_cmd {
u8 rsv2[8];
};
struct hclge_get_m7_bd_cmd {
__le32 bd_num;
u8 rsv[20];
};
int hclge_cmd_init(struct hclge_dev *hdev);
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
{

View File

@ -921,6 +921,61 @@ static void hclge_dbg_dump_rst_info(struct hclge_dev *hdev)
hdev->rst_stats.reset_cnt);
}
void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev)
{
struct hclge_desc *desc_src, *desc_tmp;
struct hclge_get_m7_bd_cmd *req;
struct hclge_desc desc;
u32 bd_num, buf_len;
int ret, i;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_M7_STATS_BD, true);
req = (struct hclge_get_m7_bd_cmd *)desc.data;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"get firmware statistics bd number failed, ret=%d\n",
ret);
return;
}
bd_num = le32_to_cpu(req->bd_num);
buf_len = sizeof(struct hclge_desc) * bd_num;
desc_src = kzalloc(buf_len, GFP_KERNEL);
if (!desc_src) {
dev_err(&hdev->pdev->dev,
"allocate desc for get_m7_stats failed\n");
return;
}
desc_tmp = desc_src;
ret = hclge_dbg_cmd_send(hdev, desc_tmp, 0, bd_num,
HCLGE_OPC_M7_STATS_INFO);
if (ret) {
kfree(desc_src);
dev_err(&hdev->pdev->dev,
"get firmware statistics failed, ret=%d\n", ret);
return;
}
for (i = 0; i < bd_num; i++) {
dev_info(&hdev->pdev->dev, "0x%08x 0x%08x 0x%08x\n",
le32_to_cpu(desc_tmp->data[0]),
le32_to_cpu(desc_tmp->data[1]),
le32_to_cpu(desc_tmp->data[2]));
dev_info(&hdev->pdev->dev, "0x%08x 0x%08x 0x%08x\n",
le32_to_cpu(desc_tmp->data[3]),
le32_to_cpu(desc_tmp->data[4]),
le32_to_cpu(desc_tmp->data[5]));
desc_tmp++;
}
kfree(desc_src);
}
/* hclge_dbg_dump_ncl_config: print specified range of NCL_CONFIG file
* @hdev: pointer to struct hclge_dev
* @cmd_buf: string that contains offset and length
@ -1029,6 +1084,8 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, char *cmd_buf)
hclge_dbg_dump_reg_cmd(hdev, cmd_buf);
} else if (strncmp(cmd_buf, "dump reset info", 15) == 0) {
hclge_dbg_dump_rst_info(hdev);
} else if (strncmp(cmd_buf, "dump m7 info", 12) == 0) {
hclge_dbg_get_m7_stats_info(hdev);
} else if (strncmp(cmd_buf, "dump ncl_config", 15) == 0) {
hclge_dbg_dump_ncl_config(hdev,
&cmd_buf[sizeof("dump ncl_config")]);

View File

@ -2427,7 +2427,8 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
static void hclge_reset_task_schedule(struct hclge_dev *hdev)
{
if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
schedule_work(&hdev->rst_service_task);
}
@ -2873,6 +2874,10 @@ int hclge_notify_client(struct hclge_dev *hdev,
struct hnae3_client *client = hdev->nic_client;
u16 i;
if (!test_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state) ||
!client)
return 0;
if (!client->ops->reset_notify)
return -EOPNOTSUPP;
@ -2898,7 +2903,8 @@ static int hclge_notify_roce_client(struct hclge_dev *hdev,
int ret = 0;
u16 i;
if (!client)
if (!test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state) ||
!client)
return 0;
if (!client->ops->reset_notify)
@ -3192,6 +3198,8 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev)
static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
{
#define HCLGE_RESET_SYNC_TIME 100
u32 reg_val;
int ret = 0;
@ -3200,7 +3208,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
/* There is no mechanism for PF to know if VF has stopped IO
* for now, just wait 100 ms for VF to stop IO
*/
msleep(100);
msleep(HCLGE_RESET_SYNC_TIME);
ret = hclge_func_reset_cmd(hdev, 0);
if (ret) {
dev_err(&hdev->pdev->dev,
@ -3220,7 +3228,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
/* There is no mechanism for PF to know if VF has stopped IO
* for now, just wait 100 ms for VF to stop IO
*/
msleep(100);
msleep(HCLGE_RESET_SYNC_TIME);
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
set_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
hdev->rst_stats.flr_rst_cnt++;
@ -3234,6 +3242,10 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
break;
}
/* inform hardware that preparatory work is done */
msleep(HCLGE_RESET_SYNC_TIME);
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG,
HCLGE_NIC_CMQ_ENABLE);
dev_info(&hdev->pdev->dev, "prepare wait ok\n");
return ret;
@ -5682,7 +5694,6 @@ static void hclge_fd_build_arfs_rule(const struct hclge_fd_rule_tuples *tuples,
static int hclge_add_fd_entry_by_arfs(struct hnae3_handle *handle, u16 queue_id,
u16 flow_id, struct flow_keys *fkeys)
{
#ifdef CONFIG_RFS_ACCEL
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_fd_rule_tuples new_tuples;
struct hclge_dev *hdev = vport->back;
@ -5758,7 +5769,6 @@ static int hclge_add_fd_entry_by_arfs(struct hnae3_handle *handle, u16 queue_id,
}
return rule->location;
#endif
}
static void hclge_rfs_filter_expire(struct hclge_dev *hdev)
@ -8166,6 +8176,52 @@ static void hclge_info_show(struct hclge_dev *hdev)
dev_info(dev, "PF info end.\n");
}
static int hclge_init_nic_client_instance(struct hnae3_ae_dev *ae_dev,
struct hclge_vport *vport)
{
struct hnae3_client *client = vport->nic.client;
struct hclge_dev *hdev = ae_dev->priv;
int ret;
ret = client->ops->init_instance(&vport->nic);
if (ret)
return ret;
set_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state);
hnae3_set_client_init_flag(client, ae_dev, 1);
if (netif_msg_drv(&hdev->vport->nic))
hclge_info_show(hdev);
return 0;
}
static int hclge_init_roce_client_instance(struct hnae3_ae_dev *ae_dev,
struct hclge_vport *vport)
{
struct hnae3_client *client = vport->roce.client;
struct hclge_dev *hdev = ae_dev->priv;
int ret;
if (!hnae3_dev_roce_supported(hdev) || !hdev->roce_client ||
!hdev->nic_client)
return 0;
client = hdev->roce_client;
ret = hclge_init_roce_base_info(vport);
if (ret)
return ret;
ret = client->ops->init_instance(&vport->roce);
if (ret)
return ret;
set_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
hnae3_set_client_init_flag(client, ae_dev, 1);
return 0;
}
static int hclge_init_client_instance(struct hnae3_client *client,
struct hnae3_ae_dev *ae_dev)
{
@ -8181,30 +8237,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
hdev->nic_client = client;
vport->nic.client = client;
ret = client->ops->init_instance(&vport->nic);
ret = hclge_init_nic_client_instance(ae_dev, vport);
if (ret)
goto clear_nic;
hnae3_set_client_init_flag(client, ae_dev, 1);
if (netif_msg_drv(&hdev->vport->nic))
hclge_info_show(hdev);
if (hdev->roce_client &&
hnae3_dev_roce_supported(hdev)) {
struct hnae3_client *rc = hdev->roce_client;
ret = hclge_init_roce_base_info(vport);
if (ret)
goto clear_roce;
ret = rc->ops->init_instance(&vport->roce);
if (ret)
goto clear_roce;
hnae3_set_client_init_flag(hdev->roce_client,
ae_dev, 1);
}
ret = hclge_init_roce_client_instance(ae_dev, vport);
if (ret)
goto clear_roce;
break;
case HNAE3_CLIENT_UNIC:
@ -8224,17 +8263,9 @@ static int hclge_init_client_instance(struct hnae3_client *client,
vport->roce.client = client;
}
if (hdev->roce_client && hdev->nic_client) {
ret = hclge_init_roce_base_info(vport);
if (ret)
goto clear_roce;
ret = client->ops->init_instance(&vport->roce);
if (ret)
goto clear_roce;
hnae3_set_client_init_flag(client, ae_dev, 1);
}
ret = hclge_init_roce_client_instance(ae_dev, vport);
if (ret)
goto clear_roce;
break;
default:
@ -8264,6 +8295,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
for (i = 0; i < hdev->num_vmdq_vport + 1; i++) {
vport = &hdev->vport[i];
if (hdev->roce_client) {
clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
hdev->roce_client->ops->uninit_instance(&vport->roce,
0);
hdev->roce_client = NULL;
@ -8272,6 +8304,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
if (client->type == HNAE3_CLIENT_ROCE)
return;
if (hdev->nic_client && client->ops->uninit_instance) {
clear_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state);
client->ops->uninit_instance(&vport->nic, 0);
hdev->nic_client = NULL;
vport->nic.client = NULL;
@ -8353,6 +8386,7 @@ static void hclge_state_init(struct hclge_dev *hdev)
static void hclge_state_uninit(struct hclge_dev *hdev)
{
set_bit(HCLGE_STATE_DOWN, &hdev->state);
set_bit(HCLGE_STATE_REMOVING, &hdev->state);
if (hdev->service_timer.function)
del_timer_sync(&hdev->service_timer);

View File

@ -201,6 +201,8 @@ enum HCLGE_DEV_STATE {
HCLGE_STATE_DOWN,
HCLGE_STATE_DISABLED,
HCLGE_STATE_REMOVING,
HCLGE_STATE_NIC_REGISTERED,
HCLGE_STATE_ROCE_REGISTERED,
HCLGE_STATE_SERVICE_INITED,
HCLGE_STATE_SERVICE_SCHED,
HCLGE_STATE_RST_SERVICE_SCHED,

View File

@ -192,12 +192,10 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
return ret;
ret = hclge_bind_ring_with_vector(vport, vector_id, en, &ring_chain);
if (ret)
return ret;
hclge_free_vector_ring_chain(&ring_chain);
return 0;
return ret;
}
static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,

View File

@ -98,7 +98,6 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val);
reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
reg_val |= HCLGEVF_NIC_CMQ_ENABLE;
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0);
@ -110,7 +109,6 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_BASEADDR_H_REG, reg_val);
reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
reg_val |= HCLGEVF_NIC_CMQ_ENABLE;
hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_DEPTH_REG, reg_val);
hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_HEAD_REG, 0);

View File

@ -1306,6 +1306,10 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev,
struct hnae3_handle *handle = &hdev->nic;
int ret;
if (!test_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state) ||
!client)
return 0;
if (!client->ops->reset_notify)
return -EOPNOTSUPP;
@ -1410,6 +1414,8 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
{
#define HCLGEVF_RESET_SYNC_TIME 100
int ret = 0;
switch (hdev->reset_type) {
@ -1427,7 +1433,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
}
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
/* inform hardware that preparatory work is done */
msleep(HCLGEVF_RESET_SYNC_TIME);
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
HCLGEVF_NIC_CMQ_ENABLE);
dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n",
hdev->reset_type, ret);
@ -1612,7 +1621,8 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
{
if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state)) {
if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) &&
!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state)) {
set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
schedule_work(&hdev->rst_service_task);
}
@ -2123,6 +2133,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
static void hclgevf_state_uninit(struct hclgevf_dev *hdev)
{
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
set_bit(HCLGEVF_STATE_REMOVING, &hdev->state);
if (hdev->keep_alive_timer.function)
del_timer_sync(&hdev->keep_alive_timer);
@ -2249,6 +2260,48 @@ static void hclgevf_info_show(struct hclgevf_dev *hdev)
dev_info(dev, "VF info end.\n");
}
static int hclgevf_init_nic_client_instance(struct hnae3_ae_dev *ae_dev,
struct hnae3_client *client)
{
struct hclgevf_dev *hdev = ae_dev->priv;
int ret;
ret = client->ops->init_instance(&hdev->nic);
if (ret)
return ret;
set_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state);
hnae3_set_client_init_flag(client, ae_dev, 1);
if (netif_msg_drv(&hdev->nic))
hclgevf_info_show(hdev);
return 0;
}
static int hclgevf_init_roce_client_instance(struct hnae3_ae_dev *ae_dev,
struct hnae3_client *client)
{
struct hclgevf_dev *hdev = ae_dev->priv;
int ret;
if (!hnae3_dev_roce_supported(hdev) || !hdev->roce_client ||
!hdev->nic_client)
return 0;
ret = hclgevf_init_roce_base_info(hdev);
if (ret)
return ret;
ret = client->ops->init_instance(&hdev->roce);
if (ret)
return ret;
hnae3_set_client_init_flag(client, ae_dev, 1);
return 0;
}
static int hclgevf_init_client_instance(struct hnae3_client *client,
struct hnae3_ae_dev *ae_dev)
{
@ -2260,28 +2313,15 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
hdev->nic_client = client;
hdev->nic.client = client;
ret = client->ops->init_instance(&hdev->nic);
ret = hclgevf_init_nic_client_instance(ae_dev, client);
if (ret)
goto clear_nic;
hnae3_set_client_init_flag(client, ae_dev, 1);
ret = hclgevf_init_roce_client_instance(ae_dev,
hdev->roce_client);
if (ret)
goto clear_roce;
if (netif_msg_drv(&hdev->nic))
hclgevf_info_show(hdev);
if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) {
struct hnae3_client *rc = hdev->roce_client;
ret = hclgevf_init_roce_base_info(hdev);
if (ret)
goto clear_roce;
ret = rc->ops->init_instance(&hdev->roce);
if (ret)
goto clear_roce;
hnae3_set_client_init_flag(hdev->roce_client, ae_dev,
1);
}
break;
case HNAE3_CLIENT_UNIC:
hdev->nic_client = client;
@ -2299,17 +2339,10 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
hdev->roce.client = client;
}
if (hdev->roce_client && hdev->nic_client) {
ret = hclgevf_init_roce_base_info(hdev);
if (ret)
goto clear_roce;
ret = hclgevf_init_roce_client_instance(ae_dev, client);
if (ret)
goto clear_roce;
ret = client->ops->init_instance(&hdev->roce);
if (ret)
goto clear_roce;
}
hnae3_set_client_init_flag(client, ae_dev, 1);
break;
default:
return -EINVAL;
@ -2342,6 +2375,8 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
/* un-init nic/unic, if this was not called by roce client */
if (client->ops->uninit_instance && hdev->nic_client &&
client->type != HNAE3_CLIENT_ROCE) {
clear_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state);
client->ops->uninit_instance(&hdev->nic, 0);
hdev->nic_client = NULL;
hdev->nic.client = NULL;

View File

@ -130,6 +130,8 @@ enum hclgevf_states {
HCLGEVF_STATE_DOWN,
HCLGEVF_STATE_DISABLED,
HCLGEVF_STATE_IRQ_INITED,
HCLGEVF_STATE_REMOVING,
HCLGEVF_STATE_NIC_REGISTERED,
/* task states */
HCLGEVF_STATE_SERVICE_SCHED,
HCLGEVF_STATE_RST_SERVICE_SCHED,