Extend pcie_tph_get_cpu_st() to accept enum tph_req_policy, so callers can retrieve Steering Tag for standard or extended TPH explicitly. Add input validation and extended TPH capability check. Update function prototype, inline stub, kernel-doc and Documentation/PCI/tph.rst. Signed-off-by: Chengwen Feng --- Documentation/PCI/tph.rst | 10 ++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 ++ .../net/ethernet/mellanox/mlx5/core/lib/st.c | 3 ++- drivers/pci/tph.c | 26 ++++++++++++++++--- include/linux/pci-tph.h | 9 +++++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Documentation/PCI/tph.rst b/Documentation/PCI/tph.rst index a5f14d17977c..17a369e72af1 100644 --- a/Documentation/PCI/tph.rst +++ b/Documentation/PCI/tph.rst @@ -87,11 +87,13 @@ To retrieve a Steering Tag for a target memory associated with a specific CPU, use the following function:: int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type, + enum tph_req_policy req_policy, unsigned int cpu, u16 *tag); The `type` argument is used to specify the memory type, either volatile -or persistent, of the target memory. The `cpu` argument specifies the -CPU where the memory is associated to. +or persistent, of the target memory. The `req_policy` used to select +standard/extended ST. The `cpu` argument specifies the CPU where the memory +is associated to. After the ST value is retrieved, the device driver can use the following function to write the ST into the device:: @@ -125,8 +127,8 @@ been changed. Here is a sample code for IRQ affinity notifier: /* Pick a right CPU as the target - here is just an example */ cpu_id = cpumask_first(irq->cpu_mask); - if (pcie_tph_get_cpu_st(irq->pdev, TPH_MEM_TYPE_VM, cpu_id, - &tag)) + if (pcie_tph_get_cpu_st(irq->pdev, TPH_MEM_TYPE_VM, TPH_REQ_AUTO, + cpu_id, &tag)) return; if (pcie_tph_set_st_entry(irq->pdev, irq->msix_nr, tag)) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1f8d3e728a9f..c3cb7cd7b74a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -11734,6 +11734,7 @@ static void bnxt_irq_affinity_notify(struct irq_affinity_notify *notify, return; if (pcie_tph_get_cpu_st(irq->bp->pdev, TPH_MEM_TYPE_VM, + TPH_REQ_AUTO, cpumask_first(irq->cpu_mask), &tag)) return; @@ -11892,6 +11893,7 @@ static int bnxt_request_irq(struct bnxt *bp) /* Init ST table entry */ if (pcie_tph_get_cpu_st(irq->bp->pdev, TPH_MEM_TYPE_VM, + TPH_REQ_AUTO, cpumask_first(irq->cpu_mask), &tag)) continue; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c index 26ce59d16785..043e13c95028 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c @@ -105,7 +105,8 @@ int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum tph_mem_type mem_type, if (!st) return -EOPNOTSUPP; - ret = pcie_tph_get_cpu_st(dev->pdev, mem_type, cpu_uid, &tag); + ret = pcie_tph_get_cpu_st(dev->pdev, mem_type, TPH_REQ_AUTO, + cpu_uid, &tag); if (ret) return ret; diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c index f7758445988e..4a2c3575a883 100644 --- a/drivers/pci/tph.c +++ b/drivers/pci/tph.c @@ -236,24 +236,44 @@ static int write_tag_to_st_table(struct pci_dev *pdev, int index, u16 tag) * with a specific CPU * @pdev: PCI device * @mem_type: target memory type (volatile or persistent RAM) + * @req_policy: TPH requester selection policy + * + * - TPH_REQ_AUTO: Use currently active requester type + * - TPH_REQ_STANDARD: Retrieve tag for standard TPH (8-bit ST) + * - TPH_REQ_EXTENDED: Retrieve tag for extended TPH (16-bit ST) + * * @cpu: associated CPU id * @tag: Steering Tag to be returned * - * Return the Steering Tag for a target memory that is associated with a - * specific CPU as indicated by cpu. + * Return the Steering Tag for a target memory and requester policy that is + * associated with a specific CPU as indicated by cpu. * * Return: 0 if success, otherwise negative value (-errno) */ int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type, + enum tph_req_policy req_policy, unsigned int cpu, u16 *tag) { #ifdef CONFIG_ACPI struct pci_dev *rp; acpi_handle rp_acpi_handle; union st_info info; + u8 tph_req_type; u32 cpu_uid; int ret; + if (req_policy == TPH_REQ_AUTO) { + tph_req_type = pdev->tph_req_type; + } else if (req_policy == TPH_REQ_STANDARD) { + tph_req_type = PCI_TPH_REQ_TPH_ONLY; + } else if (req_policy == TPH_REQ_EXTENDED) { + if (!pdev->tph_ext_requester) + return -EINVAL; + tph_req_type = PCI_TPH_REQ_EXT_TPH; + } else { + return -EINVAL; + } + ret = acpi_get_cpu_uid(cpu, &cpu_uid); if (ret != 0) return ret; @@ -269,7 +289,7 @@ int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type mem_type, return -EINVAL; } - *tag = tph_extract_tag(mem_type, pdev->tph_req_type, &info); + *tag = tph_extract_tag(mem_type, tph_req_type, &info); pci_dbg(pdev, "get steering tag: mem_type=%s, cpu=%d, tag=%#04x\n", (mem_type == TPH_MEM_TYPE_VM) ? "volatile" : "persistent", diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h index eb7f165b2570..7f78a40173c9 100644 --- a/include/linux/pci-tph.h +++ b/include/linux/pci-tph.h @@ -23,10 +23,13 @@ enum tph_mem_type { /* * TPH requester selection policy - * Used to choose standard/extended TPH when enabling TPH + * Used to choose standard/extended TPH when enabling TPH, + * and select requester type for Steering Tag retrieval. */ enum tph_req_policy { - TPH_REQ_AUTO, /* Auto select by capability */ + TPH_REQ_AUTO, /* Auto select by capability or + * use active requester type + */ TPH_REQ_STANDARD, /* Force standard TPH (8-bit ST) */ TPH_REQ_EXTENDED /* Force extended TPH (16-bit ST) */ }; @@ -36,6 +39,7 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag); int pcie_tph_get_cpu_st(struct pci_dev *dev, enum tph_mem_type mem_type, + enum tph_req_policy req_policy, unsigned int cpu, u16 *tag); void pcie_disable_tph(struct pci_dev *pdev); int pcie_enable_tph(struct pci_dev *pdev, int mode, @@ -48,6 +52,7 @@ static inline int pcie_tph_set_st_entry(struct pci_dev *pdev, { return -EINVAL; } static inline int pcie_tph_get_cpu_st(struct pci_dev *dev, enum tph_mem_type mem_type, + enum tph_req_policy req_policy, unsigned int cpu, u16 *tag) { return -EINVAL; } static inline void pcie_disable_tph(struct pci_dev *pdev) { } -- 2.17.1