aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@pathscale.com>2006-09-28 12:00:00 -0400
committerRoland Dreier <rolandd@cisco.com>2006-09-28 14:16:27 -0400
commit2c9446a1d63f1ca570e92f89422595732efedf44 (patch)
tree9b401358de12f9f88e79ac471c5950b61aba45a3
parent9929b0fb0f35f54371e9364bab809bcd753f9d3a (diff)
IB/ipath: Support revision 2 InfiniPath PCIE devices
This also entailed a little GPIO-interrupt general cleanup. Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c116
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c88
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h18
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c28
5 files changed, 215 insertions, 37 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index 46b7b20d8a91..382956d2ea4b 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -186,6 +186,8 @@ typedef enum _ipath_ureg {
186#define IPATH_RUNTIME_FORCE_WC_ORDER 0x4 186#define IPATH_RUNTIME_FORCE_WC_ORDER 0x4
187#define IPATH_RUNTIME_RCVHDR_COPY 0x8 187#define IPATH_RUNTIME_RCVHDR_COPY 0x8
188#define IPATH_RUNTIME_MASTER 0x10 188#define IPATH_RUNTIME_MASTER 0x10
189#define IPATH_RUNTIME_PBC_REWRITE 0x20
190#define IPATH_RUNTIME_LOOSE_DMA_ALIGN 0x40
189 191
190/* 192/*
191 * This structure is returned by ipath_userinit() immediately after 193 * This structure is returned by ipath_userinit() immediately after
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index d86516d23df6..d64b87bf1f97 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -294,6 +294,13 @@ static const struct ipath_cregs ipath_pe_cregs = {
294#define IPATH_GPIO_SCL (1ULL << \ 294#define IPATH_GPIO_SCL (1ULL << \
295 (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) 295 (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
296 296
297/*
298 * Rev2 silicon allows suppressing check for ArmLaunch errors.
299 * this can speed up short packet sends on systems that do
300 * not guaranteee write-order.
301 */
302#define INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR (1ULL<<63)
303
297/** 304/**
298 * ipath_pe_handle_hwerrors - display hardware errors. 305 * ipath_pe_handle_hwerrors - display hardware errors.
299 * @dd: the infinipath device 306 * @dd: the infinipath device
@@ -571,9 +578,12 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
571 if (!dd->ipath_boardrev) // no PLL for Emulator 578 if (!dd->ipath_boardrev) // no PLL for Emulator
572 val &= ~INFINIPATH_HWE_SERDESPLLFAILED; 579 val &= ~INFINIPATH_HWE_SERDESPLLFAILED;
573 580
574 /* workaround bug 9460 in internal interface bus parity checking */ 581 if (dd->ipath_minrev < 2) {
575 val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM; 582 /* workaround bug 9460 in internal interface bus parity
576 583 * checking. Fixed (HW bug 9490) in Rev2.
584 */
585 val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
586 }
577 dd->ipath_hwerrmask = val; 587 dd->ipath_hwerrmask = val;
578} 588}
579 589
@@ -583,8 +593,8 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
583 */ 593 */
584static int ipath_pe_bringup_serdes(struct ipath_devdata *dd) 594static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
585{ 595{
586 u64 val, tmp, config1; 596 u64 val, tmp, config1, prev_val;
587 int ret = 0, change = 0; 597 int ret = 0;
588 598
589 ipath_dbg("Trying to bringup serdes\n"); 599 ipath_dbg("Trying to bringup serdes\n");
590 600
@@ -641,6 +651,7 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
641 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 651 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
642 652
643 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); 653 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
654 prev_val = val;
644 if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) & 655 if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) &
645 INFINIPATH_XGXS_MDIOADDR_MASK) != 3) { 656 INFINIPATH_XGXS_MDIOADDR_MASK) != 3) {
646 val &= 657 val &=
@@ -648,11 +659,9 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
648 INFINIPATH_XGXS_MDIOADDR_SHIFT); 659 INFINIPATH_XGXS_MDIOADDR_SHIFT);
649 /* MDIO address 3 */ 660 /* MDIO address 3 */
650 val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT; 661 val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT;
651 change = 1;
652 } 662 }
653 if (val & INFINIPATH_XGXS_RESET) { 663 if (val & INFINIPATH_XGXS_RESET) {
654 val &= ~INFINIPATH_XGXS_RESET; 664 val &= ~INFINIPATH_XGXS_RESET;
655 change = 1;
656 } 665 }
657 if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) & 666 if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
658 INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) { 667 INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
@@ -661,9 +670,19 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
661 INFINIPATH_XGXS_RX_POL_SHIFT); 670 INFINIPATH_XGXS_RX_POL_SHIFT);
662 val |= dd->ipath_rx_pol_inv << 671 val |= dd->ipath_rx_pol_inv <<
663 INFINIPATH_XGXS_RX_POL_SHIFT; 672 INFINIPATH_XGXS_RX_POL_SHIFT;
664 change = 1;
665 } 673 }
666 if (change) 674 if (dd->ipath_minrev >= 2) {
675 /* Rev 2. can tolerate multiple writes to PBC, and
676 * allowing them can provide lower latency on some
677 * CPUs, but this feature is off by default, only
678 * turned on by setting D63 of XGXSconfig reg.
679 * May want to make this conditional more
680 * fine-grained in future. This is not exactly
681 * related to XGXS, but where the bit ended up.
682 */
683 val |= INFINIPATH_XGXS_SUPPRESS_ARMLAUNCH_ERR;
684 }
685 if (val != prev_val)
667 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); 686 ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
668 687
669 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); 688 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
@@ -717,9 +736,25 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
717 ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); 736 ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
718} 737}
719 738
720/* this is not yet needed on this chip, so just return 0. */
721static int ipath_pe_intconfig(struct ipath_devdata *dd) 739static int ipath_pe_intconfig(struct ipath_devdata *dd)
722{ 740{
741 u64 val;
742 u32 chiprev;
743
744 /*
745 * If the chip supports added error indication via GPIO pins,
746 * enable interrupts on those bits so the interrupt routine
747 * can count the events. Also set flag so interrupt routine
748 * can know they are expected.
749 */
750 chiprev = dd->ipath_revision >> INFINIPATH_R_CHIPREVMINOR_SHIFT;
751 if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) {
752 /* Rev2+ reports extra errors via internal GPIO pins */
753 dd->ipath_flags |= IPATH_GPIO_ERRINTRS;
754 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
755 val |= IPATH_GPIO_ERRINTR_MASK;
756 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
757 }
723 return 0; 758 return 0;
724} 759}
725 760
@@ -1082,6 +1117,45 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
1082 mmiowb(); 1117 mmiowb();
1083 spin_unlock_irqrestore(&dd->ipath_tid_lock, flags); 1118 spin_unlock_irqrestore(&dd->ipath_tid_lock, flags);
1084} 1119}
1120/**
1121 * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher
1122 * @dd: the infinipath device
1123 * @tidptr: pointer to the expected TID (in chip) to udpate
1124 * @tidtype: 0 for eager, 1 for expected
1125 * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
1126 *
1127 * This exists as a separate routine to allow for selection of the
1128 * appropriate "flavor". The static calls in cleanup just use the
1129 * revision-agnostic form, as they are not performance critical.
1130 */
1131static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
1132 u32 type, unsigned long pa)
1133{
1134 u32 __iomem *tidp32 = (u32 __iomem *)tidptr;
1135
1136 if (pa != dd->ipath_tidinvalid) {
1137 if (pa & ((1U << 11) - 1)) {
1138 dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
1139 "not 4KB aligned!\n", pa);
1140 return;
1141 }
1142 pa >>= 11;
1143 /* paranoia check */
1144 if (pa & (7<<29))
1145 ipath_dev_err(dd,
1146 "BUG: Physical page address 0x%lx "
1147 "has bits set in 31-29\n", pa);
1148
1149 if (type == 0)
1150 pa |= dd->ipath_tidtemplate;
1151 else /* for now, always full 4KB page */
1152 pa |= 2 << 29;
1153 }
1154 if (dd->ipath_kregbase)
1155 writel(pa, tidp32);
1156 mmiowb();
1157}
1158
1085 1159
1086/** 1160/**
1087 * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager 1161 * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager
@@ -1203,7 +1277,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
1203 1277
1204/** 1278/**
1205 * ipath_init_pe_get_base_info - set chip-specific flags for user code 1279 * ipath_init_pe_get_base_info - set chip-specific flags for user code
1206 * @dd: the infinipath device 1280 * @pd: the infinipath port
1207 * @kbase: ipath_base_info pointer 1281 * @kbase: ipath_base_info pointer
1208 * 1282 *
1209 * We set the PCIE flag because the lower bandwidth on PCIe vs 1283 * We set the PCIE flag because the lower bandwidth on PCIe vs
@@ -1212,6 +1286,7 @@ int __attribute__((weak)) ipath_unordered_wc(void)
1212static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase) 1286static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
1213{ 1287{
1214 struct ipath_base_info *kinfo = kbase; 1288 struct ipath_base_info *kinfo = kbase;
1289 struct ipath_devdata *dd;
1215 1290
1216 if (ipath_unordered_wc()) { 1291 if (ipath_unordered_wc()) {
1217 kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER; 1292 kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER;
@@ -1220,8 +1295,20 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
1220 else 1295 else
1221 ipath_cdbg(PROC, "Not Intel processor, WC ordered\n"); 1296 ipath_cdbg(PROC, "Not Intel processor, WC ordered\n");
1222 1297
1223 kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE; 1298 if (pd == NULL)
1299 goto done;
1300
1301 dd = pd->port_dd;
1302
1303 if (dd != NULL && dd->ipath_minrev >= 2) {
1304 ipath_cdbg(PROC, "IBA6120 Rev2, allow multiple PBC write\n");
1305 kinfo->spi_runtime_flags |= IPATH_RUNTIME_PBC_REWRITE;
1306 ipath_cdbg(PROC, "IBA6120 Rev2, allow loose DMA alignment\n");
1307 kinfo->spi_runtime_flags |= IPATH_RUNTIME_LOOSE_DMA_ALIGN;
1308 }
1224 1309
1310done:
1311 kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE;
1225 return 0; 1312 return 0;
1226} 1313}
1227 1314
@@ -1244,7 +1331,10 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
1244 dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; 1331 dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes;
1245 dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; 1332 dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes;
1246 dd->ipath_f_clear_tids = ipath_pe_clear_tids; 1333 dd->ipath_f_clear_tids = ipath_pe_clear_tids;
1247 dd->ipath_f_put_tid = ipath_pe_put_tid; 1334 if (dd->ipath_minrev >= 2)
1335 dd->ipath_f_put_tid = ipath_pe_put_tid_2;
1336 else
1337 dd->ipath_f_put_tid = ipath_pe_put_tid;
1248 dd->ipath_f_cleanup = ipath_setup_pe_cleanup; 1338 dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
1249 dd->ipath_f_setextled = ipath_setup_pe_setextled; 1339 dd->ipath_f_setextled = ipath_setup_pe_setextled;
1250 dd->ipath_f_get_base_info = ipath_pe_get_base_info; 1340 dd->ipath_f_get_base_info = ipath_pe_get_base_info;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 49bf7bb15b04..5762b87d12ec 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -808,7 +808,7 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
808 if (oldhead != curtail) { 808 if (oldhead != curtail) {
809 if (dd->ipath_flags & IPATH_GPIO_INTR) { 809 if (dd->ipath_flags & IPATH_GPIO_INTR) {
810 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 810 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
811 (u64) (1 << 2)); 811 (u64) (1 << IPATH_GPIO_PORT0_BIT));
812 istat = port0rbits | INFINIPATH_I_GPIO; 812 istat = port0rbits | INFINIPATH_I_GPIO;
813 } 813 }
814 else 814 else
@@ -867,26 +867,80 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
867 867
868 if (istat & INFINIPATH_I_GPIO) { 868 if (istat & INFINIPATH_I_GPIO) {
869 /* 869 /*
870 * Packets are available in the port 0 rcv queue. 870 * GPIO interrupts fall in two broad classes:
871 * Eventually this needs to be generalized to check 871 * GPIO_2 indicates (on some HT4xx boards) that a packet
872 * IPATH_GPIO_INTR, and the specific GPIO bit, if 872 * has arrived for Port 0. Checking for this
873 * GPIO interrupts are used for anything else. 873 * is controlled by flag IPATH_GPIO_INTR.
874 * GPIO_3..5 on IBA6120 Rev2 chips indicate errors
875 * that we need to count. Checking for this
876 * is controlled by flag IPATH_GPIO_ERRINTRS.
874 */ 877 */
875 if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) { 878 u32 gpiostatus;
876 u32 gpiostatus; 879 u32 to_clear = 0;
877 gpiostatus = ipath_read_kreg32( 880
878 dd, dd->ipath_kregs->kr_gpio_status); 881 gpiostatus = ipath_read_kreg32(
879 ipath_dbg("Unexpected GPIO interrupt bits %x\n", 882 dd, dd->ipath_kregs->kr_gpio_status);
880 gpiostatus); 883 /* First the error-counter case.
881 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 884 */
882 gpiostatus); 885 if ((gpiostatus & IPATH_GPIO_ERRINTR_MASK) &&
886 (dd->ipath_flags & IPATH_GPIO_ERRINTRS)) {
887 /* want to clear the bits we see asserted. */
888 to_clear |= (gpiostatus & IPATH_GPIO_ERRINTR_MASK);
889
890 /*
891 * Count appropriately, clear bits out of our copy,
892 * as they have been "handled".
893 */
894 if (gpiostatus & (1 << IPATH_GPIO_RXUVL_BIT)) {
895 ipath_dbg("FlowCtl on UnsupVL\n");
896 dd->ipath_rxfc_unsupvl_errs++;
897 }
898 if (gpiostatus & (1 << IPATH_GPIO_OVRUN_BIT)) {
899 ipath_dbg("Overrun Threshold exceeded\n");
900 dd->ipath_overrun_thresh_errs++;
901 }
902 if (gpiostatus & (1 << IPATH_GPIO_LLI_BIT)) {
903 ipath_dbg("Local Link Integrity error\n");
904 dd->ipath_lli_errs++;
905 }
906 gpiostatus &= ~IPATH_GPIO_ERRINTR_MASK;
883 } 907 }
884 else { 908 /* Now the Port0 Receive case */
885 /* Clear GPIO status bit 2 */ 909 if ((gpiostatus & (1 << IPATH_GPIO_PORT0_BIT)) &&
886 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 910 (dd->ipath_flags & IPATH_GPIO_INTR)) {
887 (u64) (1 << 2)); 911 /*
912 * GPIO status bit 2 is set, and we expected it.
913 * clear it and indicate in p0bits.
914 * This probably only happens if a Port0 pkt
915 * arrives at _just_ the wrong time, and we
916 * handle that by seting chk0rcv;
917 */
918 to_clear |= (1 << IPATH_GPIO_PORT0_BIT);
919 gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT);
888 chk0rcv = 1; 920 chk0rcv = 1;
889 } 921 }
922 if (unlikely(gpiostatus)) {
923 /*
924 * Some unexpected bits remain. If they could have
925 * caused the interrupt, complain and clear.
926 * MEA: this is almost certainly non-ideal.
927 * we should look into auto-disable of unexpected
928 * GPIO interrupts, possibly on a "three strikes"
929 * basis.
930 */
931 u32 mask;
932 mask = ipath_read_kreg32(
933 dd, dd->ipath_kregs->kr_gpio_mask);
934 if (mask & gpiostatus) {
935 ipath_dbg("Unexpected GPIO IRQ bits %x\n",
936 gpiostatus & mask);
937 to_clear |= (gpiostatus & mask);
938 }
939 }
940 if (to_clear) {
941 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
942 (u64) to_clear);
943 }
890 } 944 }
891 chk0rcv |= istat & port0rbits; 945 chk0rcv |= istat & port0rbits;
892 946
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 0cabd4f16234..e9cd95f3c2e1 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -524,6 +524,15 @@ struct ipath_devdata {
524 u32 ipath_lli_counter; 524 u32 ipath_lli_counter;
525 /* local link integrity errors */ 525 /* local link integrity errors */
526 u32 ipath_lli_errors; 526 u32 ipath_lli_errors;
527 /*
528 * Above counts only cases where _successive_ LocalLinkIntegrity
529 * errors were seen in the receive headers of kern-packets.
530 * Below are the three (monotonically increasing) counters
531 * maintained via GPIO interrupts on iba6120-rev2.
532 */
533 u32 ipath_rxfc_unsupvl_errs;
534 u32 ipath_overrun_thresh_errs;
535 u32 ipath_lli_errs;
527}; 536};
528 537
529/* Private data for file operations */ 538/* Private data for file operations */
@@ -636,6 +645,15 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
636 /* can miss port0 rx interrupts */ 645 /* can miss port0 rx interrupts */
637#define IPATH_POLL_RX_INTR 0x40000 646#define IPATH_POLL_RX_INTR 0x40000
638#define IPATH_DISABLED 0x80000 /* administratively disabled */ 647#define IPATH_DISABLED 0x80000 /* administratively disabled */
648 /* Use GPIO interrupts for new counters */
649#define IPATH_GPIO_ERRINTRS 0x100000
650
651/* Bits in GPIO for the added interrupts */
652#define IPATH_GPIO_PORT0_BIT 2
653#define IPATH_GPIO_RXUVL_BIT 3
654#define IPATH_GPIO_OVRUN_BIT 4
655#define IPATH_GPIO_LLI_BIT 5
656#define IPATH_GPIO_ERRINTR_MASK 0x38
639 657
640/* portdata flag bit offsets */ 658/* portdata flag bit offsets */
641 /* waiting for a packet to arrive */ 659 /* waiting for a packet to arrive */
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index a4bf870c5e31..56c01938f714 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -898,7 +898,8 @@ int ipath_get_counters(struct ipath_devdata *dd,
898 ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) + 898 ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) +
899 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) + 899 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) +
900 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) + 900 ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) +
901 ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt); 901 ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt) +
902 dd->ipath_rxfc_unsupvl_errs;
902 cntrs->port_rcv_remphys_errors = 903 cntrs->port_rcv_remphys_errors =
903 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt); 904 ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt);
904 cntrs->port_xmit_discards = 905 cntrs->port_xmit_discards =
@@ -911,8 +912,10 @@ int ipath_get_counters(struct ipath_devdata *dd,
911 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); 912 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt);
912 cntrs->port_rcv_packets = 913 cntrs->port_rcv_packets =
913 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); 914 ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt);
914 cntrs->local_link_integrity_errors = dd->ipath_lli_errors; 915 cntrs->local_link_integrity_errors =
915 cntrs->excessive_buffer_overrun_errors = 0; /* XXX */ 916 (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ?
917 dd->ipath_lli_errs : dd->ipath_lli_errors;
918 cntrs->excessive_buffer_overrun_errors = dd->ipath_overrun_thresh_errs;
916 919
917 ret = 0; 920 ret = 0;
918 921
@@ -1380,11 +1383,13 @@ static int enable_timer(struct ipath_devdata *dd)
1380 * processing. 1383 * processing.
1381 */ 1384 */
1382 if (dd->ipath_flags & IPATH_GPIO_INTR) { 1385 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1386 u64 val;
1383 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect, 1387 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
1384 0x2074076542310ULL); 1388 0x2074076542310ULL);
1385 /* Enable GPIO bit 2 interrupt */ 1389 /* Enable GPIO bit 2 interrupt */
1386 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 1390 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
1387 (u64) (1 << 2)); 1391 val |= (u64) (1 << IPATH_GPIO_PORT0_BIT);
1392 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
1388 } 1393 }
1389 1394
1390 init_timer(&dd->verbs_timer); 1395 init_timer(&dd->verbs_timer);
@@ -1399,8 +1404,17 @@ static int enable_timer(struct ipath_devdata *dd)
1399static int disable_timer(struct ipath_devdata *dd) 1404static int disable_timer(struct ipath_devdata *dd)
1400{ 1405{
1401 /* Disable GPIO bit 2 interrupt */ 1406 /* Disable GPIO bit 2 interrupt */
1402 if (dd->ipath_flags & IPATH_GPIO_INTR) 1407 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1403 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0); 1408 u64 val;
1409 /* Disable GPIO bit 2 interrupt */
1410 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
1411 val &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT));
1412 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val);
1413 /*
1414 * We might want to undo changes to debugportselect,
1415 * but how?
1416 */
1417 }
1404 1418
1405 del_timer_sync(&dd->verbs_timer); 1419 del_timer_sync(&dd->verbs_timer);
1406 1420