xref: /freebsd/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
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