1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2023 Intel Corporation */
3 #include <linux/iopoll.h>
4 #include <adf_accel_devices.h>
7 #include <adf_cfg_services.h>
9 #include <adf_common_drv.h>
10 #include <adf_fw_config.h>
11 #include <adf_gen4_config.h>
12 #include <adf_gen4_dc.h>
13 #include <adf_gen4_hw_csr_data.h>
14 #include <adf_gen4_hw_data.h>
15 #include <adf_gen4_pfvf.h>
16 #include <adf_gen4_pm.h>
17 #include <adf_gen4_ras.h>
18 #include <adf_gen4_timer.h>
19 #include <adf_gen4_tl.h>
20 #include <adf_gen4_vf_mig.h>
21 #include "adf_420xx_hw_data.h"
22 #include "icp_qat_hw.h"
24 #define ADF_AE_GROUP_0 GENMASK(3, 0)
25 #define ADF_AE_GROUP_1 GENMASK(7, 4)
26 #define ADF_AE_GROUP_2 GENMASK(11, 8)
27 #define ADF_AE_GROUP_3 GENMASK(15, 12)
28 #define ADF_AE_GROUP_4 BIT(16)
30 #define ENA_THD_MASK_ASYM GENMASK(1, 0)
31 #define ENA_THD_MASK_SYM GENMASK(3, 0)
32 #define ENA_THD_MASK_DC GENMASK(1, 0)
34 static const char * const adf_420xx_fw_objs
[] = {
35 [ADF_FW_SYM_OBJ
] = ADF_420XX_SYM_OBJ
,
36 [ADF_FW_ASYM_OBJ
] = ADF_420XX_ASYM_OBJ
,
37 [ADF_FW_DC_OBJ
] = ADF_420XX_DC_OBJ
,
38 [ADF_FW_ADMIN_OBJ
] = ADF_420XX_ADMIN_OBJ
,
41 static const struct adf_fw_config adf_fw_cy_config
[] = {
42 {ADF_AE_GROUP_3
, ADF_FW_SYM_OBJ
},
43 {ADF_AE_GROUP_2
, ADF_FW_ASYM_OBJ
},
44 {ADF_AE_GROUP_1
, ADF_FW_SYM_OBJ
},
45 {ADF_AE_GROUP_0
, ADF_FW_ASYM_OBJ
},
46 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
49 static const struct adf_fw_config adf_fw_dc_config
[] = {
50 {ADF_AE_GROUP_1
, ADF_FW_DC_OBJ
},
51 {ADF_AE_GROUP_0
, ADF_FW_DC_OBJ
},
52 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
55 static const struct adf_fw_config adf_fw_sym_config
[] = {
56 {ADF_AE_GROUP_3
, ADF_FW_SYM_OBJ
},
57 {ADF_AE_GROUP_2
, ADF_FW_SYM_OBJ
},
58 {ADF_AE_GROUP_1
, ADF_FW_SYM_OBJ
},
59 {ADF_AE_GROUP_0
, ADF_FW_SYM_OBJ
},
60 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
63 static const struct adf_fw_config adf_fw_asym_config
[] = {
64 {ADF_AE_GROUP_3
, ADF_FW_ASYM_OBJ
},
65 {ADF_AE_GROUP_2
, ADF_FW_ASYM_OBJ
},
66 {ADF_AE_GROUP_1
, ADF_FW_ASYM_OBJ
},
67 {ADF_AE_GROUP_0
, ADF_FW_ASYM_OBJ
},
68 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
71 static const struct adf_fw_config adf_fw_asym_dc_config
[] = {
72 {ADF_AE_GROUP_3
, ADF_FW_ASYM_OBJ
},
73 {ADF_AE_GROUP_2
, ADF_FW_ASYM_OBJ
},
74 {ADF_AE_GROUP_1
, ADF_FW_ASYM_OBJ
},
75 {ADF_AE_GROUP_0
, ADF_FW_DC_OBJ
},
76 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
79 static const struct adf_fw_config adf_fw_sym_dc_config
[] = {
80 {ADF_AE_GROUP_2
, ADF_FW_SYM_OBJ
},
81 {ADF_AE_GROUP_1
, ADF_FW_SYM_OBJ
},
82 {ADF_AE_GROUP_0
, ADF_FW_DC_OBJ
},
83 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
86 static const struct adf_fw_config adf_fw_dcc_config
[] = {
87 {ADF_AE_GROUP_1
, ADF_FW_DC_OBJ
},
88 {ADF_AE_GROUP_0
, ADF_FW_SYM_OBJ
},
89 {ADF_AE_GROUP_4
, ADF_FW_ADMIN_OBJ
},
93 static struct adf_hw_device_class adf_420xx_class
= {
94 .name
= ADF_420XX_DEVICE_NAME
,
99 static u32
get_ae_mask(struct adf_hw_device_data
*self
)
101 u32 me_disable
= self
->fuses
;
103 return ~me_disable
& ADF_420XX_ACCELENGINES_MASK
;
106 static u32
uof_get_num_objs(struct adf_accel_dev
*accel_dev
)
108 switch (adf_get_service_enabled(accel_dev
)) {
111 return ARRAY_SIZE(adf_fw_cy_config
);
113 return ARRAY_SIZE(adf_fw_dc_config
);
115 return ARRAY_SIZE(adf_fw_dcc_config
);
117 return ARRAY_SIZE(adf_fw_sym_config
);
119 return ARRAY_SIZE(adf_fw_asym_config
);
122 return ARRAY_SIZE(adf_fw_asym_dc_config
);
125 return ARRAY_SIZE(adf_fw_sym_dc_config
);
131 static const struct adf_fw_config
*get_fw_config(struct adf_accel_dev
*accel_dev
)
133 switch (adf_get_service_enabled(accel_dev
)) {
136 return adf_fw_cy_config
;
138 return adf_fw_dc_config
;
140 return adf_fw_dcc_config
;
142 return adf_fw_sym_config
;
144 return adf_fw_asym_config
;
147 return adf_fw_asym_dc_config
;
150 return adf_fw_sym_dc_config
;
156 static void update_ae_mask(struct adf_accel_dev
*accel_dev
)
158 struct adf_hw_device_data
*hw_data
= GET_HW_DATA(accel_dev
);
159 const struct adf_fw_config
*fw_config
;
160 u32 config_ae_mask
= 0;
161 u32 ae_mask
, num_objs
;
164 ae_mask
= get_ae_mask(hw_data
);
166 /* Modify the AE mask based on the firmware configuration loaded */
167 fw_config
= get_fw_config(accel_dev
);
168 num_objs
= uof_get_num_objs(accel_dev
);
170 config_ae_mask
|= ADF_420XX_ADMIN_AE_MASK
;
171 for (i
= 0; i
< num_objs
; i
++)
172 config_ae_mask
|= fw_config
[i
].ae_mask
;
174 hw_data
->ae_mask
= ae_mask
& config_ae_mask
;
177 static u32
get_accel_cap(struct adf_accel_dev
*accel_dev
)
179 u32 capabilities_sym
, capabilities_asym
, capabilities_dc
;
180 struct pci_dev
*pdev
= accel_dev
->accel_pci_dev
.pci_dev
;
181 u32 capabilities_dcc
;
184 /* As a side effect, update ae_mask based on configuration */
185 update_ae_mask(accel_dev
);
187 /* Read accelerator capabilities mask */
188 pci_read_config_dword(pdev
, ADF_GEN4_FUSECTL1_OFFSET
, &fusectl1
);
190 capabilities_sym
= ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC
|
191 ICP_ACCEL_CAPABILITIES_CIPHER
|
192 ICP_ACCEL_CAPABILITIES_AUTHENTICATION
|
193 ICP_ACCEL_CAPABILITIES_SHA3
|
194 ICP_ACCEL_CAPABILITIES_SHA3_EXT
|
195 ICP_ACCEL_CAPABILITIES_HKDF
|
196 ICP_ACCEL_CAPABILITIES_CHACHA_POLY
|
197 ICP_ACCEL_CAPABILITIES_AESGCM_SPC
|
198 ICP_ACCEL_CAPABILITIES_SM3
|
199 ICP_ACCEL_CAPABILITIES_SM4
|
200 ICP_ACCEL_CAPABILITIES_AES_V2
|
201 ICP_ACCEL_CAPABILITIES_ZUC
|
202 ICP_ACCEL_CAPABILITIES_ZUC_256
|
203 ICP_ACCEL_CAPABILITIES_WIRELESS_CRYPTO_EXT
|
204 ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN
;
206 /* A set bit in fusectl1 means the feature is OFF in this SKU */
207 if (fusectl1
& ICP_ACCEL_GEN4_MASK_CIPHER_SLICE
) {
208 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC
;
209 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_HKDF
;
210 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_CIPHER
;
213 if (fusectl1
& ICP_ACCEL_GEN4_MASK_UCS_SLICE
) {
214 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY
;
215 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC
;
216 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_AES_V2
;
217 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_CIPHER
;
220 if (fusectl1
& ICP_ACCEL_GEN4_MASK_AUTH_SLICE
) {
221 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION
;
222 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_SHA3
;
223 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT
;
224 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_CIPHER
;
227 if (fusectl1
& ICP_ACCEL_GEN4_MASK_SMX_SLICE
) {
228 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_SM3
;
229 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_SM4
;
232 if (fusectl1
& ICP_ACCEL_GEN4_MASK_WCP_WAT_SLICE
) {
233 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_ZUC
;
234 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_ZUC_256
;
235 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_WIRELESS_CRYPTO_EXT
;
238 if (fusectl1
& ICP_ACCEL_GEN4_MASK_EIA3_SLICE
) {
239 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_ZUC
;
240 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_ZUC_256
;
243 if (fusectl1
& ICP_ACCEL_GEN4_MASK_ZUC_256_SLICE
)
244 capabilities_sym
&= ~ICP_ACCEL_CAPABILITIES_ZUC_256
;
246 capabilities_asym
= ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC
|
247 ICP_ACCEL_CAPABILITIES_SM2
|
248 ICP_ACCEL_CAPABILITIES_ECEDMONT
;
250 if (fusectl1
& ICP_ACCEL_GEN4_MASK_PKE_SLICE
) {
251 capabilities_asym
&= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC
;
252 capabilities_asym
&= ~ICP_ACCEL_CAPABILITIES_SM2
;
253 capabilities_asym
&= ~ICP_ACCEL_CAPABILITIES_ECEDMONT
;
256 capabilities_dc
= ICP_ACCEL_CAPABILITIES_COMPRESSION
|
257 ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION
|
258 ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION
|
259 ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64
;
261 if (fusectl1
& ICP_ACCEL_GEN4_MASK_COMPRESS_SLICE
) {
262 capabilities_dc
&= ~ICP_ACCEL_CAPABILITIES_COMPRESSION
;
263 capabilities_dc
&= ~ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION
;
264 capabilities_dc
&= ~ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION
;
265 capabilities_dc
&= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64
;
268 switch (adf_get_service_enabled(accel_dev
)) {
271 return capabilities_sym
| capabilities_asym
;
273 return capabilities_dc
;
276 * Sym capabilities are available for chaining operations,
277 * but sym crypto instances cannot be supported
279 capabilities_dcc
= capabilities_dc
| capabilities_sym
;
280 capabilities_dcc
&= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC
;
281 return capabilities_dcc
;
283 return capabilities_sym
;
285 return capabilities_asym
;
288 return capabilities_asym
| capabilities_dc
;
291 return capabilities_sym
| capabilities_dc
;
297 static const u32
*adf_get_arbiter_mapping(struct adf_accel_dev
*accel_dev
)
299 if (adf_gen4_init_thd2arb_map(accel_dev
))
300 dev_warn(&GET_DEV(accel_dev
),
301 "Failed to generate thread to arbiter mapping");
303 return GET_HW_DATA(accel_dev
)->thd_to_arb_map
;
306 static void adf_init_rl_data(struct adf_rl_hw_data
*rl_data
)
308 rl_data
->pciout_tb_offset
= ADF_GEN4_RL_TOKEN_PCIEOUT_BUCKET_OFFSET
;
309 rl_data
->pciin_tb_offset
= ADF_GEN4_RL_TOKEN_PCIEIN_BUCKET_OFFSET
;
310 rl_data
->r2l_offset
= ADF_GEN4_RL_R2L_OFFSET
;
311 rl_data
->l2c_offset
= ADF_GEN4_RL_L2C_OFFSET
;
312 rl_data
->c2s_offset
= ADF_GEN4_RL_C2S_OFFSET
;
314 rl_data
->pcie_scale_div
= ADF_420XX_RL_PCIE_SCALE_FACTOR_DIV
;
315 rl_data
->pcie_scale_mul
= ADF_420XX_RL_PCIE_SCALE_FACTOR_MUL
;
316 rl_data
->dcpr_correction
= ADF_420XX_RL_DCPR_CORRECTION
;
317 rl_data
->max_tp
[ADF_SVC_ASYM
] = ADF_420XX_RL_MAX_TP_ASYM
;
318 rl_data
->max_tp
[ADF_SVC_SYM
] = ADF_420XX_RL_MAX_TP_SYM
;
319 rl_data
->max_tp
[ADF_SVC_DC
] = ADF_420XX_RL_MAX_TP_DC
;
320 rl_data
->scan_interval
= ADF_420XX_RL_SCANS_PER_SEC
;
321 rl_data
->scale_ref
= ADF_420XX_RL_SLICE_REF
;
324 static int get_rp_group(struct adf_accel_dev
*accel_dev
, u32 ae_mask
)
333 if (get_fw_config(accel_dev
) == adf_fw_cy_config
)
338 dev_dbg(&GET_DEV(accel_dev
), "ae_mask not recognized");
343 static u32
get_ena_thd_mask(struct adf_accel_dev
*accel_dev
, u32 obj_num
)
345 const struct adf_fw_config
*fw_config
;
347 if (obj_num
>= uof_get_num_objs(accel_dev
))
348 return ADF_GEN4_ENA_THD_MASK_ERROR
;
350 fw_config
= get_fw_config(accel_dev
);
352 return ADF_GEN4_ENA_THD_MASK_ERROR
;
354 switch (fw_config
[obj_num
].obj
) {
355 case ADF_FW_ASYM_OBJ
:
356 return ENA_THD_MASK_ASYM
;
358 return ENA_THD_MASK_SYM
;
360 return ENA_THD_MASK_DC
;
362 return ADF_GEN4_ENA_THD_MASK_ERROR
;
366 static const char *uof_get_name(struct adf_accel_dev
*accel_dev
, u32 obj_num
,
367 const char * const fw_objs
[], int num_objs
)
369 const struct adf_fw_config
*fw_config
;
372 fw_config
= get_fw_config(accel_dev
);
374 id
= fw_config
[obj_num
].obj
;
378 if (id
< 0 || id
>= num_objs
)
384 static const char *uof_get_name_420xx(struct adf_accel_dev
*accel_dev
, u32 obj_num
)
386 int num_fw_objs
= ARRAY_SIZE(adf_420xx_fw_objs
);
388 return uof_get_name(accel_dev
, obj_num
, adf_420xx_fw_objs
, num_fw_objs
);
391 static int uof_get_obj_type(struct adf_accel_dev
*accel_dev
, u32 obj_num
)
393 const struct adf_fw_config
*fw_config
;
395 if (obj_num
>= uof_get_num_objs(accel_dev
))
398 fw_config
= get_fw_config(accel_dev
);
402 return fw_config
[obj_num
].obj
;
405 static u32
uof_get_ae_mask(struct adf_accel_dev
*accel_dev
, u32 obj_num
)
407 const struct adf_fw_config
*fw_config
;
409 fw_config
= get_fw_config(accel_dev
);
413 return fw_config
[obj_num
].ae_mask
;
416 static void adf_gen4_set_err_mask(struct adf_dev_err_mask
*dev_err_mask
)
418 dev_err_mask
->cppagentcmdpar_mask
= ADF_420XX_HICPPAGENTCMDPARERRLOG_MASK
;
419 dev_err_mask
->parerr_ath_cph_mask
= ADF_420XX_PARITYERRORMASK_ATH_CPH_MASK
;
420 dev_err_mask
->parerr_cpr_xlt_mask
= ADF_420XX_PARITYERRORMASK_CPR_XLT_MASK
;
421 dev_err_mask
->parerr_dcpr_ucs_mask
= ADF_420XX_PARITYERRORMASK_DCPR_UCS_MASK
;
422 dev_err_mask
->parerr_pke_mask
= ADF_420XX_PARITYERRORMASK_PKE_MASK
;
423 dev_err_mask
->ssmfeatren_mask
= ADF_420XX_SSMFEATREN_MASK
;
426 void adf_init_hw_data_420xx(struct adf_hw_device_data
*hw_data
, u32 dev_id
)
428 hw_data
->dev_class
= &adf_420xx_class
;
429 hw_data
->instance_id
= adf_420xx_class
.instances
++;
430 hw_data
->num_banks
= ADF_GEN4_ETR_MAX_BANKS
;
431 hw_data
->num_banks_per_vf
= ADF_GEN4_NUM_BANKS_PER_VF
;
432 hw_data
->num_rings_per_bank
= ADF_GEN4_NUM_RINGS_PER_BANK
;
433 hw_data
->num_accel
= ADF_GEN4_MAX_ACCELERATORS
;
434 hw_data
->num_engines
= ADF_420XX_MAX_ACCELENGINES
;
435 hw_data
->num_logical_accel
= 1;
436 hw_data
->tx_rx_gap
= ADF_GEN4_RX_RINGS_OFFSET
;
437 hw_data
->tx_rings_mask
= ADF_GEN4_TX_RINGS_MASK
;
438 hw_data
->ring_to_svc_map
= ADF_GEN4_DEFAULT_RING_TO_SRV_MAP
;
439 hw_data
->alloc_irq
= adf_isr_resource_alloc
;
440 hw_data
->free_irq
= adf_isr_resource_free
;
441 hw_data
->enable_error_correction
= adf_gen4_enable_error_correction
;
442 hw_data
->get_accel_mask
= adf_gen4_get_accel_mask
;
443 hw_data
->get_ae_mask
= get_ae_mask
;
444 hw_data
->get_num_accels
= adf_gen4_get_num_accels
;
445 hw_data
->get_num_aes
= adf_gen4_get_num_aes
;
446 hw_data
->get_sram_bar_id
= adf_gen4_get_sram_bar_id
;
447 hw_data
->get_etr_bar_id
= adf_gen4_get_etr_bar_id
;
448 hw_data
->get_misc_bar_id
= adf_gen4_get_misc_bar_id
;
449 hw_data
->get_arb_info
= adf_gen4_get_arb_info
;
450 hw_data
->get_admin_info
= adf_gen4_get_admin_info
;
451 hw_data
->get_accel_cap
= get_accel_cap
;
452 hw_data
->get_sku
= adf_gen4_get_sku
;
453 hw_data
->init_admin_comms
= adf_init_admin_comms
;
454 hw_data
->exit_admin_comms
= adf_exit_admin_comms
;
455 hw_data
->send_admin_init
= adf_send_admin_init
;
456 hw_data
->init_arb
= adf_init_arb
;
457 hw_data
->exit_arb
= adf_exit_arb
;
458 hw_data
->get_arb_mapping
= adf_get_arbiter_mapping
;
459 hw_data
->enable_ints
= adf_gen4_enable_ints
;
460 hw_data
->init_device
= adf_gen4_init_device
;
461 hw_data
->reset_device
= adf_reset_flr
;
462 hw_data
->admin_ae_mask
= ADF_420XX_ADMIN_AE_MASK
;
463 hw_data
->num_rps
= ADF_GEN4_MAX_RPS
;
464 hw_data
->fw_name
= ADF_420XX_FW
;
465 hw_data
->fw_mmp_name
= ADF_420XX_MMP
;
466 hw_data
->uof_get_name
= uof_get_name_420xx
;
467 hw_data
->uof_get_num_objs
= uof_get_num_objs
;
468 hw_data
->uof_get_obj_type
= uof_get_obj_type
;
469 hw_data
->uof_get_ae_mask
= uof_get_ae_mask
;
470 hw_data
->get_rp_group
= get_rp_group
;
471 hw_data
->get_ena_thd_mask
= get_ena_thd_mask
;
472 hw_data
->set_msix_rttable
= adf_gen4_set_msix_default_rttable
;
473 hw_data
->set_ssm_wdtimer
= adf_gen4_set_ssm_wdtimer
;
474 hw_data
->get_ring_to_svc_map
= adf_gen4_get_ring_to_svc_map
;
475 hw_data
->disable_iov
= adf_disable_sriov
;
476 hw_data
->ring_pair_reset
= adf_gen4_ring_pair_reset
;
477 hw_data
->enable_pm
= adf_gen4_enable_pm
;
478 hw_data
->handle_pm_interrupt
= adf_gen4_handle_pm_interrupt
;
479 hw_data
->dev_config
= adf_gen4_dev_config
;
480 hw_data
->start_timer
= adf_gen4_timer_start
;
481 hw_data
->stop_timer
= adf_gen4_timer_stop
;
482 hw_data
->get_hb_clock
= adf_gen4_get_heartbeat_clock
;
483 hw_data
->num_hb_ctrs
= ADF_NUM_HB_CNT_PER_AE
;
484 hw_data
->clock_frequency
= ADF_420XX_AE_FREQ
;
486 adf_gen4_set_err_mask(&hw_data
->dev_err_mask
);
487 adf_gen4_init_hw_csr_ops(&hw_data
->csr_ops
);
488 adf_gen4_init_pf_pfvf_ops(&hw_data
->pfvf_ops
);
489 adf_gen4_init_dc_ops(&hw_data
->dc_ops
);
490 adf_gen4_init_ras_ops(&hw_data
->ras_ops
);
491 adf_gen4_init_tl_data(&hw_data
->tl_data
);
492 adf_gen4_init_vf_mig_ops(&hw_data
->vfmig_ops
);
493 adf_init_rl_data(&hw_data
->rl_data
);
496 void adf_clean_hw_data_420xx(struct adf_hw_device_data
*hw_data
)
498 hw_data
->dev_class
->instances
--;