Skip to content

Commit 43d67ec

Browse files
AkshGarg-19bjorn-helgaas
authored andcommitted
PCI: dwc: ep: Fix resizable BAR support for multi-PF configurations
The resizable BAR support added by the commit 3a3d4ca ("PCI: dwc: ep: Allow EPF drivers to configure the size of Resizable BARs") incorrectly configures the resizable BARs only for the first Physical Function (PF0) in EP mode. The resizable BAR configuration functions use generic dw_pcie_*_dbi() operations instead of physical function specific dw_pcie_ep_*_dbi() operations. This causes resizable BAR configuration to always target PF0 regardless of the requested function number. Additionally, dw_pcie_ep_init_non_sticky_registers() only initializes resizable BAR registers for PF0, leaving other PFs unconfigured during the execution of this function. Fix this by using physical function specific configuration space access operations throughout the resizable BAR code path and initializing registers for all the physical functions that support resizable BARs. Fixes: 3a3d4ca ("PCI: dwc: ep: Allow EPF drivers to configure the size of Resizable BARs") Signed-off-by: Aksh Garg <a-garg7@ti.com> [mani: added stable tag] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Niklas Cassel <cassel@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260130115516.515082-2-a-garg7@ti.com
1 parent ffcc485 commit 43d67ec

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
7575
cap, NULL, ep, func_no);
7676
}
7777

78+
static u16 dw_pcie_ep_find_ext_capability(struct dw_pcie_ep *ep,
79+
u8 func_no, u8 cap)
80+
{
81+
return PCI_FIND_NEXT_EXT_CAP(dw_pcie_ep_read_cfg, 0,
82+
cap, NULL, ep, func_no);
83+
}
84+
7885
static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
7986
struct pci_epf_header *hdr)
8087
{
@@ -350,22 +357,22 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
350357
ep->epf_bar[bar] = NULL;
351358
}
352359

353-
static unsigned int dw_pcie_ep_get_rebar_offset(struct dw_pcie *pci,
360+
static unsigned int dw_pcie_ep_get_rebar_offset(struct dw_pcie_ep *ep, u8 func_no,
354361
enum pci_barno bar)
355362
{
356363
u32 reg, bar_index;
357364
unsigned int offset, nbars;
358365
int i;
359366

360-
offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
367+
offset = dw_pcie_ep_find_ext_capability(ep, func_no, PCI_EXT_CAP_ID_REBAR);
361368
if (!offset)
362369
return offset;
363370

364-
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
371+
reg = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_REBAR_CTRL);
365372
nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, reg);
366373

367374
for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL) {
368-
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
375+
reg = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_REBAR_CTRL);
369376
bar_index = FIELD_GET(PCI_REBAR_CTRL_BAR_IDX, reg);
370377
if (bar_index == bar)
371378
return offset;
@@ -386,7 +393,7 @@ static int dw_pcie_ep_set_bar_resizable(struct dw_pcie_ep *ep, u8 func_no,
386393
u32 rebar_cap, rebar_ctrl;
387394
int ret;
388395

389-
rebar_offset = dw_pcie_ep_get_rebar_offset(pci, bar);
396+
rebar_offset = dw_pcie_ep_get_rebar_offset(ep, func_no, bar);
390397
if (!rebar_offset)
391398
return -EINVAL;
392399

@@ -416,16 +423,16 @@ static int dw_pcie_ep_set_bar_resizable(struct dw_pcie_ep *ep, u8 func_no,
416423
* 1 MB to 128 TB. Bits 31:16 in PCI_REBAR_CTRL define "supported sizes"
417424
* bits for sizes 256 TB to 8 EB. Disallow sizes 256 TB to 8 EB.
418425
*/
419-
rebar_ctrl = dw_pcie_readl_dbi(pci, rebar_offset + PCI_REBAR_CTRL);
426+
rebar_ctrl = dw_pcie_ep_readl_dbi(ep, func_no, rebar_offset + PCI_REBAR_CTRL);
420427
rebar_ctrl &= ~GENMASK(31, 16);
421-
dw_pcie_writel_dbi(pci, rebar_offset + PCI_REBAR_CTRL, rebar_ctrl);
428+
dw_pcie_ep_writel_dbi(ep, func_no, rebar_offset + PCI_REBAR_CTRL, rebar_ctrl);
422429

423430
/*
424431
* The "selected size" (bits 13:8) in PCI_REBAR_CTRL are automatically
425432
* updated when writing PCI_REBAR_CAP, see "Figure 3-26 Resizable BAR
426433
* Example for 32-bit Memory BAR0" in DWC EP databook 5.96a.
427434
*/
428-
dw_pcie_writel_dbi(pci, rebar_offset + PCI_REBAR_CAP, rebar_cap);
435+
dw_pcie_ep_writel_dbi(ep, func_no, rebar_offset + PCI_REBAR_CAP, rebar_cap);
429436

430437
dw_pcie_dbi_ro_wr_dis(pci);
431438

@@ -1023,20 +1030,17 @@ void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
10231030
}
10241031
EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit);
10251032

1026-
static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
1033+
static void dw_pcie_ep_init_rebar_registers(struct dw_pcie_ep *ep, u8 func_no)
10271034
{
1028-
struct dw_pcie_ep *ep = &pci->ep;
10291035
unsigned int offset;
10301036
unsigned int nbars;
10311037
enum pci_barno bar;
10321038
u32 reg, i, val;
10331039

1034-
offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
1035-
1036-
dw_pcie_dbi_ro_wr_en(pci);
1040+
offset = dw_pcie_ep_find_ext_capability(ep, func_no, PCI_EXT_CAP_ID_REBAR);
10371041

10381042
if (offset) {
1039-
reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
1043+
reg = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_REBAR_CTRL);
10401044
nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, reg);
10411045

10421046
/*
@@ -1057,16 +1061,28 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
10571061
* the controller when RESBAR_CAP_REG is written, which
10581062
* is why RESBAR_CAP_REG is written here.
10591063
*/
1060-
val = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
1064+
val = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_REBAR_CTRL);
10611065
bar = FIELD_GET(PCI_REBAR_CTRL_BAR_IDX, val);
10621066
if (ep->epf_bar[bar])
10631067
pci_epc_bar_size_to_rebar_cap(ep->epf_bar[bar]->size, &val);
10641068
else
10651069
val = BIT(4);
10661070

1067-
dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, val);
1071+
dw_pcie_ep_writel_dbi(ep, func_no, offset + PCI_REBAR_CAP, val);
10681072
}
10691073
}
1074+
}
1075+
1076+
static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
1077+
{
1078+
struct dw_pcie_ep *ep = &pci->ep;
1079+
u8 funcs = ep->epc->max_functions;
1080+
u8 func_no;
1081+
1082+
dw_pcie_dbi_ro_wr_en(pci);
1083+
1084+
for (func_no = 0; func_no < funcs; func_no++)
1085+
dw_pcie_ep_init_rebar_registers(ep, func_no);
10701086

10711087
dw_pcie_setup(pci);
10721088
dw_pcie_dbi_ro_wr_dis(pci);

0 commit comments

Comments
 (0)