pcie_tph_get_st_table_loc() incorrectly uses FIELD_GET(), which shifts the field value to bit 0. But the function is designed to return raw PCI_TPH_LOC_* values as defined in the function comment. This causes incorrect ST table location detection. Fix it by using bitwise AND with PCI_TPH_CAP_LOC_MASK to return the unshifted field value matching the function specification. This doesn't make a difference to mlx5_st_create(), the lone external caller, because it only checks for PCI_TPH_LOC_NONE (0), but will be needed for callers that check for PCI_TPH_LOC_CAP or PCI_TPH_LOC_MSIX. Fixes: d2e8a34876ce ("PCI/TPH: Add Steering Tag support") Cc: stable@vger.kernel.org Signed-off-by: Chengwen Feng Reviewed-by: Alex Williamson Reviewed-by: Bjorn Helgaas --- drivers/pci/tph.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c index 91145e8d9d95..877cf556242b 100644 --- a/drivers/pci/tph.c +++ b/drivers/pci/tph.c @@ -170,7 +170,7 @@ u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev) pci_read_config_dword(pdev, pdev->tph_cap + PCI_TPH_CAP, ®); - return FIELD_GET(PCI_TPH_CAP_LOC_MASK, reg); + return reg & PCI_TPH_CAP_LOC_MASK; } EXPORT_SYMBOL(pcie_tph_get_st_table_loc); @@ -185,9 +185,6 @@ u16 pcie_tph_get_st_table_size(struct pci_dev *pdev) /* Check ST table location first */ loc = pcie_tph_get_st_table_loc(pdev); - - /* Convert loc to match with PCI_TPH_LOC_* defined in pci_regs.h */ - loc = FIELD_PREP(PCI_TPH_CAP_LOC_MASK, loc); if (loc != PCI_TPH_LOC_CAP) return 0; @@ -316,8 +313,6 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag) set_ctrl_reg_req_en(pdev, PCI_TPH_REQ_DISABLE); loc = pcie_tph_get_st_table_loc(pdev); - /* Convert loc to match with PCI_TPH_LOC_* */ - loc = FIELD_PREP(PCI_TPH_CAP_LOC_MASK, loc); switch (loc) { case PCI_TPH_LOC_MSIX: -- 2.17.1