diff options
Diffstat (limited to 'drivers/net/ethernet/huawei/hinic3/hinic3_lld.c')
| -rw-r--r-- | drivers/net/ethernet/huawei/hinic3/hinic3_lld.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c index 3db8241a3b0c..87413e192f10 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c @@ -5,15 +5,22 @@ #include <linux/iopoll.h> #include "hinic3_hw_cfg.h" +#include "hinic3_hw_comm.h" #include "hinic3_hwdev.h" +#include "hinic3_hwif.h" #include "hinic3_lld.h" #include "hinic3_mgmt.h" #include "hinic3_pci_id_tbl.h" #define HINIC3_VF_PCI_CFG_REG_BAR 0 +#define HINIC3_PF_PCI_CFG_REG_BAR 1 #define HINIC3_PCI_INTR_REG_BAR 2 +/* Only PF has mgmt bar */ +#define HINIC3_PCI_MGMT_REG_BAR 3 #define HINIC3_PCI_DB_BAR 4 +#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == PCI_DEV_ID_HINIC3_VF) + #define HINIC3_EVENT_POLL_SLEEP_US 1000 #define HINIC3_EVENT_POLL_TIMEOUT_US 10000000 @@ -181,8 +188,12 @@ void hinic3_adev_event_unregister(struct auxiliary_device *adev) static int hinic3_mapping_bar(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter) { - pci_adapter->cfg_reg_base = pci_ioremap_bar(pdev, - HINIC3_VF_PCI_CFG_REG_BAR); + int cfg_bar; + + cfg_bar = HINIC3_IS_VF_DEV(pdev) ? + HINIC3_VF_PCI_CFG_REG_BAR : HINIC3_PF_PCI_CFG_REG_BAR; + + pci_adapter->cfg_reg_base = pci_ioremap_bar(pdev, cfg_bar); if (!pci_adapter->cfg_reg_base) { dev_err(&pdev->dev, "Failed to map configuration regs\n"); return -ENOMEM; @@ -195,19 +206,30 @@ static int hinic3_mapping_bar(struct pci_dev *pdev, goto err_unmap_cfg_reg_base; } + if (!HINIC3_IS_VF_DEV(pdev)) { + pci_adapter->mgmt_reg_base = + pci_ioremap_bar(pdev, HINIC3_PCI_MGMT_REG_BAR); + if (!pci_adapter->mgmt_reg_base) { + dev_err(&pdev->dev, "Failed to map mgmt regs\n"); + goto err_unmap_intr_reg_base; + } + } + pci_adapter->db_base_phy = pci_resource_start(pdev, HINIC3_PCI_DB_BAR); pci_adapter->db_dwqe_len = pci_resource_len(pdev, HINIC3_PCI_DB_BAR); pci_adapter->db_base = pci_ioremap_bar(pdev, HINIC3_PCI_DB_BAR); if (!pci_adapter->db_base) { dev_err(&pdev->dev, "Failed to map doorbell regs\n"); - goto err_unmap_intr_reg_base; + goto err_unmap_mgmt_reg_base; } return 0; +err_unmap_mgmt_reg_base: + if (!HINIC3_IS_VF_DEV(pdev)) + iounmap(pci_adapter->mgmt_reg_base); err_unmap_intr_reg_base: iounmap(pci_adapter->intr_reg_base); - err_unmap_cfg_reg_base: iounmap(pci_adapter->cfg_reg_base); @@ -217,6 +239,8 @@ err_unmap_cfg_reg_base: static void hinic3_unmapping_bar(struct hinic3_pcidev *pci_adapter) { iounmap(pci_adapter->db_base); + if (!HINIC3_IS_VF_DEV(pci_adapter->pdev)) + iounmap(pci_adapter->mgmt_reg_base); iounmap(pci_adapter->intr_reg_base); iounmap(pci_adapter->cfg_reg_base); } @@ -260,10 +284,8 @@ static int hinic3_pci_init(struct pci_dev *pdev) err_release_regions: pci_clear_master(pdev); pci_release_regions(pdev); - err_disable_device: pci_disable_device(pdev); - err_free_pci_adapter: pci_set_drvdata(pdev, NULL); mutex_destroy(&pci_adapter->pdev_mutex); @@ -295,6 +317,9 @@ static int hinic3_func_init(struct pci_dev *pdev, return err; } + if (HINIC3_IS_PF(pci_adapter->hwdev)) + hinic3_sync_time_to_fw(pci_adapter->hwdev); + err = hinic3_attach_aux_devices(pci_adapter->hwdev); if (err) goto err_free_hwdev; @@ -311,6 +336,8 @@ static void hinic3_func_uninit(struct pci_dev *pdev) { struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev); + /* disable mgmt reporting before flushing mgmt work-queue. */ + hinic3_set_pf_status(pci_adapter->hwdev->hwif, HINIC3_PF_STATUS_INIT); hinic3_flush_mgmt_workq(pci_adapter->hwdev); hinic3_detach_aux_devices(pci_adapter->hwdev); hinic3_free_hwdev(pci_adapter->hwdev); @@ -319,6 +346,7 @@ static void hinic3_func_uninit(struct pci_dev *pdev) static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter) { struct pci_dev *pdev = pci_adapter->pdev; + struct comm_cmd_bdf_info bdf_info = {}; int err; err = hinic3_mapping_bar(pdev, pci_adapter); @@ -331,11 +359,26 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter) if (err) goto err_unmap_bar; + if (HINIC3_IS_PF(pci_adapter->hwdev)) { + bdf_info.function_idx = + hinic3_global_func_id(pci_adapter->hwdev); + bdf_info.bus = pdev->bus->number; + bdf_info.device = PCI_SLOT(pdev->devfn); + bdf_info.function = PCI_FUNC(pdev->devfn); + + err = hinic3_set_bdf_ctxt(pci_adapter->hwdev, &bdf_info); + if (err) { + dev_err(&pdev->dev, "Failed to set BDF info to fw\n"); + goto err_uninit_func; + } + } + return 0; +err_uninit_func: + hinic3_func_uninit(pdev); err_unmap_bar: hinic3_unmapping_bar(pci_adapter); - err_out: dev_err(&pdev->dev, "PCIe device probe function failed\n"); @@ -368,7 +411,6 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_uninit_pci: hinic3_pci_uninit(pdev); - err_out: dev_err(&pdev->dev, "PCIe device probe failed\n"); |
