diff options
author | David S. Miller <davem@davemloft.net> | 2021-11-01 13:21:49 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-11-01 13:21:49 +0000 |
commit | c6e03dbe0c7cdbe7b259deeae0f193d15ec5002f (patch) | |
tree | d739b2dcd39b03b1a7db755215e76a1816166f8c /drivers/net/ethernet/microsoft/mana/gdma_main.c | |
parent | 986d2e3da7d7f24c16d419f926c65af1a994a04a (diff) | |
parent | 635096a86edb067d55a1e04b4a918f5c6dac0c51 (diff) | |
download | linux-c6e03dbe0c7cdbe7b259deeae0f193d15ec5002f.tar.bz2 |
Merge branch 'mana-misc'
Dexuan Cui says:
====================
net: mana: some misc patches
Patch 1 is a small fix.
Patch 2 reports OS info to the PF driver.
Before the patch, the req fields were all zeros.
Patch 3 fixes and cleans up the error handling of HWC creation failure.
Patch 4 adds the callbacks for hibernation/kexec. It's based on patch 3.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/microsoft/mana/gdma_main.c')
-rw-r--r-- | drivers/net/ethernet/microsoft/mana/gdma_main.c | 155 |
1 files changed, 117 insertions, 38 deletions
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c index cee75b561f59..c96ac81212f7 100644 --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c @@ -3,6 +3,8 @@ #include <linux/module.h> #include <linux/pci.h> +#include <linux/utsname.h> +#include <linux/version.h> #include "mana.h" @@ -848,6 +850,15 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev) req.gd_drv_cap_flags3 = GDMA_DRV_CAP_FLAGS3; req.gd_drv_cap_flags4 = GDMA_DRV_CAP_FLAGS4; + req.drv_ver = 0; /* Unused*/ + req.os_type = 0x10; /* Linux */ + req.os_ver_major = LINUX_VERSION_MAJOR; + req.os_ver_minor = LINUX_VERSION_PATCHLEVEL; + req.os_ver_build = LINUX_VERSION_SUBLEVEL; + strscpy(req.os_ver_str1, utsname()->sysname, sizeof(req.os_ver_str1)); + strscpy(req.os_ver_str2, utsname()->release, sizeof(req.os_ver_str2)); + strscpy(req.os_ver_str3, utsname()->version, sizeof(req.os_ver_str3)); + err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); if (err || resp.hdr.status) { dev_err(gc->dev, "VfVerifyVersionOutput: %d, status=0x%x\n", @@ -1247,6 +1258,52 @@ static void mana_gd_remove_irqs(struct pci_dev *pdev) gc->irq_contexts = NULL; } +static int mana_gd_setup(struct pci_dev *pdev) +{ + struct gdma_context *gc = pci_get_drvdata(pdev); + int err; + + mana_gd_init_registers(pdev); + mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base); + + err = mana_gd_setup_irqs(pdev); + if (err) + return err; + + err = mana_hwc_create_channel(gc); + if (err) + goto remove_irq; + + err = mana_gd_verify_vf_version(pdev); + if (err) + goto destroy_hwc; + + err = mana_gd_query_max_resources(pdev); + if (err) + goto destroy_hwc; + + err = mana_gd_detect_devices(pdev); + if (err) + goto destroy_hwc; + + return 0; + +destroy_hwc: + mana_hwc_destroy_channel(gc); +remove_irq: + mana_gd_remove_irqs(pdev); + return err; +} + +static void mana_gd_cleanup(struct pci_dev *pdev) +{ + struct gdma_context *gc = pci_get_drvdata(pdev); + + mana_hwc_destroy_channel(gc); + + mana_gd_remove_irqs(pdev); +} + static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct gdma_context *gc; @@ -1276,6 +1333,9 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!gc) goto release_region; + mutex_init(&gc->eq_test_event_mutex); + pci_set_drvdata(pdev, gc); + bar0_va = pci_iomap(pdev, bar, 0); if (!bar0_va) goto free_gc; @@ -1283,49 +1343,23 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) gc->bar0_va = bar0_va; gc->dev = &pdev->dev; - pci_set_drvdata(pdev, gc); - mana_gd_init_registers(pdev); - - mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base); - - err = mana_gd_setup_irqs(pdev); + err = mana_gd_setup(pdev); if (err) goto unmap_bar; - mutex_init(&gc->eq_test_event_mutex); - - err = mana_hwc_create_channel(gc); - if (err) - goto remove_irq; - - err = mana_gd_verify_vf_version(pdev); - if (err) - goto remove_irq; - - err = mana_gd_query_max_resources(pdev); - if (err) - goto remove_irq; - - err = mana_gd_detect_devices(pdev); + err = mana_probe(&gc->mana, false); if (err) - goto remove_irq; - - err = mana_probe(&gc->mana); - if (err) - goto clean_up_gdma; + goto cleanup_gd; return 0; -clean_up_gdma: - mana_hwc_destroy_channel(gc); - vfree(gc->cq_table); - gc->cq_table = NULL; -remove_irq: - mana_gd_remove_irqs(pdev); +cleanup_gd: + mana_gd_cleanup(pdev); unmap_bar: pci_iounmap(pdev, bar0_va); free_gc: + pci_set_drvdata(pdev, NULL); vfree(gc); release_region: pci_release_regions(pdev); @@ -1340,13 +1374,9 @@ static void mana_gd_remove(struct pci_dev *pdev) { struct gdma_context *gc = pci_get_drvdata(pdev); - mana_remove(&gc->mana); + mana_remove(&gc->mana, false); - mana_hwc_destroy_channel(gc); - vfree(gc->cq_table); - gc->cq_table = NULL; - - mana_gd_remove_irqs(pdev); + mana_gd_cleanup(pdev); pci_iounmap(pdev, gc->bar0_va); @@ -1357,6 +1387,52 @@ static void mana_gd_remove(struct pci_dev *pdev) pci_disable_device(pdev); } +/* The 'state' parameter is not used. */ +static int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct gdma_context *gc = pci_get_drvdata(pdev); + + mana_remove(&gc->mana, true); + + mana_gd_cleanup(pdev); + + return 0; +} + +/* In case the NIC hardware stops working, the suspend and resume callbacks will + * fail -- if this happens, it's safer to just report an error than try to undo + * what has been done. + */ +static int mana_gd_resume(struct pci_dev *pdev) +{ + struct gdma_context *gc = pci_get_drvdata(pdev); + int err; + + err = mana_gd_setup(pdev); + if (err) + return err; + + err = mana_probe(&gc->mana, true); + if (err) + return err; + + return 0; +} + +/* Quiesce the device for kexec. This is also called upon reboot/shutdown. */ +static void mana_gd_shutdown(struct pci_dev *pdev) +{ + struct gdma_context *gc = pci_get_drvdata(pdev); + + dev_info(&pdev->dev, "Shutdown was calledd\n"); + + mana_remove(&gc->mana, true); + + mana_gd_cleanup(pdev); + + pci_disable_device(pdev); +} + #ifndef PCI_VENDOR_ID_MICROSOFT #define PCI_VENDOR_ID_MICROSOFT 0x1414 #endif @@ -1371,6 +1447,9 @@ static struct pci_driver mana_driver = { .id_table = mana_id_table, .probe = mana_gd_probe, .remove = mana_gd_remove, + .suspend = mana_gd_suspend, + .resume = mana_gd_resume, + .shutdown = mana_gd_shutdown, }; module_pci_driver(mana_driver); |