* [PATCH 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes
@ 2026-02-02 7:27 Aksh Garg
2026-02-02 7:27 ` [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function Aksh Garg
2026-02-02 7:27 ` [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions Aksh Garg
0 siblings, 2 replies; 9+ messages in thread
From: Aksh Garg @ 2026-02-02 7:27 UTC (permalink / raw)
To: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, cassel
Cc: linux-kernel, s-vadapalli, danishanwar, Aksh Garg
This series addresses multi-function endpoint configuration issues in
the DWC PCIe controller driver. The changes enable proper operations
for physical functions and enhance the multi-function endpoint support.
This patch series can be seen as an extension of the patch series:
https://lore.kernel.org/all/20260130115516.515082-1-a-garg7@ti.com/
Base: controller/dwc branch, latest:
commit a24149881558 ("PCI: dwc: ep: Add comment explaining controller level
PTM access in multi PF setup")
Aksh Garg (2):
PCI: dwc: ep: Fix MSI-X configuration to write to correct physical
function
PCI: dwc: ep: Mirror the max link width and speed fields to all
functions
.../pci/controller/dwc/pcie-designware-ep.c | 26 +++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function
2026-02-02 7:27 [PATCH 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes Aksh Garg
@ 2026-02-02 7:27 ` Aksh Garg
2026-02-02 7:55 ` Niklas Cassel
2026-02-02 7:27 ` [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions Aksh Garg
1 sibling, 1 reply; 9+ messages in thread
From: Aksh Garg @ 2026-02-02 7:27 UTC (permalink / raw)
To: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, cassel
Cc: linux-kernel, s-vadapalli, danishanwar, Aksh Garg
The MSI-X configuration code reads from the correct physical function's
register space using dw_pcie_ep_readw_dbi(), but writes back only to
PF0 using the old dw_pcie_writew_dbi() helper. This causes incorrect
MSI-X configuration for other PFs.
Fix this by using dw_pcie_ep_writew_dbi() to write to the correct PF's
register space, matching the read operation.
Fixes: 70fa02ca1446 ("PCI: dwc: Add dw_pcie_ep_{read,write}_dbi[2] helpers")
Signed-off-by: Aksh Garg <a-garg7@ti.com>
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 7e7844ff0f7e..771241e1a2c9 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -745,7 +745,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
val &= ~PCI_MSIX_FLAGS_QSIZE;
val |= nr_irqs - 1; /* encoded as N-1 */
- dw_pcie_writew_dbi(pci, reg, val);
+ dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
reg = ep_func->msix_cap + PCI_MSIX_TABLE;
val = offset | bir;
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions
2026-02-02 7:27 [PATCH 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes Aksh Garg
2026-02-02 7:27 ` [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function Aksh Garg
@ 2026-02-02 7:27 ` Aksh Garg
2026-02-18 13:38 ` Manivannan Sadhasivam
1 sibling, 1 reply; 9+ messages in thread
From: Aksh Garg @ 2026-02-02 7:27 UTC (permalink / raw)
To: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, cassel
Cc: linux-kernel, s-vadapalli, danishanwar, Aksh Garg
PCIe r6.0, section 7.5.3.6 states that for multi-function devices, the
Max Link Width and Max Link Speed fields in the Link Capabilities
Register must report the same values for all functions.
Currently, dw_pcie_setup() programs these fields only for physical
function 0 (PF0) via dw_pcie_link_set_max_speed() and
dw_pcie_link_set_max_link_width(). For multi-function endpoint
configurations, PF1 and beyond retain their default values, violating
the PCIe specification.
Fix this by reading the Max Link Width and Max Link Speed fields from
PF0's Link Capabilities Register after dw_pcie_setup() completes,
then mirroring these values to all other physical functions.
Fixes: 24ede430fa49 ("PCI: designware-ep: Add multiple PFs support for DWC")
Fixes: 89db0793c9f2 ("PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling")
Signed-off-by: Aksh Garg <a-garg7@ti.com>
---
The link speed and width would be negotiated through PF0 during
initialization that controls the link behaviour, hence it didn't broke
the driver. However, the change is proposed just to make the driver
compatible with the PCIe base specifications.
The fix is implemented in pcie-designware-ep.c rather than modifying
dw_pcie_setup() directly to keep pcie-designware.c independent of RC/EP
specifics and maintain it as common code.
.../pci/controller/dwc/pcie-designware-ep.c | 24 ++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 771241e1a2c9..4ac25da2b117 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -1094,7 +1094,8 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
{
struct dw_pcie_ep *ep = &pci->ep;
u8 funcs = ep->epc->max_functions;
- u8 func_no;
+ u32 ref_lnkcap, lnkcap;
+ u8 func_no, offset;
dw_pcie_dbi_ro_wr_en(pci);
@@ -1102,6 +1103,27 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
dw_pcie_ep_init_rebar_registers(ep, func_no);
dw_pcie_setup(pci);
+
+ /*
+ * PCIe r6.0, section 7.5.3.6 states that for multi-function endpoints,
+ * max link width and speed fields must report same values for all functions.
+ * However, dw_pcie_setup() programs these fields only for physical function 0.
+ * Hence, mirror these fields to all other physical functions as well.
+ */
+ if (funcs > 1) {
+ offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ ref_lnkcap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
+ ref_lnkcap &= PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS;
+
+ for (func_no = 1; func_no < funcs; func_no++) {
+ offset = dw_pcie_ep_find_capability(ep, func_no, PCI_CAP_ID_EXP);
+ lnkcap = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_EXP_LNKCAP);
+ lnkcap &= ~(PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
+ lnkcap |= ref_lnkcap;
+ dw_pcie_ep_writel_dbi(ep, func_no, offset + PCI_EXP_LNKCAP, lnkcap);
+ }
+ }
+
dw_pcie_dbi_ro_wr_dis(pci);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function
2026-02-02 7:27 ` [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function Aksh Garg
@ 2026-02-02 7:55 ` Niklas Cassel
2026-02-02 7:57 ` Niklas Cassel
0 siblings, 1 reply; 9+ messages in thread
From: Niklas Cassel @ 2026-02-02 7:55 UTC (permalink / raw)
To: Aksh Garg
Cc: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, linux-kernel, s-vadapalli, danishanwar
On Mon, Feb 02, 2026 at 12:57:57PM +0530, Aksh Garg wrote:
> The MSI-X configuration code reads from the correct physical function's
> register space using dw_pcie_ep_readw_dbi(), but writes back only to
> PF0 using the old dw_pcie_writew_dbi() helper. This causes incorrect
> MSI-X configuration for other PFs.
>
> Fix this by using dw_pcie_ep_writew_dbi() to write to the correct PF's
> register space, matching the read operation.
>
> Fixes: 70fa02ca1446 ("PCI: dwc: Add dw_pcie_ep_{read,write}_dbi[2] helpers")
> Signed-off-by: Aksh Garg <a-garg7@ti.com>
> ---
> drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 7e7844ff0f7e..771241e1a2c9 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -745,7 +745,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
> val &= ~PCI_MSIX_FLAGS_QSIZE;
> val |= nr_irqs - 1; /* encoded as N-1 */
> - dw_pcie_writew_dbi(pci, reg, val);
> + dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
>
> reg = ep_func->msix_cap + PCI_MSIX_TABLE;
> val = offset | bir;
> --
> 2.34.1
>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
However, please also fix the only remaining place in this file which still
uses the incorrect dw_pcie_writew_dbi() instead of dw_pcie_ep_writew_dbi()
i.e.:
dw_pcie_ep_raise_msix_irq_doorbell().
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function
2026-02-02 7:55 ` Niklas Cassel
@ 2026-02-02 7:57 ` Niklas Cassel
2026-02-02 8:15 ` Aksh Garg
0 siblings, 1 reply; 9+ messages in thread
From: Niklas Cassel @ 2026-02-02 7:57 UTC (permalink / raw)
To: Aksh Garg
Cc: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, linux-kernel, s-vadapalli, danishanwar
On Mon, Feb 02, 2026 at 08:55:52AM +0100, Niklas Cassel wrote:
> On Mon, Feb 02, 2026 at 12:57:57PM +0530, Aksh Garg wrote:
> > The MSI-X configuration code reads from the correct physical function's
> > register space using dw_pcie_ep_readw_dbi(), but writes back only to
> > PF0 using the old dw_pcie_writew_dbi() helper. This causes incorrect
> > MSI-X configuration for other PFs.
> >
> > Fix this by using dw_pcie_ep_writew_dbi() to write to the correct PF's
> > register space, matching the read operation.
> >
> > Fixes: 70fa02ca1446 ("PCI: dwc: Add dw_pcie_ep_{read,write}_dbi[2] helpers")
> > Signed-off-by: Aksh Garg <a-garg7@ti.com>
> > ---
> > drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 7e7844ff0f7e..771241e1a2c9 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -745,7 +745,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> > val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
> > val &= ~PCI_MSIX_FLAGS_QSIZE;
> > val |= nr_irqs - 1; /* encoded as N-1 */
> > - dw_pcie_writew_dbi(pci, reg, val);
> > + dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
> >
> > reg = ep_func->msix_cap + PCI_MSIX_TABLE;
> > val = offset | bir;
> > --
> > 2.34.1
> >
>
> Reviewed-by: Niklas Cassel <cassel@kernel.org>
>
>
> However, please also fix the only remaining place in this file which still
> uses the incorrect dw_pcie_writew_dbi() instead of dw_pcie_ep_writew_dbi()
>
> i.e.:
> dw_pcie_ep_raise_msix_irq_doorbell().
Perhaps doorbell is special, and there is only one register for this...
But then, perhaps add a comment why this is the only place that needs
to not supply func_no.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function
2026-02-02 7:57 ` Niklas Cassel
@ 2026-02-02 8:15 ` Aksh Garg
2026-02-02 8:47 ` Niklas Cassel
0 siblings, 1 reply; 9+ messages in thread
From: Aksh Garg @ 2026-02-02 8:15 UTC (permalink / raw)
To: Niklas Cassel
Cc: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, linux-kernel, s-vadapalli, danishanwar
On 02/02/26 13:27, Niklas Cassel wrote:
> On Mon, Feb 02, 2026 at 08:55:52AM +0100, Niklas Cassel wrote:
>> On Mon, Feb 02, 2026 at 12:57:57PM +0530, Aksh Garg wrote:
>> > The MSI-X configuration code reads from the correct physical function's
>> > register space using dw_pcie_ep_readw_dbi(), but writes back only to
>> > PF0 using the old dw_pcie_writew_dbi() helper. This causes incorrect
>> > MSI-X configuration for other PFs.
>> >
>> > Fix this by using dw_pcie_ep_writew_dbi() to write to the correct PF's
>> > register space, matching the read operation.
>> >
>> > Fixes: 70fa02ca1446 ("PCI: dwc: Add dw_pcie_ep_{read,write}_dbi[2] helpers")
>> > Signed-off-by: Aksh Garg <a-garg7@ti.com>
>> > ---
>> > drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
>> > 1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
>> > index 7e7844ff0f7e..771241e1a2c9 100644
>> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
>> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
>> > @@ -745,7 +745,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
>> > val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
>> > val &= ~PCI_MSIX_FLAGS_QSIZE;
>> > val |= nr_irqs - 1; /* encoded as N-1 */
>> > - dw_pcie_writew_dbi(pci, reg, val);
>> > + dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
>> >
>> > reg = ep_func->msix_cap + PCI_MSIX_TABLE;
>> > val = offset | bir;
>> > --
>> > 2.34.1
>> >
>>
>> Reviewed-by: Niklas Cassel <cassel@kernel.org>
>>
>>
>> However, please also fix the only remaining place in this file which still
>> uses the incorrect dw_pcie_writew_dbi() instead of dw_pcie_ep_writew_dbi()
>>
>> i.e.:
>> dw_pcie_ep_raise_msix_irq_doorbell().
>
> Perhaps doorbell is special, and there is only one register for this...
>
Yes, we have only one doorbell register.
> But then, perhaps add a comment why this is the only place that needs
> to not supply func_no.
However, I think the offset (0x948) of the register is self-explanatory,
as after 0x700, we have port logic registers, which are per-device, not
per-PF.
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function
2026-02-02 8:15 ` Aksh Garg
@ 2026-02-02 8:47 ` Niklas Cassel
0 siblings, 0 replies; 9+ messages in thread
From: Niklas Cassel @ 2026-02-02 8:47 UTC (permalink / raw)
To: Aksh Garg
Cc: linux-pci, jingoohan1, mani, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, linux-kernel, s-vadapalli, danishanwar
On Mon, Feb 02, 2026 at 01:45:49PM +0530, Aksh Garg wrote:
> On 02/02/26 13:27, Niklas Cassel wrote:
> > On Mon, Feb 02, 2026 at 08:55:52AM +0100, Niklas Cassel wrote:
> > > On Mon, Feb 02, 2026 at 12:57:57PM +0530, Aksh Garg wrote:
> > > > The MSI-X configuration code reads from the correct physical function's
> > > > register space using dw_pcie_ep_readw_dbi(), but writes back only to
> > > > PF0 using the old dw_pcie_writew_dbi() helper. This causes incorrect
> > > > MSI-X configuration for other PFs.
> > > > > Fix this by using dw_pcie_ep_writew_dbi() to write to the
> > > correct PF's
> > > > register space, matching the read operation.
> > > > > Fixes: 70fa02ca1446 ("PCI: dwc: Add
> > > dw_pcie_ep_{read,write}_dbi[2] helpers")
> > > > Signed-off-by: Aksh Garg <a-garg7@ti.com>
> > > > ---
> > > > drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > index 7e7844ff0f7e..771241e1a2c9 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > @@ -745,7 +745,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> > > > val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
> > > > val &= ~PCI_MSIX_FLAGS_QSIZE;
> > > > val |= nr_irqs - 1; /* encoded as N-1 */
> > > > - dw_pcie_writew_dbi(pci, reg, val);
> > > > + dw_pcie_ep_writew_dbi(ep, func_no, reg, val);
> > > > > reg = ep_func->msix_cap + PCI_MSIX_TABLE;
> > > > val = offset | bir;
> > > > -- > 2.34.1
> > > >
> > >
> > > Reviewed-by: Niklas Cassel <cassel@kernel.org>
> > >
> > >
> > > However, please also fix the only remaining place in this file which still
> > > uses the incorrect dw_pcie_writew_dbi() instead of dw_pcie_ep_writew_dbi()
> > >
> > > i.e.:
> > > dw_pcie_ep_raise_msix_irq_doorbell().
> >
> > Perhaps doorbell is special, and there is only one register for this...
> >
>
> Yes, we have only one doorbell register.
>
> > But then, perhaps add a comment why this is the only place that needs
> > to not supply func_no.
>
> However, I think the offset (0x948) of the register is self-explanatory,
> as after 0x700, we have port logic registers, which are per-device, not
> per-PF.
The macro PCIE_MSIX_DOORBELL does kind of hide the offset, and not everyone
who reads the driver might know the that PL registers start at 0x700.
But sure, msg_data which is written to the doorbell was crafted with a func_no
shift, so perhaps it is self explanatory if you look some lines above the
dw_pcie_writel_dbi() which does not supply func_no, so perhaps a comment is
superfluous in this case.
Kind regards,
Niklas
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions
2026-02-02 7:27 ` [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions Aksh Garg
@ 2026-02-18 13:38 ` Manivannan Sadhasivam
2026-02-23 18:12 ` Bjorn Helgaas
0 siblings, 1 reply; 9+ messages in thread
From: Manivannan Sadhasivam @ 2026-02-18 13:38 UTC (permalink / raw)
To: Aksh Garg
Cc: linux-pci, jingoohan1, lpieralisi, kwilczynski, robh, bhelgaas,
yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, cassel, linux-kernel, s-vadapalli, danishanwar
On Mon, Feb 02, 2026 at 12:57:58PM +0530, Aksh Garg wrote:
> PCIe r6.0, section 7.5.3.6 states that for multi-function devices, the
> Max Link Width and Max Link Speed fields in the Link Capabilities
> Register must report the same values for all functions.
>
> Currently, dw_pcie_setup() programs these fields only for physical
> function 0 (PF0) via dw_pcie_link_set_max_speed() and
> dw_pcie_link_set_max_link_width(). For multi-function endpoint
> configurations, PF1 and beyond retain their default values, violating
> the PCIe specification.
>
> Fix this by reading the Max Link Width and Max Link Speed fields from
> PF0's Link Capabilities Register after dw_pcie_setup() completes,
> then mirroring these values to all other physical functions.
>
> Fixes: 24ede430fa49 ("PCI: designware-ep: Add multiple PFs support for DWC")
> Fixes: 89db0793c9f2 ("PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling")
> Signed-off-by: Aksh Garg <a-garg7@ti.com>
> ---
>
> The link speed and width would be negotiated through PF0 during
> initialization that controls the link behaviour, hence it didn't broke
> the driver. However, the change is proposed just to make the driver
> compatible with the PCIe base specifications.
>
> The fix is implemented in pcie-designware-ep.c rather than modifying
> dw_pcie_setup() directly to keep pcie-designware.c independent of RC/EP
> specifics and maintain it as common code.
>
> .../pci/controller/dwc/pcie-designware-ep.c | 24 ++++++++++++++++++-
> 1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 771241e1a2c9..4ac25da2b117 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -1094,7 +1094,8 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
> {
> struct dw_pcie_ep *ep = &pci->ep;
> u8 funcs = ep->epc->max_functions;
> - u8 func_no;
> + u32 ref_lnkcap, lnkcap;
> + u8 func_no, offset;
>
> dw_pcie_dbi_ro_wr_en(pci);
>
> @@ -1102,6 +1103,27 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
> dw_pcie_ep_init_rebar_registers(ep, func_no);
>
> dw_pcie_setup(pci);
> +
> + /*
> + * PCIe r6.0, section 7.5.3.6 states that for multi-function endpoints,
> + * max link width and speed fields must report same values for all functions.
> + * However, dw_pcie_setup() programs these fields only for physical function 0.
> + * Hence, mirror these fields to all other physical functions as well.
> + */
> + if (funcs > 1) {
> + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> + ref_lnkcap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> + ref_lnkcap &= PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS;
Use FIELD_* macros please.
- Mani
> +
> + for (func_no = 1; func_no < funcs; func_no++) {
> + offset = dw_pcie_ep_find_capability(ep, func_no, PCI_CAP_ID_EXP);
> + lnkcap = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_EXP_LNKCAP);
> + lnkcap &= ~(PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
> + lnkcap |= ref_lnkcap;
> + dw_pcie_ep_writel_dbi(ep, func_no, offset + PCI_EXP_LNKCAP, lnkcap);
> + }
> + }
> +
> dw_pcie_dbi_ro_wr_dis(pci);
> }
>
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions
2026-02-18 13:38 ` Manivannan Sadhasivam
@ 2026-02-23 18:12 ` Bjorn Helgaas
0 siblings, 0 replies; 9+ messages in thread
From: Bjorn Helgaas @ 2026-02-23 18:12 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Aksh Garg, linux-pci, jingoohan1, lpieralisi, kwilczynski, robh,
bhelgaas, yoshihiro.shimoda.uh, fancer.lancer, Zhiqiang.Hou,
gustavo.pimentel, cassel, linux-kernel, s-vadapalli, danishanwar
On Wed, Feb 18, 2026 at 07:08:20PM +0530, Manivannan Sadhasivam wrote:
> On Mon, Feb 02, 2026 at 12:57:58PM +0530, Aksh Garg wrote:
> > PCIe r6.0, section 7.5.3.6 states that for multi-function devices, the
> > Max Link Width and Max Link Speed fields in the Link Capabilities
> > Register must report the same values for all functions.
> ...
> > @@ -1102,6 +1103,27 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
> > dw_pcie_ep_init_rebar_registers(ep, func_no);
> >
> > dw_pcie_setup(pci);
> > +
> > + /*
> > + * PCIe r6.0, section 7.5.3.6 states that for multi-function endpoints,
> > + * max link width and speed fields must report same values for all functions.
> > + * However, dw_pcie_setup() programs these fields only for physical function 0.
> > + * Hence, mirror these fields to all other physical functions as well.
> > + */
> > + if (funcs > 1) {
> > + offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> > + ref_lnkcap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> > + ref_lnkcap &= PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS;
>
> Use FIELD_* macros please.
>
> > +
> > + for (func_no = 1; func_no < funcs; func_no++) {
> > + offset = dw_pcie_ep_find_capability(ep, func_no, PCI_CAP_ID_EXP);
> > + lnkcap = dw_pcie_ep_readl_dbi(ep, func_no, offset + PCI_EXP_LNKCAP);
> > + lnkcap &= ~(PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
> > + lnkcap |= ref_lnkcap;
I think this can also use FIELD_MODIFY().
> > + dw_pcie_ep_writel_dbi(ep, func_no, offset + PCI_EXP_LNKCAP, lnkcap);
> > + }
> > + }
> > +
> > dw_pcie_dbi_ro_wr_dis(pci);
> > }
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-02-23 18:12 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-02 7:27 [PATCH 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes Aksh Garg
2026-02-02 7:27 ` [PATCH 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function Aksh Garg
2026-02-02 7:55 ` Niklas Cassel
2026-02-02 7:57 ` Niklas Cassel
2026-02-02 8:15 ` Aksh Garg
2026-02-02 8:47 ` Niklas Cassel
2026-02-02 7:27 ` [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions Aksh Garg
2026-02-18 13:38 ` Manivannan Sadhasivam
2026-02-23 18:12 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox