Re: [PATCH 2/2] PCI: dwc: ep: Mirror the max link width and speed fields to all functions
From: Bjorn Helgaas
Date: Mon Feb 23 2026 - 13:13:05 EST
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);
> > }