1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "qat_freebsd.h"
5 #include "adf_cfg.h"
6 #include <adf_accel_devices.h>
7 #include <adf_pf2vf_msg.h>
8 #include <adf_common_drv.h>
9 #include <adf_dev_err.h>
10 #include "adf_dh895xcc_hw_data.h"
11 #include "icp_qat_hw.h"
12 #include "adf_heartbeat.h"
13 
14 /* Worker thread to service arbiter mappings based on dev SKUs */
15 static const u32 thrd_to_arb_map_sku4[] =
16     { 0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666, 0x12222AAA, 0x11222222,
17       0x12222AAA, 0x11222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
18 
19 static const u32 thrd_to_arb_map_sku6[] =
20     { 0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666, 0x12222AAA, 0x11222222,
21       0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222 };
22 
23 static const u32 thrd_to_arb_map_sku3[] =
24     { 0x00000888, 0x00000000, 0x00000888, 0x00000000, 0x00000888, 0x00000000,
25       0x00000888, 0x00000000, 0x00000888, 0x00000000, 0x00000888, 0x00000000 };
26 
27 static u32 thrd_to_arb_map_gen[ADF_DH895XCC_MAX_ACCELENGINES] = { 0 };
28 
29 static struct adf_hw_device_class dh895xcc_class =
30     {.name = ADF_DH895XCC_DEVICE_NAME, .type = DEV_DH895XCC, .instances = 0 };
31 
32 static u32
33 get_accel_mask(struct adf_accel_dev *accel_dev)
34 {
35 	device_t pdev = accel_dev->accel_pci_dev.pci_dev;
36 	u32 fuse;
37 
38 	fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4);
39 
40 	return (~fuse) >> ADF_DH895XCC_ACCELERATORS_REG_OFFSET &
41 	    ADF_DH895XCC_ACCELERATORS_MASK;
42 }
43 
44 static u32
45 get_ae_mask(struct adf_accel_dev *accel_dev)
46 {
47 	device_t pdev = accel_dev->accel_pci_dev.pci_dev;
48 	u32 fuse;
49 
50 	fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4);
51 
52 	return (~fuse) & ADF_DH895XCC_ACCELENGINES_MASK;
53 }
54 
55 static uint32_t
56 get_num_accels(struct adf_hw_device_data *self)
57 {
58 	uint32_t i, ctr = 0;
59 
60 	if (!self || !self->accel_mask)
61 		return 0;
62 
63 	for (i = 0; i < ADF_DH895XCC_MAX_ACCELERATORS; i++) {
64 		if (self->accel_mask & (1 << i))
65 			ctr++;
66 	}
67 	return ctr;
68 }
69 
70 static uint32_t
71 get_num_aes(struct adf_hw_device_data *self)
72 {
73 	uint32_t i, ctr = 0;
74 
75 	if (!self || !self->ae_mask)
76 		return 0;
77 
78 	for (i = 0; i < ADF_DH895XCC_MAX_ACCELENGINES; i++) {
79 		if (self->ae_mask & (1 << i))
80 			ctr++;
81 	}
82 	return ctr;
83 }
84 
85 static uint32_t
86 get_misc_bar_id(struct adf_hw_device_data *self)
87 {
88 	return ADF_DH895XCC_PMISC_BAR;
89 }
90 
91 static uint32_t
92 get_etr_bar_id(struct adf_hw_device_data *self)
93 {
94 	return ADF_DH895XCC_ETR_BAR;
95 }
96 
97 static uint32_t
98 get_sram_bar_id(struct adf_hw_device_data *self)
99 {
100 	return ADF_DH895XCC_SRAM_BAR;
101 }
102 
103 static enum dev_sku_info
104 get_sku(struct adf_hw_device_data *self)
105 {
106 	int sku = (self->fuses & ADF_DH895XCC_FUSECTL_SKU_MASK) >>
107 	    ADF_DH895XCC_FUSECTL_SKU_SHIFT;
108 
109 	switch (sku) {
110 	case ADF_DH895XCC_FUSECTL_SKU_1:
111 		return DEV_SKU_1;
112 	case ADF_DH895XCC_FUSECTL_SKU_2:
113 		return DEV_SKU_2;
114 	case ADF_DH895XCC_FUSECTL_SKU_3:
115 		return DEV_SKU_3;
116 	case ADF_DH895XCC_FUSECTL_SKU_4:
117 		return DEV_SKU_4;
118 	default:
119 		return DEV_SKU_UNKNOWN;
120 	}
121 	return DEV_SKU_UNKNOWN;
122 }
123 
124 static void
125 adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
126 			u32 const **arb_map_config)
127 {
128 	switch (accel_dev->accel_pci_dev.sku) {
129 	case DEV_SKU_1:
130 		adf_cfg_gen_dispatch_arbiter(accel_dev,
131 					     thrd_to_arb_map_sku4,
132 					     thrd_to_arb_map_gen,
133 					     ADF_DH895XCC_MAX_ACCELENGINES);
134 		*arb_map_config = thrd_to_arb_map_gen;
135 		break;
136 
137 	case DEV_SKU_2:
138 	case DEV_SKU_4:
139 		adf_cfg_gen_dispatch_arbiter(accel_dev,
140 					     thrd_to_arb_map_sku6,
141 					     thrd_to_arb_map_gen,
142 					     ADF_DH895XCC_MAX_ACCELENGINES);
143 		*arb_map_config = thrd_to_arb_map_gen;
144 		break;
145 
146 	case DEV_SKU_3:
147 		adf_cfg_gen_dispatch_arbiter(accel_dev,
148 					     thrd_to_arb_map_sku3,
149 					     thrd_to_arb_map_gen,
150 					     ADF_DH895XCC_MAX_ACCELENGINES);
151 		*arb_map_config = thrd_to_arb_map_gen;
152 		break;
153 
154 	default:
155 		device_printf(GET_DEV(accel_dev),
156 			      "The configuration doesn't match any SKU");
157 		*arb_map_config = NULL;
158 	}
159 }
160 
161 static uint32_t
162 get_pf2vf_offset(uint32_t i)
163 {
164 	return ADF_DH895XCC_PF2VF_OFFSET(i);
165 }
166 
167 static uint32_t
168 get_vintmsk_offset(uint32_t i)
169 {
170 	return ADF_DH895XCC_VINTMSK_OFFSET(i);
171 }
172 
173 static void
174 get_arb_info(struct arb_info *arb_csrs_info)
175 {
176 	arb_csrs_info->arbiter_offset = ADF_DH895XCC_ARB_OFFSET;
177 	arb_csrs_info->wrk_thd_2_srv_arb_map =
178 	    ADF_DH895XCC_ARB_WRK_2_SER_MAP_OFFSET;
179 	arb_csrs_info->wrk_cfg_offset = ADF_DH895XCC_ARB_WQCFG_OFFSET;
180 }
181 
182 static void
183 get_admin_info(struct admin_info *admin_csrs_info)
184 {
185 	admin_csrs_info->mailbox_offset = ADF_DH895XCC_MAILBOX_BASE_OFFSET;
186 	admin_csrs_info->admin_msg_ur = ADF_DH895XCC_ADMINMSGUR_OFFSET;
187 	admin_csrs_info->admin_msg_lr = ADF_DH895XCC_ADMINMSGLR_OFFSET;
188 }
189 
190 static void
191 get_errsou_offset(u32 *errsou3, u32 *errsou5)
192 {
193 	*errsou3 = ADF_DH895XCC_ERRSOU3;
194 	*errsou5 = ADF_DH895XCC_ERRSOU5;
195 }
196 
197 static u32
198 get_clock_speed(struct adf_hw_device_data *self)
199 {
200 	/* CPP clock is half high-speed clock */
201 	return self->clock_frequency / 2;
202 }
203 
204 static void
205 adf_enable_error_correction(struct adf_accel_dev *accel_dev)
206 {
207 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
208 	struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR];
209 	struct resource *csr = misc_bar->virt_addr;
210 	unsigned int val, i;
211 	unsigned int mask;
212 
213 	/* Enable Accel Engine error detection & correction */
214 	mask = hw_device->ae_mask;
215 	for (i = 0; mask; i++, mask >>= 1) {
216 		if (!(mask & 1))
217 			continue;
218 		val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_CTX_ENABLES(i));
219 		val |= ADF_DH895XCC_ENABLE_AE_ECC_ERR;
220 		ADF_CSR_WR(csr, ADF_DH895XCC_AE_CTX_ENABLES(i), val);
221 		val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_MISC_CONTROL(i));
222 		val |= ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR;
223 		ADF_CSR_WR(csr, ADF_DH895XCC_AE_MISC_CONTROL(i), val);
224 	}
225 
226 	/* Enable shared memory error detection & correction */
227 	mask = hw_device->accel_mask;
228 	for (i = 0; mask; i++, mask >>= 1) {
229 		if (!(mask & 1))
230 			continue;
231 		val = ADF_CSR_RD(csr, ADF_DH895XCC_UERRSSMSH(i));
232 		val |= ADF_DH895XCC_ERRSSMSH_EN;
233 		ADF_CSR_WR(csr, ADF_DH895XCC_UERRSSMSH(i), val);
234 		val = ADF_CSR_RD(csr, ADF_DH895XCC_CERRSSMSH(i));
235 		val |= ADF_DH895XCC_ERRSSMSH_EN;
236 		ADF_CSR_WR(csr, ADF_DH895XCC_CERRSSMSH(i), val);
237 	}
238 }
239 
240 static void
241 adf_enable_ints(struct adf_accel_dev *accel_dev)
242 {
243 	struct resource *addr;
244 
245 	addr = (&GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR])->virt_addr;
246 
247 	/* Enable bundle and misc interrupts */
248 	ADF_CSR_WR(addr,
249 		   ADF_DH895XCC_SMIAPF0_MASK_OFFSET,
250 		   accel_dev->u1.pf.vf_info ?
251 		       0 :
252 		       (1ULL << GET_MAX_BANKS(accel_dev)) - 1);
253 	ADF_CSR_WR(addr,
254 		   ADF_DH895XCC_SMIAPF1_MASK_OFFSET,
255 		   ADF_DH895XCC_SMIA1_MASK);
256 }
257 
258 static u32
259 get_ae_clock(struct adf_hw_device_data *self)
260 {
261 	/*
262 	 * Clock update interval is <16> ticks for dh895xcc.
263 	 */
264 	return self->clock_frequency / 16;
265 }
266 
267 static int
268 get_storage_enabled(struct adf_accel_dev *accel_dev, u32 *storage_enabled)
269 {
270 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
271 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
272 
273 	strlcpy(key, ADF_STORAGE_FIRMWARE_ENABLED, sizeof(key));
274 	if (!adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) {
275 		if (kstrtouint(val, 0, storage_enabled))
276 			return -EFAULT;
277 	}
278 	return 0;
279 }
280 
281 static u32
282 dh895xcc_get_hw_cap(struct adf_accel_dev *accel_dev)
283 {
284 	device_t pdev = accel_dev->accel_pci_dev.pci_dev;
285 	u32 legfuses;
286 	u32 capabilities;
287 
288 	/* Read accelerator capabilities mask */
289 	legfuses = pci_read_config(pdev, ADF_DEVICE_LEGFUSE_OFFSET, 4);
290 	capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC +
291 	    ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC +
292 	    ICP_ACCEL_CAPABILITIES_CIPHER +
293 	    ICP_ACCEL_CAPABILITIES_AUTHENTICATION +
294 	    ICP_ACCEL_CAPABILITIES_COMPRESSION + ICP_ACCEL_CAPABILITIES_RAND +
295 	    ICP_ACCEL_CAPABILITIES_HKDF + ICP_ACCEL_CAPABILITIES_ECEDMONT +
296 	    ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN;
297 
298 	if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE)
299 		capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
300 				  ICP_ACCEL_CAPABILITIES_CIPHER |
301 				  ICP_ACCEL_CAPABILITIES_HKDF |
302 				  ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN);
303 	if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE)
304 		capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
305 	if (legfuses & ICP_ACCEL_MASK_PKE_SLICE)
306 		capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
307 				  ICP_ACCEL_CAPABILITIES_ECEDMONT);
308 	if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE)
309 		capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
310 
311 	return capabilities;
312 }
313 
314 static const char *
315 get_obj_name(struct adf_accel_dev *accel_dev,
316 	     enum adf_accel_unit_services service)
317 {
318 	return ADF_DH895XCC_AE_FW_NAME_CUSTOM1;
319 }
320 
321 static u32
322 get_objs_num(struct adf_accel_dev *accel_dev)
323 {
324 	return 1;
325 }
326 
327 static u32
328 get_obj_cfg_ae_mask(struct adf_accel_dev *accel_dev,
329 		    enum adf_accel_unit_services services)
330 {
331 	return accel_dev->hw_device->ae_mask;
332 }
333 
334 void
335 adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
336 {
337 	hw_data->dev_class = &dh895xcc_class;
338 	hw_data->instance_id = dh895xcc_class.instances++;
339 	hw_data->num_banks = ADF_DH895XCC_ETR_MAX_BANKS;
340 	hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
341 	hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS;
342 	hw_data->num_logical_accel = 1;
343 	hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES;
344 	hw_data->tx_rx_gap = ADF_DH895XCC_RX_RINGS_OFFSET;
345 	hw_data->tx_rings_mask = ADF_DH895XCC_TX_RINGS_MASK;
346 	hw_data->alloc_irq = adf_isr_resource_alloc;
347 	hw_data->free_irq = adf_isr_resource_free;
348 	hw_data->enable_error_correction = adf_enable_error_correction;
349 	hw_data->print_err_registers = adf_print_err_registers;
350 	hw_data->get_accel_mask = get_accel_mask;
351 	hw_data->get_ae_mask = get_ae_mask;
352 	hw_data->get_num_accels = get_num_accels;
353 	hw_data->get_num_aes = get_num_aes;
354 	hw_data->get_etr_bar_id = get_etr_bar_id;
355 	hw_data->get_misc_bar_id = get_misc_bar_id;
356 	hw_data->get_pf2vf_offset = get_pf2vf_offset;
357 	hw_data->get_vintmsk_offset = get_vintmsk_offset;
358 	hw_data->get_arb_info = get_arb_info;
359 	hw_data->get_admin_info = get_admin_info;
360 	hw_data->get_errsou_offset = get_errsou_offset;
361 	hw_data->get_clock_speed = get_clock_speed;
362 	hw_data->get_sram_bar_id = get_sram_bar_id;
363 	hw_data->get_sku = get_sku;
364 	hw_data->fw_name = ADF_DH895XCC_FW;
365 	hw_data->fw_mmp_name = ADF_DH895XCC_MMP;
366 	hw_data->init_admin_comms = adf_init_admin_comms;
367 	hw_data->exit_admin_comms = adf_exit_admin_comms;
368 	hw_data->disable_iov = adf_disable_sriov;
369 	hw_data->send_admin_init = adf_send_admin_init;
370 	hw_data->init_arb = adf_init_gen2_arb;
371 	hw_data->exit_arb = adf_exit_arb;
372 	hw_data->get_arb_mapping = adf_get_arbiter_mapping;
373 	hw_data->enable_ints = adf_enable_ints;
374 	hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
375 	hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms;
376 	hw_data->reset_device = adf_reset_sbr;
377 	hw_data->restore_device = adf_dev_restore;
378 	hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
379 	hw_data->get_accel_cap = dh895xcc_get_hw_cap;
380 	hw_data->get_heartbeat_status = adf_get_heartbeat_status;
381 	hw_data->get_ae_clock = get_ae_clock;
382 	hw_data->get_objs_num = get_objs_num;
383 	hw_data->get_obj_name = get_obj_name;
384 	hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask;
385 	hw_data->clock_frequency = ADF_DH895XCC_AE_FREQ;
386 	hw_data->extended_dc_capabilities = 0;
387 	hw_data->get_storage_enabled = get_storage_enabled;
388 	hw_data->query_storage_cap = 1;
389 	hw_data->get_heartbeat_status = adf_get_heartbeat_status;
390 	hw_data->get_ae_clock = get_ae_clock;
391 	hw_data->storage_enable = 0;
392 	hw_data->get_fw_image_type = adf_cfg_get_fw_image_type;
393 	hw_data->config_device = adf_config_device;
394 	hw_data->get_ring_to_svc_map = adf_cfg_get_services_enabled;
395 	hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask;
396 	hw_data->ring_to_svc_map = ADF_DEFAULT_RING_TO_SRV_MAP;
397 	hw_data->pre_reset = adf_dev_pre_reset;
398 	hw_data->post_reset = adf_dev_post_reset;
399 }
400 
401 void
402 adf_clean_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
403 {
404 	hw_data->dev_class->instances--;
405 }
406