1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 #include <adf_accel_devices.h> 4 #include <adf_common_drv.h> 5 #include <adf_cfg.h> 6 #include <adf_pfvf_msg.h> 7 #include <adf_dev_err.h> 8 #include <adf_gen2_hw_data.h> 9 #include <adf_gen2_pfvf.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 void 146 get_arb_info(struct arb_info *arb_csrs_info) 147 { 148 arb_csrs_info->arbiter_offset = ADF_C3XXX_ARB_OFFSET; 149 arb_csrs_info->wrk_thd_2_srv_arb_map = 150 ADF_C3XXX_ARB_WRK_2_SER_MAP_OFFSET; 151 arb_csrs_info->wrk_cfg_offset = ADF_C3XXX_ARB_WQCFG_OFFSET; 152 } 153 154 static void 155 get_admin_info(struct admin_info *admin_csrs_info) 156 { 157 admin_csrs_info->mailbox_offset = ADF_C3XXX_MAILBOX_BASE_OFFSET; 158 admin_csrs_info->admin_msg_ur = ADF_C3XXX_ADMINMSGUR_OFFSET; 159 admin_csrs_info->admin_msg_lr = ADF_C3XXX_ADMINMSGLR_OFFSET; 160 } 161 162 static void 163 get_errsou_offset(u32 *errsou3, u32 *errsou5) 164 { 165 *errsou3 = ADF_C3XXX_ERRSOU3; 166 *errsou5 = ADF_C3XXX_ERRSOU5; 167 } 168 169 static u32 170 get_clock_speed(struct adf_hw_device_data *self) 171 { 172 /* CPP clock is half high-speed clock */ 173 return self->clock_frequency / 2; 174 } 175 176 static void 177 adf_enable_error_correction(struct adf_accel_dev *accel_dev) 178 { 179 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 180 struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR]; 181 struct resource *csr = misc_bar->virt_addr; 182 unsigned int val, i; 183 unsigned int mask; 184 185 /* Enable Accel Engine error detection & correction */ 186 mask = hw_device->ae_mask; 187 for (i = 0; mask; i++, mask >>= 1) { 188 if (!(mask & 1)) 189 continue; 190 val = ADF_CSR_RD(csr, ADF_C3XXX_AE_CTX_ENABLES(i)); 191 val |= ADF_C3XXX_ENABLE_AE_ECC_ERR; 192 ADF_CSR_WR(csr, ADF_C3XXX_AE_CTX_ENABLES(i), val); 193 val = ADF_CSR_RD(csr, ADF_C3XXX_AE_MISC_CONTROL(i)); 194 val |= ADF_C3XXX_ENABLE_AE_ECC_PARITY_CORR; 195 ADF_CSR_WR(csr, ADF_C3XXX_AE_MISC_CONTROL(i), val); 196 } 197 198 /* Enable shared memory error detection & correction */ 199 mask = hw_device->accel_mask; 200 for (i = 0; mask; i++, mask >>= 1) { 201 if (!(mask & 1)) 202 continue; 203 val = ADF_CSR_RD(csr, ADF_C3XXX_UERRSSMSH(i)); 204 val |= ADF_C3XXX_ERRSSMSH_EN; 205 ADF_CSR_WR(csr, ADF_C3XXX_UERRSSMSH(i), val); 206 val = ADF_CSR_RD(csr, ADF_C3XXX_CERRSSMSH(i)); 207 val |= ADF_C3XXX_ERRSSMSH_EN; 208 ADF_CSR_WR(csr, ADF_C3XXX_CERRSSMSH(i), val); 209 } 210 } 211 212 static void 213 adf_enable_ints(struct adf_accel_dev *accel_dev) 214 { 215 struct resource *addr; 216 217 addr = (&GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR])->virt_addr; 218 219 /* Enable bundle and misc interrupts */ 220 ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF0_MASK_OFFSET, ADF_C3XXX_SMIA0_MASK); 221 ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF1_MASK_OFFSET, ADF_C3XXX_SMIA1_MASK); 222 } 223 224 static u32 225 get_ae_clock(struct adf_hw_device_data *self) 226 { 227 /* 228 * Clock update interval is <16> ticks for c3xxx. 229 */ 230 return self->clock_frequency / 16; 231 } 232 233 static int 234 get_storage_enabled(struct adf_accel_dev *accel_dev, uint32_t *storage_enabled) 235 { 236 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; 237 char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; 238 239 strlcpy(key, ADF_STORAGE_FIRMWARE_ENABLED, sizeof(key)); 240 if (!adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) { 241 if (kstrtouint(val, 0, storage_enabled)) 242 return -EFAULT; 243 } 244 return 0; 245 } 246 247 static int 248 measure_clock(struct adf_accel_dev *accel_dev) 249 { 250 u32 frequency; 251 int ret = 0; 252 253 ret = adf_dev_measure_clock(accel_dev, 254 &frequency, 255 ADF_C3XXX_MIN_AE_FREQ, 256 ADF_C3XXX_MAX_AE_FREQ); 257 if (ret) 258 return ret; 259 260 accel_dev->hw_device->clock_frequency = frequency; 261 return 0; 262 } 263 264 static u32 265 c3xxx_get_hw_cap(struct adf_accel_dev *accel_dev) 266 { 267 device_t pdev = accel_dev->accel_pci_dev.pci_dev; 268 u32 legfuses; 269 u32 capabilities; 270 u32 straps; 271 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 272 u32 fuses = hw_data->fuses; 273 274 /* Read accelerator capabilities mask */ 275 legfuses = pci_read_config(pdev, ADF_DEVICE_LEGFUSE_OFFSET, 4); 276 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC + 277 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC + 278 ICP_ACCEL_CAPABILITIES_CIPHER + 279 ICP_ACCEL_CAPABILITIES_AUTHENTICATION + 280 ICP_ACCEL_CAPABILITIES_COMPRESSION + ICP_ACCEL_CAPABILITIES_ZUC + 281 ICP_ACCEL_CAPABILITIES_SHA3 + ICP_ACCEL_CAPABILITIES_HKDF + 282 ICP_ACCEL_CAPABILITIES_ECEDMONT + 283 ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN; 284 if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) 285 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | 286 ICP_ACCEL_CAPABILITIES_CIPHER | 287 ICP_ACCEL_CAPABILITIES_HKDF | 288 ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN); 289 if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) 290 capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; 291 if (legfuses & ICP_ACCEL_MASK_PKE_SLICE) 292 capabilities &= ~(ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | 293 ICP_ACCEL_CAPABILITIES_ECEDMONT); 294 if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) 295 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; 296 if (legfuses & ICP_ACCEL_MASK_EIA3_SLICE) 297 capabilities &= ~ICP_ACCEL_CAPABILITIES_ZUC; 298 if (legfuses & ICP_ACCEL_MASK_SHA3_SLICE) 299 capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3; 300 301 straps = pci_read_config(pdev, ADF_C3XXX_SOFTSTRAP_CSR_OFFSET, 4); 302 if ((straps | fuses) & ADF_C3XXX_POWERGATE_PKE) 303 capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; 304 if ((straps | fuses) & ADF_C3XXX_POWERGATE_CY) 305 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; 306 307 return capabilities; 308 } 309 310 static const char * 311 get_obj_name(struct adf_accel_dev *accel_dev, 312 enum adf_accel_unit_services service) 313 { 314 return ADF_CXXX_AE_FW_NAME_CUSTOM1; 315 } 316 317 static uint32_t 318 get_objs_num(struct adf_accel_dev *accel_dev) 319 { 320 return 1; 321 } 322 323 static uint32_t 324 get_obj_cfg_ae_mask(struct adf_accel_dev *accel_dev, 325 enum adf_accel_unit_services services) 326 { 327 return accel_dev->hw_device->ae_mask; 328 } 329 330 void 331 adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) 332 { 333 hw_data->dev_class = &c3xxx_class; 334 hw_data->instance_id = c3xxx_class.instances++; 335 hw_data->num_banks = ADF_C3XXX_ETR_MAX_BANKS; 336 hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK; 337 hw_data->num_accel = ADF_C3XXX_MAX_ACCELERATORS; 338 hw_data->num_logical_accel = 1; 339 hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES; 340 hw_data->tx_rx_gap = ADF_C3XXX_RX_RINGS_OFFSET; 341 hw_data->tx_rings_mask = ADF_C3XXX_TX_RINGS_MASK; 342 hw_data->alloc_irq = adf_isr_resource_alloc; 343 hw_data->free_irq = adf_isr_resource_free; 344 hw_data->enable_error_correction = adf_enable_error_correction; 345 hw_data->print_err_registers = adf_print_err_registers; 346 hw_data->get_accel_mask = get_accel_mask; 347 hw_data->get_ae_mask = get_ae_mask; 348 hw_data->get_num_accels = get_num_accels; 349 hw_data->get_num_aes = get_num_aes; 350 hw_data->get_sram_bar_id = get_sram_bar_id; 351 hw_data->get_etr_bar_id = get_etr_bar_id; 352 hw_data->get_misc_bar_id = get_misc_bar_id; 353 hw_data->get_arb_info = get_arb_info; 354 hw_data->get_admin_info = get_admin_info; 355 hw_data->get_errsou_offset = get_errsou_offset; 356 hw_data->get_clock_speed = get_clock_speed; 357 hw_data->get_sku = get_sku; 358 hw_data->heartbeat_ctr_num = ADF_NUM_HB_CNT_PER_AE; 359 hw_data->fw_name = ADF_C3XXX_FW; 360 hw_data->fw_mmp_name = ADF_C3XXX_MMP; 361 hw_data->init_admin_comms = adf_init_admin_comms; 362 hw_data->exit_admin_comms = adf_exit_admin_comms; 363 hw_data->disable_iov = adf_disable_sriov; 364 hw_data->send_admin_init = adf_send_admin_init; 365 hw_data->init_arb = adf_init_gen2_arb; 366 hw_data->exit_arb = adf_exit_arb; 367 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 368 hw_data->enable_ints = adf_enable_ints; 369 hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; 370 hw_data->check_slice_hang = adf_check_slice_hang; 371 hw_data->restore_device = adf_dev_restore; 372 hw_data->reset_device = adf_reset_flr; 373 hw_data->measure_clock = measure_clock; 374 hw_data->get_ae_clock = get_ae_clock; 375 hw_data->reset_device = adf_reset_flr; 376 hw_data->get_objs_num = get_objs_num; 377 hw_data->get_obj_name = get_obj_name; 378 hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask; 379 hw_data->get_accel_cap = c3xxx_get_hw_cap; 380 hw_data->clock_frequency = ADF_C3XXX_AE_FREQ; 381 hw_data->extended_dc_capabilities = 0; 382 hw_data->get_storage_enabled = get_storage_enabled; 383 hw_data->query_storage_cap = 1; 384 hw_data->get_heartbeat_status = adf_get_heartbeat_status; 385 hw_data->get_ae_clock = get_ae_clock; 386 hw_data->storage_enable = 0; 387 hw_data->get_fw_image_type = adf_cfg_get_fw_image_type; 388 hw_data->get_ring_to_svc_map = adf_cfg_get_services_enabled; 389 hw_data->config_device = adf_config_device; 390 hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; 391 hw_data->ring_to_svc_map = ADF_DEFAULT_RING_TO_SRV_MAP; 392 hw_data->pre_reset = adf_dev_pre_reset; 393 hw_data->post_reset = adf_dev_post_reset; 394 395 adf_gen2_init_hw_csr_info(&hw_data->csr_info); 396 adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); 397 } 398 399 void 400 adf_clean_hw_data_c3xxx(struct adf_hw_device_data *hw_data) 401 { 402 hw_data->dev_class->instances--; 403 } 404