Re: [PATCH v8 6/8] PCI: cadence: Add support to configure virtual functions
From: Kishon Vijay Abraham I <hidden>
Date: 2021-08-18 13:56:06
Also in:
linux-arm-kernel, linux-devicetree, linux-doc, linux-pci, linux-renesas-soc, linux-rockchip
Hi Bjorn, On 17/08/21 9:08 pm, Bjorn Helgaas wrote:
On Wed, Aug 11, 2021 at 12:16:54PM +0530, Kishon Vijay Abraham I wrote:quoted
Now that support for SR-IOV is added in PCIe endpoint core, add support to configure virtual functions in the Cadence PCIe EP driver. Signed-off-by: Kishon Vijay Abraham I <redacted> --- .../pci/controller/cadence/pcie-cadence-ep.c | 136 +++++++++++++++--- drivers/pci/controller/cadence/pcie-cadence.h | 9 ++ 2 files changed, 125 insertions(+), 20 deletions(-)quoted
@@ -92,21 +118,29 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn, addr0 = lower_32_bits(bar_phys); addr1 = upper_32_bits(bar_phys); - cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), - addr0); - cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), - addr1); reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn); + if (vfn == 1) + reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);Seems sort of weird to compute "reg", then sometimes overwrite it, as opposed to: if (vfn == 1) reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn); else reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
I tried to write it without "else". But I can change it back.
Also slightly weird that "vfn" is basically used as a boolean, but it's actually a u8 virtual function number. I guess VF 1 is special and not like the other VFs?
VF1 is special in that it's enough for configuring the SR-IOV capability but below the "vfn" is used for configuring inbound window. Thanks Kishon
quoted
b = (bar < BAR_4) ? bar : bar - BAR_4; - cfg = cdns_pcie_readl(pcie, reg); - cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) | - CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)); - cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) | - CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl)); - cdns_pcie_writel(pcie, reg, cfg); + if (vfn == 0 || vfn == 1) { + cfg = cdns_pcie_readl(pcie, reg); + cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) | + CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)); + cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) | + CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl)); + cdns_pcie_writel(pcie, reg, cfg); + } + fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); + cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), + addr0); + cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), + addr1); + + if (vfn > 0) + epf = &epf->epf[vfn - 1]; epf->epf_bar[bar] = epf_bar; return 0;@@ -122,18 +156,25 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, u32 reg, cfg, b, ctrl; reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn); + if (vfn == 1) + reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);Similar recomputation of "reg".quoted
b = (bar < BAR_4) ? bar : bar - BAR_4; - ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED; - cfg = cdns_pcie_readl(pcie, reg); - cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) | - CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)); - cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl); - cdns_pcie_writel(pcie, reg, cfg); + if (vfn == 0 || vfn == 1) { + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED; + cfg = cdns_pcie_readl(pcie, reg); + cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) | + CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)); + cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl); + cdns_pcie_writel(pcie, reg, cfg); + }