1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 /* Copyright(c) 2014 - 2021 Intel Corporation */ 3 #include <adf_accel_devices.h> 4 #include <adf_common_drv.h> 5 #include <adf_gen2_config.h> 6 #include <adf_gen2_dc.h> 7 #include <adf_gen2_hw_data.h> 8 #include <adf_gen2_pfvf.h> 9 #include "adf_dh895xcc_hw_data.h" 10 #include "icp_qat_hw.h" 11 12 #define ADF_DH895XCC_VF_MSK 0xFFFFFFFF 13 14 /* Worker thread to service arbiter mappings */ 15 static const u32 thrd_to_arb_map[ADF_DH895XCC_MAX_ACCELENGINES] = { 16 0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666, 17 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222, 18 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222 19 }; 20 21 static struct adf_hw_device_class dh895xcc_class = { 22 .name = ADF_DH895XCC_DEVICE_NAME, 23 .type = DEV_DH895XCC, 24 .instances = 0 25 }; 26 27 static u32 get_accel_mask(struct adf_hw_device_data *self) 28 { 29 u32 fuses = self->fuses; 30 31 return ~fuses >> ADF_DH895XCC_ACCELERATORS_REG_OFFSET & 32 ADF_DH895XCC_ACCELERATORS_MASK; 33 } 34 35 static u32 get_ae_mask(struct adf_hw_device_data *self) 36 { 37 u32 fuses = self->fuses; 38 39 return ~fuses & ADF_DH895XCC_ACCELENGINES_MASK; 40 } 41 42 static u32 get_misc_bar_id(struct adf_hw_device_data *self) 43 { 44 return ADF_DH895XCC_PMISC_BAR; 45 } 46 47 static u32 get_etr_bar_id(struct adf_hw_device_data *self) 48 { 49 return ADF_DH895XCC_ETR_BAR; 50 } 51 52 static u32 get_sram_bar_id(struct adf_hw_device_data *self) 53 { 54 return ADF_DH895XCC_SRAM_BAR; 55 } 56 57 static u32 get_accel_cap(struct adf_accel_dev *accel_dev) 58 { 59 struct pci_dev *pdev = accel_dev->accel_pci_dev.pci_dev; 60 u32 capabilities; 61 u32 legfuses; 62 63 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | 64 ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | 65 ICP_ACCEL_CAPABILITIES_AUTHENTICATION | 66 ICP_ACCEL_CAPABILITIES_CIPHER | 67 ICP_ACCEL_CAPABILITIES_COMPRESSION; 68 69 /* Read accelerator capabilities mask */ 70 pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses); 71 72 /* A set bit in legfuses means the feature is OFF in this SKU */ 73 if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) { 74 capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; 75 capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; 76 } 77 if (legfuses & ICP_ACCEL_MASK_PKE_SLICE) 78 capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; 79 if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) { 80 capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; 81 capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; 82 } 83 if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) 84 capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; 85 86 return capabilities; 87 } 88 89 static enum dev_sku_info get_sku(struct adf_hw_device_data *self) 90 { 91 int sku = (self->fuses & ADF_DH895XCC_FUSECTL_SKU_MASK) 92 >> ADF_DH895XCC_FUSECTL_SKU_SHIFT; 93 94 switch (sku) { 95 case ADF_DH895XCC_FUSECTL_SKU_1: 96 return DEV_SKU_1; 97 case ADF_DH895XCC_FUSECTL_SKU_2: 98 return DEV_SKU_2; 99 case ADF_DH895XCC_FUSECTL_SKU_3: 100 return DEV_SKU_3; 101 case ADF_DH895XCC_FUSECTL_SKU_4: 102 return DEV_SKU_4; 103 default: 104 return DEV_SKU_UNKNOWN; 105 } 106 return DEV_SKU_UNKNOWN; 107 } 108 109 static const u32 *adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev) 110 { 111 return thrd_to_arb_map; 112 } 113 114 static void enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask) 115 { 116 /* Enable VF2PF Messaging Ints - VFs 0 through 15 per vf_mask[15:0] */ 117 if (vf_mask & 0xFFFF) { 118 u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3) 119 & ~ADF_DH895XCC_ERR_MSK_VF2PF_L(vf_mask); 120 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val); 121 } 122 123 /* Enable VF2PF Messaging Ints - VFs 16 through 31 per vf_mask[31:16] */ 124 if (vf_mask >> 16) { 125 u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5) 126 & ~ADF_DH895XCC_ERR_MSK_VF2PF_U(vf_mask); 127 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, val); 128 } 129 } 130 131 static void disable_all_vf2pf_interrupts(void __iomem *pmisc_addr) 132 { 133 u32 val; 134 135 /* Disable VF2PF interrupts for VFs 0 through 15 per vf_mask[15:0] */ 136 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3) 137 | ADF_DH895XCC_ERR_MSK_VF2PF_L(ADF_DH895XCC_VF_MSK); 138 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val); 139 140 /* Disable VF2PF interrupts for VFs 16 through 31 per vf_mask[31:16] */ 141 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5) 142 | ADF_DH895XCC_ERR_MSK_VF2PF_U(ADF_DH895XCC_VF_MSK); 143 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, val); 144 } 145 146 static u32 disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr) 147 { 148 u32 sources, pending, disabled; 149 u32 errsou3, errmsk3; 150 u32 errsou5, errmsk5; 151 152 /* Get the interrupt sources triggered by VFs */ 153 errsou3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU3); 154 errsou5 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU5); 155 sources = ADF_DH895XCC_ERR_REG_VF2PF_L(errsou3) 156 | ADF_DH895XCC_ERR_REG_VF2PF_U(errsou5); 157 158 if (!sources) 159 return 0; 160 161 /* Get the already disabled interrupts */ 162 errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3); 163 errmsk5 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5); 164 disabled = ADF_DH895XCC_ERR_REG_VF2PF_L(errmsk3) 165 | ADF_DH895XCC_ERR_REG_VF2PF_U(errmsk5); 166 167 pending = sources & ~disabled; 168 if (!pending) 169 return 0; 170 171 /* Due to HW limitations, when disabling the interrupts, we can't 172 * just disable the requested sources, as this would lead to missed 173 * interrupts if sources changes just before writing to ERRMSK3 and 174 * ERRMSK5. 175 * To work around it, disable all and re-enable only the sources that 176 * are not in vf_mask and were not already disabled. Re-enabling will 177 * trigger a new interrupt for the sources that have changed in the 178 * meantime, if any. 179 */ 180 errmsk3 |= ADF_DH895XCC_ERR_MSK_VF2PF_L(ADF_DH895XCC_VF_MSK); 181 errmsk5 |= ADF_DH895XCC_ERR_MSK_VF2PF_U(ADF_DH895XCC_VF_MSK); 182 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); 183 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5); 184 185 errmsk3 &= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled); 186 errmsk5 &= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled); 187 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3); 188 ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5); 189 190 /* Return the sources of the (new) interrupt(s) */ 191 return pending; 192 } 193 194 static void configure_iov_threads(struct adf_accel_dev *accel_dev, bool enable) 195 { 196 adf_gen2_cfg_iov_thds(accel_dev, enable, 197 ADF_DH895XCC_AE2FUNC_MAP_GRP_A_NUM_REGS, 198 ADF_DH895XCC_AE2FUNC_MAP_GRP_B_NUM_REGS); 199 } 200 201 void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) 202 { 203 hw_data->dev_class = &dh895xcc_class; 204 hw_data->instance_id = dh895xcc_class.instances++; 205 hw_data->num_banks = ADF_DH895XCC_ETR_MAX_BANKS; 206 hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK; 207 hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS; 208 hw_data->num_logical_accel = 1; 209 hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES; 210 hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET; 211 hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK; 212 hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; 213 hw_data->alloc_irq = adf_isr_resource_alloc; 214 hw_data->free_irq = adf_isr_resource_free; 215 hw_data->enable_error_correction = adf_gen2_enable_error_correction; 216 hw_data->get_accel_mask = get_accel_mask; 217 hw_data->get_ae_mask = get_ae_mask; 218 hw_data->get_accel_cap = get_accel_cap; 219 hw_data->get_num_accels = adf_gen2_get_num_accels; 220 hw_data->get_num_aes = adf_gen2_get_num_aes; 221 hw_data->get_etr_bar_id = get_etr_bar_id; 222 hw_data->get_misc_bar_id = get_misc_bar_id; 223 hw_data->get_admin_info = adf_gen2_get_admin_info; 224 hw_data->get_arb_info = adf_gen2_get_arb_info; 225 hw_data->get_sram_bar_id = get_sram_bar_id; 226 hw_data->get_sku = get_sku; 227 hw_data->fw_name = ADF_DH895XCC_FW; 228 hw_data->fw_mmp_name = ADF_DH895XCC_MMP; 229 hw_data->init_admin_comms = adf_init_admin_comms; 230 hw_data->exit_admin_comms = adf_exit_admin_comms; 231 hw_data->configure_iov_threads = configure_iov_threads; 232 hw_data->send_admin_init = adf_send_admin_init; 233 hw_data->init_arb = adf_init_arb; 234 hw_data->exit_arb = adf_exit_arb; 235 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 236 hw_data->enable_ints = adf_gen2_enable_ints; 237 hw_data->reset_device = adf_reset_sbr; 238 hw_data->disable_iov = adf_disable_sriov; 239 hw_data->dev_config = adf_gen2_dev_config; 240 241 adf_gen2_init_pf_pfvf_ops(&hw_data->pfvf_ops); 242 hw_data->pfvf_ops.enable_vf2pf_interrupts = enable_vf2pf_interrupts; 243 hw_data->pfvf_ops.disable_all_vf2pf_interrupts = disable_all_vf2pf_interrupts; 244 hw_data->pfvf_ops.disable_pending_vf2pf_interrupts = disable_pending_vf2pf_interrupts; 245 adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); 246 adf_gen2_init_dc_ops(&hw_data->dc_ops); 247 } 248 249 void adf_clean_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) 250 { 251 hw_data->dev_class->instances--; 252 } 253