Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ntb-4.10' of git://github.com/jonmason/ntb

Pull NTB update from Jon Mason:

- NTB bug fixes for removing an unnecessary call to ntb_peer_spad_read,
and correcting a free_irq inconsistency

- add Intel SKX support

- change the AMD NTB maintainer, and fix some bugs present there

* tag 'ntb-4.10' of git://github.com/jonmason/ntb:
ntb_transport: Remove unnecessary call to ntb_peer_spad_read
NTB: Fix 'request_irq()' and 'free_irq()' inconsistancy
ntb: fix SKX NTB config space size register offsets
NTB: correct ntb_peer_spad_read for case when callback is not supplied.
MAINTAINERS: Change in maintainer for AMD NTB
ntb_transport: Limit memory windows based on available, scratchpads
NTB: Register and offset values fix for memory window
NTB: add support for hotplug feature
ntb: Adding Skylake Xeon NTB support

+741 -33
+1 -1
MAINTAINERS
··· 8828 8828 F: drivers/ntb/hw/intel/ 8829 8829 8830 8830 NTB AMD DRIVER 8831 - M: Xiangliang Yu <Xiangliang.Yu@amd.com> 8831 + M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 8832 8832 L: linux-ntb@googlegroups.com 8833 8833 S: Supported 8834 8834 F: drivers/ntb/hw/amd/
+13 -12
drivers/ntb/hw/amd/ntb_hw_amd.c
··· 138 138 base_addr = pci_resource_start(ndev->ntb.pdev, bar); 139 139 140 140 if (bar != 1) { 141 - xlat_reg = AMD_BAR23XLAT_OFFSET + ((bar - 2) << 3); 142 - limit_reg = AMD_BAR23LMT_OFFSET + ((bar - 2) << 3); 141 + xlat_reg = AMD_BAR23XLAT_OFFSET + ((bar - 2) << 2); 142 + limit_reg = AMD_BAR23LMT_OFFSET + ((bar - 2) << 2); 143 143 144 144 /* Set the limit if supported */ 145 - limit = base_addr + size; 145 + limit = size; 146 146 147 147 /* set and verify setting the translation address */ 148 148 write64(addr, peer_mmio + xlat_reg); ··· 164 164 xlat_reg = AMD_BAR1XLAT_OFFSET; 165 165 limit_reg = AMD_BAR1LMT_OFFSET; 166 166 167 - /* split bar addr range must all be 32 bit */ 168 - if (addr & (~0ull << 32)) 169 - return -EINVAL; 170 - if ((addr + size) & (~0ull << 32)) 171 - return -EINVAL; 172 - 173 167 /* Set the limit if supported */ 174 - limit = base_addr + size; 168 + limit = size; 175 169 176 170 /* set and verify setting the translation address */ 177 171 write64(addr, peer_mmio + xlat_reg); ··· 193 199 if (!ndev->peer_sta) 194 200 return NTB_LNK_STA_ACTIVE(ndev->cntl_sta); 195 201 202 + if (ndev->peer_sta & AMD_LINK_UP_EVENT) { 203 + ndev->peer_sta = 0; 204 + return 1; 205 + } 206 + 196 207 /* If peer_sta is reset or D0 event, the ISR has 197 208 * started a timer to check link status of hardware. 198 209 * So here just clear status bit. And if peer_sta is ··· 206 207 */ 207 208 if (ndev->peer_sta & AMD_PEER_RESET_EVENT) 208 209 ndev->peer_sta &= ~AMD_PEER_RESET_EVENT; 209 - else if (ndev->peer_sta & AMD_PEER_D0_EVENT) 210 + else if (ndev->peer_sta & (AMD_PEER_D0_EVENT | AMD_LINK_DOWN_EVENT)) 210 211 ndev->peer_sta = 0; 211 212 212 213 return 0; ··· 490 491 break; 491 492 case AMD_PEER_D3_EVENT: 492 493 case AMD_PEER_PMETO_EVENT: 494 + case AMD_LINK_UP_EVENT: 495 + case AMD_LINK_DOWN_EVENT: 493 496 amd_ack_smu(ndev, status); 494 497 495 498 /* link down */ ··· 599 598 600 599 err_msix_request: 601 600 while (i-- > 0) 602 - free_irq(ndev->msix[i].vector, ndev); 601 + free_irq(ndev->msix[i].vector, &ndev->vec[i]); 603 602 pci_disable_msix(pdev); 604 603 err_msix_enable: 605 604 kfree(ndev->msix);
+4 -1
drivers/ntb/hw/amd/ntb_hw_amd.h
··· 148 148 AMD_PEER_D3_EVENT = BIT(2), 149 149 AMD_PEER_PMETO_EVENT = BIT(3), 150 150 AMD_PEER_D0_EVENT = BIT(4), 151 + AMD_LINK_UP_EVENT = BIT(5), 152 + AMD_LINK_DOWN_EVENT = BIT(6), 151 153 AMD_EVENT_INTMASK = (AMD_PEER_FLUSH_EVENT | 152 154 AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT | 153 - AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT), 155 + AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT | 156 + AMD_LINK_UP_EVENT | AMD_LINK_DOWN_EVENT), 154 157 155 158 AMD_PMESTAT_OFFSET = 0x480, 156 159 AMD_PMSGTRIG_OFFSET = 0x490,
+656 -6
drivers/ntb/hw/intel/ntb_hw_intel.c
··· 86 86 static const struct intel_ntb_xlat_reg xeon_sec_xlat; 87 87 static struct intel_b2b_addr xeon_b2b_usd_addr; 88 88 static struct intel_b2b_addr xeon_b2b_dsd_addr; 89 + static const struct intel_ntb_reg skx_reg; 90 + static const struct intel_ntb_alt_reg skx_pri_reg; 91 + static const struct intel_ntb_alt_reg skx_b2b_reg; 92 + static const struct intel_ntb_xlat_reg skx_sec_xlat; 89 93 static const struct ntb_dev_ops intel_ntb_ops; 94 + static const struct ntb_dev_ops intel_ntb3_ops; 90 95 91 96 static const struct file_operations intel_ntb_debugfs_info; 92 97 static struct dentry *debugfs_dir; ··· 149 144 xeon_b2b_dsd_addr.bar5_addr32, ullong, 0644); 150 145 MODULE_PARM_DESC(xeon_b2b_dsd_bar5_addr32, 151 146 "XEON B2B DSD split-BAR 5 32-bit address"); 147 + 148 + static inline enum ntb_topo xeon_ppd_topo(struct intel_ntb_dev *ndev, u8 ppd); 149 + static int xeon_init_isr(struct intel_ntb_dev *ndev); 152 150 153 151 #ifndef ioread64 154 152 #ifdef readq ··· 211 203 case PCI_DEVICE_ID_INTEL_NTB_B2B_BDX: 212 204 return 1; 213 205 } 206 + return 0; 207 + } 208 + 209 + static inline int pdev_is_skx_xeon(struct pci_dev *pdev) 210 + { 211 + if (pdev->device == PCI_DEVICE_ID_INTEL_NTB_B2B_SKX) 212 + return 1; 213 + 214 214 return 0; 215 215 } 216 216 ··· 406 390 407 391 vec_mask = ndev_vec_mask(ndev, vec); 408 392 393 + if ((ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) && (vec == 31)) 394 + vec_mask |= ndev->db_link_mask; 395 + 409 396 dev_dbg(ndev_dev(ndev), "vec %d vec_mask %llx\n", vec, vec_mask); 410 397 411 398 ndev->last_ts = jiffies; ··· 427 408 static irqreturn_t ndev_vec_isr(int irq, void *dev) 428 409 { 429 410 struct intel_ntb_vec *nvec = dev; 411 + 412 + dev_dbg(ndev_dev(nvec->ndev), "irq: %d nvec->num: %d\n", 413 + irq, nvec->num); 430 414 431 415 return ndev_interrupt(nvec->ndev, nvec->num); 432 416 } ··· 487 465 goto err_msix_request; 488 466 } 489 467 490 - dev_dbg(ndev_dev(ndev), "Using msix interrupts\n"); 468 + dev_dbg(ndev_dev(ndev), "Using %d msix interrupts\n", msix_count); 491 469 ndev->db_vec_count = msix_count; 492 470 ndev->db_vec_shift = msix_shift; 493 471 return 0; 494 472 495 473 err_msix_request: 496 474 while (i-- > 0) 497 - free_irq(ndev->msix[i].vector, ndev); 475 + free_irq(ndev->msix[i].vector, &ndev->vec[i]); 498 476 pci_disable_msix(pdev); 499 477 err_msix_enable: 500 478 kfree(ndev->msix); ··· 569 547 } 570 548 } 571 549 572 - static ssize_t ndev_debugfs_read(struct file *filp, char __user *ubuf, 573 - size_t count, loff_t *offp) 550 + static ssize_t ndev_ntb3_debugfs_read(struct file *filp, char __user *ubuf, 551 + size_t count, loff_t *offp) 552 + { 553 + struct intel_ntb_dev *ndev; 554 + void __iomem *mmio; 555 + char *buf; 556 + size_t buf_size; 557 + ssize_t ret, off; 558 + union { u64 v64; u32 v32; u16 v16; } u; 559 + 560 + ndev = filp->private_data; 561 + mmio = ndev->self_mmio; 562 + 563 + buf_size = min(count, 0x800ul); 564 + 565 + buf = kmalloc(buf_size, GFP_KERNEL); 566 + if (!buf) 567 + return -ENOMEM; 568 + 569 + off = 0; 570 + 571 + off += scnprintf(buf + off, buf_size - off, 572 + "NTB Device Information:\n"); 573 + 574 + off += scnprintf(buf + off, buf_size - off, 575 + "Connection Topology -\t%s\n", 576 + ntb_topo_string(ndev->ntb.topo)); 577 + 578 + off += scnprintf(buf + off, buf_size - off, 579 + "NTB CTL -\t\t%#06x\n", ndev->ntb_ctl); 580 + off += scnprintf(buf + off, buf_size - off, 581 + "LNK STA -\t\t%#06x\n", ndev->lnk_sta); 582 + 583 + if (!ndev->reg->link_is_up(ndev)) 584 + off += scnprintf(buf + off, buf_size - off, 585 + "Link Status -\t\tDown\n"); 586 + else { 587 + off += scnprintf(buf + off, buf_size - off, 588 + "Link Status -\t\tUp\n"); 589 + off += scnprintf(buf + off, buf_size - off, 590 + "Link Speed -\t\tPCI-E Gen %u\n", 591 + NTB_LNK_STA_SPEED(ndev->lnk_sta)); 592 + off += scnprintf(buf + off, buf_size - off, 593 + "Link Width -\t\tx%u\n", 594 + NTB_LNK_STA_WIDTH(ndev->lnk_sta)); 595 + } 596 + 597 + off += scnprintf(buf + off, buf_size - off, 598 + "Memory Window Count -\t%u\n", ndev->mw_count); 599 + off += scnprintf(buf + off, buf_size - off, 600 + "Scratchpad Count -\t%u\n", ndev->spad_count); 601 + off += scnprintf(buf + off, buf_size - off, 602 + "Doorbell Count -\t%u\n", ndev->db_count); 603 + off += scnprintf(buf + off, buf_size - off, 604 + "Doorbell Vector Count -\t%u\n", ndev->db_vec_count); 605 + off += scnprintf(buf + off, buf_size - off, 606 + "Doorbell Vector Shift -\t%u\n", ndev->db_vec_shift); 607 + 608 + off += scnprintf(buf + off, buf_size - off, 609 + "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask); 610 + off += scnprintf(buf + off, buf_size - off, 611 + "Doorbell Link Mask -\t%#llx\n", ndev->db_link_mask); 612 + off += scnprintf(buf + off, buf_size - off, 613 + "Doorbell Mask Cached -\t%#llx\n", ndev->db_mask); 614 + 615 + u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_mask); 616 + off += scnprintf(buf + off, buf_size - off, 617 + "Doorbell Mask -\t\t%#llx\n", u.v64); 618 + 619 + u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_bell); 620 + off += scnprintf(buf + off, buf_size - off, 621 + "Doorbell Bell -\t\t%#llx\n", u.v64); 622 + 623 + off += scnprintf(buf + off, buf_size - off, 624 + "\nNTB Incoming XLAT:\n"); 625 + 626 + u.v64 = ioread64(mmio + SKX_IMBAR1XBASE_OFFSET); 627 + off += scnprintf(buf + off, buf_size - off, 628 + "IMBAR1XBASE -\t\t%#018llx\n", u.v64); 629 + 630 + u.v64 = ioread64(mmio + SKX_IMBAR2XBASE_OFFSET); 631 + off += scnprintf(buf + off, buf_size - off, 632 + "IMBAR2XBASE -\t\t%#018llx\n", u.v64); 633 + 634 + u.v64 = ioread64(mmio + SKX_IMBAR1XLMT_OFFSET); 635 + off += scnprintf(buf + off, buf_size - off, 636 + "IMBAR1XLMT -\t\t\t%#018llx\n", u.v64); 637 + 638 + u.v64 = ioread64(mmio + SKX_IMBAR2XLMT_OFFSET); 639 + off += scnprintf(buf + off, buf_size - off, 640 + "IMBAR2XLMT -\t\t\t%#018llx\n", u.v64); 641 + 642 + if (ntb_topo_is_b2b(ndev->ntb.topo)) { 643 + off += scnprintf(buf + off, buf_size - off, 644 + "\nNTB Outgoing B2B XLAT:\n"); 645 + 646 + u.v64 = ioread64(mmio + SKX_EMBAR1XBASE_OFFSET); 647 + off += scnprintf(buf + off, buf_size - off, 648 + "EMBAR1XBASE -\t\t%#018llx\n", u.v64); 649 + 650 + u.v64 = ioread64(mmio + SKX_EMBAR2XBASE_OFFSET); 651 + off += scnprintf(buf + off, buf_size - off, 652 + "EMBAR2XBASE -\t\t%#018llx\n", u.v64); 653 + 654 + u.v64 = ioread64(mmio + SKX_EMBAR1XLMT_OFFSET); 655 + off += scnprintf(buf + off, buf_size - off, 656 + "EMBAR1XLMT -\t\t%#018llx\n", u.v64); 657 + 658 + u.v64 = ioread64(mmio + SKX_EMBAR2XLMT_OFFSET); 659 + off += scnprintf(buf + off, buf_size - off, 660 + "EMBAR2XLMT -\t\t%#018llx\n", u.v64); 661 + 662 + off += scnprintf(buf + off, buf_size - off, 663 + "\nNTB Secondary BAR:\n"); 664 + 665 + u.v64 = ioread64(mmio + SKX_EMBAR0_OFFSET); 666 + off += scnprintf(buf + off, buf_size - off, 667 + "EMBAR0 -\t\t%#018llx\n", u.v64); 668 + 669 + u.v64 = ioread64(mmio + SKX_EMBAR1_OFFSET); 670 + off += scnprintf(buf + off, buf_size - off, 671 + "EMBAR1 -\t\t%#018llx\n", u.v64); 672 + 673 + u.v64 = ioread64(mmio + SKX_EMBAR2_OFFSET); 674 + off += scnprintf(buf + off, buf_size - off, 675 + "EMBAR2 -\t\t%#018llx\n", u.v64); 676 + } 677 + 678 + off += scnprintf(buf + off, buf_size - off, 679 + "\nNTB Statistics:\n"); 680 + 681 + u.v16 = ioread16(mmio + SKX_USMEMMISS_OFFSET); 682 + off += scnprintf(buf + off, buf_size - off, 683 + "Upstream Memory Miss -\t%u\n", u.v16); 684 + 685 + off += scnprintf(buf + off, buf_size - off, 686 + "\nNTB Hardware Errors:\n"); 687 + 688 + if (!pci_read_config_word(ndev->ntb.pdev, 689 + SKX_DEVSTS_OFFSET, &u.v16)) 690 + off += scnprintf(buf + off, buf_size - off, 691 + "DEVSTS -\t\t%#06x\n", u.v16); 692 + 693 + if (!pci_read_config_word(ndev->ntb.pdev, 694 + SKX_LINK_STATUS_OFFSET, &u.v16)) 695 + off += scnprintf(buf + off, buf_size - off, 696 + "LNKSTS -\t\t%#06x\n", u.v16); 697 + 698 + if (!pci_read_config_dword(ndev->ntb.pdev, 699 + SKX_UNCERRSTS_OFFSET, &u.v32)) 700 + off += scnprintf(buf + off, buf_size - off, 701 + "UNCERRSTS -\t\t%#06x\n", u.v32); 702 + 703 + if (!pci_read_config_dword(ndev->ntb.pdev, 704 + SKX_CORERRSTS_OFFSET, &u.v32)) 705 + off += scnprintf(buf + off, buf_size - off, 706 + "CORERRSTS -\t\t%#06x\n", u.v32); 707 + 708 + ret = simple_read_from_buffer(ubuf, count, offp, buf, off); 709 + kfree(buf); 710 + return ret; 711 + } 712 + 713 + static ssize_t ndev_ntb_debugfs_read(struct file *filp, char __user *ubuf, 714 + size_t count, loff_t *offp) 574 715 { 575 716 struct intel_ntb_dev *ndev; 576 717 struct pci_dev *pdev; ··· 996 811 ret = simple_read_from_buffer(ubuf, count, offp, buf, off); 997 812 kfree(buf); 998 813 return ret; 814 + } 815 + 816 + static ssize_t ndev_debugfs_read(struct file *filp, char __user *ubuf, 817 + size_t count, loff_t *offp) 818 + { 819 + struct intel_ntb_dev *ndev = filp->private_data; 820 + 821 + if (pdev_is_xeon(ndev->ntb.pdev) || 822 + pdev_is_atom(ndev->ntb.pdev)) 823 + return ndev_ntb_debugfs_read(filp, ubuf, count, offp); 824 + else if (pdev_is_skx_xeon(ndev->ntb.pdev)) 825 + return ndev_ntb3_debugfs_read(filp, ubuf, count, offp); 826 + 827 + return -ENXIO; 999 828 } 1000 829 1001 830 static void ndev_init_debugfs(struct intel_ntb_dev *ndev) ··· 1625 1426 static void atom_deinit_dev(struct intel_ntb_dev *ndev) 1626 1427 { 1627 1428 atom_deinit_isr(ndev); 1429 + } 1430 + 1431 + /* Skylake Xeon NTB */ 1432 + 1433 + static u64 skx_db_ioread(void __iomem *mmio) 1434 + { 1435 + return ioread64(mmio); 1436 + } 1437 + 1438 + static void skx_db_iowrite(u64 bits, void __iomem *mmio) 1439 + { 1440 + iowrite64(bits, mmio); 1441 + } 1442 + 1443 + static int skx_init_isr(struct intel_ntb_dev *ndev) 1444 + { 1445 + int i; 1446 + 1447 + /* 1448 + * The MSIX vectors and the interrupt status bits are not lined up 1449 + * on Skylake. By default the link status bit is bit 32, however it 1450 + * is by default MSIX vector0. We need to fixup to line them up. 1451 + * The vectors at reset is 1-32,0. We need to reprogram to 0-32. 1452 + */ 1453 + 1454 + for (i = 0; i < SKX_DB_MSIX_VECTOR_COUNT; i++) 1455 + iowrite8(i, ndev->self_mmio + SKX_INTVEC_OFFSET + i); 1456 + 1457 + /* move link status down one as workaround */ 1458 + if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) { 1459 + iowrite8(SKX_DB_MSIX_VECTOR_COUNT - 2, 1460 + ndev->self_mmio + SKX_INTVEC_OFFSET + 1461 + (SKX_DB_MSIX_VECTOR_COUNT - 1)); 1462 + } 1463 + 1464 + return ndev_init_isr(ndev, SKX_DB_MSIX_VECTOR_COUNT, 1465 + SKX_DB_MSIX_VECTOR_COUNT, 1466 + SKX_DB_MSIX_VECTOR_SHIFT, 1467 + SKX_DB_TOTAL_SHIFT); 1468 + } 1469 + 1470 + static int skx_setup_b2b_mw(struct intel_ntb_dev *ndev, 1471 + const struct intel_b2b_addr *addr, 1472 + const struct intel_b2b_addr *peer_addr) 1473 + { 1474 + struct pci_dev *pdev; 1475 + void __iomem *mmio; 1476 + resource_size_t bar_size; 1477 + phys_addr_t bar_addr; 1478 + int b2b_bar; 1479 + u8 bar_sz; 1480 + 1481 + pdev = ndev_pdev(ndev); 1482 + mmio = ndev->self_mmio; 1483 + 1484 + if (ndev->b2b_idx == UINT_MAX) { 1485 + dev_dbg(ndev_dev(ndev), "not using b2b mw\n"); 1486 + b2b_bar = 0; 1487 + ndev->b2b_off = 0; 1488 + } else { 1489 + b2b_bar = ndev_mw_to_bar(ndev, ndev->b2b_idx); 1490 + if (b2b_bar < 0) 1491 + return -EIO; 1492 + 1493 + dev_dbg(ndev_dev(ndev), "using b2b mw bar %d\n", b2b_bar); 1494 + 1495 + bar_size = pci_resource_len(ndev->ntb.pdev, b2b_bar); 1496 + 1497 + dev_dbg(ndev_dev(ndev), "b2b bar size %#llx\n", bar_size); 1498 + 1499 + if (b2b_mw_share && ((bar_size >> 1) >= XEON_B2B_MIN_SIZE)) { 1500 + dev_dbg(ndev_dev(ndev), 1501 + "b2b using first half of bar\n"); 1502 + ndev->b2b_off = bar_size >> 1; 1503 + } else if (bar_size >= XEON_B2B_MIN_SIZE) { 1504 + dev_dbg(ndev_dev(ndev), 1505 + "b2b using whole bar\n"); 1506 + ndev->b2b_off = 0; 1507 + --ndev->mw_count; 1508 + } else { 1509 + dev_dbg(ndev_dev(ndev), 1510 + "b2b bar size is too small\n"); 1511 + return -EIO; 1512 + } 1513 + } 1514 + 1515 + /* 1516 + * Reset the secondary bar sizes to match the primary bar sizes, 1517 + * except disable or halve the size of the b2b secondary bar. 1518 + */ 1519 + pci_read_config_byte(pdev, SKX_IMBAR1SZ_OFFSET, &bar_sz); 1520 + dev_dbg(ndev_dev(ndev), "IMBAR1SZ %#x\n", bar_sz); 1521 + if (b2b_bar == 1) { 1522 + if (ndev->b2b_off) 1523 + bar_sz -= 1; 1524 + else 1525 + bar_sz = 0; 1526 + } 1527 + 1528 + pci_write_config_byte(pdev, SKX_EMBAR1SZ_OFFSET, bar_sz); 1529 + pci_read_config_byte(pdev, SKX_EMBAR1SZ_OFFSET, &bar_sz); 1530 + dev_dbg(ndev_dev(ndev), "EMBAR1SZ %#x\n", bar_sz); 1531 + 1532 + pci_read_config_byte(pdev, SKX_IMBAR2SZ_OFFSET, &bar_sz); 1533 + dev_dbg(ndev_dev(ndev), "IMBAR2SZ %#x\n", bar_sz); 1534 + if (b2b_bar == 2) { 1535 + if (ndev->b2b_off) 1536 + bar_sz -= 1; 1537 + else 1538 + bar_sz = 0; 1539 + } 1540 + 1541 + pci_write_config_byte(pdev, SKX_EMBAR2SZ_OFFSET, bar_sz); 1542 + pci_read_config_byte(pdev, SKX_EMBAR2SZ_OFFSET, &bar_sz); 1543 + dev_dbg(ndev_dev(ndev), "EMBAR2SZ %#x\n", bar_sz); 1544 + 1545 + /* SBAR01 hit by first part of the b2b bar */ 1546 + if (b2b_bar == 0) 1547 + bar_addr = addr->bar0_addr; 1548 + else if (b2b_bar == 1) 1549 + bar_addr = addr->bar2_addr64; 1550 + else if (b2b_bar == 2) 1551 + bar_addr = addr->bar4_addr64; 1552 + else 1553 + return -EIO; 1554 + 1555 + /* setup incoming bar limits == base addrs (zero length windows) */ 1556 + bar_addr = addr->bar2_addr64 + (b2b_bar == 1 ? ndev->b2b_off : 0); 1557 + iowrite64(bar_addr, mmio + SKX_IMBAR1XLMT_OFFSET); 1558 + bar_addr = ioread64(mmio + SKX_IMBAR1XLMT_OFFSET); 1559 + dev_dbg(ndev_dev(ndev), "IMBAR1XLMT %#018llx\n", bar_addr); 1560 + 1561 + bar_addr = addr->bar4_addr64 + (b2b_bar == 2 ? ndev->b2b_off : 0); 1562 + iowrite64(bar_addr, mmio + SKX_IMBAR2XLMT_OFFSET); 1563 + bar_addr = ioread64(mmio + SKX_IMBAR2XLMT_OFFSET); 1564 + dev_dbg(ndev_dev(ndev), "IMBAR2XLMT %#018llx\n", bar_addr); 1565 + 1566 + /* zero incoming translation addrs */ 1567 + iowrite64(0, mmio + SKX_IMBAR1XBASE_OFFSET); 1568 + iowrite64(0, mmio + SKX_IMBAR2XBASE_OFFSET); 1569 + 1570 + ndev->peer_mmio = ndev->self_mmio; 1571 + 1572 + return 0; 1573 + } 1574 + 1575 + static int skx_init_ntb(struct intel_ntb_dev *ndev) 1576 + { 1577 + int rc; 1578 + 1579 + 1580 + ndev->mw_count = XEON_MW_COUNT; 1581 + ndev->spad_count = SKX_SPAD_COUNT; 1582 + ndev->db_count = SKX_DB_COUNT; 1583 + ndev->db_link_mask = SKX_DB_LINK_BIT; 1584 + 1585 + /* DB fixup for using 31 right now */ 1586 + if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) 1587 + ndev->db_link_mask |= BIT_ULL(31); 1588 + 1589 + switch (ndev->ntb.topo) { 1590 + case NTB_TOPO_B2B_USD: 1591 + case NTB_TOPO_B2B_DSD: 1592 + ndev->self_reg = &skx_pri_reg; 1593 + ndev->peer_reg = &skx_b2b_reg; 1594 + ndev->xlat_reg = &skx_sec_xlat; 1595 + 1596 + if (ndev->ntb.topo == NTB_TOPO_B2B_USD) { 1597 + rc = skx_setup_b2b_mw(ndev, 1598 + &xeon_b2b_dsd_addr, 1599 + &xeon_b2b_usd_addr); 1600 + } else { 1601 + rc = skx_setup_b2b_mw(ndev, 1602 + &xeon_b2b_usd_addr, 1603 + &xeon_b2b_dsd_addr); 1604 + } 1605 + 1606 + if (rc) 1607 + return rc; 1608 + 1609 + /* Enable Bus Master and Memory Space on the secondary side */ 1610 + iowrite16(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, 1611 + ndev->self_mmio + SKX_SPCICMD_OFFSET); 1612 + 1613 + break; 1614 + 1615 + default: 1616 + return -EINVAL; 1617 + } 1618 + 1619 + ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1; 1620 + 1621 + ndev->reg->db_iowrite(ndev->db_valid_mask, 1622 + ndev->self_mmio + 1623 + ndev->self_reg->db_mask); 1624 + 1625 + return 0; 1626 + } 1627 + 1628 + static int skx_init_dev(struct intel_ntb_dev *ndev) 1629 + { 1630 + struct pci_dev *pdev; 1631 + u8 ppd; 1632 + int rc; 1633 + 1634 + pdev = ndev_pdev(ndev); 1635 + 1636 + ndev->reg = &skx_reg; 1637 + 1638 + rc = pci_read_config_byte(pdev, XEON_PPD_OFFSET, &ppd); 1639 + if (rc) 1640 + return -EIO; 1641 + 1642 + ndev->ntb.topo = xeon_ppd_topo(ndev, ppd); 1643 + dev_dbg(ndev_dev(ndev), "ppd %#x topo %s\n", ppd, 1644 + ntb_topo_string(ndev->ntb.topo)); 1645 + if (ndev->ntb.topo == NTB_TOPO_NONE) 1646 + return -EINVAL; 1647 + 1648 + if (pdev_is_skx_xeon(pdev)) 1649 + ndev->hwerr_flags |= NTB_HWERR_MSIX_VECTOR32_BAD; 1650 + 1651 + rc = skx_init_ntb(ndev); 1652 + if (rc) 1653 + return rc; 1654 + 1655 + return skx_init_isr(ndev); 1656 + } 1657 + 1658 + static int intel_ntb3_link_enable(struct ntb_dev *ntb, 1659 + enum ntb_speed max_speed, 1660 + enum ntb_width max_width) 1661 + { 1662 + struct intel_ntb_dev *ndev; 1663 + u32 ntb_ctl; 1664 + 1665 + ndev = container_of(ntb, struct intel_ntb_dev, ntb); 1666 + 1667 + dev_dbg(ndev_dev(ndev), 1668 + "Enabling link with max_speed %d max_width %d\n", 1669 + max_speed, max_width); 1670 + 1671 + if (max_speed != NTB_SPEED_AUTO) 1672 + dev_dbg(ndev_dev(ndev), "ignoring max_speed %d\n", max_speed); 1673 + if (max_width != NTB_WIDTH_AUTO) 1674 + dev_dbg(ndev_dev(ndev), "ignoring max_width %d\n", max_width); 1675 + 1676 + ntb_ctl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl); 1677 + ntb_ctl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK); 1678 + ntb_ctl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP; 1679 + ntb_ctl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP; 1680 + iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl); 1681 + 1682 + return 0; 1683 + } 1684 + static int intel_ntb3_mw_set_trans(struct ntb_dev *ntb, int idx, 1685 + dma_addr_t addr, resource_size_t size) 1686 + { 1687 + struct intel_ntb_dev *ndev = ntb_ndev(ntb); 1688 + unsigned long xlat_reg, limit_reg; 1689 + resource_size_t bar_size, mw_size; 1690 + void __iomem *mmio; 1691 + u64 base, limit, reg_val; 1692 + int bar; 1693 + 1694 + if (idx >= ndev->b2b_idx && !ndev->b2b_off) 1695 + idx += 1; 1696 + 1697 + bar = ndev_mw_to_bar(ndev, idx); 1698 + if (bar < 0) 1699 + return bar; 1700 + 1701 + bar_size = pci_resource_len(ndev->ntb.pdev, bar); 1702 + 1703 + if (idx == ndev->b2b_idx) 1704 + mw_size = bar_size - ndev->b2b_off; 1705 + else 1706 + mw_size = bar_size; 1707 + 1708 + /* hardware requires that addr is aligned to bar size */ 1709 + if (addr & (bar_size - 1)) 1710 + return -EINVAL; 1711 + 1712 + /* make sure the range fits in the usable mw size */ 1713 + if (size > mw_size) 1714 + return -EINVAL; 1715 + 1716 + mmio = ndev->self_mmio; 1717 + xlat_reg = ndev->xlat_reg->bar2_xlat + (idx * 0x10); 1718 + limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10); 1719 + base = pci_resource_start(ndev->ntb.pdev, bar); 1720 + 1721 + /* Set the limit if supported, if size is not mw_size */ 1722 + if (limit_reg && size != mw_size) 1723 + limit = base + size; 1724 + else 1725 + limit = base + mw_size; 1726 + 1727 + /* set and verify setting the translation address */ 1728 + iowrite64(addr, mmio + xlat_reg); 1729 + reg_val = ioread64(mmio + xlat_reg); 1730 + if (reg_val != addr) { 1731 + iowrite64(0, mmio + xlat_reg); 1732 + return -EIO; 1733 + } 1734 + 1735 + dev_dbg(ndev_dev(ndev), "BAR %d IMBARXBASE: %#Lx\n", bar, reg_val); 1736 + 1737 + /* set and verify setting the limit */ 1738 + iowrite64(limit, mmio + limit_reg); 1739 + reg_val = ioread64(mmio + limit_reg); 1740 + if (reg_val != limit) { 1741 + iowrite64(base, mmio + limit_reg); 1742 + iowrite64(0, mmio + xlat_reg); 1743 + return -EIO; 1744 + } 1745 + 1746 + dev_dbg(ndev_dev(ndev), "BAR %d IMBARXLMT: %#Lx\n", bar, reg_val); 1747 + 1748 + /* setup the EP */ 1749 + limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10) + 0x4000; 1750 + base = ioread64(mmio + SKX_EMBAR1_OFFSET + (8 * idx)); 1751 + base &= ~0xf; 1752 + 1753 + if (limit_reg && size != mw_size) 1754 + limit = base + size; 1755 + else 1756 + limit = base + mw_size; 1757 + 1758 + /* set and verify setting the limit */ 1759 + iowrite64(limit, mmio + limit_reg); 1760 + reg_val = ioread64(mmio + limit_reg); 1761 + if (reg_val != limit) { 1762 + iowrite64(base, mmio + limit_reg); 1763 + iowrite64(0, mmio + xlat_reg); 1764 + return -EIO; 1765 + } 1766 + 1767 + dev_dbg(ndev_dev(ndev), "BAR %d EMBARXLMT: %#Lx\n", bar, reg_val); 1768 + 1769 + return 0; 1770 + } 1771 + 1772 + static int intel_ntb3_peer_db_set(struct ntb_dev *ntb, u64 db_bits) 1773 + { 1774 + struct intel_ntb_dev *ndev = ntb_ndev(ntb); 1775 + int bit; 1776 + 1777 + if (db_bits & ~ndev->db_valid_mask) 1778 + return -EINVAL; 1779 + 1780 + while (db_bits) { 1781 + bit = __ffs(db_bits); 1782 + iowrite32(1, ndev->peer_mmio + 1783 + ndev->peer_reg->db_bell + (bit * 4)); 1784 + db_bits &= db_bits - 1; 1785 + } 1786 + 1787 + return 0; 1788 + } 1789 + 1790 + static u64 intel_ntb3_db_read(struct ntb_dev *ntb) 1791 + { 1792 + struct intel_ntb_dev *ndev = ntb_ndev(ntb); 1793 + 1794 + return ndev_db_read(ndev, 1795 + ndev->self_mmio + 1796 + ndev->self_reg->db_clear); 1797 + } 1798 + 1799 + static int intel_ntb3_db_clear(struct ntb_dev *ntb, u64 db_bits) 1800 + { 1801 + struct intel_ntb_dev *ndev = ntb_ndev(ntb); 1802 + 1803 + return ndev_db_write(ndev, db_bits, 1804 + ndev->self_mmio + 1805 + ndev->self_reg->db_clear); 1628 1806 } 1629 1807 1630 1808 /* XEON */ ··· 2696 2120 if (rc) 2697 2121 goto err_init_dev; 2698 2122 2123 + } else if (pdev_is_skx_xeon(pdev)) { 2124 + ndev = kzalloc_node(sizeof(*ndev), GFP_KERNEL, node); 2125 + if (!ndev) { 2126 + rc = -ENOMEM; 2127 + goto err_ndev; 2128 + } 2129 + 2130 + ndev_init_struct(ndev, pdev); 2131 + ndev->ntb.ops = &intel_ntb3_ops; 2132 + 2133 + rc = intel_ntb_init_pci(ndev, pdev); 2134 + if (rc) 2135 + goto err_init_pci; 2136 + 2137 + rc = skx_init_dev(ndev); 2138 + if (rc) 2139 + goto err_init_dev; 2140 + 2699 2141 } else { 2700 2142 rc = -EINVAL; 2701 2143 goto err_ndev; ··· 2737 2143 ndev_deinit_debugfs(ndev); 2738 2144 if (pdev_is_atom(pdev)) 2739 2145 atom_deinit_dev(ndev); 2740 - else if (pdev_is_xeon(pdev)) 2146 + else if (pdev_is_xeon(pdev) || pdev_is_skx_xeon(pdev)) 2741 2147 xeon_deinit_dev(ndev); 2742 2148 err_init_dev: 2743 2149 intel_ntb_deinit_pci(ndev); ··· 2755 2161 ndev_deinit_debugfs(ndev); 2756 2162 if (pdev_is_atom(pdev)) 2757 2163 atom_deinit_dev(ndev); 2758 - else if (pdev_is_xeon(pdev)) 2164 + else if (pdev_is_xeon(pdev) || pdev_is_skx_xeon(pdev)) 2759 2165 xeon_deinit_dev(ndev); 2760 2166 intel_ntb_deinit_pci(ndev); 2761 2167 kfree(ndev); ··· 2851 2257 .bar5_addr32 = XEON_B2B_BAR5_ADDR32, 2852 2258 }; 2853 2259 2260 + static const struct intel_ntb_reg skx_reg = { 2261 + .poll_link = xeon_poll_link, 2262 + .link_is_up = xeon_link_is_up, 2263 + .db_ioread = skx_db_ioread, 2264 + .db_iowrite = skx_db_iowrite, 2265 + .db_size = sizeof(u64), 2266 + .ntb_ctl = SKX_NTBCNTL_OFFSET, 2267 + .mw_bar = {2, 4}, 2268 + }; 2269 + 2270 + static const struct intel_ntb_alt_reg skx_pri_reg = { 2271 + .db_bell = SKX_EM_DOORBELL_OFFSET, 2272 + .db_clear = SKX_IM_INT_STATUS_OFFSET, 2273 + .db_mask = SKX_IM_INT_DISABLE_OFFSET, 2274 + .spad = SKX_IM_SPAD_OFFSET, 2275 + }; 2276 + 2277 + static const struct intel_ntb_alt_reg skx_b2b_reg = { 2278 + .db_bell = SKX_IM_DOORBELL_OFFSET, 2279 + .db_clear = SKX_EM_INT_STATUS_OFFSET, 2280 + .db_mask = SKX_EM_INT_DISABLE_OFFSET, 2281 + .spad = SKX_B2B_SPAD_OFFSET, 2282 + }; 2283 + 2284 + static const struct intel_ntb_xlat_reg skx_sec_xlat = { 2285 + /* .bar0_base = SKX_EMBAR0_OFFSET, */ 2286 + .bar2_limit = SKX_IMBAR1XLMT_OFFSET, 2287 + .bar2_xlat = SKX_IMBAR1XBASE_OFFSET, 2288 + }; 2289 + 2854 2290 /* operations for primary side of local ntb */ 2855 2291 static const struct ntb_dev_ops intel_ntb_ops = { 2856 2292 .mw_count = intel_ntb_mw_count, ··· 2899 2275 .db_clear_mask = intel_ntb_db_clear_mask, 2900 2276 .peer_db_addr = intel_ntb_peer_db_addr, 2901 2277 .peer_db_set = intel_ntb_peer_db_set, 2278 + .spad_is_unsafe = intel_ntb_spad_is_unsafe, 2279 + .spad_count = intel_ntb_spad_count, 2280 + .spad_read = intel_ntb_spad_read, 2281 + .spad_write = intel_ntb_spad_write, 2282 + .peer_spad_addr = intel_ntb_peer_spad_addr, 2283 + .peer_spad_read = intel_ntb_peer_spad_read, 2284 + .peer_spad_write = intel_ntb_peer_spad_write, 2285 + }; 2286 + 2287 + static const struct ntb_dev_ops intel_ntb3_ops = { 2288 + .mw_count = intel_ntb_mw_count, 2289 + .mw_get_range = intel_ntb_mw_get_range, 2290 + .mw_set_trans = intel_ntb3_mw_set_trans, 2291 + .link_is_up = intel_ntb_link_is_up, 2292 + .link_enable = intel_ntb3_link_enable, 2293 + .link_disable = intel_ntb_link_disable, 2294 + .db_valid_mask = intel_ntb_db_valid_mask, 2295 + .db_vector_count = intel_ntb_db_vector_count, 2296 + .db_vector_mask = intel_ntb_db_vector_mask, 2297 + .db_read = intel_ntb3_db_read, 2298 + .db_clear = intel_ntb3_db_clear, 2299 + .db_set_mask = intel_ntb_db_set_mask, 2300 + .db_clear_mask = intel_ntb_db_clear_mask, 2301 + .peer_db_addr = intel_ntb_peer_db_addr, 2302 + .peer_db_set = intel_ntb3_peer_db_set, 2902 2303 .spad_is_unsafe = intel_ntb_spad_is_unsafe, 2903 2304 .spad_count = intel_ntb_spad_count, 2904 2305 .spad_read = intel_ntb_spad_read, ··· 2956 2307 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_IVT)}, 2957 2308 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_HSX)}, 2958 2309 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_BDX)}, 2310 + {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SKX)}, 2959 2311 {0} 2960 2312 }; 2961 2313 MODULE_DEVICE_TABLE(pci, intel_ntb_pci_tbl);
+48
drivers/ntb/hw/intel/ntb_hw_intel.h
··· 70 70 #define PCI_DEVICE_ID_INTEL_NTB_B2B_BDX 0x6F0D 71 71 #define PCI_DEVICE_ID_INTEL_NTB_PS_BDX 0x6F0E 72 72 #define PCI_DEVICE_ID_INTEL_NTB_SS_BDX 0x6F0F 73 + #define PCI_DEVICE_ID_INTEL_NTB_B2B_SKX 0x201C 73 74 74 75 /* Intel Xeon hardware */ 75 76 ··· 150 149 #define XEON_DB_MSIX_VECTOR_SHIFT 5 151 150 #define XEON_DB_TOTAL_SHIFT 16 152 151 #define XEON_SPAD_COUNT 16 152 + 153 + /* Intel Skylake Xeon hardware */ 154 + #define SKX_IMBAR1SZ_OFFSET 0x00d0 155 + #define SKX_IMBAR2SZ_OFFSET 0x00d1 156 + #define SKX_EMBAR1SZ_OFFSET 0x00d2 157 + #define SKX_EMBAR2SZ_OFFSET 0x00d3 158 + #define SKX_DEVCTRL_OFFSET 0x0098 159 + #define SKX_DEVSTS_OFFSET 0x009a 160 + #define SKX_UNCERRSTS_OFFSET 0x014c 161 + #define SKX_CORERRSTS_OFFSET 0x0158 162 + #define SKX_LINK_STATUS_OFFSET 0x01a2 163 + 164 + #define SKX_NTBCNTL_OFFSET 0x0000 165 + #define SKX_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */ 166 + #define SKX_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */ 167 + #define SKX_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */ 168 + #define SKX_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */ 169 + #define SKX_IM_INT_STATUS_OFFSET 0x0040 170 + #define SKX_IM_INT_DISABLE_OFFSET 0x0048 171 + #define SKX_IM_SPAD_OFFSET 0x0080 /* SPAD */ 172 + #define SKX_USMEMMISS_OFFSET 0x0070 173 + #define SKX_INTVEC_OFFSET 0x00d0 174 + #define SKX_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */ 175 + #define SKX_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */ 176 + #define SKX_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */ 177 + #define SKX_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */ 178 + #define SKX_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */ 179 + #define SKX_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */ 180 + #define SKX_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */ 181 + #define SKX_EM_INT_STATUS_OFFSET 0x4040 182 + #define SKX_EM_INT_DISABLE_OFFSET 0x4048 183 + #define SKX_EM_SPAD_OFFSET 0x4080 /* remote SPAD */ 184 + #define SKX_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */ 185 + #define SKX_SPCICMD_OFFSET 0x4504 /* SPCICMD */ 186 + #define SKX_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */ 187 + #define SKX_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */ 188 + #define SKX_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */ 189 + 190 + #define SKX_DB_COUNT 32 191 + #define SKX_DB_LINK 32 192 + #define SKX_DB_LINK_BIT BIT_ULL(SKX_DB_LINK) 193 + #define SKX_DB_MSIX_VECTOR_COUNT 33 194 + #define SKX_DB_MSIX_VECTOR_SHIFT 1 195 + #define SKX_DB_TOTAL_SHIFT 33 196 + #define SKX_SPAD_COUNT 16 153 197 154 198 /* Intel Atom hardware */ 155 199 ··· 286 240 #define NTB_HWERR_SDOORBELL_LOCKUP BIT_ULL(0) 287 241 #define NTB_HWERR_SB01BASE_LOCKUP BIT_ULL(1) 288 242 #define NTB_HWERR_B2BDOORBELL_BIT14 BIT_ULL(2) 243 + #define NTB_HWERR_MSIX_VECTOR32_BAD BIT_ULL(3) 289 244 290 245 /* flags to indicate unsafe api */ 291 246 #define NTB_UNSAFE_DB BIT_ULL(0) ··· 310 263 struct intel_ntb_alt_reg { 311 264 unsigned long db_bell; 312 265 unsigned long db_mask; 266 + unsigned long db_clear; 313 267 unsigned long spad; 314 268 }; 315 269
+16 -13
drivers/ntb/ntb_transport.c
··· 66 66 #define NTB_TRANSPORT_VER "4" 67 67 #define NTB_TRANSPORT_NAME "ntb_transport" 68 68 #define NTB_TRANSPORT_DESC "Software Queue-Pair Transport over NTB" 69 + #define NTB_TRANSPORT_MIN_SPADS (MW0_SZ_HIGH + 2) 69 70 70 71 MODULE_DESCRIPTION(NTB_TRANSPORT_DESC); 71 72 MODULE_VERSION(NTB_TRANSPORT_VER); ··· 243 242 NUM_MWS, 244 243 MW0_SZ_HIGH, 245 244 MW0_SZ_LOW, 246 - MW1_SZ_HIGH, 247 - MW1_SZ_LOW, 248 - MAX_SPAD, 249 245 }; 250 246 251 247 #define dev_client_dev(__dev) \ ··· 809 811 { 810 812 struct ntb_transport_qp *qp; 811 813 u64 qp_bitmap_alloc; 812 - int i; 814 + unsigned int i, count; 813 815 814 816 qp_bitmap_alloc = nt->qp_bitmap & ~nt->qp_bitmap_free; 815 817 ··· 829 831 * goes down, blast them now to give them a sane value the next 830 832 * time they are accessed 831 833 */ 832 - for (i = 0; i < MAX_SPAD; i++) 834 + count = ntb_spad_count(nt->ndev); 835 + for (i = 0; i < count; i++) 833 836 ntb_spad_write(nt->ndev, i, 0); 834 837 } 835 838 ··· 959 960 ntb_peer_spad_write(nt->ndev, QP_LINKS, val | BIT(qp->qp_num)); 960 961 961 962 /* query remote spad for qp ready bits */ 962 - ntb_peer_spad_read(nt->ndev, QP_LINKS); 963 963 dev_dbg_ratelimited(&pdev->dev, "Remote QP link status = %x\n", val); 964 964 965 965 /* See if the remote side is up */ ··· 1062 1064 { 1063 1065 struct ntb_transport_ctx *nt; 1064 1066 struct ntb_transport_mw *mw; 1065 - unsigned int mw_count, qp_count; 1067 + unsigned int mw_count, qp_count, spad_count, max_mw_count_for_spads; 1066 1068 u64 qp_bitmap; 1067 1069 int node; 1068 1070 int rc, i; 1069 1071 1070 1072 mw_count = ntb_mw_count(ndev); 1071 - if (ntb_spad_count(ndev) < (NUM_MWS + 1 + mw_count * 2)) { 1072 - dev_err(&ndev->dev, "Not enough scratch pad registers for %s", 1073 - NTB_TRANSPORT_NAME); 1074 - return -EIO; 1075 - } 1076 1073 1077 1074 if (ntb_db_is_unsafe(ndev)) 1078 1075 dev_dbg(&ndev->dev, ··· 1083 1090 return -ENOMEM; 1084 1091 1085 1092 nt->ndev = ndev; 1093 + spad_count = ntb_spad_count(ndev); 1086 1094 1087 - nt->mw_count = mw_count; 1095 + /* Limit the MW's based on the availability of scratchpads */ 1096 + 1097 + if (spad_count < NTB_TRANSPORT_MIN_SPADS) { 1098 + nt->mw_count = 0; 1099 + rc = -EINVAL; 1100 + goto err; 1101 + } 1102 + 1103 + max_mw_count_for_spads = (spad_count - MW0_SZ_HIGH) / 2; 1104 + nt->mw_count = min(mw_count, max_mw_count_for_spads); 1088 1105 1089 1106 nt->mw_vec = kzalloc_node(mw_count * sizeof(*nt->mw_vec), 1090 1107 GFP_KERNEL, node);
+3
include/linux/ntb.h
··· 968 968 */ 969 969 static inline u32 ntb_peer_spad_read(struct ntb_dev *ntb, int idx) 970 970 { 971 + if (!ntb->ops->peer_spad_read) 972 + return 0; 973 + 971 974 return ntb->ops->peer_spad_read(ntb, idx); 972 975 } 973 976