diff options
author | Jon Mason <jon.mason@intel.com> | 2013-09-06 19:51:16 -0400 |
---|---|---|
committer | Jon Mason <jon.mason@intel.com> | 2013-11-20 11:57:30 -0500 |
commit | c529aa30337b928bd6bc34293608cb3d4505856e (patch) | |
tree | 48cb1e6180ecb243e923f65fa8436a7fa77db8f7 | |
parent | 5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff) |
NTB: Xeon Doorbell errata workaround
Modifications to the 14th bit of the B2BDOORBELL register will not be
mirrored to the remote system due to a hardware issue. To get around
the issue, shrink the number of available doorbell bits by 1. The max
number of doorbells was being used as a way to referencing the Link
Doorbell bit. Since this would no longer work, the driver must now
explicitly reference that bit.
This does not affect the xeon_errata_workaround case, as it is not using
the b2bdoorbell register.
Signed-off-by: Jon Mason <jon.mason@intel.com>
-rw-r--r-- | drivers/ntb/ntb_hw.c | 20 | ||||
-rw-r--r-- | drivers/ntb/ntb_regs.h | 1 |
2 files changed, 16 insertions, 5 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 1cb6e51e6bda..6c9d73348735 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -678,6 +678,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
678 | return -EINVAL; | 678 | return -EINVAL; |
679 | 679 | ||
680 | ndev->limits.max_mw = SNB_ERRATA_MAX_MW; | 680 | ndev->limits.max_mw = SNB_ERRATA_MAX_MW; |
681 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | ||
681 | ndev->reg_ofs.spad_write = ndev->mw[1].vbase + | 682 | ndev->reg_ofs.spad_write = ndev->mw[1].vbase + |
682 | SNB_SPAD_OFFSET; | 683 | SNB_SPAD_OFFSET; |
683 | ndev->reg_ofs.rdb = ndev->mw[1].vbase + | 684 | ndev->reg_ofs.rdb = ndev->mw[1].vbase + |
@@ -690,6 +691,13 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
690 | SNB_PBAR4LMT_OFFSET); | 691 | SNB_PBAR4LMT_OFFSET); |
691 | } else { | 692 | } else { |
692 | ndev->limits.max_mw = SNB_MAX_MW; | 693 | ndev->limits.max_mw = SNB_MAX_MW; |
694 | |||
695 | /* HW Errata on bit 14 of b2bdoorbell register. Writes | ||
696 | * will not be mirrored to the remote system. Shrink | ||
697 | * the number of bits by one, since bit 14 is the last | ||
698 | * bit. | ||
699 | */ | ||
700 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS - 1; | ||
693 | ndev->reg_ofs.spad_write = ndev->reg_base + | 701 | ndev->reg_ofs.spad_write = ndev->reg_base + |
694 | SNB_B2B_SPAD_OFFSET; | 702 | SNB_B2B_SPAD_OFFSET; |
695 | ndev->reg_ofs.rdb = ndev->reg_base + | 703 | ndev->reg_ofs.rdb = ndev->reg_base + |
@@ -769,6 +777,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
769 | * have an equal amount. | 777 | * have an equal amount. |
770 | */ | 778 | */ |
771 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; | 779 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; |
780 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | ||
772 | /* Note: The SDOORBELL is the cause of the errata. You REALLY | 781 | /* Note: The SDOORBELL is the cause of the errata. You REALLY |
773 | * don't want to touch it. | 782 | * don't want to touch it. |
774 | */ | 783 | */ |
@@ -793,6 +802,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
793 | * have an equal amount. | 802 | * have an equal amount. |
794 | */ | 803 | */ |
795 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; | 804 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; |
805 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | ||
796 | ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET; | 806 | ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET; |
797 | ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET; | 807 | ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET; |
798 | ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET; | 808 | ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET; |
@@ -819,7 +829,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
819 | ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET; | 829 | ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET; |
820 | ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET; | 830 | ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET; |
821 | 831 | ||
822 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | ||
823 | ndev->limits.msix_cnt = SNB_MSIX_CNT; | 832 | ndev->limits.msix_cnt = SNB_MSIX_CNT; |
824 | ndev->bits_per_vector = SNB_DB_BITS_PER_VEC; | 833 | ndev->bits_per_vector = SNB_DB_BITS_PER_VEC; |
825 | 834 | ||
@@ -986,7 +995,7 @@ static irqreturn_t xeon_event_msix_irq(int irq, void *dev) | |||
986 | dev_err(&ndev->pdev->dev, "Error determining link status\n"); | 995 | dev_err(&ndev->pdev->dev, "Error determining link status\n"); |
987 | 996 | ||
988 | /* bit 15 is always the link bit */ | 997 | /* bit 15 is always the link bit */ |
989 | writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.ldb); | 998 | writew(1 << SNB_LINK_DB, ndev->reg_ofs.ldb); |
990 | 999 | ||
991 | return IRQ_HANDLED; | 1000 | return IRQ_HANDLED; |
992 | } | 1001 | } |
@@ -1176,9 +1185,10 @@ static int ntb_setup_interrupts(struct ntb_device *ndev) | |||
1176 | */ | 1185 | */ |
1177 | if (ndev->hw_type == BWD_HW) | 1186 | if (ndev->hw_type == BWD_HW) |
1178 | writeq(~0, ndev->reg_ofs.ldb_mask); | 1187 | writeq(~0, ndev->reg_ofs.ldb_mask); |
1179 | else | 1188 | else { |
1180 | writew(~(1 << ndev->limits.max_db_bits), | 1189 | u16 var = 1 << SNB_LINK_DB; |
1181 | ndev->reg_ofs.ldb_mask); | 1190 | writew(~var, ndev->reg_ofs.ldb_mask); |
1191 | } | ||
1182 | 1192 | ||
1183 | rc = ntb_setup_msix(ndev); | 1193 | rc = ntb_setup_msix(ndev); |
1184 | if (!rc) | 1194 | if (!rc) |
diff --git a/drivers/ntb/ntb_regs.h b/drivers/ntb/ntb_regs.h index aa4bdd393c58..5381b65a6f3a 100644 --- a/drivers/ntb/ntb_regs.h +++ b/drivers/ntb/ntb_regs.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define SNB_MAX_COMPAT_SPADS 16 | 55 | #define SNB_MAX_COMPAT_SPADS 16 |
56 | /* Reserve the uppermost bit for link interrupt */ | 56 | /* Reserve the uppermost bit for link interrupt */ |
57 | #define SNB_MAX_DB_BITS 15 | 57 | #define SNB_MAX_DB_BITS 15 |
58 | #define SNB_LINK_DB 15 | ||
58 | #define SNB_DB_BITS_PER_VEC 5 | 59 | #define SNB_DB_BITS_PER_VEC 5 |
59 | #define SNB_MAX_MW 2 | 60 | #define SNB_MAX_MW 2 |
60 | #define SNB_ERRATA_MAX_MW 1 | 61 | #define SNB_ERRATA_MAX_MW 1 |