On Mon, Sep 16, 2024 at 03:50:59PM -0500, Wei Huang wrote: > Add support for PCIe TLP Processing Hints (TPH) support (see PCIe r6.2, > sec 6.17). > > Add missing TPH register definitions in pci_regs.h, including the TPH > Requester capability register, TPH Requester control register, TPH > Completer capability, and the ST fields of MSI-X entry. > > Introduce pcie_enable_tph() and pcie_disable_tph(), enabling drivers to > toggle TPH support and configure specific ST mode as needed. Also add a > new kernel parameter, "pci=notph", allowing users to disable TPH support > across the entire system. > > Co-developed-by: Jing Liu <jing2.liu@xxxxxxxxx> > Signed-off-by: Jing Liu <jing2.liu@xxxxxxxxx> > Co-developed-by: Paul Luse <paul.e.luse@xxxxxxxxxxxxxxx> > Signed-off-by: Paul Luse <paul.e.luse@xxxxxxxxxxxxxxx> > Co-developed-by: Eric Van Tassell <Eric.VanTassell@xxxxxxx> > Signed-off-by: Eric Van Tassell <Eric.VanTassell@xxxxxxx> > Signed-off-by: Wei Huang <wei.huang2@xxxxxxx> > Reviewed-by: Ajit Khaparde <ajit.khaparde@xxxxxxxxxxxx> > Reviewed-by: Somnath Kotur <somnath.kotur@xxxxxxxxxxxx> > Reviewed-by: Andy Gospodarek <andrew.gospodarek@xxxxxxxxxxxx> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > Reviewed-by: Lukas Wunner <lukas@xxxxxxxxx> ... > diff --git a/drivers/pci/pcie/tph.c b/drivers/pci/pcie/tph.c ... > +/** > + * pcie_enable_tph - Enable TPH support for device using a specific ST mode > + * @pdev: PCI device > + * @mode: ST mode to enable. Current supported modes include: > + * > + * - PCI_TPH_ST_NS_MODE: NO ST Mode > + * - PCI_TPH_ST_IV_MODE: Interrupt Vector Mode > + * - PCI_TPH_ST_DS_MODE: Device Specific Mode > + * > + * Checks whether the mode is actually supported by the device before enabling > + * and returns an error if not. Additionally determines what types of requests, > + * TPH or extended TPH, can be issued by the device based on its TPH requester > + * capability and the Root Port's completer capability. > + * > + * Return: 0 on success, otherwise negative value (-errno) > + */ > +int pcie_enable_tph(struct pci_dev *pdev, int mode) > +{ > + u32 reg; > + u8 dev_modes; > + u8 rp_req_type; > + > + /* Honor "notph" kernel parameter */ > + if (pci_tph_disabled) > + return -EINVAL; > + > + if (!pdev->tph_cap) > + return -EINVAL; > + > + if (pdev->tph_enabled) > + return -EBUSY; > + > + /* Sanitize and check ST mode comptability */ Hi Wei Huang, all, Another minor nit from my side (the last one, I think): comptability -> compatibility Flagged by checkpatch.pl --codespell > + mode &= PCI_TPH_CTRL_MODE_SEL_MASK; > + dev_modes = get_st_modes(pdev); > + if (!((1 << mode) & dev_modes)) > + return -EINVAL; > + > + pdev->tph_mode = mode; > + > + /* Get req_type supported by device and its Root Port */ > + pci_read_config_dword(pdev, pdev->tph_cap + PCI_TPH_CAP, ®); > + if (FIELD_GET(PCI_TPH_CAP_EXT_TPH, reg)) > + pdev->tph_req_type = PCI_TPH_REQ_EXT_TPH; > + else > + pdev->tph_req_type = PCI_TPH_REQ_TPH_ONLY; > + > + rp_req_type = get_rp_completer_type(pdev); > + > + /* Final req_type is the smallest value of two */ > + pdev->tph_req_type = min(pdev->tph_req_type, rp_req_type); > + > + if (pdev->tph_req_type == PCI_TPH_REQ_DISABLE) > + return -EINVAL; > + > + /* Write them into TPH control register */ > + pci_read_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, ®); > + > + reg &= ~PCI_TPH_CTRL_MODE_SEL_MASK; > + reg |= FIELD_PREP(PCI_TPH_CTRL_MODE_SEL_MASK, pdev->tph_mode); > + > + reg &= ~PCI_TPH_CTRL_REQ_EN_MASK; > + reg |= FIELD_PREP(PCI_TPH_CTRL_REQ_EN_MASK, pdev->tph_req_type); > + > + pci_write_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, reg); > + > + pdev->tph_enabled = 1; > + > + return 0; > +} > +EXPORT_SYMBOL(pcie_enable_tph); ...