Add vendor specific extended configuration space capability search API
using struct dw_pcie pointer for DW controllers.
Signed-off-by: Shradha Todi <[email protected]>
---
drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++++++++
drivers/pci/controller/dwc/pcie-designware.h | 4 ++++
2 files changed, 20 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index a945f0c0e73d..348f6f696976 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -90,6 +90,22 @@ static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
return 0;
}
+u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap)
+{
+ u16 vsec = 0;
+ u32 header;
+
+ while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
+ PCI_EXT_CAP_ID_VNDR))) {
+ header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
+ if (PCI_VNDR_HEADER_ID(header) == vsec_cap)
+ return vsec;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_pcie_find_vsec_capability);
+
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
{
return dw_pcie_find_next_ext_capability(pci, 0, cap);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 7d6e9b7576be..307525aaa063 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -155,6 +155,9 @@
#define MAX_IATU_IN 256
#define MAX_IATU_OUT 256
+/* Synopsys Vendor specific data */
+#define DW_PCIE_RAS_CAP_ID 0x2
+
struct pcie_port;
struct dw_pcie;
struct dw_pcie_ep;
@@ -284,6 +287,7 @@ struct dw_pcie {
u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
+u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap);
int dw_pcie_read(void __iomem *addr, int size, u32 *val);
int dw_pcie_write(void __iomem *addr, int size, u32 val);
--
2.17.1
Hi Shradha,
[...]
> +u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap)
> +{
> + u16 vsec = 0;
> + u32 header;
> +
> + while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
> + PCI_EXT_CAP_ID_VNDR))) {
> + header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
> + if (PCI_VNDR_HEADER_ID(header) == vsec_cap)
> + return vsec;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(dw_pcie_find_vsec_capability);
A small question as I am curious: why not use pci_find_vsec_capability()
here? The implementation looks very similar, which is why I am asking,
but it might be that I am missing something, and for that I apologise in
advance.
Krzysztof
On 5/18/2021 11:16 PM, Shradha Todi wrote:
> External email: Use caution opening links or attachments
>
>
> Add vendor specific extended configuration space capability search API
> using struct dw_pcie pointer for DW controllers.
>
> Signed-off-by: Shradha Todi <[email protected]>
> ---
> drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++++++++
> drivers/pci/controller/dwc/pcie-designware.h | 4 ++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index a945f0c0e73d..348f6f696976 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -90,6 +90,22 @@ static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
> return 0;
> }
>
> +u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap)
> +{
> + u16 vsec = 0;
> + u32 header;
> +
> + while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
> + PCI_EXT_CAP_ID_VNDR))) {
> + header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
> + if (PCI_VNDR_HEADER_ID(header) == vsec_cap)
> + return vsec;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(dw_pcie_find_vsec_capability);
> +
> u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
> {
> return dw_pcie_find_next_ext_capability(pci, 0, cap);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 7d6e9b7576be..307525aaa063 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -155,6 +155,9 @@
> #define MAX_IATU_IN 256
> #define MAX_IATU_OUT 256
>
> +/* Synopsys Vendor specific data */
> +#define DW_PCIE_RAS_CAP_ID 0x2
This is not used in this patch. Better to move it to the second patch in
this series where it is used.
> +
> struct pcie_port;
> struct dw_pcie;
> struct dw_pcie_ep;
> @@ -284,6 +287,7 @@ struct dw_pcie {
>
> u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
> +u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap);
>
> int dw_pcie_read(void __iomem *addr, int size, u32 *val);
> int dw_pcie_write(void __iomem *addr, int size, u32 val);
> --
> 2.17.1
>
On 5/22/2021 5:01 AM, Krzysztof Wilczyński wrote:
> External email: Use caution opening links or attachments
>
>
> Hi Shradha,
>
> [...]
>> +u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci, u8 vsec_cap)
>> +{
>> + u16 vsec = 0;
>> + u32 header;
>> +
>> + while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
>> + PCI_EXT_CAP_ID_VNDR))) {
>> + header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
>> + if (PCI_VNDR_HEADER_ID(header) == vsec_cap)
>> + return vsec;
>> + }
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(dw_pcie_find_vsec_capability);
>
> A small question as I am curious: why not use pci_find_vsec_capability()
> here? The implementation looks very similar, which is why I am asking,
> but it might be that I am missing something, and for that I apologise in
> advance.
pci_find_vsec_capability() expects struct pci_dev * which we get only
after enumeration is done. In the current scenario, we are still in
pre-link up phase and don't have struct pci_dev * yet, hence this
implementation, right Shradha??
>
> Krzysztof
>