1a977168cSMichal Gulbicki /* SPDX-License-Identifier: BSD-3-Clause */
2a977168cSMichal Gulbicki /* Copyright(c) 2007 - 2022 Intel Corporation */
3a977168cSMichal Gulbicki #include "qat_freebsd.h"
4a977168cSMichal Gulbicki #include "adf_cfg.h"
5a977168cSMichal Gulbicki #include "adf_common_drv.h"
6a977168cSMichal Gulbicki #include "adf_accel_devices.h"
7a977168cSMichal Gulbicki #include "adf_4xxx_hw_data.h"
8a977168cSMichal Gulbicki #include "adf_gen4_hw_data.h"
9a977168cSMichal Gulbicki #include "adf_fw_counters.h"
10a977168cSMichal Gulbicki #include "adf_cfg_device.h"
11a977168cSMichal Gulbicki #include <sys/types.h>
12a977168cSMichal Gulbicki #include <sys/kernel.h>
13a977168cSMichal Gulbicki #include <sys/malloc.h>
14a977168cSMichal Gulbicki #include <machine/bus_dma.h>
15a977168cSMichal Gulbicki #include <dev/pci/pcireg.h>
16a977168cSMichal Gulbicki #include "adf_heartbeat_dbg.h"
17a977168cSMichal Gulbicki #include "adf_cnvnr_freq_counters.h"
18a977168cSMichal Gulbicki
19a977168cSMichal Gulbicki static MALLOC_DEFINE(M_QAT_4XXX, "qat_4xxx", "qat_4xxx");
20a977168cSMichal Gulbicki
21a977168cSMichal Gulbicki #define ADF_SYSTEM_DEVICE(device_id) \
22a977168cSMichal Gulbicki { \
23a977168cSMichal Gulbicki PCI_VENDOR_ID_INTEL, device_id \
24a977168cSMichal Gulbicki }
25a977168cSMichal Gulbicki
26a977168cSMichal Gulbicki static const struct pci_device_id adf_pci_tbl[] =
27a977168cSMichal Gulbicki { ADF_SYSTEM_DEVICE(ADF_4XXX_PCI_DEVICE_ID),
28a977168cSMichal Gulbicki ADF_SYSTEM_DEVICE(ADF_401XX_PCI_DEVICE_ID),
29a977168cSMichal Gulbicki {
30a977168cSMichal Gulbicki 0,
31a977168cSMichal Gulbicki } };
32a977168cSMichal Gulbicki
33a977168cSMichal Gulbicki static int
adf_probe(device_t dev)34a977168cSMichal Gulbicki adf_probe(device_t dev)
35a977168cSMichal Gulbicki {
36a977168cSMichal Gulbicki const struct pci_device_id *id;
37a977168cSMichal Gulbicki
38a977168cSMichal Gulbicki for (id = adf_pci_tbl; id->vendor != 0; id++) {
39a977168cSMichal Gulbicki if (pci_get_vendor(dev) == id->vendor &&
40a977168cSMichal Gulbicki pci_get_device(dev) == id->device) {
41a977168cSMichal Gulbicki device_set_desc(dev,
42a977168cSMichal Gulbicki "Intel " ADF_4XXX_DEVICE_NAME
43a977168cSMichal Gulbicki " QuickAssist");
44a977168cSMichal Gulbicki return BUS_PROBE_GENERIC;
45a977168cSMichal Gulbicki }
46a977168cSMichal Gulbicki }
47a977168cSMichal Gulbicki return ENXIO;
48a977168cSMichal Gulbicki }
49a977168cSMichal Gulbicki
50a977168cSMichal Gulbicki static void
adf_cleanup_accel(struct adf_accel_dev * accel_dev)51a977168cSMichal Gulbicki adf_cleanup_accel(struct adf_accel_dev *accel_dev)
52a977168cSMichal Gulbicki {
53a977168cSMichal Gulbicki struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
54a977168cSMichal Gulbicki int i;
55a977168cSMichal Gulbicki
56a977168cSMichal Gulbicki if (accel_dev->dma_tag)
57a977168cSMichal Gulbicki bus_dma_tag_destroy(accel_dev->dma_tag);
58a977168cSMichal Gulbicki for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
59a977168cSMichal Gulbicki struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
60a977168cSMichal Gulbicki
61a977168cSMichal Gulbicki if (bar->virt_addr)
62a977168cSMichal Gulbicki bus_free_resource(accel_pci_dev->pci_dev,
63a977168cSMichal Gulbicki SYS_RES_MEMORY,
64a977168cSMichal Gulbicki bar->virt_addr);
65a977168cSMichal Gulbicki }
66a977168cSMichal Gulbicki
67a977168cSMichal Gulbicki if (accel_dev->hw_device) {
68a977168cSMichal Gulbicki switch (pci_get_device(accel_pci_dev->pci_dev)) {
69a977168cSMichal Gulbicki case ADF_4XXX_PCI_DEVICE_ID:
70a977168cSMichal Gulbicki case ADF_401XX_PCI_DEVICE_ID:
71a977168cSMichal Gulbicki adf_clean_hw_data_4xxx(accel_dev->hw_device);
72a977168cSMichal Gulbicki break;
73a977168cSMichal Gulbicki default:
74a977168cSMichal Gulbicki break;
75a977168cSMichal Gulbicki }
76a977168cSMichal Gulbicki free(accel_dev->hw_device, M_QAT_4XXX);
77a977168cSMichal Gulbicki accel_dev->hw_device = NULL;
78a977168cSMichal Gulbicki }
79a977168cSMichal Gulbicki adf_cfg_dev_remove(accel_dev);
80a977168cSMichal Gulbicki adf_devmgr_rm_dev(accel_dev, NULL);
81a977168cSMichal Gulbicki }
82a977168cSMichal Gulbicki
83a977168cSMichal Gulbicki static int
adf_attach(device_t dev)84a977168cSMichal Gulbicki adf_attach(device_t dev)
85a977168cSMichal Gulbicki {
86a977168cSMichal Gulbicki struct adf_accel_dev *accel_dev;
87a977168cSMichal Gulbicki struct adf_accel_pci *accel_pci_dev;
88a977168cSMichal Gulbicki struct adf_hw_device_data *hw_data;
89*22cf89c9SPiotr Kasierski unsigned int bar_nr;
90a977168cSMichal Gulbicki int ret, rid;
91a977168cSMichal Gulbicki struct adf_cfg_device *cfg_dev = NULL;
92a977168cSMichal Gulbicki
93266b0663SKrzysztof Zdziarski /* Set pci MaxPayLoad to 512. Implemented to avoid the issue of
94a977168cSMichal Gulbicki * Pci-passthrough causing Maxpayload to be reset to 128 bytes
95a977168cSMichal Gulbicki * when the device is reset.
96a977168cSMichal Gulbicki */
97266b0663SKrzysztof Zdziarski if (pci_get_max_payload(dev) != 512)
98266b0663SKrzysztof Zdziarski pci_set_max_payload(dev, 512);
99a977168cSMichal Gulbicki
100a977168cSMichal Gulbicki accel_dev = device_get_softc(dev);
101a977168cSMichal Gulbicki
102a977168cSMichal Gulbicki INIT_LIST_HEAD(&accel_dev->crypto_list);
103a977168cSMichal Gulbicki accel_pci_dev = &accel_dev->accel_pci_dev;
104a977168cSMichal Gulbicki accel_pci_dev->pci_dev = dev;
105a977168cSMichal Gulbicki
106a977168cSMichal Gulbicki if (bus_get_domain(dev, &accel_pci_dev->node) != 0)
107a977168cSMichal Gulbicki accel_pci_dev->node = 0;
108a977168cSMichal Gulbicki
109a977168cSMichal Gulbicki /* Add accel device to accel table.
110a977168cSMichal Gulbicki * This should be called before adf_cleanup_accel is called
111a977168cSMichal Gulbicki */
112a977168cSMichal Gulbicki if (adf_devmgr_add_dev(accel_dev, NULL)) {
113a977168cSMichal Gulbicki device_printf(dev, "Failed to add new accelerator device.\n");
114a977168cSMichal Gulbicki return ENXIO;
115a977168cSMichal Gulbicki }
116a977168cSMichal Gulbicki
117a977168cSMichal Gulbicki /* Allocate and configure device configuration structure */
118a977168cSMichal Gulbicki hw_data = malloc(sizeof(*hw_data), M_QAT_4XXX, M_WAITOK | M_ZERO);
119a977168cSMichal Gulbicki
120a977168cSMichal Gulbicki accel_dev->hw_device = hw_data;
121266b0663SKrzysztof Zdziarski adf_init_hw_data_4xxx(accel_dev->hw_device, pci_get_device(dev));
122a977168cSMichal Gulbicki accel_pci_dev->revid = pci_get_revid(dev);
123a977168cSMichal Gulbicki hw_data->fuses = pci_read_config(dev, ADF_4XXX_FUSECTL4_OFFSET, 4);
124a977168cSMichal Gulbicki if (accel_pci_dev->revid == 0x00) {
125a977168cSMichal Gulbicki device_printf(dev, "A0 stepping is not supported.\n");
126a977168cSMichal Gulbicki ret = ENODEV;
127a977168cSMichal Gulbicki goto out_err;
128a977168cSMichal Gulbicki }
129a977168cSMichal Gulbicki
130a977168cSMichal Gulbicki /* Get PPAERUCM values and store */
131a977168cSMichal Gulbicki ret = adf_aer_store_ppaerucm_reg(dev, hw_data);
132a977168cSMichal Gulbicki if (ret)
133a977168cSMichal Gulbicki goto out_err;
134a977168cSMichal Gulbicki
135a977168cSMichal Gulbicki /* Get Accelerators and Accelerators Engines masks */
136a977168cSMichal Gulbicki hw_data->accel_mask = hw_data->get_accel_mask(accel_dev);
137a977168cSMichal Gulbicki hw_data->ae_mask = hw_data->get_ae_mask(accel_dev);
138a977168cSMichal Gulbicki
139a977168cSMichal Gulbicki accel_pci_dev->sku = hw_data->get_sku(hw_data);
140a977168cSMichal Gulbicki /* If the device has no acceleration engines then ignore it. */
141a977168cSMichal Gulbicki if (!hw_data->accel_mask || !hw_data->ae_mask ||
142a977168cSMichal Gulbicki (~hw_data->ae_mask & 0x01)) {
143a977168cSMichal Gulbicki device_printf(dev, "No acceleration units found\n");
144a977168cSMichal Gulbicki ret = ENXIO;
145a977168cSMichal Gulbicki goto out_err;
146a977168cSMichal Gulbicki }
147a977168cSMichal Gulbicki
148a977168cSMichal Gulbicki /* Create device configuration table */
149a977168cSMichal Gulbicki ret = adf_cfg_dev_add(accel_dev);
150a977168cSMichal Gulbicki if (ret)
151a977168cSMichal Gulbicki goto out_err;
152a977168cSMichal Gulbicki ret = adf_clock_debugfs_add(accel_dev);
153a977168cSMichal Gulbicki if (ret)
154a977168cSMichal Gulbicki goto out_err;
155a977168cSMichal Gulbicki
156266b0663SKrzysztof Zdziarski pci_set_max_read_req(dev, 4096);
157a977168cSMichal Gulbicki
158a977168cSMichal Gulbicki ret = bus_dma_tag_create(bus_get_dma_tag(dev),
159a977168cSMichal Gulbicki 1,
160a977168cSMichal Gulbicki 0,
161a977168cSMichal Gulbicki BUS_SPACE_MAXADDR,
162a977168cSMichal Gulbicki BUS_SPACE_MAXADDR,
163a977168cSMichal Gulbicki NULL,
164a977168cSMichal Gulbicki NULL,
165a977168cSMichal Gulbicki BUS_SPACE_MAXSIZE,
166a977168cSMichal Gulbicki /* BUS_SPACE_UNRESTRICTED */ 1,
167a977168cSMichal Gulbicki BUS_SPACE_MAXSIZE,
168a977168cSMichal Gulbicki 0,
169a977168cSMichal Gulbicki NULL,
170a977168cSMichal Gulbicki NULL,
171a977168cSMichal Gulbicki &accel_dev->dma_tag);
172a977168cSMichal Gulbicki if (ret)
173a977168cSMichal Gulbicki goto out_err;
174a977168cSMichal Gulbicki
175a977168cSMichal Gulbicki if (hw_data->get_accel_cap) {
176a977168cSMichal Gulbicki hw_data->accel_capabilities_mask =
177a977168cSMichal Gulbicki hw_data->get_accel_cap(accel_dev);
178a977168cSMichal Gulbicki }
179a977168cSMichal Gulbicki
180a977168cSMichal Gulbicki /* Find and map all the device's BARS */
181*22cf89c9SPiotr Kasierski /* Logical BARs configuration for 64bit BARs:
182*22cf89c9SPiotr Kasierski bar 0 and 1 - logical BAR0
183*22cf89c9SPiotr Kasierski bar 2 and 3 - logical BAR1
184*22cf89c9SPiotr Kasierski bar 4 and 5 - logical BAR3
185*22cf89c9SPiotr Kasierski */
186*22cf89c9SPiotr Kasierski for (bar_nr = 0;
187*22cf89c9SPiotr Kasierski bar_nr < (ADF_PCI_MAX_BARS * 2) && bar_nr < PCIR_MAX_BAR_0;
188*22cf89c9SPiotr Kasierski bar_nr += 2) {
189a977168cSMichal Gulbicki struct adf_bar *bar;
190a977168cSMichal Gulbicki
191a977168cSMichal Gulbicki rid = PCIR_BAR(bar_nr);
192*22cf89c9SPiotr Kasierski bar = &accel_pci_dev->pci_bars[bar_nr / 2];
193*22cf89c9SPiotr Kasierski
194a977168cSMichal Gulbicki bar->virt_addr = bus_alloc_resource_any(dev,
195a977168cSMichal Gulbicki SYS_RES_MEMORY,
196a977168cSMichal Gulbicki &rid,
197a977168cSMichal Gulbicki RF_ACTIVE);
198a977168cSMichal Gulbicki if (!bar->virt_addr) {
199a977168cSMichal Gulbicki device_printf(dev, "Failed to map BAR %d\n", bar_nr);
200a977168cSMichal Gulbicki ret = ENXIO;
201a977168cSMichal Gulbicki goto out_err;
202a977168cSMichal Gulbicki }
203a977168cSMichal Gulbicki bar->base_addr = rman_get_start(bar->virt_addr);
204a977168cSMichal Gulbicki bar->size = rman_get_size(bar->virt_addr);
205a977168cSMichal Gulbicki }
206a977168cSMichal Gulbicki pci_enable_busmaster(dev);
207a977168cSMichal Gulbicki
208a977168cSMichal Gulbicki if (!accel_dev->hw_device->config_device) {
209a977168cSMichal Gulbicki ret = EFAULT;
210a977168cSMichal Gulbicki goto out_err;
211a977168cSMichal Gulbicki }
212a977168cSMichal Gulbicki
213a977168cSMichal Gulbicki ret = accel_dev->hw_device->config_device(accel_dev);
214a977168cSMichal Gulbicki if (ret)
215a977168cSMichal Gulbicki goto out_err;
216a977168cSMichal Gulbicki
217a977168cSMichal Gulbicki ret = adf_dev_init(accel_dev);
218a977168cSMichal Gulbicki if (ret)
219a977168cSMichal Gulbicki goto out_dev_shutdown;
220a977168cSMichal Gulbicki
221a977168cSMichal Gulbicki ret = adf_dev_start(accel_dev);
222a977168cSMichal Gulbicki if (ret)
223a977168cSMichal Gulbicki goto out_dev_stop;
224a977168cSMichal Gulbicki
225a977168cSMichal Gulbicki cfg_dev = accel_dev->cfg->dev;
226a977168cSMichal Gulbicki adf_cfg_device_clear(cfg_dev, accel_dev);
227a977168cSMichal Gulbicki free(cfg_dev, M_QAT);
228a977168cSMichal Gulbicki accel_dev->cfg->dev = NULL;
229a977168cSMichal Gulbicki return ret;
230a977168cSMichal Gulbicki out_dev_stop:
231a977168cSMichal Gulbicki adf_dev_stop(accel_dev);
232a977168cSMichal Gulbicki out_dev_shutdown:
233a977168cSMichal Gulbicki adf_dev_shutdown(accel_dev);
234a977168cSMichal Gulbicki out_err:
235a977168cSMichal Gulbicki adf_cleanup_accel(accel_dev);
236a977168cSMichal Gulbicki return ret;
237a977168cSMichal Gulbicki }
238a977168cSMichal Gulbicki
239a977168cSMichal Gulbicki static int
adf_detach(device_t dev)240a977168cSMichal Gulbicki adf_detach(device_t dev)
241a977168cSMichal Gulbicki {
242a977168cSMichal Gulbicki struct adf_accel_dev *accel_dev = device_get_softc(dev);
243a977168cSMichal Gulbicki
244a977168cSMichal Gulbicki if (adf_dev_stop(accel_dev)) {
245a977168cSMichal Gulbicki device_printf(dev, "Failed to stop QAT accel dev\n");
246a977168cSMichal Gulbicki return EBUSY;
247a977168cSMichal Gulbicki }
248a977168cSMichal Gulbicki
249a977168cSMichal Gulbicki adf_dev_shutdown(accel_dev);
250a977168cSMichal Gulbicki
251a977168cSMichal Gulbicki adf_cleanup_accel(accel_dev);
252a977168cSMichal Gulbicki
253a977168cSMichal Gulbicki return 0;
254a977168cSMichal Gulbicki }
255a977168cSMichal Gulbicki
256a977168cSMichal Gulbicki static device_method_t adf_methods[] = { DEVMETHOD(device_probe, adf_probe),
257a977168cSMichal Gulbicki DEVMETHOD(device_attach, adf_attach),
258a977168cSMichal Gulbicki DEVMETHOD(device_detach, adf_detach),
259a977168cSMichal Gulbicki
260a977168cSMichal Gulbicki DEVMETHOD_END };
261a977168cSMichal Gulbicki
262a977168cSMichal Gulbicki static driver_t adf_driver = { "qat",
263a977168cSMichal Gulbicki adf_methods,
264a977168cSMichal Gulbicki sizeof(struct adf_accel_dev) };
265a977168cSMichal Gulbicki
266a977168cSMichal Gulbicki DRIVER_MODULE_ORDERED(qat_4xxx, pci, adf_driver, NULL, NULL, SI_ORDER_THIRD);
267a977168cSMichal Gulbicki MODULE_VERSION(qat_4xxx, 1);
268a977168cSMichal Gulbicki MODULE_DEPEND(qat_4xxx, qat_common, 1, 1, 1);
269a977168cSMichal Gulbicki MODULE_DEPEND(qat_4xxx, qat_api, 1, 1, 1);
270a977168cSMichal Gulbicki MODULE_DEPEND(qat_4xxx, linuxkpi, 1, 1, 1);
271