]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ntb: intel: fix port config status offset for SPR
authorDave Jiang <dave.jiang@intel.com>
Thu, 27 Jan 2022 20:31:12 +0000 (13:31 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Mar 2022 18:09:32 +0000 (19:09 +0100)
commit d5081bf5dcfb1cb83fb538708b0ac07a10a79cc4 upstream.

The field offset for port configuration status on SPR has been changed to
bit 14 from ICX where it resides at bit 12. By chance link status detection
continued to work on SPR. This is due to bit 12 being a configuration bit
which is in sync with the status bit. Fix this by checking for a SPR device
and checking correct status bit.

Fixes: 26bfe3d0b227 ("ntb: intel: Add Icelake (gen4) support for Intel NTB")
Tested-by: Jerry Dai <jerry.dai@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/ntb/hw/intel/ntb_hw_gen4.c
drivers/ntb/hw/intel/ntb_hw_gen4.h

index bc4541cbf8c6e174011851c09627971613a17057..99a5fc1ab0aafb2f0d1f0f969ea8a229cf70a10b 100644 (file)
@@ -168,6 +168,18 @@ static enum ntb_topo gen4_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
        return NTB_TOPO_NONE;
 }
 
+static enum ntb_topo spr_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
+{
+       switch (ppd & SPR_PPD_TOPO_MASK) {
+       case SPR_PPD_TOPO_B2B_USD:
+               return NTB_TOPO_B2B_USD;
+       case SPR_PPD_TOPO_B2B_DSD:
+               return NTB_TOPO_B2B_DSD;
+       }
+
+       return NTB_TOPO_NONE;
+}
+
 int gen4_init_dev(struct intel_ntb_dev *ndev)
 {
        struct pci_dev *pdev = ndev->ntb.pdev;
@@ -181,7 +193,10 @@ int gen4_init_dev(struct intel_ntb_dev *ndev)
                ndev->hwerr_flags |= NTB_HWERR_BAR_ALIGN;
 
        ppd1 = ioread32(ndev->self_mmio + GEN4_PPD1_OFFSET);
-       ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1);
+       if (pdev_is_ICX(pdev))
+               ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1);
+       else if (pdev_is_SPR(pdev))
+               ndev->ntb.topo = spr_ppd_topo(ndev, ppd1);
        dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd1,
                ntb_topo_string(ndev->ntb.topo));
        if (ndev->ntb.topo == NTB_TOPO_NONE)
index a868c788de02f3abf37a1ac862814344e1d22f52..ec293953d665f7f7d98ca8134e69387f7fa8a9a3 100644 (file)
 #define GEN4_PPD_CLEAR_TRN             0x0001
 #define GEN4_PPD_LINKTRN               0x0008
 #define GEN4_PPD_CONN_MASK             0x0300
+#define SPR_PPD_CONN_MASK              0x0700
 #define GEN4_PPD_CONN_B2B              0x0200
 #define GEN4_PPD_DEV_MASK              0x1000
 #define GEN4_PPD_DEV_DSD               0x1000
 #define GEN4_PPD_DEV_USD               0x0000
+#define SPR_PPD_DEV_MASK               0x4000
+#define SPR_PPD_DEV_DSD                0x4000
+#define SPR_PPD_DEV_USD                0x0000
 #define GEN4_LINK_CTRL_LINK_DISABLE    0x0010
 
 #define GEN4_SLOTSTS                   0xb05a
 #define GEN4_PPD_TOPO_B2B_USD  (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_USD)
 #define GEN4_PPD_TOPO_B2B_DSD  (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_DSD)
 
+#define SPR_PPD_TOPO_MASK      (SPR_PPD_CONN_MASK | SPR_PPD_DEV_MASK)
+#define SPR_PPD_TOPO_B2B_USD   (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_USD)
+#define SPR_PPD_TOPO_B2B_DSD   (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_DSD)
+
 #define GEN4_DB_COUNT                  32
 #define GEN4_DB_LINK                   32
 #define GEN4_DB_LINK_BIT               BIT_ULL(GEN4_DB_LINK)
@@ -97,4 +105,12 @@ static inline int pdev_is_ICX(struct pci_dev *pdev)
        return 0;
 }
 
+static inline int pdev_is_SPR(struct pci_dev *pdev)
+{
+       if (pdev_is_gen4(pdev) &&
+           pdev->revision > PCI_DEVICE_REVISION_ICX_MAX)
+               return 1;
+       return 0;
+}
+
 #endif