0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00
};
+static const unsigned long thrd_mask_wcy[ADF_6XXX_MAX_ACCELENGINES] = {
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00
+};
+
static const char *const adf_6xxx_fw_objs[] = {
[ADF_FW_CY_OBJ] = ADF_6XXX_CY_OBJ,
[ADF_FW_DC_OBJ] = ADF_6XXX_DC_OBJ,
[ADF_FW_ADMIN_OBJ] = ADF_6XXX_ADMIN_OBJ,
+ [ADF_FW_WCY_OBJ] = ADF_6XXX_WCY_OBJ,
};
static const struct adf_fw_config adf_default_fw_config[] = {
{ ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ },
};
+static const struct adf_fw_config adf_wcy_fw_config[] = {
+ { ADF_AE_GROUP_1, ADF_FW_WCY_OBJ },
+ { ADF_AE_GROUP_0, ADF_FW_WCY_OBJ },
+ { ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ },
+};
+
static struct adf_hw_device_class adf_6xxx_class = {
.name = ADF_6XXX_DEVICE_NAME,
.type = DEV_6XXX,
}
}
+static bool wcy_services_supported(unsigned long mask)
+{
+ /* The wireless SKU supports only the symmetric crypto service */
+ return mask == BIT(SVC_SYM);
+}
+
static int get_service(unsigned long *mask)
{
if (test_and_clear_bit(SVC_ASYM, mask))
}
}
-static const unsigned long *get_thrd_mask(unsigned int service)
+static const unsigned long *get_thrd_mask(struct adf_accel_dev *accel_dev,
+ unsigned int service)
{
+ if (adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)))
+ return (service == SVC_SYM) ? thrd_mask_wcy : NULL;
+
switch (service) {
case SVC_SYM:
return thrd_mask_sym;
return service;
rp_config[i].ring_type = get_ring_type(service);
- rp_config[i].thrd_mask = get_thrd_mask(service);
+ rp_config[i].thrd_mask = get_thrd_mask(accel_dev, service);
/*
* If there is only one service enabled, use all ring pairs for
ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTCNVL_OFFSET, ADF_SSMWDTCNVH_OFFSET, val);
ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTUCSL_OFFSET, ADF_SSMWDTUCSH_OFFSET, val);
ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTDCPRL_OFFSET, ADF_SSMWDTDCPRH_OFFSET, val);
+ ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTWCPL_OFFSET, ADF_SSMWDTWCPH_OFFSET, val);
+ ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTWATL_OFFSET, ADF_SSMWDTWATH_OFFSET, val);
/* Enable watchdog timer for pke */
ADF_CSR_WR64_LO_HI(addr, ADF_SSMWDTPKEL_OFFSET, ADF_SSMWDTPKEH_OFFSET, val_pke);
return set_vc_config(accel_dev);
}
+static const struct adf_fw_config *get_fw_config(struct adf_accel_dev *accel_dev)
+{
+ return adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)) ? adf_wcy_fw_config :
+ adf_default_fw_config;
+}
+
static u32 get_ae_mask(struct adf_hw_device_data *self)
{
unsigned long fuses = self->fuses[ADF_FUSECTL4];
return mask;
}
+static u32 get_accel_cap_wcy(struct adf_accel_dev *accel_dev)
+{
+ u32 capabilities_sym;
+ u32 fuse;
+
+ fuse = GET_HW_DATA(accel_dev)->fuses[ADF_FUSECTL1];
+
+ capabilities_sym = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CIPHER |
+ ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
+ ICP_ACCEL_CAPABILITIES_WIRELESS_CRYPTO_EXT |
+ ICP_ACCEL_CAPABILITIES_5G |
+ ICP_ACCEL_CAPABILITIES_ZUC |
+ ICP_ACCEL_CAPABILITIES_ZUC_256 |
+ ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN;
+
+ if (fuse & ICP_ACCEL_GEN6_MASK_EIA3_SLICE) {
+ capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_ZUC;
+ capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_ZUC_256;
+ }
+ if (fuse & ICP_ACCEL_GEN6_MASK_ZUC_256_SLICE)
+ capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_ZUC_256;
+
+ if (fuse & ICP_ACCEL_GEN6_MASK_5G_SLICE)
+ capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_5G;
+
+ if (adf_get_service_enabled(accel_dev) == SVC_SYM)
+ return capabilities_sym;
+
+ return 0;
+}
+
static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
{
u32 capabilities_sym, capabilities_asym;
u32 caps = 0;
u32 fusectl1;
+ if (adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)))
+ return get_accel_cap_wcy(accel_dev);
+
fusectl1 = GET_HW_DATA(accel_dev)->fuses[ADF_FUSECTL1];
/* Read accelerator capabilities mask */
static u32 uof_get_num_objs(struct adf_accel_dev *accel_dev)
{
- return ARRAY_SIZE(adf_default_fw_config);
+ return adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)) ?
+ ARRAY_SIZE(adf_wcy_fw_config) :
+ ARRAY_SIZE(adf_default_fw_config);
}
static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num)
{
int num_fw_objs = ARRAY_SIZE(adf_6xxx_fw_objs);
+ const struct adf_fw_config *fw_config;
int id;
- id = adf_default_fw_config[obj_num].obj;
+ fw_config = get_fw_config(accel_dev);
+ id = fw_config[obj_num].obj;
if (id >= num_fw_objs)
return NULL;
static int uof_get_obj_type(struct adf_accel_dev *accel_dev, u32 obj_num)
{
+ const struct adf_fw_config *fw_config;
+
if (obj_num >= uof_get_num_objs(accel_dev))
return -EINVAL;
- return adf_default_fw_config[obj_num].obj;
+ fw_config = get_fw_config(accel_dev);
+
+ return fw_config[obj_num].obj;
}
static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num)
{
- return adf_default_fw_config[obj_num].ae_mask;
+ const struct adf_fw_config *fw_config;
+
+ fw_config = get_fw_config(accel_dev);
+ return fw_config[obj_num].ae_mask;
}
static const u32 *adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev)
init_num_svc_aes(rl_data);
}
+static void adf_gen6_init_services_supported(struct adf_hw_device_data *hw_data)
+{
+ if (adf_6xxx_is_wcy(hw_data))
+ hw_data->services_supported = wcy_services_supported;
+ else
+ hw_data->services_supported = services_supported;
+}
+
void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data)
{
hw_data->dev_class = &adf_6xxx_class;
hw_data->stop_timer = adf_timer_stop;
hw_data->init_device = adf_init_device;
hw_data->enable_pm = enable_pm;
- hw_data->services_supported = services_supported;
hw_data->num_rps = ADF_GEN6_ETR_MAX_BANKS;
hw_data->clock_frequency = ADF_6XXX_AE_FREQ;
hw_data->get_svc_slice_cnt = adf_gen6_get_svc_slice_cnt;
+ adf_gen6_init_services_supported(hw_data);
adf_gen6_init_hw_csr_ops(&hw_data->csr_ops);
adf_gen6_init_pf_pfvf_ops(&hw_data->pfvf_ops);
adf_gen6_init_dc_ops(&hw_data->dc_ops);
#define ADF_SSMWDTATHH_OFFSET 0x520C
#define ADF_SSMWDTCNVL_OFFSET 0x5408
#define ADF_SSMWDTCNVH_OFFSET 0x540C
+#define ADF_SSMWDTWCPL_OFFSET 0x5608
+#define ADF_SSMWDTWCPH_OFFSET 0x560C
#define ADF_SSMWDTUCSL_OFFSET 0x5808
#define ADF_SSMWDTUCSH_OFFSET 0x580C
#define ADF_SSMWDTDCPRL_OFFSET 0x5A08
#define ADF_SSMWDTDCPRH_OFFSET 0x5A0C
+#define ADF_SSMWDTWATL_OFFSET 0x5C08
+#define ADF_SSMWDTWATH_OFFSET 0x5C0C
#define ADF_SSMWDTPKEL_OFFSET 0x5E08
#define ADF_SSMWDTPKEH_OFFSET 0x5E0C
#define ADF_6XXX_CY_OBJ "qat_6xxx_cy.bin"
#define ADF_6XXX_DC_OBJ "qat_6xxx_dc.bin"
#define ADF_6XXX_ADMIN_OBJ "qat_6xxx_admin.bin"
+#define ADF_6XXX_WCY_OBJ "qat_6xxx_wcy.bin"
/* RL constants */
#define ADF_6XXX_RL_PCIE_SCALE_FACTOR_DIV 100
ICP_ACCEL_GEN6_MASK_PKE_SLICE = BIT(2),
ICP_ACCEL_GEN6_MASK_CPR_SLICE = BIT(3),
ICP_ACCEL_GEN6_MASK_DCPRZ_SLICE = BIT(4),
+ ICP_ACCEL_GEN6_MASK_EIA3_SLICE = BIT(5),
ICP_ACCEL_GEN6_MASK_WCP_WAT_SLICE = BIT(6),
+ ICP_ACCEL_GEN6_MASK_ZUC_256_SLICE = BIT(7),
+ ICP_ACCEL_GEN6_MASK_5G_SLICE = BIT(8),
};
+/* Return true if the device is a wireless crypto (WCY) SKU */
+static inline bool adf_6xxx_is_wcy(struct adf_hw_device_data *hw_data)
+{
+ return !(hw_data->fuses[ADF_FUSECTL1] & ICP_ACCEL_GEN6_MASK_WCP_WAT_SLICE);
+}
+
void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data);
void adf_clean_hw_data_6xxx(struct adf_hw_device_data *hw_data);
#include "adf_gen6_shared.h"
#include "adf_6xxx_hw_data.h"
+#include "adf_heartbeat.h"
static int bar_map[] = {
0, /* SRAM */
adf_devmgr_rm_dev(accel_dev, NULL);
}
+static int adf_gen6_cfg_dev_init(struct adf_accel_dev *accel_dev)
+{
+ const char *config;
+ int ret;
+
+ /*
+ * Wireless SKU - symmetric crypto service only
+ * Non-wireless SKU - crypto service for even devices and compression for odd devices
+ */
+ if (adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)))
+ config = ADF_CFG_SYM;
+ else
+ config = accel_dev->accel_id % 2 ? ADF_CFG_DC : ADF_CFG_CY;
+
+ ret = adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
+ if (ret)
+ return ret;
+
+ ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,
+ ADF_SERVICES_ENABLED, config,
+ ADF_STR);
+ if (ret)
+ return ret;
+
+ adf_heartbeat_save_cfg_param(accel_dev, ADF_CFG_HB_TIMER_MIN_MS);
+
+ return 0;
+}
+
static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct adf_accel_pci *accel_pci_dev;
pci_read_config_dword(pdev, ADF_GEN6_FUSECTL0_OFFSET, &hw_data->fuses[ADF_FUSECTL0]);
pci_read_config_dword(pdev, ADF_GEN6_FUSECTL1_OFFSET, &hw_data->fuses[ADF_FUSECTL1]);
- if (!(hw_data->fuses[ADF_FUSECTL1] & ICP_ACCEL_GEN6_MASK_WCP_WAT_SLICE))
- return dev_err_probe(dev, -EFAULT, "Wireless mode is not supported.\n");
-
/* Enable PCI device */
ret = pcim_enable_device(pdev);
if (ret)