1bea44e38SLarysa Zaremba // SPDX-License-Identifier: GPL-2.0-only
2bea44e38SLarysa Zaremba /* Copyright (C) 2025 Intel Corporation */
3bea44e38SLarysa Zaremba
4bea44e38SLarysa Zaremba #include "ixd.h"
529735d99SLarysa Zaremba #include "ixd_ctlq.h"
6bea44e38SLarysa Zaremba #include "ixd_lan_regs.h"
7*f290d48fSAmritha Nambiar #include "ixd_devlink.h"
8bea44e38SLarysa Zaremba
9bea44e38SLarysa Zaremba MODULE_DESCRIPTION("Intel(R) Control Plane Function Device Driver");
1031ddf796SLarysa Zaremba MODULE_IMPORT_NS("LIBIE_CP");
11bea44e38SLarysa Zaremba MODULE_IMPORT_NS("LIBIE_PCI");
12bea44e38SLarysa Zaremba MODULE_LICENSE("GPL");
13bea44e38SLarysa Zaremba
14bea44e38SLarysa Zaremba /**
15bea44e38SLarysa Zaremba * ixd_remove - remove a CPF PCI device
16bea44e38SLarysa Zaremba * @pdev: PCI device being removed
17bea44e38SLarysa Zaremba */
ixd_remove(struct pci_dev * pdev)18bea44e38SLarysa Zaremba static void ixd_remove(struct pci_dev *pdev)
19bea44e38SLarysa Zaremba {
20bea44e38SLarysa Zaremba struct ixd_adapter *adapter = pci_get_drvdata(pdev);
21bea44e38SLarysa Zaremba
2231ddf796SLarysa Zaremba /* Do not mix removal with (re)initialization */
2331ddf796SLarysa Zaremba cancel_delayed_work_sync(&adapter->init_task.init_work);
2429735d99SLarysa Zaremba
25*f290d48fSAmritha Nambiar ixd_devlink_unregister(adapter);
26*f290d48fSAmritha Nambiar
2731ddf796SLarysa Zaremba /* Leave the device clean on exit */
2831ddf796SLarysa Zaremba if (adapter->xnm)
2931ddf796SLarysa Zaremba libie_ctlq_xn_shutdown(adapter->xnm);
3031ddf796SLarysa Zaremba ixd_trigger_reset(adapter);
3131ddf796SLarysa Zaremba ixd_deinit_dflt_mbx(adapter);
3231ddf796SLarysa Zaremba
3331ddf796SLarysa Zaremba libie_pci_unmap_all_mmio_regions(&adapter->cp_ctx.mmio_info);
34*f290d48fSAmritha Nambiar ixd_devlink_free(adapter);
35bea44e38SLarysa Zaremba }
36bea44e38SLarysa Zaremba
37bea44e38SLarysa Zaremba /**
38bea44e38SLarysa Zaremba * ixd_shutdown - shut down a CPF PCI device
39bea44e38SLarysa Zaremba * @pdev: PCI device being shut down
40bea44e38SLarysa Zaremba */
ixd_shutdown(struct pci_dev * pdev)41bea44e38SLarysa Zaremba static void ixd_shutdown(struct pci_dev *pdev)
42bea44e38SLarysa Zaremba {
43bea44e38SLarysa Zaremba ixd_remove(pdev);
44bea44e38SLarysa Zaremba
45bea44e38SLarysa Zaremba if (system_state == SYSTEM_POWER_OFF)
46bea44e38SLarysa Zaremba pci_set_power_state(pdev, PCI_D3hot);
47bea44e38SLarysa Zaremba }
48bea44e38SLarysa Zaremba
49bea44e38SLarysa Zaremba /**
50bea44e38SLarysa Zaremba * ixd_iomap_regions - iomap PCI BARs
51bea44e38SLarysa Zaremba * @adapter: adapter to map memory regions for
52bea44e38SLarysa Zaremba *
53bea44e38SLarysa Zaremba * Returns: %0 on success, negative on failure
54bea44e38SLarysa Zaremba */
ixd_iomap_regions(struct ixd_adapter * adapter)55bea44e38SLarysa Zaremba static int ixd_iomap_regions(struct ixd_adapter *adapter)
56bea44e38SLarysa Zaremba {
57bea44e38SLarysa Zaremba const struct ixd_bar_region regions[] = {
58bea44e38SLarysa Zaremba {
59bea44e38SLarysa Zaremba .offset = PFGEN_RTRIG,
60bea44e38SLarysa Zaremba .size = PFGEN_RTRIG_REG_LEN,
61bea44e38SLarysa Zaremba },
62bea44e38SLarysa Zaremba {
63bea44e38SLarysa Zaremba .offset = PF_FW_MBX,
64bea44e38SLarysa Zaremba .size = PF_FW_MBX_REG_LEN,
65bea44e38SLarysa Zaremba },
66bea44e38SLarysa Zaremba };
67bea44e38SLarysa Zaremba
68bea44e38SLarysa Zaremba for (int i = 0; i < ARRAY_SIZE(regions); i++) {
6931ddf796SLarysa Zaremba struct libie_mmio_info *mmio_info = &adapter->cp_ctx.mmio_info;
70bea44e38SLarysa Zaremba bool map_ok;
71bea44e38SLarysa Zaremba
72bea44e38SLarysa Zaremba map_ok = libie_pci_map_mmio_region(mmio_info,
73bea44e38SLarysa Zaremba regions[i].offset,
74bea44e38SLarysa Zaremba regions[i].size);
75bea44e38SLarysa Zaremba if (!map_ok) {
76bea44e38SLarysa Zaremba dev_err(ixd_to_dev(adapter),
77bea44e38SLarysa Zaremba "Failed to map PCI device MMIO region\n");
78bea44e38SLarysa Zaremba
79bea44e38SLarysa Zaremba libie_pci_unmap_all_mmio_regions(mmio_info);
80bea44e38SLarysa Zaremba return -EIO;
81bea44e38SLarysa Zaremba }
82bea44e38SLarysa Zaremba }
83bea44e38SLarysa Zaremba
84bea44e38SLarysa Zaremba return 0;
85bea44e38SLarysa Zaremba }
86bea44e38SLarysa Zaremba
87bea44e38SLarysa Zaremba /**
88bea44e38SLarysa Zaremba * ixd_probe - probe a CPF PCI device
89bea44e38SLarysa Zaremba * @pdev: corresponding PCI device
90bea44e38SLarysa Zaremba * @ent: entry in ixd_pci_tbl
91bea44e38SLarysa Zaremba *
92bea44e38SLarysa Zaremba * Returns: %0 on success, negative errno code on failure
93bea44e38SLarysa Zaremba */
ixd_probe(struct pci_dev * pdev,const struct pci_device_id * ent)94bea44e38SLarysa Zaremba static int ixd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
95bea44e38SLarysa Zaremba {
96bea44e38SLarysa Zaremba struct ixd_adapter *adapter;
97bea44e38SLarysa Zaremba int err;
98bea44e38SLarysa Zaremba
99*f290d48fSAmritha Nambiar adapter = ixd_adapter_alloc(&pdev->dev);
100bea44e38SLarysa Zaremba if (!adapter)
101bea44e38SLarysa Zaremba return -ENOMEM;
10231ddf796SLarysa Zaremba
10331ddf796SLarysa Zaremba adapter->cp_ctx.mmio_info.pdev = pdev;
10431ddf796SLarysa Zaremba INIT_LIST_HEAD(&adapter->cp_ctx.mmio_info.mmio_list);
105bea44e38SLarysa Zaremba
106bea44e38SLarysa Zaremba err = libie_pci_init_dev(pdev);
107bea44e38SLarysa Zaremba if (err)
108*f290d48fSAmritha Nambiar goto free_adapter;
109bea44e38SLarysa Zaremba
110bea44e38SLarysa Zaremba pci_set_drvdata(pdev, adapter);
111bea44e38SLarysa Zaremba
11231ddf796SLarysa Zaremba err = ixd_iomap_regions(adapter);
11331ddf796SLarysa Zaremba if (err)
114*f290d48fSAmritha Nambiar goto free_adapter;
11531ddf796SLarysa Zaremba
11631ddf796SLarysa Zaremba INIT_DELAYED_WORK(&adapter->init_task.init_work,
11731ddf796SLarysa Zaremba ixd_init_task);
11829735d99SLarysa Zaremba INIT_DELAYED_WORK(&adapter->mbx_task, ixd_ctlq_rx_task);
11931ddf796SLarysa Zaremba
12031ddf796SLarysa Zaremba ixd_trigger_reset(adapter);
12131ddf796SLarysa Zaremba queue_delayed_work(system_dfl_wq, &adapter->init_task.init_work,
12231ddf796SLarysa Zaremba IXD_INIT_TASK_DELAY_JIFFIES);
12331ddf796SLarysa Zaremba
12431ddf796SLarysa Zaremba return 0;
125*f290d48fSAmritha Nambiar
126*f290d48fSAmritha Nambiar free_adapter:
127*f290d48fSAmritha Nambiar ixd_devlink_free(adapter);
128*f290d48fSAmritha Nambiar return err;
129bea44e38SLarysa Zaremba }
130bea44e38SLarysa Zaremba
131bea44e38SLarysa Zaremba static const struct pci_device_id ixd_pci_tbl[] = {
132bea44e38SLarysa Zaremba { PCI_VDEVICE(INTEL, IXD_DEV_ID_CPF) },
133bea44e38SLarysa Zaremba { }
134bea44e38SLarysa Zaremba };
135bea44e38SLarysa Zaremba MODULE_DEVICE_TABLE(pci, ixd_pci_tbl);
136bea44e38SLarysa Zaremba
137bea44e38SLarysa Zaremba static struct pci_driver ixd_driver = {
138bea44e38SLarysa Zaremba .name = KBUILD_MODNAME,
139bea44e38SLarysa Zaremba .id_table = ixd_pci_tbl,
140bea44e38SLarysa Zaremba .probe = ixd_probe,
141bea44e38SLarysa Zaremba .remove = ixd_remove,
142bea44e38SLarysa Zaremba .shutdown = ixd_shutdown,
143bea44e38SLarysa Zaremba };
144bea44e38SLarysa Zaremba module_pci_driver(ixd_driver);
145