From: Aksh Garg <a-garg7@ti.com>
To: <linux-pci@vger.kernel.org>, <jingoohan1@gmail.com>,
<mani@kernel.org>, <lpieralisi@kernel.org>,
<kwilczynski@kernel.org>, <robh@kernel.org>,
<bhelgaas@google.com>, <yoshihiro.shimoda.uh@renesas.com>,
<fancer.lancer@gmail.com>, <Zhiqiang.Hou@nxp.com>,
<gustavo.pimentel@synopsys.com>, <cassel@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <s-vadapalli@ti.com>,
<danishanwar@ti.com>, Aksh Garg <a-garg7@ti.com>
Subject: [PATCH v3 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions
Date: Tue, 24 Feb 2026 14:08:17 +0530 [thread overview]
Message-ID: <20260224083817.916782-3-a-garg7@ti.com> (raw)
In-Reply-To: <20260224083817.916782-1-a-garg7@ti.com>
PCIe r7.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 Function 0
via dw_pcie_link_set_max_speed() and dw_pcie_link_set_max_link_width().
For multi-function endpoint configurations, Function 1 and beyond retain
their default values, violating the PCIe specification.
Fix this by reading the Max Link Width and Max Link Speed fields from
Link Capabilities Register of Function 0 after dw_pcie_setup() completes,
then mirroring these values to all other 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.
Changes from v2 to v3:
- Wrapped the patches to fit within 80 columns
- Updated the term 'physical function' to 'Function'
Changes from v1 to v2:
- Used FIELD_* macros
v2: https://lore.kernel.org/all/20260219064511.695086-3-a-garg7@ti.com/
v1: https://lore.kernel.org/all/20260202072758.101845-3-a-garg7@ti.com/
.../pci/controller/dwc/pcie-designware-ep.c | 29 ++++++++++++++++++-
1 file changed, 28 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..8041c7a0d381 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,32 @@ 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 r7.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 function 0. Hence, mirror these fields
+ * to all other 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 = FIELD_GET(PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS,
+ ref_lnkcap);
+
+ 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);
+ FIELD_MODIFY(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
next prev parent reply other threads:[~2026-02-24 8:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 8:38 [PATCH v3 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes Aksh Garg
2026-02-24 8:38 ` [PATCH v3 1/2] PCI: dwc: ep: Fix MSI-X configuration to write to correct physical function Aksh Garg
2026-03-06 18:45 ` Bjorn Helgaas
2026-03-09 4:49 ` Aksh Garg
2026-03-09 6:31 ` Manivannan Sadhasivam
2026-02-24 8:38 ` Aksh Garg [this message]
2026-03-05 5:04 ` [PATCH v3 0/2] PCI: dwc: ep: Multi-function endpoint configuration fixes Manivannan Sadhasivam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260224083817.916782-3-a-garg7@ti.com \
--to=a-garg7@ti.com \
--cc=Zhiqiang.Hou@nxp.com \
--cc=bhelgaas@google.com \
--cc=cassel@kernel.org \
--cc=danishanwar@ti.com \
--cc=fancer.lancer@gmail.com \
--cc=gustavo.pimentel@synopsys.com \
--cc=jingoohan1@gmail.com \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mani@kernel.org \
--cc=robh@kernel.org \
--cc=s-vadapalli@ti.com \
--cc=yoshihiro.shimoda.uh@renesas.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox