Add pcie_tph_enabled_req_type() so drivers can query the enabled TPH requester mode without reaching into pci_dev internals.
Add pcie_tph_completer_type() so drivers that publish TPH metadata for a device acting as a completer can gate on the "TPH Completer Supported" field of Device Capabilities 2 (bits 13:12, PCI_EXP_DEVCAP2_TPH_COMP_MASK) rather than reusing requester-side state. It reuses the same reserved- encoding fold as get_rp_completer_type() so the completer decode stays in one place. This keeps pci_dev::tph_req_type and the completer-capability decode inside the PCI/TPH code and provides !CONFIG_PCIE_TPH stubs for callers. Signed-off-by: Zhiping Zhang <[email protected]> --- drivers/pci/tph.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/pci-tph.h | 8 ++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c index ebe1aa5ba5eb..64a6e1da99dc 100644 --- a/drivers/pci/tph.c +++ b/drivers/pci/tph.c @@ -230,6 +230,45 @@ static u8 get_rp_completer_type(struct pci_dev *pdev) reg)); } +/** + * pcie_tph_enabled_req_type - Return the device's enabled TPH requester type + * @pdev: PCI device to query + * + * Return: PCI_TPH_REQ_DISABLE, PCI_TPH_REQ_TPH_ONLY or PCI_TPH_REQ_EXT_TPH. + */ +u8 pcie_tph_enabled_req_type(struct pci_dev *pdev) +{ + return pdev->tph_req_type; +} +EXPORT_SYMBOL(pcie_tph_enabled_req_type); + +/** + * pcie_tph_completer_type - Return the device's TPH Completer support + * @pdev: PCI device to query + * + * Reads the "TPH Completer Supported" field (bits 13:12) of Device + * Capabilities 2. The reserved 0b10 encoding is folded into + * "not supported" so callers only need to compare against the three + * defined values. + * + * Return: one of %PCI_EXP_DEVCAP2_TPH_COMP_NONE, + * %PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY or + * %PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH. + */ +u8 pcie_tph_completer_type(struct pci_dev *pdev) +{ + u32 reg; + + if (pcie_capability_read_dword(pdev, PCI_EXP_DEVCAP2, ®)) + return PCI_EXP_DEVCAP2_TPH_COMP_NONE; + if (PCI_POSSIBLE_ERROR(reg)) + return PCI_EXP_DEVCAP2_TPH_COMP_NONE; + + return tph_completer_type_fold(FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, + reg)); +} +EXPORT_SYMBOL(pcie_tph_completer_type); + /* Write tag to ST table - Return 0 if OK, otherwise -errno */ static int write_tag_to_st_table(struct pci_dev *pdev, int index, u16 tag) { diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h index be68cd17f2f8..7743af6fe432 100644 --- a/include/linux/pci-tph.h +++ b/include/linux/pci-tph.h @@ -9,6 +9,8 @@ #ifndef LINUX_PCI_TPH_H #define LINUX_PCI_TPH_H +#include <linux/pci_regs.h> + /* * According to the ECN for PCI Firmware Spec, Steering Tag can be different * depending on the memory type: Volatile Memory or Persistent Memory. When a @@ -30,6 +32,8 @@ void pcie_disable_tph(struct pci_dev *pdev); int pcie_enable_tph(struct pci_dev *pdev, int mode); u16 pcie_tph_get_st_table_size(struct pci_dev *pdev); u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev); +u8 pcie_tph_enabled_req_type(struct pci_dev *pdev); +u8 pcie_tph_completer_type(struct pci_dev *pdev); #else static inline int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag) @@ -41,6 +45,10 @@ static inline int pcie_tph_get_cpu_st(struct pci_dev *dev, static inline void pcie_disable_tph(struct pci_dev *pdev) { } static inline int pcie_enable_tph(struct pci_dev *pdev, int mode) { return -EINVAL; } +static inline u8 pcie_tph_enabled_req_type(struct pci_dev *pdev) +{ return PCI_TPH_REQ_DISABLE; } +static inline u8 pcie_tph_completer_type(struct pci_dev *pdev) +{ return PCI_EXP_DEVCAP2_TPH_COMP_NONE; } #endif #endif /* LINUX_PCI_TPH_H */ -- 2.53.0-Meta
