diff options
author | Dave Jiang <dave.jiang@intel.com> | 2014-08-28 16:53:23 -0400 |
---|---|---|
committer | Jon Mason <jdmason@kudzu.us> | 2014-10-17 07:08:51 -0400 |
commit | ab760a0c5667519b375ea9c5ab3a23501c4817ef (patch) | |
tree | 29d2b7dd165287dd635ff4b320fcb6a9dc5a7eae | |
parent | 069684e888da73f175da0f10fe26da4f450d8c18 (diff) |
ntb: Adding split BAR support for Haswell platforms
On the Haswell platform, a split BAR option to allow creation of 2
32bit BARs (4 and 5) from the 64bit BAR 4. Adding support for this
new option.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>
-rw-r--r-- | drivers/ntb/ntb_hw.c | 225 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.h | 14 | ||||
-rw-r--r-- | drivers/ntb/ntb_regs.h | 31 |
3 files changed, 210 insertions, 60 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 53b739df8cd5..cd29b1038c5e 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -84,8 +84,8 @@ static struct dentry *debugfs_dir; | |||
84 | 84 | ||
85 | #define BWD_LINK_RECOVERY_TIME 500 | 85 | #define BWD_LINK_RECOVERY_TIME 500 |
86 | 86 | ||
87 | /* Translate memory window 0,1 to BAR 2,4 */ | 87 | /* Translate memory window 0,1,2 to BAR 2,4,5 */ |
88 | #define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2) | 88 | #define MW_TO_BAR(mw) (mw == 0 ? 2 : (mw == 1 ? 4 : 5)) |
89 | 89 | ||
90 | static const struct pci_device_id ntb_pci_tbl[] = { | 90 | static const struct pci_device_id ntb_pci_tbl[] = { |
91 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, | 91 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, |
@@ -506,8 +506,14 @@ void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) | |||
506 | case NTB_BAR_23: | 506 | case NTB_BAR_23: |
507 | writeq(addr, ndev->reg_ofs.bar2_xlat); | 507 | writeq(addr, ndev->reg_ofs.bar2_xlat); |
508 | break; | 508 | break; |
509 | case NTB_BAR_45: | 509 | case NTB_BAR_4: |
510 | writeq(addr, ndev->reg_ofs.bar4_xlat); | 510 | if (ndev->split_bar) |
511 | writel(addr, ndev->reg_ofs.bar4_xlat); | ||
512 | else | ||
513 | writeq(addr, ndev->reg_ofs.bar4_xlat); | ||
514 | break; | ||
515 | case NTB_BAR_5: | ||
516 | writel(addr, ndev->reg_ofs.bar5_xlat); | ||
511 | break; | 517 | break; |
512 | } | 518 | } |
513 | } | 519 | } |
@@ -729,6 +735,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
729 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; | 735 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; |
730 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; | 736 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; |
731 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; | 737 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; |
738 | if (ndev->split_bar) | ||
739 | ndev->reg_ofs.bar5_xlat = | ||
740 | ndev->reg_base + SNB_SBAR5XLAT_OFFSET; | ||
732 | ndev->limits.max_spads = SNB_MAX_B2B_SPADS; | 741 | ndev->limits.max_spads = SNB_MAX_B2B_SPADS; |
733 | 742 | ||
734 | /* There is a Xeon hardware errata related to writes to | 743 | /* There is a Xeon hardware errata related to writes to |
@@ -738,15 +747,16 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
738 | * scratch pad registers on the remote system. | 747 | * scratch pad registers on the remote system. |
739 | */ | 748 | */ |
740 | if (ndev->wa_flags & WA_SNB_ERR) { | 749 | if (ndev->wa_flags & WA_SNB_ERR) { |
741 | if (!ndev->mw[1].bar_sz) | 750 | if (!ndev->mw[ndev->limits.max_mw - 1].bar_sz) |
742 | return -EINVAL; | 751 | return -EINVAL; |
743 | 752 | ||
744 | ndev->limits.max_mw = SNB_ERRATA_MAX_MW; | ||
745 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | 753 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; |
746 | ndev->reg_ofs.spad_write = ndev->mw[1].vbase + | 754 | ndev->reg_ofs.spad_write = |
747 | SNB_SPAD_OFFSET; | 755 | ndev->mw[ndev->limits.max_mw - 1].vbase + |
748 | ndev->reg_ofs.rdb = ndev->mw[1].vbase + | 756 | SNB_SPAD_OFFSET; |
749 | SNB_PDOORBELL_OFFSET; | 757 | ndev->reg_ofs.rdb = |
758 | ndev->mw[ndev->limits.max_mw - 1].vbase + | ||
759 | SNB_PDOORBELL_OFFSET; | ||
750 | 760 | ||
751 | /* Set the Limit register to 4k, the minimum size, to | 761 | /* Set the Limit register to 4k, the minimum size, to |
752 | * prevent an illegal access | 762 | * prevent an illegal access |
@@ -759,9 +769,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
759 | * the driver defaults, but write the Limit registers | 769 | * the driver defaults, but write the Limit registers |
760 | * first just in case. | 770 | * first just in case. |
761 | */ | 771 | */ |
762 | } else { | ||
763 | ndev->limits.max_mw = SNB_MAX_MW; | ||
764 | 772 | ||
773 | ndev->limits.max_mw = SNB_ERRATA_MAX_MW; | ||
774 | } else { | ||
765 | /* HW Errata on bit 14 of b2bdoorbell register. Writes | 775 | /* HW Errata on bit 14 of b2bdoorbell register. Writes |
766 | * will not be mirrored to the remote system. Shrink | 776 | * will not be mirrored to the remote system. Shrink |
767 | * the number of bits by one, since bit 14 is the last | 777 | * the number of bits by one, since bit 14 is the last |
@@ -774,7 +784,8 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
774 | SNB_B2B_DOORBELL_OFFSET; | 784 | SNB_B2B_DOORBELL_OFFSET; |
775 | 785 | ||
776 | /* Disable the Limit register, just incase it is set to | 786 | /* Disable the Limit register, just incase it is set to |
777 | * something silly | 787 | * something silly. A 64bit write should handle it |
788 | * regardless of whether it has a split BAR or not. | ||
778 | */ | 789 | */ |
779 | writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET); | 790 | writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET); |
780 | /* HW errata on the Limit registers. They can only be | 791 | /* HW errata on the Limit registers. They can only be |
@@ -783,6 +794,10 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
783 | * the driver defaults, but write the Limit registers | 794 | * the driver defaults, but write the Limit registers |
784 | * first just in case. | 795 | * first just in case. |
785 | */ | 796 | */ |
797 | if (ndev->split_bar) | ||
798 | ndev->limits.max_mw = HSX_SPLITBAR_MAX_MW; | ||
799 | else | ||
800 | ndev->limits.max_mw = SNB_MAX_MW; | ||
786 | } | 801 | } |
787 | 802 | ||
788 | /* The Xeon errata workaround requires setting SBAR Base | 803 | /* The Xeon errata workaround requires setting SBAR Base |
@@ -796,8 +811,18 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
796 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + | 811 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + |
797 | SNB_PBAR4XLAT_OFFSET); | 812 | SNB_PBAR4XLAT_OFFSET); |
798 | else { | 813 | else { |
799 | writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base + | 814 | if (ndev->split_bar) { |
800 | SNB_PBAR4XLAT_OFFSET); | 815 | writel(SNB_MBAR4_DSD_ADDR, |
816 | ndev->reg_base + | ||
817 | SNB_PBAR4XLAT_OFFSET); | ||
818 | writel(SNB_MBAR5_DSD_ADDR, | ||
819 | ndev->reg_base + | ||
820 | SNB_PBAR5XLAT_OFFSET); | ||
821 | } else | ||
822 | writeq(SNB_MBAR4_DSD_ADDR, | ||
823 | ndev->reg_base + | ||
824 | SNB_PBAR4XLAT_OFFSET); | ||
825 | |||
801 | /* B2B_XLAT_OFFSET is a 64bit register, but can | 826 | /* B2B_XLAT_OFFSET is a 64bit register, but can |
802 | * only take 32bit writes | 827 | * only take 32bit writes |
803 | */ | 828 | */ |
@@ -811,8 +836,14 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
811 | SNB_SBAR0BASE_OFFSET); | 836 | SNB_SBAR0BASE_OFFSET); |
812 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + | 837 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + |
813 | SNB_SBAR2BASE_OFFSET); | 838 | SNB_SBAR2BASE_OFFSET); |
814 | writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base + | 839 | if (ndev->split_bar) { |
815 | SNB_SBAR4BASE_OFFSET); | 840 | writel(SNB_MBAR4_USD_ADDR, ndev->reg_base + |
841 | SNB_SBAR4BASE_OFFSET); | ||
842 | writel(SNB_MBAR5_USD_ADDR, ndev->reg_base + | ||
843 | SNB_SBAR5BASE_OFFSET); | ||
844 | } else | ||
845 | writeq(SNB_MBAR4_USD_ADDR, ndev->reg_base + | ||
846 | SNB_SBAR4BASE_OFFSET); | ||
816 | } else { | 847 | } else { |
817 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + | 848 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + |
818 | SNB_PBAR2XLAT_OFFSET); | 849 | SNB_PBAR2XLAT_OFFSET); |
@@ -820,9 +851,20 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
820 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + | 851 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + |
821 | SNB_PBAR4XLAT_OFFSET); | 852 | SNB_PBAR4XLAT_OFFSET); |
822 | else { | 853 | else { |
823 | writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base + | 854 | if (ndev->split_bar) { |
824 | SNB_PBAR4XLAT_OFFSET); | 855 | writel(SNB_MBAR4_USD_ADDR, |
825 | /* B2B_XLAT_OFFSET is a 64bit register, but can | 856 | ndev->reg_base + |
857 | SNB_PBAR4XLAT_OFFSET); | ||
858 | writel(SNB_MBAR5_USD_ADDR, | ||
859 | ndev->reg_base + | ||
860 | SNB_PBAR5XLAT_OFFSET); | ||
861 | } else | ||
862 | writeq(SNB_MBAR4_USD_ADDR, | ||
863 | ndev->reg_base + | ||
864 | SNB_PBAR4XLAT_OFFSET); | ||
865 | |||
866 | /* | ||
867 | * B2B_XLAT_OFFSET is a 64bit register, but can | ||
826 | * only take 32bit writes | 868 | * only take 32bit writes |
827 | */ | 869 | */ |
828 | writel(SNB_MBAR01_USD_ADDR & 0xffffffff, | 870 | writel(SNB_MBAR01_USD_ADDR & 0xffffffff, |
@@ -834,8 +876,15 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
834 | SNB_SBAR0BASE_OFFSET); | 876 | SNB_SBAR0BASE_OFFSET); |
835 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + | 877 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + |
836 | SNB_SBAR2BASE_OFFSET); | 878 | SNB_SBAR2BASE_OFFSET); |
837 | writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base + | 879 | if (ndev->split_bar) { |
838 | SNB_SBAR4BASE_OFFSET); | 880 | writel(SNB_MBAR4_DSD_ADDR, ndev->reg_base + |
881 | SNB_SBAR4BASE_OFFSET); | ||
882 | writel(SNB_MBAR5_DSD_ADDR, ndev->reg_base + | ||
883 | SNB_SBAR5BASE_OFFSET); | ||
884 | } else | ||
885 | writeq(SNB_MBAR4_DSD_ADDR, ndev->reg_base + | ||
886 | SNB_SBAR4BASE_OFFSET); | ||
887 | |||
839 | } | 888 | } |
840 | break; | 889 | break; |
841 | case NTB_CONN_RP: | 890 | case NTB_CONN_RP: |
@@ -865,7 +914,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
865 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; | 914 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; |
866 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; | 915 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; |
867 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; | 916 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; |
868 | ndev->limits.max_mw = SNB_MAX_MW; | 917 | if (ndev->split_bar) { |
918 | ndev->reg_ofs.bar5_xlat = | ||
919 | ndev->reg_base + SNB_SBAR5XLAT_OFFSET; | ||
920 | ndev->limits.max_mw = HSX_SPLITBAR_MAX_MW; | ||
921 | } else | ||
922 | ndev->limits.max_mw = SNB_MAX_MW; | ||
869 | break; | 923 | break; |
870 | case NTB_CONN_TRANSPARENT: | 924 | case NTB_CONN_TRANSPARENT: |
871 | if (ndev->wa_flags & WA_SNB_ERR) { | 925 | if (ndev->wa_flags & WA_SNB_ERR) { |
@@ -892,7 +946,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
892 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_PBAR2XLAT_OFFSET; | 946 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_PBAR2XLAT_OFFSET; |
893 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_PBAR4XLAT_OFFSET; | 947 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_PBAR4XLAT_OFFSET; |
894 | 948 | ||
895 | ndev->limits.max_mw = SNB_MAX_MW; | 949 | if (ndev->split_bar) { |
950 | ndev->reg_ofs.bar5_xlat = | ||
951 | ndev->reg_base + SNB_PBAR5XLAT_OFFSET; | ||
952 | ndev->limits.max_mw = HSX_SPLITBAR_MAX_MW; | ||
953 | } else | ||
954 | ndev->limits.max_mw = SNB_MAX_MW; | ||
896 | break; | 955 | break; |
897 | default: | 956 | default: |
898 | /* | 957 | /* |
@@ -1499,7 +1558,11 @@ static void ntb_hw_link_up(struct ntb_device *ndev) | |||
1499 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); | 1558 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); |
1500 | ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK); | 1559 | ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK); |
1501 | ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP; | 1560 | ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP; |
1502 | ntb_cntl |= NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP; | 1561 | ntb_cntl |= NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP; |
1562 | if (ndev->split_bar) | ||
1563 | ntb_cntl |= NTB_CNTL_P2S_BAR5_SNOOP | | ||
1564 | NTB_CNTL_S2P_BAR5_SNOOP; | ||
1565 | |||
1503 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); | 1566 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); |
1504 | } | 1567 | } |
1505 | } | 1568 | } |
@@ -1516,14 +1579,26 @@ static void ntb_hw_link_down(struct ntb_device *ndev) | |||
1516 | /* Bring NTB link down */ | 1579 | /* Bring NTB link down */ |
1517 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); | 1580 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); |
1518 | ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP); | 1581 | ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP); |
1519 | ntb_cntl &= ~(NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP); | 1582 | ntb_cntl &= ~(NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP); |
1583 | if (ndev->split_bar) | ||
1584 | ntb_cntl &= ~(NTB_CNTL_P2S_BAR5_SNOOP | | ||
1585 | NTB_CNTL_S2P_BAR5_SNOOP); | ||
1520 | ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK; | 1586 | ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK; |
1521 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); | 1587 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); |
1522 | } | 1588 | } |
1523 | 1589 | ||
1590 | static void ntb_max_mw_detect(struct ntb_device *ndev) | ||
1591 | { | ||
1592 | if (ndev->split_bar) | ||
1593 | ndev->limits.max_mw = HSX_SPLITBAR_MAX_MW; | ||
1594 | else | ||
1595 | ndev->limits.max_mw = SNB_MAX_MW; | ||
1596 | } | ||
1597 | |||
1524 | static int ntb_xeon_detect(struct ntb_device *ndev) | 1598 | static int ntb_xeon_detect(struct ntb_device *ndev) |
1525 | { | 1599 | { |
1526 | int rc; | 1600 | int rc, bars_mask; |
1601 | u32 bars; | ||
1527 | u8 ppd; | 1602 | u8 ppd; |
1528 | 1603 | ||
1529 | ndev->hw_type = SNB_HW; | 1604 | ndev->hw_type = SNB_HW; |
@@ -1537,6 +1612,8 @@ static int ntb_xeon_detect(struct ntb_device *ndev) | |||
1537 | else | 1612 | else |
1538 | ndev->dev_type = NTB_DEV_DSD; | 1613 | ndev->dev_type = NTB_DEV_DSD; |
1539 | 1614 | ||
1615 | ndev->split_bar = (ppd & SNB_PPD_SPLIT_BAR) ? 1 : 0; | ||
1616 | |||
1540 | switch (ppd & SNB_PPD_CONN_TYPE) { | 1617 | switch (ppd & SNB_PPD_CONN_TYPE) { |
1541 | case NTB_CONN_B2B: | 1618 | case NTB_CONN_B2B: |
1542 | dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); | 1619 | dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); |
@@ -1555,12 +1632,25 @@ static int ntb_xeon_detect(struct ntb_device *ndev) | |||
1555 | * NTB. We will just force correct here. | 1632 | * NTB. We will just force correct here. |
1556 | */ | 1633 | */ |
1557 | ndev->dev_type = NTB_DEV_USD; | 1634 | ndev->dev_type = NTB_DEV_USD; |
1635 | |||
1636 | /* | ||
1637 | * This is a way for transparent BAR to figure out if we | ||
1638 | * are doing split BAR or not. There is no way for the hw | ||
1639 | * on the transparent side to know and set the PPD. | ||
1640 | */ | ||
1641 | bars_mask = pci_select_bars(ndev->pdev, IORESOURCE_MEM); | ||
1642 | bars = hweight32(bars_mask); | ||
1643 | if (bars == (HSX_SPLITBAR_MAX_MW + 1)) | ||
1644 | ndev->split_bar = 1; | ||
1645 | |||
1558 | break; | 1646 | break; |
1559 | default: | 1647 | default: |
1560 | dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", ppd); | 1648 | dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", ppd); |
1561 | return -ENODEV; | 1649 | return -ENODEV; |
1562 | } | 1650 | } |
1563 | 1651 | ||
1652 | ntb_max_mw_detect(ndev); | ||
1653 | |||
1564 | return 0; | 1654 | return 0; |
1565 | } | 1655 | } |
1566 | 1656 | ||
@@ -1638,22 +1728,50 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1638 | if (rc) | 1728 | if (rc) |
1639 | goto err; | 1729 | goto err; |
1640 | 1730 | ||
1641 | rc = pci_request_selected_regions(pdev, NTB_BAR_MASK, KBUILD_MODNAME); | 1731 | ndev->mw = kcalloc(ndev->limits.max_mw, sizeof(struct ntb_mw), |
1642 | if (rc) | 1732 | GFP_KERNEL); |
1733 | if (!ndev->mw) { | ||
1734 | rc = -ENOMEM; | ||
1643 | goto err1; | 1735 | goto err1; |
1736 | } | ||
1737 | |||
1738 | if (ndev->split_bar) | ||
1739 | rc = pci_request_selected_regions(pdev, NTB_SPLITBAR_MASK, | ||
1740 | KBUILD_MODNAME); | ||
1741 | else | ||
1742 | rc = pci_request_selected_regions(pdev, NTB_BAR_MASK, | ||
1743 | KBUILD_MODNAME); | ||
1744 | |||
1745 | if (rc) | ||
1746 | goto err2; | ||
1644 | 1747 | ||
1645 | ndev->reg_base = pci_ioremap_bar(pdev, NTB_BAR_MMIO); | 1748 | ndev->reg_base = pci_ioremap_bar(pdev, NTB_BAR_MMIO); |
1646 | if (!ndev->reg_base) { | 1749 | if (!ndev->reg_base) { |
1647 | dev_warn(&pdev->dev, "Cannot remap BAR 0\n"); | 1750 | dev_warn(&pdev->dev, "Cannot remap BAR 0\n"); |
1648 | rc = -EIO; | 1751 | rc = -EIO; |
1649 | goto err2; | 1752 | goto err3; |
1650 | } | 1753 | } |
1651 | 1754 | ||
1652 | for (i = 0; i < NTB_MAX_NUM_MW; i++) { | 1755 | for (i = 0; i < ndev->limits.max_mw; i++) { |
1653 | ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i)); | 1756 | ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i)); |
1654 | ndev->mw[i].vbase = | 1757 | |
1655 | ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), | 1758 | /* |
1656 | ndev->mw[i].bar_sz); | 1759 | * with the errata we need to steal last of the memory |
1760 | * windows for workarounds and they point to MMIO registers. | ||
1761 | */ | ||
1762 | if ((ndev->wa_flags & WA_SNB_ERR) && | ||
1763 | (i == (ndev->limits.max_mw - 1))) { | ||
1764 | ndev->mw[i].vbase = | ||
1765 | ioremap_nocache(pci_resource_start(pdev, | ||
1766 | MW_TO_BAR(i)), | ||
1767 | ndev->mw[i].bar_sz); | ||
1768 | } else { | ||
1769 | ndev->mw[i].vbase = | ||
1770 | ioremap_wc(pci_resource_start(pdev, | ||
1771 | MW_TO_BAR(i)), | ||
1772 | ndev->mw[i].bar_sz); | ||
1773 | } | ||
1774 | |||
1657 | dev_info(&pdev->dev, "MW %d size %llu\n", i, | 1775 | dev_info(&pdev->dev, "MW %d size %llu\n", i, |
1658 | (unsigned long long) ndev->mw[i].bar_sz); | 1776 | (unsigned long long) ndev->mw[i].bar_sz); |
1659 | if (!ndev->mw[i].vbase) { | 1777 | if (!ndev->mw[i].vbase) { |
@@ -1668,7 +1786,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1668 | if (rc) { | 1786 | if (rc) { |
1669 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 1787 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
1670 | if (rc) | 1788 | if (rc) |
1671 | goto err3; | 1789 | goto err4; |
1672 | 1790 | ||
1673 | dev_warn(&pdev->dev, "Cannot DMA highmem\n"); | 1791 | dev_warn(&pdev->dev, "Cannot DMA highmem\n"); |
1674 | } | 1792 | } |
@@ -1677,22 +1795,22 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1677 | if (rc) { | 1795 | if (rc) { |
1678 | rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 1796 | rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
1679 | if (rc) | 1797 | if (rc) |
1680 | goto err3; | 1798 | goto err4; |
1681 | 1799 | ||
1682 | dev_warn(&pdev->dev, "Cannot DMA consistent highmem\n"); | 1800 | dev_warn(&pdev->dev, "Cannot DMA consistent highmem\n"); |
1683 | } | 1801 | } |
1684 | 1802 | ||
1685 | rc = ntb_device_setup(ndev); | 1803 | rc = ntb_device_setup(ndev); |
1686 | if (rc) | 1804 | if (rc) |
1687 | goto err3; | 1805 | goto err4; |
1688 | 1806 | ||
1689 | rc = ntb_create_callbacks(ndev); | 1807 | rc = ntb_create_callbacks(ndev); |
1690 | if (rc) | 1808 | if (rc) |
1691 | goto err4; | 1809 | goto err5; |
1692 | 1810 | ||
1693 | rc = ntb_setup_interrupts(ndev); | 1811 | rc = ntb_setup_interrupts(ndev); |
1694 | if (rc) | 1812 | if (rc) |
1695 | goto err5; | 1813 | goto err6; |
1696 | 1814 | ||
1697 | /* The scratchpad registers keep the values between rmmod/insmod, | 1815 | /* The scratchpad registers keep the values between rmmod/insmod, |
1698 | * blast them now | 1816 | * blast them now |
@@ -1704,24 +1822,29 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1704 | 1822 | ||
1705 | rc = ntb_transport_init(pdev); | 1823 | rc = ntb_transport_init(pdev); |
1706 | if (rc) | 1824 | if (rc) |
1707 | goto err6; | 1825 | goto err7; |
1708 | 1826 | ||
1709 | ntb_hw_link_up(ndev); | 1827 | ntb_hw_link_up(ndev); |
1710 | 1828 | ||
1711 | return 0; | 1829 | return 0; |
1712 | 1830 | ||
1713 | err6: | 1831 | err7: |
1714 | ntb_free_interrupts(ndev); | 1832 | ntb_free_interrupts(ndev); |
1715 | err5: | 1833 | err6: |
1716 | ntb_free_callbacks(ndev); | 1834 | ntb_free_callbacks(ndev); |
1717 | err4: | 1835 | err5: |
1718 | ntb_device_free(ndev); | 1836 | ntb_device_free(ndev); |
1719 | err3: | 1837 | err4: |
1720 | for (i--; i >= 0; i--) | 1838 | for (i--; i >= 0; i--) |
1721 | iounmap(ndev->mw[i].vbase); | 1839 | iounmap(ndev->mw[i].vbase); |
1722 | iounmap(ndev->reg_base); | 1840 | iounmap(ndev->reg_base); |
1841 | err3: | ||
1842 | if (ndev->split_bar) | ||
1843 | pci_release_selected_regions(pdev, NTB_SPLITBAR_MASK); | ||
1844 | else | ||
1845 | pci_release_selected_regions(pdev, NTB_BAR_MASK); | ||
1723 | err2: | 1846 | err2: |
1724 | pci_release_selected_regions(pdev, NTB_BAR_MASK); | 1847 | kfree(ndev->mw); |
1725 | err1: | 1848 | err1: |
1726 | pci_disable_device(pdev); | 1849 | pci_disable_device(pdev); |
1727 | err: | 1850 | err: |
@@ -1745,11 +1868,19 @@ static void ntb_pci_remove(struct pci_dev *pdev) | |||
1745 | ntb_free_callbacks(ndev); | 1868 | ntb_free_callbacks(ndev); |
1746 | ntb_device_free(ndev); | 1869 | ntb_device_free(ndev); |
1747 | 1870 | ||
1748 | for (i = 0; i < NTB_MAX_NUM_MW; i++) | 1871 | /* need to reset max_mw limits so we can unmap properly */ |
1872 | if (ndev->hw_type == SNB_HW) | ||
1873 | ntb_max_mw_detect(ndev); | ||
1874 | |||
1875 | for (i = 0; i < ndev->limits.max_mw; i++) | ||
1749 | iounmap(ndev->mw[i].vbase); | 1876 | iounmap(ndev->mw[i].vbase); |
1750 | 1877 | ||
1878 | kfree(ndev->mw); | ||
1751 | iounmap(ndev->reg_base); | 1879 | iounmap(ndev->reg_base); |
1752 | pci_release_selected_regions(pdev, NTB_BAR_MASK); | 1880 | if (ndev->split_bar) |
1881 | pci_release_selected_regions(pdev, NTB_SPLITBAR_MASK); | ||
1882 | else | ||
1883 | pci_release_selected_regions(pdev, NTB_BAR_MASK); | ||
1753 | pci_disable_device(pdev); | 1884 | pci_disable_device(pdev); |
1754 | ntb_free_debugfs(ndev); | 1885 | ntb_free_debugfs(ndev); |
1755 | kfree(ndev); | 1886 | kfree(ndev); |
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h index 5380ca16198a..96de5fc95f90 100644 --- a/drivers/ntb/ntb_hw.h +++ b/drivers/ntb/ntb_hw.h | |||
@@ -78,14 +78,16 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
78 | 78 | ||
79 | #define NTB_BAR_MMIO 0 | 79 | #define NTB_BAR_MMIO 0 |
80 | #define NTB_BAR_23 2 | 80 | #define NTB_BAR_23 2 |
81 | #define NTB_BAR_45 4 | 81 | #define NTB_BAR_4 4 |
82 | #define NTB_BAR_5 5 | ||
83 | |||
82 | #define NTB_BAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ | 84 | #define NTB_BAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ |
83 | (1 << NTB_BAR_45)) | 85 | (1 << NTB_BAR_4)) |
86 | #define NTB_SPLITBAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ | ||
87 | (1 << NTB_BAR_4) | (1 << NTB_BAR_5)) | ||
84 | 88 | ||
85 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) | 89 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) |
86 | 90 | ||
87 | #define NTB_MAX_NUM_MW 2 | ||
88 | |||
89 | enum ntb_hw_event { | 91 | enum ntb_hw_event { |
90 | NTB_EVENT_SW_EVENT0 = 0, | 92 | NTB_EVENT_SW_EVENT0 = 0, |
91 | NTB_EVENT_SW_EVENT1, | 93 | NTB_EVENT_SW_EVENT1, |
@@ -115,7 +117,7 @@ struct ntb_device { | |||
115 | struct pci_dev *pdev; | 117 | struct pci_dev *pdev; |
116 | struct msix_entry *msix_entries; | 118 | struct msix_entry *msix_entries; |
117 | void __iomem *reg_base; | 119 | void __iomem *reg_base; |
118 | struct ntb_mw mw[NTB_MAX_NUM_MW]; | 120 | struct ntb_mw *mw; |
119 | struct { | 121 | struct { |
120 | unsigned char max_mw; | 122 | unsigned char max_mw; |
121 | unsigned char max_spads; | 123 | unsigned char max_spads; |
@@ -128,6 +130,7 @@ struct ntb_device { | |||
128 | void __iomem *rdb; | 130 | void __iomem *rdb; |
129 | void __iomem *bar2_xlat; | 131 | void __iomem *bar2_xlat; |
130 | void __iomem *bar4_xlat; | 132 | void __iomem *bar4_xlat; |
133 | void __iomem *bar5_xlat; | ||
131 | void __iomem *spad_write; | 134 | void __iomem *spad_write; |
132 | void __iomem *spad_read; | 135 | void __iomem *spad_read; |
133 | void __iomem *lnk_cntl; | 136 | void __iomem *lnk_cntl; |
@@ -147,6 +150,7 @@ struct ntb_device { | |||
147 | unsigned char link_width; | 150 | unsigned char link_width; |
148 | unsigned char link_speed; | 151 | unsigned char link_speed; |
149 | unsigned char link_status; | 152 | unsigned char link_status; |
153 | unsigned char split_bar; | ||
150 | 154 | ||
151 | struct delayed_work hb_timer; | 155 | struct delayed_work hb_timer; |
152 | unsigned long last_ts; | 156 | unsigned long last_ts; |
diff --git a/drivers/ntb/ntb_regs.h b/drivers/ntb/ntb_regs.h index 07872057c76e..f028ff81fd77 100644 --- a/drivers/ntb/ntb_regs.h +++ b/drivers/ntb/ntb_regs.h | |||
@@ -57,6 +57,7 @@ | |||
57 | #define SNB_MAX_DB_BITS 15 | 57 | #define SNB_MAX_DB_BITS 15 |
58 | #define SNB_LINK_DB 15 | 58 | #define SNB_LINK_DB 15 |
59 | #define SNB_DB_BITS_PER_VEC 5 | 59 | #define SNB_DB_BITS_PER_VEC 5 |
60 | #define HSX_SPLITBAR_MAX_MW 3 | ||
60 | #define SNB_MAX_MW 2 | 61 | #define SNB_MAX_MW 2 |
61 | #define SNB_ERRATA_MAX_MW 1 | 62 | #define SNB_ERRATA_MAX_MW 1 |
62 | 63 | ||
@@ -72,15 +73,20 @@ | |||
72 | 73 | ||
73 | #define SNB_PBAR2LMT_OFFSET 0x0000 | 74 | #define SNB_PBAR2LMT_OFFSET 0x0000 |
74 | #define SNB_PBAR4LMT_OFFSET 0x0008 | 75 | #define SNB_PBAR4LMT_OFFSET 0x0008 |
76 | #define SNB_PBAR5LMT_OFFSET 0x000C | ||
75 | #define SNB_PBAR2XLAT_OFFSET 0x0010 | 77 | #define SNB_PBAR2XLAT_OFFSET 0x0010 |
76 | #define SNB_PBAR4XLAT_OFFSET 0x0018 | 78 | #define SNB_PBAR4XLAT_OFFSET 0x0018 |
79 | #define SNB_PBAR5XLAT_OFFSET 0x001C | ||
77 | #define SNB_SBAR2LMT_OFFSET 0x0020 | 80 | #define SNB_SBAR2LMT_OFFSET 0x0020 |
78 | #define SNB_SBAR4LMT_OFFSET 0x0028 | 81 | #define SNB_SBAR4LMT_OFFSET 0x0028 |
82 | #define SNB_SBAR5LMT_OFFSET 0x002C | ||
79 | #define SNB_SBAR2XLAT_OFFSET 0x0030 | 83 | #define SNB_SBAR2XLAT_OFFSET 0x0030 |
80 | #define SNB_SBAR4XLAT_OFFSET 0x0038 | 84 | #define SNB_SBAR4XLAT_OFFSET 0x0038 |
85 | #define SNB_SBAR5XLAT_OFFSET 0x003C | ||
81 | #define SNB_SBAR0BASE_OFFSET 0x0040 | 86 | #define SNB_SBAR0BASE_OFFSET 0x0040 |
82 | #define SNB_SBAR2BASE_OFFSET 0x0048 | 87 | #define SNB_SBAR2BASE_OFFSET 0x0048 |
83 | #define SNB_SBAR4BASE_OFFSET 0x0050 | 88 | #define SNB_SBAR4BASE_OFFSET 0x0050 |
89 | #define SNB_SBAR5BASE_OFFSET 0x0054 | ||
84 | #define SNB_NTBCNTL_OFFSET 0x0058 | 90 | #define SNB_NTBCNTL_OFFSET 0x0058 |
85 | #define SNB_SBDF_OFFSET 0x005C | 91 | #define SNB_SBDF_OFFSET 0x005C |
86 | #define SNB_PDOORBELL_OFFSET 0x0060 | 92 | #define SNB_PDOORBELL_OFFSET 0x0060 |
@@ -96,12 +102,18 @@ | |||
96 | #define SNB_B2B_XLAT_OFFSETL 0x0144 | 102 | #define SNB_B2B_XLAT_OFFSETL 0x0144 |
97 | #define SNB_B2B_XLAT_OFFSETU 0x0148 | 103 | #define SNB_B2B_XLAT_OFFSETU 0x0148 |
98 | 104 | ||
99 | #define SNB_MBAR01_USD_ADDR 0x000000210000000CULL | 105 | /* |
100 | #define SNB_MBAR23_USD_ADDR 0x000000410000000CULL | 106 | * The addresses are setup so the 32bit BARs can function. Thus |
101 | #define SNB_MBAR45_USD_ADDR 0x000000810000000CULL | 107 | * the addresses are all in 32bit space |
102 | #define SNB_MBAR01_DSD_ADDR 0x000000200000000CULL | 108 | */ |
103 | #define SNB_MBAR23_DSD_ADDR 0x000000400000000CULL | 109 | #define SNB_MBAR01_USD_ADDR 0x000000002100000CULL |
104 | #define SNB_MBAR45_DSD_ADDR 0x000000800000000CULL | 110 | #define SNB_MBAR23_USD_ADDR 0x000000004100000CULL |
111 | #define SNB_MBAR4_USD_ADDR 0x000000008100000CULL | ||
112 | #define SNB_MBAR5_USD_ADDR 0x00000000A100000CULL | ||
113 | #define SNB_MBAR01_DSD_ADDR 0x000000002000000CULL | ||
114 | #define SNB_MBAR23_DSD_ADDR 0x000000004000000CULL | ||
115 | #define SNB_MBAR4_DSD_ADDR 0x000000008000000CULL | ||
116 | #define SNB_MBAR5_DSD_ADDR 0x00000000A000000CULL | ||
105 | 117 | ||
106 | #define BWD_MSIX_CNT 34 | 118 | #define BWD_MSIX_CNT 34 |
107 | #define BWD_MAX_SPADS 16 | 119 | #define BWD_MAX_SPADS 16 |
@@ -150,13 +162,16 @@ | |||
150 | #define NTB_CNTL_LINK_DISABLE (1 << 1) | 162 | #define NTB_CNTL_LINK_DISABLE (1 << 1) |
151 | #define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2) | 163 | #define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2) |
152 | #define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4) | 164 | #define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4) |
153 | #define NTB_CNTL_S2P_BAR45_SNOOP (1 << 6) | 165 | #define NTB_CNTL_S2P_BAR4_SNOOP (1 << 6) |
154 | #define NTB_CNTL_P2S_BAR45_SNOOP (1 << 8) | 166 | #define NTB_CNTL_P2S_BAR4_SNOOP (1 << 8) |
167 | #define NTB_CNTL_S2P_BAR5_SNOOP (1 << 12) | ||
168 | #define NTB_CNTL_P2S_BAR5_SNOOP (1 << 14) | ||
155 | #define BWD_CNTL_LINK_DOWN (1 << 16) | 169 | #define BWD_CNTL_LINK_DOWN (1 << 16) |
156 | 170 | ||
157 | #define NTB_PPD_OFFSET 0x00D4 | 171 | #define NTB_PPD_OFFSET 0x00D4 |
158 | #define SNB_PPD_CONN_TYPE 0x0003 | 172 | #define SNB_PPD_CONN_TYPE 0x0003 |
159 | #define SNB_PPD_DEV_TYPE 0x0010 | 173 | #define SNB_PPD_DEV_TYPE 0x0010 |
174 | #define SNB_PPD_SPLIT_BAR (1 << 6) | ||
160 | #define BWD_PPD_INIT_LINK 0x0008 | 175 | #define BWD_PPD_INIT_LINK 0x0008 |
161 | #define BWD_PPD_CONN_TYPE 0x0300 | 176 | #define BWD_PPD_CONN_TYPE 0x0300 |
162 | #define BWD_PPD_DEV_TYPE 0x1000 | 177 | #define BWD_PPD_DEV_TYPE 0x1000 |