PCI: endpoint: Add pci_epc_bar_size_to_rebar_cap()

Add a helper function to convert a size to the representation used by the
Resizable BAR Capability Register.

Signed-off-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20250131182949.465530-11-cassel@kernel.org
[mani: squashed the change that added PCIe spec reference to comments
from https://lore.kernel.org/linux-pci/20250219171454.2903059-2-cassel@kernel.org]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
This commit is contained in:
Niklas Cassel 2025-01-31 19:29:51 +01:00 committed by Krzysztof Wilczyński
parent 52132f3a63
commit 4eb208424c
No known key found for this signature in database
GPG Key ID: 7C64768D3DE334E7
2 changed files with 28 additions and 0 deletions

View File

@ -638,6 +638,33 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
}
EXPORT_SYMBOL_GPL(pci_epc_set_bar);
/**
* pci_epc_bar_size_to_rebar_cap() - convert a size to the representation used
* by the Resizable BAR Capability Register
* @size: the size to convert
* @cap: where to store the result
*
* Returns 0 on success and a negative error code in case of error.
*/
int pci_epc_bar_size_to_rebar_cap(size_t size, u32 *cap)
{
/*
* As per PCIe r6.0, sec 7.8.6.2, min size for a resizable BAR is 1 MB,
* thus disallow a requested BAR size smaller than 1 MB.
* Disallow a requested BAR size larger than 128 TB.
*/
if (size < SZ_1M || (u64)size > (SZ_128G * 1024))
return -EINVAL;
*cap = ilog2(size) - ilog2(SZ_1M);
/* Sizes in REBAR_CAP start at BIT(4). */
*cap = BIT(*cap + 4);
return 0;
}
EXPORT_SYMBOL_GPL(pci_epc_bar_size_to_rebar_cap);
/**
* pci_epc_write_header() - write standard configuration header
* @epc: the EPC device to which the configuration header should be written

View File

@ -275,6 +275,7 @@ void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
enum pci_epc_interface_type type);
int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
struct pci_epf_header *hdr);
int pci_epc_bar_size_to_rebar_cap(size_t size, u32 *cap);
int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
struct pci_epf_bar *epf_bar);
void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,