// SPDX-License-Identifier: GPL-2.0 /* Marvell OcteonTx2 RVU Admin Function driver * * Copyright (C) 2018 Marvell International Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include "rvu.h" #define DRV_NAME "octeontx2-af" #define DRV_STRING "Marvell OcteonTX2 RVU Admin Function Driver" #define DRV_VERSION "1.0" /* Supported devices */ static const struct pci_device_id rvu_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_AF) }, { 0, } /* end of table */ }; MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION(DRV_STRING); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRV_VERSION); MODULE_DEVICE_TABLE(pci, rvu_id_table); static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct device *dev = &pdev->dev; struct rvu *rvu; int err; rvu = devm_kzalloc(dev, sizeof(*rvu), GFP_KERNEL); if (!rvu) return -ENOMEM; pci_set_drvdata(pdev, rvu); rvu->pdev = pdev; rvu->dev = &pdev->dev; err = pci_enable_device(pdev); if (err) { dev_err(dev, "Failed to enable PCI device\n"); goto err_freemem; } err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(dev, "PCI request regions failed 0x%x\n", err); goto err_disable_device; } err = pci_set_dma_mask(pdev, DMA_BIT_MASK(48)); if (err) { dev_err(dev, "Unable to set DMA mask\n"); goto err_release_regions; } err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(48)); if (err) { dev_err(dev, "Unable to set consistent DMA mask\n"); goto err_release_regions; } /* Map Admin function CSRs */ rvu->afreg_base = pcim_iomap(pdev, PCI_AF_REG_BAR_NUM, 0); rvu->pfreg_base = pcim_iomap(pdev, PCI_PF_REG_BAR_NUM, 0); if (!rvu->afreg_base || !rvu->pfreg_base) { dev_err(dev, "Unable to map admin function CSRs, aborting\n"); err = -ENOMEM; goto err_release_regions; } return 0; err_release_regions: pci_release_regions(pdev); err_disable_device: pci_disable_device(pdev); err_freemem: pci_set_drvdata(pdev, NULL); devm_kfree(dev, rvu); return err; } static void rvu_remove(struct pci_dev *pdev) { struct rvu *rvu = pci_get_drvdata(pdev); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); devm_kfree(&pdev->dev, rvu); } static struct pci_driver rvu_driver = { .name = DRV_NAME, .id_table = rvu_id_table, .probe = rvu_probe, .remove = rvu_remove, }; static int __init rvu_init_module(void) { pr_info("%s: %s\n", DRV_NAME, DRV_STRING); return pci_register_driver(&rvu_driver); } static void __exit rvu_cleanup_module(void) { pci_unregister_driver(&rvu_driver); } module_init(rvu_init_module); module_exit(rvu_cleanup_module);