net: hns3: uninitialize command queue while unloading PF driver

According to the hardware's description, the driver should clear
the command queue's registers when uloading driver. Otherwise,
these existing value may lead the IMP get into a wrong state.

Also this patch adds hclge_cmd_uninit() to do the command queue
uninitialization which includes clearing registers and freeing
memory.

Fixes: 68c0a5c706 ("net: hns3: Add HNS3 IMP(Integrated Mgmt Proc) Cmd Interface Support")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Huazhong Tan 2019-02-20 10:32:50 +08:00 коммит произвёл David S. Miller
Родитель c6075b1934
Коммит 232d0d55fc
3 изменённых файлов: 29 добавлений и 3 удалений

Просмотреть файл

@ -390,6 +390,20 @@ int hclge_cmd_init(struct hclge_dev *hdev)
return 0;
}
static void hclge_cmd_uninit_regs(struct hclge_hw *hw)
{
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_BASEADDR_L_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_BASEADDR_H_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_DEPTH_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CRQ_TAIL_REG, 0);
}
static void hclge_destroy_queue(struct hclge_cmq_ring *ring)
{
spin_lock(&ring->lock);
@ -402,3 +416,15 @@ void hclge_destroy_cmd_queue(struct hclge_hw *hw)
hclge_destroy_queue(&hw->cmq.csq);
hclge_destroy_queue(&hw->cmq.crq);
}
void hclge_cmd_uninit(struct hclge_dev *hdev)
{
spin_lock_bh(&hdev->hw.cmq.csq.lock);
spin_lock(&hdev->hw.cmq.crq.lock);
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
hclge_cmd_uninit_regs(&hdev->hw);
spin_unlock(&hdev->hw.cmq.crq.lock);
spin_unlock_bh(&hdev->hw.cmq.csq.lock);
hclge_destroy_cmd_queue(&hdev->hw);
}

Просмотреть файл

@ -975,6 +975,6 @@ enum hclge_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw,
enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw,
struct hclge_desc *desc);
void hclge_destroy_cmd_queue(struct hclge_hw *hw);
void hclge_cmd_uninit(struct hclge_dev *hdev);
int hclge_cmd_queue_init(struct hclge_dev *hdev);
#endif

Просмотреть файл

@ -7669,7 +7669,7 @@ err_msi_irq_uninit:
err_msi_uninit:
pci_free_irq_vectors(pdev);
err_cmd_uninit:
hclge_destroy_cmd_queue(&hdev->hw);
hclge_cmd_uninit(hdev);
err_pci_uninit:
pcim_iounmap(pdev, hdev->hw.io_base);
pci_clear_master(pdev);
@ -7796,7 +7796,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
synchronize_irq(hdev->misc_vector.vector_irq);
hclge_hw_error_set_state(hdev, false);
hclge_destroy_cmd_queue(&hdev->hw);
hclge_cmd_uninit(hdev);
hclge_misc_irq_uninit(hdev);
hclge_pci_uninit(hdev);
mutex_destroy(&hdev->vport_lock);