Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
0002 /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
0003 #include <linux/debugfs.h>
0004 #include <linux/delay.h>
0005 #include <linux/init.h>
0006 #include <linux/interrupt.h>
0007 #include <linux/module.h>
0008 #include <linux/pci.h>
0009 #include <linux/random.h>
0010 #include <linux/slab.h>
0011 #include <linux/ntb.h>
0012 #include <linux/log2.h>
0013 
0014 #include "ntb_hw_intel.h"
0015 #include "ntb_hw_gen1.h"
0016 #include "ntb_hw_gen3.h"
0017 #include "ntb_hw_gen4.h"
0018 
0019 static int gen4_poll_link(struct intel_ntb_dev *ndev);
0020 static int gen4_link_is_up(struct intel_ntb_dev *ndev);
0021 
0022 static const struct intel_ntb_reg gen4_reg = {
0023     .poll_link      = gen4_poll_link,
0024     .link_is_up     = gen4_link_is_up,
0025     .db_ioread      = gen3_db_ioread,
0026     .db_iowrite     = gen3_db_iowrite,
0027     .db_size        = sizeof(u32),
0028     .ntb_ctl        = GEN4_NTBCNTL_OFFSET,
0029     .mw_bar         = {2, 4},
0030 };
0031 
0032 static const struct intel_ntb_alt_reg gen4_pri_reg = {
0033     .db_clear       = GEN4_IM_INT_STATUS_OFFSET,
0034     .db_mask        = GEN4_IM_INT_DISABLE_OFFSET,
0035     .spad           = GEN4_IM_SPAD_OFFSET,
0036 };
0037 
0038 static const struct intel_ntb_xlat_reg gen4_sec_xlat = {
0039     .bar2_limit     = GEN4_IM23XLMT_OFFSET,
0040     .bar2_xlat      = GEN4_IM23XBASE_OFFSET,
0041     .bar2_idx       = GEN4_IM23XBASEIDX_OFFSET,
0042 };
0043 
0044 static const struct intel_ntb_alt_reg gen4_b2b_reg = {
0045     .db_bell        = GEN4_IM_DOORBELL_OFFSET,
0046     .spad           = GEN4_EM_SPAD_OFFSET,
0047 };
0048 
0049 static int gen4_poll_link(struct intel_ntb_dev *ndev)
0050 {
0051     u16 reg_val;
0052 
0053     /*
0054      * We need to write to DLLSCS bit in the SLOTSTS before we
0055      * can clear the hardware link interrupt on ICX NTB.
0056      */
0057     iowrite16(GEN4_SLOTSTS_DLLSCS, ndev->self_mmio + GEN4_SLOTSTS);
0058     ndev->reg->db_iowrite(ndev->db_link_mask,
0059                   ndev->self_mmio +
0060                   ndev->self_reg->db_clear);
0061 
0062     reg_val = ioread16(ndev->self_mmio + GEN4_LINK_STATUS_OFFSET);
0063     if (reg_val == ndev->lnk_sta)
0064         return 0;
0065 
0066     ndev->lnk_sta = reg_val;
0067 
0068     return 1;
0069 }
0070 
0071 static int gen4_link_is_up(struct intel_ntb_dev *ndev)
0072 {
0073     return NTB_LNK_STA_ACTIVE(ndev->lnk_sta);
0074 }
0075 
0076 static int gen4_init_isr(struct intel_ntb_dev *ndev)
0077 {
0078     int i;
0079 
0080     /*
0081      * The MSIX vectors and the interrupt status bits are not lined up
0082      * on Gen3 (Skylake) and Gen4. By default the link status bit is bit
0083      * 32, however it is by default MSIX vector0. We need to fixup to
0084      * line them up. The vectors at reset is 1-32,0. We need to reprogram
0085      * to 0-32.
0086      */
0087     for (i = 0; i < GEN4_DB_MSIX_VECTOR_COUNT; i++)
0088         iowrite8(i, ndev->self_mmio + GEN4_INTVEC_OFFSET + i);
0089 
0090     return ndev_init_isr(ndev, GEN4_DB_MSIX_VECTOR_COUNT,
0091                  GEN4_DB_MSIX_VECTOR_COUNT,
0092                  GEN4_DB_MSIX_VECTOR_SHIFT,
0093                  GEN4_DB_TOTAL_SHIFT);
0094 }
0095 
0096 static int gen4_setup_b2b_mw(struct intel_ntb_dev *ndev,
0097                 const struct intel_b2b_addr *addr,
0098                 const struct intel_b2b_addr *peer_addr)
0099 {
0100     struct pci_dev *pdev;
0101     void __iomem *mmio;
0102     phys_addr_t bar_addr;
0103 
0104     pdev = ndev->ntb.pdev;
0105     mmio = ndev->self_mmio;
0106 
0107     /* setup incoming bar limits == base addrs (zero length windows) */
0108     bar_addr = addr->bar2_addr64;
0109     iowrite64(bar_addr, mmio + GEN4_IM23XLMT_OFFSET);
0110     bar_addr = ioread64(mmio + GEN4_IM23XLMT_OFFSET);
0111     dev_dbg(&pdev->dev, "IM23XLMT %#018llx\n", bar_addr);
0112 
0113     bar_addr = addr->bar4_addr64;
0114     iowrite64(bar_addr, mmio + GEN4_IM45XLMT_OFFSET);
0115     bar_addr = ioread64(mmio + GEN4_IM45XLMT_OFFSET);
0116     dev_dbg(&pdev->dev, "IM45XLMT %#018llx\n", bar_addr);
0117 
0118     /* zero incoming translation addrs */
0119     iowrite64(0, mmio + GEN4_IM23XBASE_OFFSET);
0120     iowrite64(0, mmio + GEN4_IM45XBASE_OFFSET);
0121 
0122     ndev->peer_mmio = ndev->self_mmio;
0123 
0124     return 0;
0125 }
0126 
0127 static int gen4_init_ntb(struct intel_ntb_dev *ndev)
0128 {
0129     int rc;
0130 
0131 
0132     ndev->mw_count = XEON_MW_COUNT;
0133     ndev->spad_count = GEN4_SPAD_COUNT;
0134     ndev->db_count = GEN4_DB_COUNT;
0135     ndev->db_link_mask = GEN4_DB_LINK_BIT;
0136 
0137     ndev->self_reg = &gen4_pri_reg;
0138     ndev->xlat_reg = &gen4_sec_xlat;
0139     ndev->peer_reg = &gen4_b2b_reg;
0140 
0141     if (ndev->ntb.topo == NTB_TOPO_B2B_USD)
0142         rc = gen4_setup_b2b_mw(ndev, &xeon_b2b_dsd_addr,
0143                 &xeon_b2b_usd_addr);
0144     else
0145         rc = gen4_setup_b2b_mw(ndev, &xeon_b2b_usd_addr,
0146                 &xeon_b2b_dsd_addr);
0147     if (rc)
0148         return rc;
0149 
0150     ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
0151 
0152     ndev->reg->db_iowrite(ndev->db_valid_mask,
0153                   ndev->self_mmio +
0154                   ndev->self_reg->db_mask);
0155 
0156     return 0;
0157 }
0158 
0159 static enum ntb_topo gen4_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
0160 {
0161     switch (ppd & GEN4_PPD_TOPO_MASK) {
0162     case GEN4_PPD_TOPO_B2B_USD:
0163         return NTB_TOPO_B2B_USD;
0164     case GEN4_PPD_TOPO_B2B_DSD:
0165         return NTB_TOPO_B2B_DSD;
0166     }
0167 
0168     return NTB_TOPO_NONE;
0169 }
0170 
0171 static enum ntb_topo spr_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
0172 {
0173     switch (ppd & SPR_PPD_TOPO_MASK) {
0174     case SPR_PPD_TOPO_B2B_USD:
0175         return NTB_TOPO_B2B_USD;
0176     case SPR_PPD_TOPO_B2B_DSD:
0177         return NTB_TOPO_B2B_DSD;
0178     }
0179 
0180     return NTB_TOPO_NONE;
0181 }
0182 
0183 int gen4_init_dev(struct intel_ntb_dev *ndev)
0184 {
0185     struct pci_dev *pdev = ndev->ntb.pdev;
0186     u32 ppd1/*, ppd0*/;
0187     u16 lnkctl;
0188     int rc;
0189 
0190     ndev->reg = &gen4_reg;
0191 
0192     if (pdev_is_ICX(pdev)) {
0193         ndev->hwerr_flags |= NTB_HWERR_BAR_ALIGN;
0194         ndev->hwerr_flags |= NTB_HWERR_LTR_BAD;
0195     }
0196 
0197     ppd1 = ioread32(ndev->self_mmio + GEN4_PPD1_OFFSET);
0198     if (pdev_is_ICX(pdev))
0199         ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1);
0200     else if (pdev_is_SPR(pdev) || pdev_is_gen5(pdev))
0201         ndev->ntb.topo = spr_ppd_topo(ndev, ppd1);
0202     dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd1,
0203         ntb_topo_string(ndev->ntb.topo));
0204     if (ndev->ntb.topo == NTB_TOPO_NONE)
0205         return -EINVAL;
0206 
0207     rc = gen4_init_ntb(ndev);
0208     if (rc)
0209         return rc;
0210 
0211     /* init link setup */
0212     lnkctl = ioread16(ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0213     lnkctl |= GEN4_LINK_CTRL_LINK_DISABLE;
0214     iowrite16(lnkctl, ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0215 
0216     return gen4_init_isr(ndev);
0217 }
0218 
0219 ssize_t ndev_ntb4_debugfs_read(struct file *filp, char __user *ubuf,
0220                       size_t count, loff_t *offp)
0221 {
0222     struct intel_ntb_dev *ndev;
0223     void __iomem *mmio;
0224     char *buf;
0225     size_t buf_size;
0226     ssize_t ret, off;
0227     union { u64 v64; u32 v32; u16 v16; } u;
0228 
0229     ndev = filp->private_data;
0230     mmio = ndev->self_mmio;
0231 
0232     buf_size = min(count, 0x800ul);
0233 
0234     buf = kmalloc(buf_size, GFP_KERNEL);
0235     if (!buf)
0236         return -ENOMEM;
0237 
0238     off = 0;
0239 
0240     off += scnprintf(buf + off, buf_size - off,
0241              "NTB Device Information:\n");
0242 
0243     off += scnprintf(buf + off, buf_size - off,
0244              "Connection Topology -\t%s\n",
0245              ntb_topo_string(ndev->ntb.topo));
0246 
0247     off += scnprintf(buf + off, buf_size - off,
0248              "NTB CTL -\t\t%#06x\n", ndev->ntb_ctl);
0249     off += scnprintf(buf + off, buf_size - off,
0250              "LNK STA (cached) -\t\t%#06x\n", ndev->lnk_sta);
0251 
0252     if (!ndev->reg->link_is_up(ndev))
0253         off += scnprintf(buf + off, buf_size - off,
0254                  "Link Status -\t\tDown\n");
0255     else {
0256         off += scnprintf(buf + off, buf_size - off,
0257                  "Link Status -\t\tUp\n");
0258         off += scnprintf(buf + off, buf_size - off,
0259                  "Link Speed -\t\tPCI-E Gen %u\n",
0260                  NTB_LNK_STA_SPEED(ndev->lnk_sta));
0261         off += scnprintf(buf + off, buf_size - off,
0262                  "Link Width -\t\tx%u\n",
0263                  NTB_LNK_STA_WIDTH(ndev->lnk_sta));
0264     }
0265 
0266     off += scnprintf(buf + off, buf_size - off,
0267              "Memory Window Count -\t%u\n", ndev->mw_count);
0268     off += scnprintf(buf + off, buf_size - off,
0269              "Scratchpad Count -\t%u\n", ndev->spad_count);
0270     off += scnprintf(buf + off, buf_size - off,
0271              "Doorbell Count -\t%u\n", ndev->db_count);
0272     off += scnprintf(buf + off, buf_size - off,
0273              "Doorbell Vector Count -\t%u\n", ndev->db_vec_count);
0274     off += scnprintf(buf + off, buf_size - off,
0275              "Doorbell Vector Shift -\t%u\n", ndev->db_vec_shift);
0276 
0277     off += scnprintf(buf + off, buf_size - off,
0278              "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask);
0279     off += scnprintf(buf + off, buf_size - off,
0280              "Doorbell Link Mask -\t%#llx\n", ndev->db_link_mask);
0281     off += scnprintf(buf + off, buf_size - off,
0282              "Doorbell Mask Cached -\t%#llx\n", ndev->db_mask);
0283 
0284     u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_mask);
0285     off += scnprintf(buf + off, buf_size - off,
0286              "Doorbell Mask -\t\t%#llx\n", u.v64);
0287 
0288     off += scnprintf(buf + off, buf_size - off,
0289              "\nNTB Incoming XLAT:\n");
0290 
0291     u.v64 = ioread64(mmio + GEN4_IM23XBASE_OFFSET);
0292     off += scnprintf(buf + off, buf_size - off,
0293              "IM23XBASE -\t\t%#018llx\n", u.v64);
0294 
0295     u.v64 = ioread64(mmio + GEN4_IM45XBASE_OFFSET);
0296     off += scnprintf(buf + off, buf_size - off,
0297              "IM45XBASE -\t\t%#018llx\n", u.v64);
0298 
0299     u.v64 = ioread64(mmio + GEN4_IM23XLMT_OFFSET);
0300     off += scnprintf(buf + off, buf_size - off,
0301              "IM23XLMT -\t\t\t%#018llx\n", u.v64);
0302 
0303     u.v64 = ioread64(mmio + GEN4_IM45XLMT_OFFSET);
0304     off += scnprintf(buf + off, buf_size - off,
0305              "IM45XLMT -\t\t\t%#018llx\n", u.v64);
0306 
0307     off += scnprintf(buf + off, buf_size - off,
0308              "\nNTB Statistics:\n");
0309 
0310     off += scnprintf(buf + off, buf_size - off,
0311              "\nNTB Hardware Errors:\n");
0312 
0313     if (!pci_read_config_word(ndev->ntb.pdev,
0314                   GEN4_DEVSTS_OFFSET, &u.v16))
0315         off += scnprintf(buf + off, buf_size - off,
0316                 "DEVSTS -\t\t%#06x\n", u.v16);
0317 
0318     u.v16 = ioread16(mmio + GEN4_LINK_STATUS_OFFSET);
0319     off += scnprintf(buf + off, buf_size - off,
0320             "LNKSTS -\t\t%#06x\n", u.v16);
0321 
0322     if (!pci_read_config_dword(ndev->ntb.pdev,
0323                    GEN4_UNCERRSTS_OFFSET, &u.v32))
0324         off += scnprintf(buf + off, buf_size - off,
0325                  "UNCERRSTS -\t\t%#06x\n", u.v32);
0326 
0327     if (!pci_read_config_dword(ndev->ntb.pdev,
0328                    GEN4_CORERRSTS_OFFSET, &u.v32))
0329         off += scnprintf(buf + off, buf_size - off,
0330                  "CORERRSTS -\t\t%#06x\n", u.v32);
0331 
0332     ret = simple_read_from_buffer(ubuf, count, offp, buf, off);
0333     kfree(buf);
0334     return ret;
0335 }
0336 
0337 static int intel_ntb4_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
0338                    dma_addr_t addr, resource_size_t size)
0339 {
0340     struct intel_ntb_dev *ndev = ntb_ndev(ntb);
0341     unsigned long xlat_reg, limit_reg, idx_reg;
0342     unsigned short base_idx, reg_val16;
0343     resource_size_t bar_size, mw_size;
0344     void __iomem *mmio;
0345     u64 base, limit, reg_val;
0346     int bar;
0347 
0348     if (pidx != NTB_DEF_PEER_IDX)
0349         return -EINVAL;
0350 
0351     if (idx >= ndev->b2b_idx && !ndev->b2b_off)
0352         idx += 1;
0353 
0354     bar = ndev_mw_to_bar(ndev, idx);
0355     if (bar < 0)
0356         return bar;
0357 
0358     bar_size = pci_resource_len(ndev->ntb.pdev, bar);
0359 
0360     if (idx == ndev->b2b_idx)
0361         mw_size = bar_size - ndev->b2b_off;
0362     else
0363         mw_size = bar_size;
0364 
0365     if (ndev->hwerr_flags & NTB_HWERR_BAR_ALIGN) {
0366         /* hardware requires that addr is aligned to bar size */
0367         if (addr & (bar_size - 1))
0368             return -EINVAL;
0369     } else {
0370         if (addr & (PAGE_SIZE - 1))
0371             return -EINVAL;
0372     }
0373 
0374     /* make sure the range fits in the usable mw size */
0375     if (size > mw_size)
0376         return -EINVAL;
0377 
0378     mmio = ndev->self_mmio;
0379     xlat_reg = ndev->xlat_reg->bar2_xlat + (idx * 0x10);
0380     limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10);
0381     base = pci_resource_start(ndev->ntb.pdev, bar);
0382 
0383     /* Set the limit if supported, if size is not mw_size */
0384     if (limit_reg && size != mw_size) {
0385         limit = base + size;
0386         base_idx = __ilog2_u64(size);
0387     } else {
0388         limit = base + mw_size;
0389         base_idx = __ilog2_u64(mw_size);
0390     }
0391 
0392 
0393     /* set and verify setting the translation address */
0394     iowrite64(addr, mmio + xlat_reg);
0395     reg_val = ioread64(mmio + xlat_reg);
0396     if (reg_val != addr) {
0397         iowrite64(0, mmio + xlat_reg);
0398         return -EIO;
0399     }
0400 
0401     dev_dbg(&ntb->pdev->dev, "BAR %d IMXBASE: %#Lx\n", bar, reg_val);
0402 
0403     /* set and verify setting the limit */
0404     iowrite64(limit, mmio + limit_reg);
0405     reg_val = ioread64(mmio + limit_reg);
0406     if (reg_val != limit) {
0407         iowrite64(base, mmio + limit_reg);
0408         iowrite64(0, mmio + xlat_reg);
0409         return -EIO;
0410     }
0411 
0412     dev_dbg(&ntb->pdev->dev, "BAR %d IMXLMT: %#Lx\n", bar, reg_val);
0413 
0414     if (ndev->hwerr_flags & NTB_HWERR_BAR_ALIGN) {
0415         idx_reg = ndev->xlat_reg->bar2_idx + (idx * 0x2);
0416         iowrite16(base_idx, mmio + idx_reg);
0417         reg_val16 = ioread16(mmio + idx_reg);
0418         if (reg_val16 != base_idx) {
0419             iowrite64(base, mmio + limit_reg);
0420             iowrite64(0, mmio + xlat_reg);
0421             iowrite16(0, mmio + idx_reg);
0422             return -EIO;
0423         }
0424         dev_dbg(&ntb->pdev->dev, "BAR %d IMBASEIDX: %#x\n", bar, reg_val16);
0425     }
0426 
0427 
0428     return 0;
0429 }
0430 
0431 static int intel_ntb4_link_enable(struct ntb_dev *ntb,
0432         enum ntb_speed max_speed, enum ntb_width max_width)
0433 {
0434     struct intel_ntb_dev *ndev;
0435     u32 ntb_ctl, ppd0;
0436     u16 lnkctl;
0437 
0438     ndev = container_of(ntb, struct intel_ntb_dev, ntb);
0439 
0440     dev_dbg(&ntb->pdev->dev,
0441             "Enabling link with max_speed %d max_width %d\n",
0442             max_speed, max_width);
0443 
0444     if (max_speed != NTB_SPEED_AUTO)
0445         dev_dbg(&ntb->pdev->dev,
0446                 "ignoring max_speed %d\n", max_speed);
0447     if (max_width != NTB_WIDTH_AUTO)
0448         dev_dbg(&ntb->pdev->dev,
0449                 "ignoring max_width %d\n", max_width);
0450 
0451     if (!(ndev->hwerr_flags & NTB_HWERR_LTR_BAD)) {
0452         u32 ltr;
0453 
0454         /* Setup active snoop LTR values */
0455         ltr = NTB_LTR_ACTIVE_REQMNT | NTB_LTR_ACTIVE_VAL | NTB_LTR_ACTIVE_LATSCALE;
0456         /* Setup active non-snoop values */
0457         ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
0458         iowrite32(ltr, ndev->self_mmio + GEN4_LTR_ACTIVE_OFFSET);
0459 
0460         /* Setup idle snoop LTR values */
0461         ltr = NTB_LTR_IDLE_VAL | NTB_LTR_IDLE_LATSCALE | NTB_LTR_IDLE_REQMNT;
0462         /* Setup idle non-snoop values */
0463         ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
0464         iowrite32(ltr, ndev->self_mmio + GEN4_LTR_IDLE_OFFSET);
0465 
0466         /* setup PCIe LTR to active */
0467         iowrite8(NTB_LTR_SWSEL_ACTIVE, ndev->self_mmio + GEN4_LTR_SWSEL_OFFSET);
0468     }
0469 
0470     ntb_ctl = NTB_CTL_E2I_BAR23_SNOOP | NTB_CTL_I2E_BAR23_SNOOP;
0471     ntb_ctl |= NTB_CTL_E2I_BAR45_SNOOP | NTB_CTL_I2E_BAR45_SNOOP;
0472     iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl);
0473 
0474     lnkctl = ioread16(ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0475     lnkctl &= ~GEN4_LINK_CTRL_LINK_DISABLE;
0476     iowrite16(lnkctl, ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0477 
0478     /* start link training in PPD0 */
0479     ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET);
0480     ppd0 |= GEN4_PPD_LINKTRN;
0481     iowrite32(ppd0, ndev->self_mmio + GEN4_PPD0_OFFSET);
0482 
0483     /* make sure link training has started */
0484     ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET);
0485     if (!(ppd0 & GEN4_PPD_LINKTRN)) {
0486         dev_warn(&ntb->pdev->dev, "Link is not training\n");
0487         return -ENXIO;
0488     }
0489 
0490     ndev->dev_up = 1;
0491 
0492     return 0;
0493 }
0494 
0495 static int intel_ntb4_link_disable(struct ntb_dev *ntb)
0496 {
0497     struct intel_ntb_dev *ndev;
0498     u32 ntb_cntl;
0499     u16 lnkctl;
0500 
0501     ndev = container_of(ntb, struct intel_ntb_dev, ntb);
0502 
0503     dev_dbg(&ntb->pdev->dev, "Disabling link\n");
0504 
0505     /* clear the snoop bits */
0506     ntb_cntl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl);
0507     ntb_cntl &= ~(NTB_CTL_E2I_BAR23_SNOOP | NTB_CTL_I2E_BAR23_SNOOP);
0508     ntb_cntl &= ~(NTB_CTL_E2I_BAR45_SNOOP | NTB_CTL_I2E_BAR45_SNOOP);
0509     iowrite32(ntb_cntl, ndev->self_mmio + ndev->reg->ntb_ctl);
0510 
0511     lnkctl = ioread16(ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0512     lnkctl |= GEN4_LINK_CTRL_LINK_DISABLE;
0513     iowrite16(lnkctl, ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
0514 
0515     /* set LTR to idle */
0516     if (!(ndev->hwerr_flags & NTB_HWERR_LTR_BAD))
0517         iowrite8(NTB_LTR_SWSEL_IDLE, ndev->self_mmio + GEN4_LTR_SWSEL_OFFSET);
0518 
0519     ndev->dev_up = 0;
0520 
0521     return 0;
0522 }
0523 
0524 static int intel_ntb4_mw_get_align(struct ntb_dev *ntb, int pidx, int idx,
0525                    resource_size_t *addr_align,
0526                    resource_size_t *size_align,
0527                    resource_size_t *size_max)
0528 {
0529     struct intel_ntb_dev *ndev = ntb_ndev(ntb);
0530     resource_size_t bar_size, mw_size;
0531     int bar;
0532 
0533     if (pidx != NTB_DEF_PEER_IDX)
0534         return -EINVAL;
0535 
0536     if (idx >= ndev->b2b_idx && !ndev->b2b_off)
0537         idx += 1;
0538 
0539     bar = ndev_mw_to_bar(ndev, idx);
0540     if (bar < 0)
0541         return bar;
0542 
0543     bar_size = pci_resource_len(ndev->ntb.pdev, bar);
0544 
0545     if (idx == ndev->b2b_idx)
0546         mw_size = bar_size - ndev->b2b_off;
0547     else
0548         mw_size = bar_size;
0549 
0550     if (addr_align) {
0551         if (ndev->hwerr_flags & NTB_HWERR_BAR_ALIGN)
0552             *addr_align = pci_resource_len(ndev->ntb.pdev, bar);
0553         else
0554             *addr_align = PAGE_SIZE;
0555     }
0556 
0557     if (size_align)
0558         *size_align = 1;
0559 
0560     if (size_max)
0561         *size_max = mw_size;
0562 
0563     return 0;
0564 }
0565 
0566 const struct ntb_dev_ops intel_ntb4_ops = {
0567     .mw_count       = intel_ntb_mw_count,
0568     .mw_get_align       = intel_ntb4_mw_get_align,
0569     .mw_set_trans       = intel_ntb4_mw_set_trans,
0570     .peer_mw_count      = intel_ntb_peer_mw_count,
0571     .peer_mw_get_addr   = intel_ntb_peer_mw_get_addr,
0572     .link_is_up     = intel_ntb_link_is_up,
0573     .link_enable        = intel_ntb4_link_enable,
0574     .link_disable       = intel_ntb4_link_disable,
0575     .db_valid_mask      = intel_ntb_db_valid_mask,
0576     .db_vector_count    = intel_ntb_db_vector_count,
0577     .db_vector_mask     = intel_ntb_db_vector_mask,
0578     .db_read        = intel_ntb3_db_read,
0579     .db_clear       = intel_ntb3_db_clear,
0580     .db_set_mask        = intel_ntb_db_set_mask,
0581     .db_clear_mask      = intel_ntb_db_clear_mask,
0582     .peer_db_addr       = intel_ntb3_peer_db_addr,
0583     .peer_db_set        = intel_ntb3_peer_db_set,
0584     .spad_is_unsafe     = intel_ntb_spad_is_unsafe,
0585     .spad_count     = intel_ntb_spad_count,
0586     .spad_read      = intel_ntb_spad_read,
0587     .spad_write     = intel_ntb_spad_write,
0588     .peer_spad_addr     = intel_ntb_peer_spad_addr,
0589     .peer_spad_read     = intel_ntb_peer_spad_read,
0590     .peer_spad_write    = intel_ntb_peer_spad_write,
0591 };
0592