From e01c9797c0ebb307c9bb196c677f6e571335773e Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Fri, 16 Feb 2024 14:45:14 +0100 Subject: PCI: endpoint: Clean up hardware description for BARs The hardware description for BARs is scattered in many different variables in pci_epc_features. Some of these things are mutually exclusive, so it can create confusion over which variable that has precedence over another. Improve the situation by creating a struct pci_epc_bar_desc, and a new enum pci_epc_bar_type, and convert the endpoint controller drivers to use this more well defined format. Additionally, some endpoint controller drivers mark the BAR succeeding a "64-bit only BAR" as reserved, while some do not. By definition, a 64-bit BAR uses the succeeding BAR for the upper 32-bits, so an EPF driver cannot use a BAR succeeding a 64-bit BAR. Ensure that all endpoint controller drivers are uniform, and actually describe a reserved BAR as reserved. Signed-off-by: Niklas Cassel Reviewed-by: Kishon Vijay Abraham I Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20240216134524.1142149-2-cassel@kernel.org Signed-off-by: Manivannan Sadhasivam --- drivers/pci/endpoint/functions/pci-epf-ntb.c | 4 ++-- drivers/pci/endpoint/functions/pci-epf-test.c | 8 +++---- drivers/pci/endpoint/functions/pci-epf-vntb.c | 2 +- drivers/pci/endpoint/pci-epc-core.c | 32 ++++++++++++++------------- drivers/pci/endpoint/pci-epf-core.c | 15 +++++++------ 5 files changed, 31 insertions(+), 30 deletions(-) (limited to 'drivers/pci/endpoint') diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c index 43cd309ce22f..e01a98e74d21 100644 --- a/drivers/pci/endpoint/functions/pci-epf-ntb.c +++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c @@ -1012,13 +1012,13 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb, epc_features = ntb_epc->epc_features; barno = ntb_epc->epf_ntb_bar[BAR_CONFIG]; - size = epc_features->bar_fixed_size[barno]; + size = epc_features->bar[barno].fixed_size; align = epc_features->align; peer_ntb_epc = ntb->epc[!type]; peer_epc_features = peer_ntb_epc->epc_features; peer_barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD]; - peer_size = peer_epc_features->bar_fixed_size[peer_barno]; + peer_size = peer_epc_features->bar[peer_barno].fixed_size; /* Check if epc_features is populated incorrectly */ if ((!IS_ALIGNED(size, align))) diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 981894e40681..cd4ffb39dcdc 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -729,7 +729,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) */ add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1; - if (!!(epc_features->reserved_bar & (1 << bar))) + if (epc_features->bar[bar].type == BAR_RESERVED) continue; ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, @@ -856,7 +856,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) if (bar == test_reg_bar) continue; - if (!!(epc_features->reserved_bar & (1 << bar))) + if (epc_features->bar[bar].type == BAR_RESERVED) continue; base = pci_epf_alloc_space(epf, bar_size[bar], bar, @@ -874,13 +874,11 @@ static void pci_epf_configure_bar(struct pci_epf *epf, const struct pci_epc_features *epc_features) { struct pci_epf_bar *epf_bar; - bool bar_fixed_64bit; int i; for (i = 0; i < PCI_STD_NUM_BARS; i++) { epf_bar = &epf->bar[i]; - bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i)); - if (bar_fixed_64bit) + if (epc_features->bar[i].only_64bit) epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; } } diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c index 0675929fc529..8e779eecd62d 100644 --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c @@ -422,7 +422,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb) epf->func_no, epf->vfunc_no); barno = ntb->epf_ntb_bar[BAR_CONFIG]; - size = epc_features->bar_fixed_size[barno]; + size = epc_features->bar[barno].fixed_size; align = epc_features->align; if ((!IS_ALIGNED(size, align))) diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index dcd4e66430c1..7fe8f4336765 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pci_epc_get); * @epc_features: pci_epc_features structure that holds the reserved bar bitmap * * Invoke to get the first unreserved BAR that can be used by the endpoint - * function. For any incorrect value in reserved_bar return '0'. + * function. */ enum pci_barno pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features) @@ -102,32 +102,34 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); * @bar: the starting BAR number from where unreserved BAR should be searched * * Invoke to get the next unreserved BAR starting from @bar that can be used - * for endpoint function. For any incorrect value in reserved_bar return '0'. + * for endpoint function. */ enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features *epc_features, enum pci_barno bar) { - unsigned long free_bar; + int i; if (!epc_features) return BAR_0; /* If 'bar - 1' is a 64-bit BAR, move to the next BAR */ - if ((epc_features->bar_fixed_64bit << 1) & 1 << bar) + if (bar > 0 && epc_features->bar[bar - 1].only_64bit) bar++; - /* Find if the reserved BAR is also a 64-bit BAR */ - free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit; - - /* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */ - free_bar <<= 1; - free_bar |= epc_features->reserved_bar; - - free_bar = find_next_zero_bit(&free_bar, 6, bar); - if (free_bar > 5) - return NO_BAR; + for (i = bar; i < PCI_STD_NUM_BARS; i++) { + /* If the BAR is not reserved, return it. */ + if (epc_features->bar[i].type != BAR_RESERVED) + return i; + + /* + * If the BAR is reserved, and marked as 64-bit only, then the + * succeeding BAR is also reserved. + */ + if (epc_features->bar[i].only_64bit) + i++; + } - return free_bar; + return NO_BAR; } EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar); diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index f2b4d34454c4..0a28a0b0911b 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -260,7 +260,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, const struct pci_epc_features *epc_features, enum pci_epc_interface_type type) { - u64 bar_fixed_size = epc_features->bar_fixed_size[bar]; + u64 bar_fixed_size = epc_features->bar[bar].fixed_size; size_t align = epc_features->align; struct pci_epf_bar *epf_bar; dma_addr_t phys_addr; @@ -271,13 +271,14 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, if (size < 128) size = 128; - if (bar_fixed_size && size > bar_fixed_size) { - dev_err(&epf->dev, "requested BAR size is larger than fixed size\n"); - return NULL; - } - - if (bar_fixed_size) + if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) { + if (size > bar_fixed_size) { + dev_err(&epf->dev, + "requested BAR size is larger than fixed size\n"); + return NULL; + } size = bar_fixed_size; + } if (align) size = ALIGN(size, align); -- cgit v1.2.3