RE: [PATCH v1] fpga: dfl: check feature type before parse irq info

From: Zhang, Tianfei
Date: Thu Mar 03 2022 - 19:20:53 EST




> -----Original Message-----
> From: Wu, Hao <hao.wu@xxxxxxxxx>
> Sent: Tuesday, March 1, 2022 10:23 AM
> To: Zhang, Tianfei <tianfei.zhang@xxxxxxxxx>; trix@xxxxxxxxxx;
> mdf@xxxxxxxxxx; Xu, Yilun <yilun.xu@xxxxxxxxx>; linux-fpga@xxxxxxxxxxxxxxx;
> linux-doc@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
> Cc: corbet@xxxxxxx
> Subject: RE: [PATCH v1] fpga: dfl: check feature type before parse irq info
>
> > > -----Original Message-----
> > > From: Wu, Hao <hao.wu@xxxxxxxxx>
> > > Sent: Monday, February 28, 2022 7:10 PM
> > > To: Zhang, Tianfei <tianfei.zhang@xxxxxxxxx>; trix@xxxxxxxxxx;
> > > mdf@xxxxxxxxxx; Xu, Yilun <yilun.xu@xxxxxxxxx>;
> > > linux-fpga@xxxxxxxxxxxxxxx; linux-doc@xxxxxxxxxxxxxxx;
> > > linux-kernel@xxxxxxxxxxxxxxx
> > > Cc: corbet@xxxxxxx
> > > Subject: RE: [PATCH v1] fpga: dfl: check feature type before parse
> > > irq info
> > >
> > > > Subject: [PATCH v1] fpga: dfl: check feature type before parse irq
> > > > info
> > > >
> > > > From: Tianfei Zhang <tianfei.zhang@xxxxxxxxx>
> > > >
> > > > The feature ID of "Port User Interrupt" and the "PMCI Subsystem"
> > > > are identical, 0x12, but one is for FME, other is for Port. It
> > > > should check the feature type While parsing the irq info in
> > > > parse_feature_irqs().
> > > >
> > > > Fixes: 8d021039cbb5 ("fpga: dfl: parse interrupt info for feature
> > > > devices on
> > > > enumeration")
> > >
> > > Actually this is not a real bug, as in original design, there is no
> > > overlap for FME and Port features. This is why you see features for Port
> doesn't start from 0.
> > But
> > > anyway I am good with such extension.
> >
> > I think this is a bug, I add some printk debug log in DFL driver, we
> > observed that
>
> Per original design, you should not use overlap feature IDs for FME and Port as
> existing products. It extends the scope/rules of using feature IDs, for your new
> cards, so to me, this is not a sw bug but extension.

Tom in the previous patch commented that this is a bug fix.

Hi Tom, do you agree this is extension or a DFL software bug?

>
> > it was mistaken for
> > the "Port User Interrput" feature device while we are parsing the FME
> > feature devices, so actually it read out the PMCI MMIO space for "Port
> > User Interrput".
> >
> > Here is the log:
> >
> > [90273.482859] parse_feature: DFH_TYPE_FIU [90273.482861]
> > parse_feature_fiu: id:0 fme [90273.482864] create_feature_instance:
> > feature id: 0xfe [90273.482868] parse_feature: DFH_TYPE_PRIVATE
> > [90273.482870] create_feature_instance: feature id: 0x1 [90273.482872]
> > parse_feature: DFH_TYPE_PRIVATE [90273.482874]
> > create_feature_instance: feature id: 0x7 ...
> > [90273.482895] create_feature_instance: feature id: 0x12
> > [90273.482898] parse_feature_irqs, PORT_UINT_DFH: 0x3000000200001012
> > [90273.482898] parse_feature_irqs, PORT_UINT_CAP: 0xbaadbeefdeadbeef
> > [90273.482899] dfl-pci 0000:b1:00.0: feature: 0x12, irq_base: 2779, nr_irqs:
> > 3823
> > [90273.482901] dfl-pci 0000:b1:00.0: Ignoring nvalid interrupt number
> > in feature
> > 0x12 6602 > 7
> >
> > >
> > > > Link: https://lore.kernel.org/linux-
> > > >
> > >
> >
> fpga/BN9PR11MB54833D7636348D62F931526CE33A9@xxxxxxxxxxxxxxxxx
> > > > prd11.prod.outlook.com/
> > > >
> > > > Signed-off-by: Tianfei Zhang <tianfei.zhang@xxxxxxxxx>
> > > > ---
> > > > Documentation/fpga/dfl.rst | 5 +++++
> > > > drivers/fpga/dfl.c | 38 ++++++++++++++++++++++----------------
> > > > 2 files changed, 27 insertions(+), 16 deletions(-)
> > > >
> > > > diff --git a/Documentation/fpga/dfl.rst
> > > > b/Documentation/fpga/dfl.rst index ef9eec71f6f3..9ce418da1876
> > > > 100644
> > > > --- a/Documentation/fpga/dfl.rst
> > > > +++ b/Documentation/fpga/dfl.rst
> > > > @@ -502,6 +502,11 @@ Developer only needs to provide a sub feature
> > > > driver with matched feature id.
> > > > FME Partial Reconfiguration Sub Feature driver (see
> > > > drivers/fpga/dfl-fme-pr.c) could be a reference.
> > > >
> > > > +Individual DFL drivers are bound DFL devices based on Feature
> > > > +Type and
> > > > Feature ID.
> > > > +The definition of Feature Type and Feature ID can be found:
> > > > +
> > > > +https://github.com/OPAE/linux-dfl-feature-id/blob/master/dfl-feat
> > > > +ure-
> > > > +ids.rst
> > >
> > > Thanks for tracking ID allocations. could we also add some
> > > description that if user want to implement a new private feature,
> > > then they need to submit new
> > ID
> > > application to https://github.com/OPAE/linux-dfl-feature-id, and add
> > > some README file to guide people for the application process?
> >
> > That is a good point, I will add this for next version patch.
> >
> > >
> > > Thanks
> > > Hao
> > >
> > > > +
> > > > Location of DFLs on a PCI Device
> > > > ================================
> > > > The original method for finding a DFL on a PCI device assumed the
> > > > start of the diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
> > > > index 599bb21d86af..6bff39ff21a0 100644
> > > > --- a/drivers/fpga/dfl.c
> > > > +++ b/drivers/fpga/dfl.c
> > > > @@ -940,9 +940,12 @@ static int parse_feature_irqs(struct
> > > > build_feature_devs_info *binfo, {
> > > > void __iomem *base = binfo->ioaddr + ofst;
> > > > unsigned int i, ibase, inr = 0;
> > > > + enum dfl_id_type type;
> > > > int virq;
> > > > u64 v;
> > > >
> > > > + type = feature_dev_id_type(binfo->feature_dev);
> > > > +
> > > > /*
> > > > * Ideally DFL framework should only read info from DFL header, but
> > > > * current version DFL only provides mmio resources information
> > > > for @@ -957,22 +960,25 @@ static int parse_feature_irqs(struct
> > > > build_feature_devs_info *binfo,
> > > > * code will be added. But in order to be compatible to old version
> > > > * DFL, the driver may still fall back to these quirks.
> > > > */
> > > > - switch (fid) {
> > > > - case PORT_FEATURE_ID_UINT:
> > > > - v = readq(base + PORT_UINT_CAP);
> > > > - ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
> > > > - inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
> > > > - break;
> > > > - case PORT_FEATURE_ID_ERROR:
> > > > - v = readq(base + PORT_ERROR_CAP);
> > > > - ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
> > > > - inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
> > > > - break;
> > > > - case FME_FEATURE_ID_GLOBAL_ERR:
> > > > - v = readq(base + FME_ERROR_CAP);
> > > > - ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
> > > > - inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
> > > > - break;
> > > > + if (type == PORT_ID) {
> > > > + switch (fid) {
> > > > + case PORT_FEATURE_ID_UINT:
> > > > + v = readq(base + PORT_UINT_CAP);
> > > > + ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
> > > > + inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
> > > > + break;
> > > > + case PORT_FEATURE_ID_ERROR:
> > > > + v = readq(base + PORT_ERROR_CAP);
> > > > + ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
> > > > + inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
> > > > + break;
> > > > + }
> > > > + } else if (type == FME_ID) {
> > > > + if (fid == FME_FEATURE_ID_GLOBAL_ERR) {
> > > > + v = readq(base + FME_ERROR_CAP);
> > > > + ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
> > > > + inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
> > > > + }
> > > > }
> > > >
> > > > if (!inr) {
> > > > --
> > > > 2.26.2