1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 #include <adf_accel_devices.h> 5 #include <adf_common_drv.h> 6 #include <adf_cfg.h> 7 #include <adf_pf2vf_msg.h> 8 #include <adf_dev_err.h> 9 #include <adf_gen2_hw_data.h> 10 #include "adf_c3xxx_hw_data.h" 11 #include "icp_qat_hw.h" 12 #include "adf_heartbeat.h" 13 14 /* Worker thread to service arbiter mappings */ 15 static const u32 thrd_to_arb_map[ADF_C3XXX_MAX_ACCELENGINES] = 16 { 0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA, 0x12222AAA, 0x11222AAA }; 17 18 enum { DEV_C3XXX_SKU_1 = 0, DEV_C3XXX_SKU_2 = 1, DEV_C3XXX_SKU_3 = 2 }; 19 20 static u32 thrd_to_arb_map_gen[ADF_C3XXX_MAX_ACCELENGINES] = { 0 }; 21 22 static struct adf_hw_device_class c3xxx_class = {.name = ADF_C3XXX_DEVICE_NAME, 23 .type = DEV_C3XXX, 24 .instances = 0 }; 25 26 static u32 27 get_accel_mask(struct adf_accel_dev *accel_dev) 28 { 29 device_t pdev = accel_dev->accel_pci_dev.pci_dev; 30 31 u32 fuse; 32 u32 straps; 33 34 fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4); 35 straps = pci_read_config(pdev, ADF_C3XXX_SOFTSTRAP_CSR_OFFSET, 4); 36 37 return (~(fuse | straps)) >> ADF_C3XXX_ACCELERATORS_REG_OFFSET & 38 ADF_C3XXX_ACCELERATORS_MASK; 39 } 40 41 static u32 42 get_ae_mask(struct adf_accel_dev *accel_dev) 43 { 44 device_t pdev = accel_dev->accel_pci_dev.pci_dev; 45 u32 fuse; 46 u32 me_straps; 47 u32 me_disable; 48 u32 ssms_disabled; 49 50 fuse = pci_read_config(pdev, ADF_DEVICE_FUSECTL_OFFSET, 4); 51 me_straps = pci_read_config(pdev, ADF_C3XXX_SOFTSTRAP_CSR_OFFSET, 4); 52 53 /* If SSMs are disabled, then disable the corresponding MEs */ 54 ssms_disabled = 55 (~get_accel_mask(accel_dev)) & ADF_C3XXX_ACCELERATORS_MASK; 56 me_disable = 0x3; 57 while (ssms_disabled) { 58 if (ssms_disabled & 1) 59 me_straps |= me_disable; 60 ssms_disabled >>= 1; 61 me_disable <<= 2; 62 } 63 64 return (~(fuse | me_straps)) & ADF_C3XXX_ACCELENGINES_MASK; 65 } 66 67 static u32 68 get_num_accels(struct adf_hw_device_data *self) 69 { 70 u32 i, ctr = 0; 71 72 if (!self || !self->accel_mask) 73 return 0; 74 75 for (i = 0; i < ADF_C3XXX_MAX_ACCELERATORS; i++) { 76 if (self->accel_mask & (1 << i)) 77 ctr++; 78 } 79 return ctr; 80 } 81 82 static u32 83 get_num_aes(struct adf_hw_device_data *self) 84 { 85 u32 i, ctr = 0; 86 87 if (!self || !self->ae_mask) 88 return 0; 89 90 for (i = 0; i < ADF_C3XXX_MAX_ACCELENGINES; i++) { 91 if (self->ae_mask & (1 << i)) 92 ctr++; 93 } 94 return ctr; 95 } 96 97 static u32 98 get_misc_bar_id(struct adf_hw_device_data *self) 99 { 100 return ADF_C3XXX_PMISC_BAR; 101 } 102 103 static u32 104 get_etr_bar_id(struct adf_hw_device_data *self) 105 { 106 return ADF_C3XXX_ETR_BAR; 107 } 108 109 static u32 110 get_sram_bar_id(struct adf_hw_device_data *self) 111 { 112 return 0; 113 } 114 115 static enum dev_sku_info 116 get_sku(struct adf_hw_device_data *self) 117 { 118 int aes = get_num_aes(self); 119 120 if (aes == 6) 121 return DEV_SKU_4; 122 123 return DEV_SKU_UNKNOWN; 124 } 125 126 static void 127 adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev, 128 u32 const **arb_map_config) 129 { 130 int i; 131 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 132 133 for (i = 0; i < ADF_C3XXX_MAX_ACCELENGINES; i++) { 134 thrd_to_arb_map_gen[i] = 0; 135 if (hw_device->ae_mask & (1 << i)) 136 thrd_to_arb_map_gen[i] = thrd_to_arb_map[i]; 137 } 138 adf_cfg_gen_dispatch_arbiter(accel_dev, 139 thrd_to_arb_map, 140 thrd_to_arb_map_gen, 141 ADF_C3XXX_MAX_ACCELENGINES); 142 *arb_map_config = thrd_to_arb_map_gen; 143 } 144 145 static u32 146 get_pf2vf_offset(u32 i) 147 { 148 return ADF_C3XXX_PF2VF_OFFSET(i); 149 } 150 151 static u32 152 get_vintmsk_offset(u32 i) 153 { 154 return ADF_C3XXX_VINTMSK_OFFSET(i); 155 } 156 157 static void 158 get_arb_info(struct arb_info *arb_csrs_info) 159 { 160 arb_csrs_info->arbiter_offset = ADF_C3XXX_ARB_OFFSET; 161 arb_csrs_info->wrk_thd_2_srv_arb_map = 162 ADF_C3XXX_ARB_WRK_2_SER_MAP_OFFSET; 163 arb_csrs_info->wrk_cfg_offset = ADF_C3XXX_ARB_WQCFG_OFFSET; 164 } 165 166 static void 167 get_admin_info(struct admin_info *admin_csrs_info) 168 { 169 admin_csrs_info->mailbox_offset = ADF_C3XXX_MAILBOX_BASE_OFFSET; 170 admin_csrs_info->admin_msg_ur = ADF_C3XXX_ADMINMSGUR_OFFSET; 171 admin_csrs_info->admin_msg_lr = ADF_C3XXX_ADMINMSGLR_OFFSET; 172 } 173 174 static void 175 get_errsou_offset(u32 *errsou3, u32 *errsou5) 176 { 177 *errsou3 = ADF_C3XXX_ERRSOU3; 178 *errsou5 = ADF_C3XXX_ERRSOU5; 179 } 180 181 static u32 182 get_clock_speed(struct adf_hw_device_data *self) 183 { 184 /* CPP clock is half high-speed clock */ 185 return self->clock_frequency / 2; 186 } 187 188 static void 189 adf_enable_error_correction(struct adf_accel_dev *accel_dev) 190 { 191 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 192 struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR]; 193 struct resource *csr = misc_bar->virt_addr; 194 unsigned int val, i; 195 unsigned int mask; 196 197 /* Enable Accel Engine error detection & correction */ 198 mask = hw_device->ae_mask; 199 for (i = 0; mask; i++, mask >>= 1) { 200 if (!(mask & 1)) 201 continue; 202 val = ADF_CSR_RD(csr, ADF_C3XXX_AE_CTX_ENABLES(i)); 203 val |= ADF_C3XXX_ENABLE_AE_ECC_ERR; 204 ADF_CSR_WR(csr, ADF_C3XXX_AE_CTX_ENABLES(i), val); 205 val = ADF_CSR_RD(csr, ADF_C3XXX_AE_MISC_CONTROL(i)); 206 val |= ADF_C3XXX_ENABLE_AE_ECC_PARITY_CORR; 207 ADF_CSR_WR(csr, ADF_C3XXX_AE_MISC_CONTROL(i), val); 208 } 209 210 /* Enable shared memory error detection & correction */ 211 mask = hw_device->accel_mask; 212 for (i = 0; mask; i++, mask >>= 1) { 213 if (!(mask & 1)) 214 continue; 215 val = ADF_CSR_RD(csr, ADF_C3XXX_UERRSSMSH(i)); 216 val |= ADF_C3XXX_ERRSSMSH_EN; 217 ADF_CSR_WR(csr, ADF_C3XXX_UERRSSMSH(i), val); 218 val = ADF_CSR_RD(csr, ADF_C3XXX_CERRSSMSH(i)); 219 val |= ADF_C3XXX_ERRSSMSH_EN; 220 ADF_CSR_WR(csr, ADF_C3XXX_CERRSSMSH(i), val); 221 } 222 } 223 224 static void 225 adf_enable_ints(struct adf_accel_dev *accel_dev) 226 { 227 struct resource *addr; 228 229 addr = (&GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR])->virt_addr; 230 231 /* Enable bundle and misc interrupts */ 232 ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF0_MASK_OFFSET, ADF_C3XXX_SMIA0_MASK); 233 ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF1_MASK_OFFSET, ADF_C3XXX_SMIA1_MASK); 234 } 235 236 static u32 237 get_ae_clock(struct adf_hw_device_data *self) 238 { 239 /* 240 * Clock update interval is <16> ticks for c3xxx. 241 */ 242 return self->clock_frequency / 16; 243 } 244 245 static int 246 get_storage_enabled(struct adf_accel_dev *accel_dev, uint32_t *storage_enabled) 247 { 248 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; 249 char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; 250 251 strlcpy(key, ADF_STORAGE_FIRMWARE_ENABLED, sizeof(key)); 252 if (!adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) { 253 if (kstrtouint(val, 0, storage_enabled)) 254 return -EFAULT; 255 } 256 return 0; 257 } 258 259 static int 260 measure_clock(struct adf_accel_dev *accel_dev) 261 { 262 u32 frequency; 263 int ret = 0; 264 265 ret = adf_dev_measure_clock(accel_dev, 266 &frequency, 267 ADF_C3XXX_MIN_AE_FREQ, 268 ADF_C3XXX_MAX_AE_FREQ); 269 if (ret) 270 return ret; 271 272 accel_dev->hw_device->clock_frequency = frequency; 273 return 0; 274 } 275 276 static u32 277 c3xxx_get_hw_cap(struct adf_accel_dev *accel_dev) 278 { 279 device_t pdev = accel_dev->accel_pci_dev.pci_dev; 280 u32 legfuses; 281 u32 capabilities; 282 u32 straps; 283 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 284 u32 fuses = hw_data->fuses; 285 286 /* Read accelerator capabilities mask */ 287 legfuses = pci_read_config(pdev, ADF_DEVICE_LEGFUSE_OFFSET, 4); 288 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC + 289 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC + 290 ICP_ACCEL_CAPABILITIES_CIPHER + 291 ICP_ACCEL_CAPABILITIES_AUTHENTICATION + 292 ICP_ACCEL_CAPABILITIES_COMPRESSION + ICP_ACCEL_CAPABILITIES_ZUC + 293 ICP_ACCEL_CAPABILITIES_SHA3 + ICP_ACCEL_CAPABILITIES_HKDF + 294 ICP_ACCEL_CAPABILITIES_ECEDMONT + 295 ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN; 296 if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) 297 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | 298 ICP_ACCEL_CAPABILITIES_CIPHER | 299 ICP_ACCEL_CAPABILITIES_HKDF | 300 ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN); 301 if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) 302 capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; 303 if (legfuses & ICP_ACCEL_MASK_PKE_SLICE) 304 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | 305 ICP_ACCEL_CAPABILITIES_ECEDMONT); 306 if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) 307 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; 308 if (legfuses & ICP_ACCEL_MASK_EIA3_SLICE) 309 capabilities &= ~ICP_ACCEL_CAPABILITIES_ZUC; 310 if (legfuses & ICP_ACCEL_MASK_SHA3_SLICE) 311 capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3; 312 313 straps = pci_read_config(pdev, ADF_C3XXX_SOFTSTRAP_CSR_OFFSET, 4); 314 if ((straps | fuses) & ADF_C3XXX_POWERGATE_PKE) 315 capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; 316 if ((straps | fuses) & ADF_C3XXX_POWERGATE_CY) 317 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; 318 319 return capabilities; 320 } 321 322 static const char * 323 get_obj_name(struct adf_accel_dev *accel_dev, 324 enum adf_accel_unit_services service) 325 { 326 return ADF_CXXX_AE_FW_NAME_CUSTOM1; 327 } 328 329 static uint32_t 330 get_objs_num(struct adf_accel_dev *accel_dev) 331 { 332 return 1; 333 } 334 335 static uint32_t 336 get_obj_cfg_ae_mask(struct adf_accel_dev *accel_dev, 337 enum adf_accel_unit_services services) 338 { 339 return accel_dev->hw_device->ae_mask; 340 } 341 342 void 343 adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) 344 { 345 hw_data->dev_class = &c3xxx_class; 346 hw_data->instance_id = c3xxx_class.instances++; 347 hw_data->num_banks = ADF_C3XXX_ETR_MAX_BANKS; 348 hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK; 349 hw_data->num_accel = ADF_C3XXX_MAX_ACCELERATORS; 350 hw_data->num_logical_accel = 1; 351 hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES; 352 hw_data->tx_rx_gap = ADF_C3XXX_RX_RINGS_OFFSET; 353 hw_data->tx_rings_mask = ADF_C3XXX_TX_RINGS_MASK; 354 hw_data->alloc_irq = adf_isr_resource_alloc; 355 hw_data->free_irq = adf_isr_resource_free; 356 hw_data->enable_error_correction = adf_enable_error_correction; 357 hw_data->print_err_registers = adf_print_err_registers; 358 hw_data->get_accel_mask = get_accel_mask; 359 hw_data->get_ae_mask = get_ae_mask; 360 hw_data->get_num_accels = get_num_accels; 361 hw_data->get_num_aes = get_num_aes; 362 hw_data->get_sram_bar_id = get_sram_bar_id; 363 hw_data->get_etr_bar_id = get_etr_bar_id; 364 hw_data->get_misc_bar_id = get_misc_bar_id; 365 hw_data->get_pf2vf_offset = get_pf2vf_offset; 366 hw_data->get_vintmsk_offset = get_vintmsk_offset; 367 hw_data->get_arb_info = get_arb_info; 368 hw_data->get_admin_info = get_admin_info; 369 hw_data->get_errsou_offset = get_errsou_offset; 370 hw_data->get_clock_speed = get_clock_speed; 371 hw_data->get_sku = get_sku; 372 hw_data->heartbeat_ctr_num = ADF_NUM_HB_CNT_PER_AE; 373 hw_data->fw_name = ADF_C3XXX_FW; 374 hw_data->fw_mmp_name = ADF_C3XXX_MMP; 375 hw_data->init_admin_comms = adf_init_admin_comms; 376 hw_data->exit_admin_comms = adf_exit_admin_comms; 377 hw_data->disable_iov = adf_disable_sriov; 378 hw_data->send_admin_init = adf_send_admin_init; 379 hw_data->init_arb = adf_init_gen2_arb; 380 hw_data->exit_arb = adf_exit_arb; 381 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 382 hw_data->enable_ints = adf_enable_ints; 383 hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; 384 hw_data->check_slice_hang = adf_check_slice_hang; 385 hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; 386 hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; 387 hw_data->restore_device = adf_dev_restore; 388 hw_data->reset_device = adf_reset_flr; 389 hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; 390 hw_data->measure_clock = measure_clock; 391 hw_data->get_ae_clock = get_ae_clock; 392 hw_data->reset_device = adf_reset_flr; 393 hw_data->get_objs_num = get_objs_num; 394 hw_data->get_obj_name = get_obj_name; 395 hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask; 396 hw_data->get_accel_cap = c3xxx_get_hw_cap; 397 hw_data->clock_frequency = ADF_C3XXX_AE_FREQ; 398 hw_data->extended_dc_capabilities = 0; 399 hw_data->get_storage_enabled = get_storage_enabled; 400 hw_data->query_storage_cap = 1; 401 hw_data->get_heartbeat_status = adf_get_heartbeat_status; 402 hw_data->get_ae_clock = get_ae_clock; 403 hw_data->storage_enable = 0; 404 hw_data->get_fw_image_type = adf_cfg_get_fw_image_type; 405 hw_data->get_ring_to_svc_map = adf_cfg_get_services_enabled; 406 hw_data->config_device = adf_config_device; 407 hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; 408 hw_data->ring_to_svc_map = ADF_DEFAULT_RING_TO_SRV_MAP; 409 hw_data->pre_reset = adf_dev_pre_reset; 410 hw_data->post_reset = adf_dev_post_reset; 411 412 adf_gen2_init_hw_csr_info(&hw_data->csr_info); 413 } 414 415 void 416 adf_clean_hw_data_c3xxx(struct adf_hw_device_data *hw_data) 417 { 418 hw_data->dev_class->instances--; 419 } 420