0001
0002
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
0055
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
0082
0083
0084
0085
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
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
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;
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
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
0367 if (addr & (bar_size - 1))
0368 return -EINVAL;
0369 } else {
0370 if (addr & (PAGE_SIZE - 1))
0371 return -EINVAL;
0372 }
0373
0374
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
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
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
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
0455 ltr = NTB_LTR_ACTIVE_REQMNT | NTB_LTR_ACTIVE_VAL | NTB_LTR_ACTIVE_LATSCALE;
0456
0457 ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
0458 iowrite32(ltr, ndev->self_mmio + GEN4_LTR_ACTIVE_OFFSET);
0459
0460
0461 ltr = NTB_LTR_IDLE_VAL | NTB_LTR_IDLE_LATSCALE | NTB_LTR_IDLE_REQMNT;
0462
0463 ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
0464 iowrite32(ltr, ndev->self_mmio + GEN4_LTR_IDLE_OFFSET);
0465
0466
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
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
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
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
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