/* * if there were not enough actags for the function, each afu * reduces its count as well
*/
actag_count = afu->config.actag_supported *
fn->actag_enabled / fn->actag_supported;
actag_offset = ocxl_actag_afu_alloc(fn, actag_count); if (actag_offset < 0) {
dev_err(&pci_dev->dev, "Can't allocate %d actags for AFU: %d\n",
actag_count, actag_offset); return actag_offset;
}
afu->actag_base = fn->actag_base + actag_offset;
afu->actag_enabled = actag_count;
/* * We only support the case where the function configuration * requested enough PASIDs to cover all AFUs.
*/
pasid_count = 1 << afu->config.pasid_supported_log;
pasid_offset = ocxl_pasid_afu_alloc(fn, pasid_count); if (pasid_offset < 0) {
dev_err(&pci_dev->dev, "Can't allocate %d PASIDs for AFU: %d\n",
pasid_count, pasid_offset); return pasid_offset;
}
afu->pasid_base = fn->pasid_base + pasid_offset;
afu->pasid_count = 0;
afu->pasid_max = pasid_count;
afu->global_mmio_ptr = ioremap(afu->global_mmio_start,
afu->config.global_mmio_size); if (!afu->global_mmio_ptr) {
release_fn_bar(afu->fn, afu->config.pp_mmio_bar);
release_fn_bar(afu->fn, afu->config.global_mmio_bar);
dev_err(&pci_dev->dev, "Error mapping global mmio area\n"); return -ENOMEM;
}
/* * Leave an empty page between the per-process mmio area and * the AFU interrupt mappings
*/
afu->irq_base_offset = afu->config.pp_mmio_stride + PAGE_SIZE; return 0;
}
/* A function may not require any PASID */ if (fn->config.max_pasid_log < 0) return 0;
rc = ocxl_config_get_pasid_info(dev, &max_count); if (rc) return rc;
desired_count = 1 << fn->config.max_pasid_log;
if (desired_count > max_count) {
dev_err(&fn->dev, "Function requires more PASIDs than is available (%d vs. %d)\n",
desired_count, max_count); return -ENOSPC;
}
fn->pasid_base = 0; return 0;
}
staticint configure_function(struct ocxl_fn *fn, struct pci_dev *dev)
{ int rc;
/* * Once it has been confirmed to work on our hardware, we * should reset the function, to force the adapter to restart * from scratch. * A function reset would also reset all its AFUs. * * Some hints for implementation: * * - there's not status bit to know when the reset is done. We * should try reading the config space to know when it's * done. * - probably something like: * Reset * wait 100ms * issue config read * allow device up to 1 sec to return success on config * read before declaring it broken * * Some shared logic on the card (CFG, TLX) won't be reset, so * there's no guarantee that it will be enough.
*/
rc = ocxl_config_read_function(dev, &fn->config); if (rc) return rc;
rc = set_function_device(fn, dev); if (rc) return rc;
rc = assign_function_actag(fn); if (rc) return rc;
rc = set_function_pasid(fn); if (rc) return rc;
rc = ocxl_link_setup(dev, 0, &fn->link); if (rc) return rc;
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.