if (!mcode || !mcode->code) {
dev_err(dev, "Either the mcode is null or data is NULL\n"); return -EINVAL;
}
if (mcode->code_size == 0) {
dev_err(dev, "microcode size is 0\n"); return -EINVAL;
}
/* Assumes 0-9 are SE cores for UCODE_BASE registers and * AE core bases follow
*/ if (mcode->is_ae) {
core = CPT_MAX_SE_CORES; /* start couting from 10 */
total_cores = CPT_MAX_TOTAL_CORES; /* upto 15 */
} else {
core = 0; /* start couting from 0 */
total_cores = CPT_MAX_SE_CORES; /* upto 9 */
}
/* Point to microcode for each core of the group */ for (; core < total_cores ; core++, shift++) { if (mcode->core_mask & (1 << shift)) {
cpt_write_csr64(cpt->reg_base,
CPTX_PF_ENGX_UCODE_BASE(0, core),
(u64)mcode->phys_base);
}
} return ret;
}
staticint do_cpt_init(struct cpt_device *cpt, struct microcode *mcode)
{ int ret = 0; struct device *dev = &cpt->pdev->dev;
/* Make device not ready */
cpt->flags &= ~CPT_FLAG_DEVICE_READY; /* Disable All PF interrupts */
cpt_disable_all_interrupts(cpt); /* Calculate mcode group and coremasks */ if (mcode->is_ae) { if (mcode->num_cores > cpt->max_ae_cores) {
dev_err(dev, "Requested for more cores than available AE cores\n");
ret = -EINVAL; goto cpt_init_fail;
}
if (cpt->next_group >= CPT_MAX_CORE_GROUPS) {
dev_err(dev, "Can't load, all eight microcode groups in use"); return -ENFILE;
}
mcode->group = cpt->next_group; /* Convert requested cores to mask */
mcode->core_mask = GENMASK(mcode->num_cores, 0);
cpt_disable_cores(cpt, mcode->core_mask, AE_TYPES,
mcode->group); /* Load microcode for AE engines */
ret = cpt_load_microcode(cpt, mcode); if (ret) {
dev_err(dev, "Microcode load Failed for %s\n",
mcode->version); goto cpt_init_fail;
}
cpt->next_group++; /* Configure group mask for the mcode */
cpt_configure_group(cpt, mcode->group, mcode->core_mask,
AE_TYPES); /* Enable AE cores for the group mask */
cpt_enable_cores(cpt, mcode->core_mask, AE_TYPES);
} else { if (mcode->num_cores > cpt->max_se_cores) {
dev_err(dev, "Requested for more cores than available SE cores\n");
ret = -EINVAL; goto cpt_init_fail;
} if (cpt->next_group >= CPT_MAX_CORE_GROUPS) {
dev_err(dev, "Can't load, all eight microcode groups in use"); return -ENFILE;
}
mcode->group = cpt->next_group; /* Covert requested cores to mask */
mcode->core_mask = GENMASK(mcode->num_cores, 0);
cpt_disable_cores(cpt, mcode->core_mask, SE_TYPES,
mcode->group); /* Load microcode for SE engines */
ret = cpt_load_microcode(cpt, mcode); if (ret) {
dev_err(dev, "Microcode load Failed for %s\n",
mcode->version); goto cpt_init_fail;
}
cpt->next_group++; /* Configure group mask for the mcode */
cpt_configure_group(cpt, mcode->group, mcode->core_mask,
SE_TYPES); /* Enable SE cores for the group mask */
cpt_enable_cores(cpt, mcode->core_mask, SE_TYPES);
}
/* Allocate DMAable space */
mcode->code = dma_alloc_coherent(&cpt->pdev->dev, mcode->code_size,
&mcode->phys_base, GFP_KERNEL); if (!mcode->code) {
dev_err(dev, "Unable to allocate space for microcode");
ret = -ENOMEM; goto fw_release;
}
/* * Ensure all cores are disengaged from all groups by * calling cpt_disable_all_cores() before calling this * function.
*/ staticvoid cpt_unload_microcode(struct cpt_device *cpt)
{
u32 grp = 0, core;
/* Free microcode bases and reset group masks */ for (grp = 0; grp < CPT_MAX_CORE_GROUPS; grp++) { struct microcode *mcode = &cpt->mcode[grp];
if (cpt->mcode[grp].code)
dma_free_coherent(&cpt->pdev->dev, mcode->code_size,
mcode->code, mcode->phys_base);
mcode->code = NULL;
} /* Clear UCODE_BASE registers for all engines */ for (core = 0; core < CPT_MAX_TOTAL_CORES; core++)
cpt_write_csr64(cpt->reg_base,
CPTX_PF_ENGX_UCODE_BASE(0, core), 0ull);
}
staticint cpt_sriov_init(struct cpt_device *cpt, int num_vfs)
{ int pos = 0; int err;
u16 total_vf_cnt; struct pci_dev *pdev = cpt->pdev;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); if (!pos) {
dev_err(&pdev->dev, "SRIOV capability is not found in PCIe config space\n"); return -ENODEV;
}
cpt->num_vf_en = num_vfs; /* User requested VFs */
pci_read_config_word(pdev, (pos + PCI_SRIOV_TOTAL_VF), &total_vf_cnt); if (total_vf_cnt < cpt->num_vf_en)
cpt->num_vf_en = total_vf_cnt;
if (!total_vf_cnt) return 0;
/*Enabled the available VFs */
err = pci_enable_sriov(pdev, cpt->num_vf_en); if (err) {
dev_err(&pdev->dev, "SRIOV enable failed, num VF is %d\n",
cpt->num_vf_en);
cpt->num_vf_en = 0; return err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.