aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c61
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba7220.c76
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_stats.c8
4 files changed, 155 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index 421cc2af891f..fbf8c5379ea8 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -721,6 +721,12 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
721 INFINIPATH_HWE_SERDESPLLFAILED); 721 INFINIPATH_HWE_SERDESPLLFAILED);
722 } 722 }
723 723
724 dd->ibdeltainprog = 1;
725 dd->ibsymsnap =
726 ipath_read_creg32(dd, dd->ipath_cregs->cr_ibsymbolerrcnt);
727 dd->iblnkerrsnap =
728 ipath_read_creg32(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt);
729
724 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); 730 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
725 config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1); 731 config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1);
726 732
@@ -810,6 +816,36 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
810{ 816{
811 u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); 817 u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
812 818
819 if (dd->ibsymdelta || dd->iblnkerrdelta ||
820 dd->ibdeltainprog) {
821 u64 diagc;
822 /* enable counter writes */
823 diagc = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwdiagctrl);
824 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl,
825 diagc | INFINIPATH_DC_COUNTERWREN);
826
827 if (dd->ibsymdelta || dd->ibdeltainprog) {
828 val = ipath_read_creg32(dd,
829 dd->ipath_cregs->cr_ibsymbolerrcnt);
830 if (dd->ibdeltainprog)
831 val -= val - dd->ibsymsnap;
832 val -= dd->ibsymdelta;
833 ipath_write_creg(dd,
834 dd->ipath_cregs->cr_ibsymbolerrcnt, val);
835 }
836 if (dd->iblnkerrdelta || dd->ibdeltainprog) {
837 val = ipath_read_creg32(dd,
838 dd->ipath_cregs->cr_iblinkerrrecovcnt);
839 if (dd->ibdeltainprog)
840 val -= val - dd->iblnkerrsnap;
841 val -= dd->iblnkerrdelta;
842 ipath_write_creg(dd,
843 dd->ipath_cregs->cr_iblinkerrrecovcnt, val);
844 }
845
846 /* and disable counter writes */
847 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, diagc);
848 }
813 val |= INFINIPATH_SERDC0_TXIDLE; 849 val |= INFINIPATH_SERDC0_TXIDLE;
814 ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n", 850 ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n",
815 (unsigned long long) val); 851 (unsigned long long) val);
@@ -1749,6 +1785,31 @@ static void ipath_pe_config_jint(struct ipath_devdata *dd, u16 a, u16 b)
1749 1785
1750static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) 1786static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
1751{ 1787{
1788 if (ibup) {
1789 if (dd->ibdeltainprog) {
1790 dd->ibdeltainprog = 0;
1791 dd->ibsymdelta +=
1792 ipath_read_creg32(dd,
1793 dd->ipath_cregs->cr_ibsymbolerrcnt) -
1794 dd->ibsymsnap;
1795 dd->iblnkerrdelta +=
1796 ipath_read_creg32(dd,
1797 dd->ipath_cregs->cr_iblinkerrrecovcnt) -
1798 dd->iblnkerrsnap;
1799 }
1800 } else {
1801 dd->ipath_lli_counter = 0;
1802 if (!dd->ibdeltainprog) {
1803 dd->ibdeltainprog = 1;
1804 dd->ibsymsnap =
1805 ipath_read_creg32(dd,
1806 dd->ipath_cregs->cr_ibsymbolerrcnt);
1807 dd->iblnkerrsnap =
1808 ipath_read_creg32(dd,
1809 dd->ipath_cregs->cr_iblinkerrrecovcnt);
1810 }
1811 }
1812
1752 ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs), 1813 ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs),
1753 ipath_ib_linktrstate(dd, ibcs)); 1814 ipath_ib_linktrstate(dd, ibcs));
1754 return 0; 1815 return 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index 9839e20119bc..3b38bc9a331d 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -951,6 +951,12 @@ static int ipath_7220_bringup_serdes(struct ipath_devdata *dd)
951 INFINIPATH_HWE_SERDESPLLFAILED); 951 INFINIPATH_HWE_SERDESPLLFAILED);
952 } 952 }
953 953
954 dd->ibdeltainprog = 1;
955 dd->ibsymsnap =
956 ipath_read_creg32(dd, dd->ipath_cregs->cr_ibsymbolerrcnt);
957 dd->iblnkerrsnap =
958 ipath_read_creg32(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt);
959
954 if (!dd->ipath_ibcddrctrl) { 960 if (!dd->ipath_ibcddrctrl) {
955 /* not on re-init after reset */ 961 /* not on re-init after reset */
956 dd->ipath_ibcddrctrl = 962 dd->ipath_ibcddrctrl =
@@ -1084,6 +1090,37 @@ static void ipath_7220_config_jint(struct ipath_devdata *dd,
1084static void ipath_7220_quiet_serdes(struct ipath_devdata *dd) 1090static void ipath_7220_quiet_serdes(struct ipath_devdata *dd)
1085{ 1091{
1086 u64 val; 1092 u64 val;
1093 if (dd->ibsymdelta || dd->iblnkerrdelta ||
1094 dd->ibdeltainprog) {
1095 u64 diagc;
1096 /* enable counter writes */
1097 diagc = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwdiagctrl);
1098 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl,
1099 diagc | INFINIPATH_DC_COUNTERWREN);
1100
1101 if (dd->ibsymdelta || dd->ibdeltainprog) {
1102 val = ipath_read_creg32(dd,
1103 dd->ipath_cregs->cr_ibsymbolerrcnt);
1104 if (dd->ibdeltainprog)
1105 val -= val - dd->ibsymsnap;
1106 val -= dd->ibsymdelta;
1107 ipath_write_creg(dd,
1108 dd->ipath_cregs->cr_ibsymbolerrcnt, val);
1109 }
1110 if (dd->iblnkerrdelta || dd->ibdeltainprog) {
1111 val = ipath_read_creg32(dd,
1112 dd->ipath_cregs->cr_iblinkerrrecovcnt);
1113 if (dd->ibdeltainprog)
1114 val -= val - dd->iblnkerrsnap;
1115 val -= dd->iblnkerrdelta;
1116 ipath_write_creg(dd,
1117 dd->ipath_cregs->cr_iblinkerrrecovcnt, val);
1118 }
1119
1120 /* and disable counter writes */
1121 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, diagc);
1122 }
1123
1087 dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; 1124 dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG;
1088 wake_up(&dd->ipath_autoneg_wait); 1125 wake_up(&dd->ipath_autoneg_wait);
1089 cancel_delayed_work(&dd->ipath_autoneg_work); 1126 cancel_delayed_work(&dd->ipath_autoneg_work);
@@ -2325,7 +2362,7 @@ static void try_auto_neg(struct ipath_devdata *dd)
2325 2362
2326static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) 2363static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2327{ 2364{
2328 int ret = 0; 2365 int ret = 0, symadj = 0;
2329 u32 ltstate = ipath_ib_linkstate(dd, ibcs); 2366 u32 ltstate = ipath_ib_linkstate(dd, ibcs);
2330 2367
2331 dd->ipath_link_width_active = 2368 dd->ipath_link_width_active =
@@ -2368,6 +2405,13 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2368 ipath_dbg("DDR negotiation try, %u/%u\n", 2405 ipath_dbg("DDR negotiation try, %u/%u\n",
2369 dd->ipath_autoneg_tries, 2406 dd->ipath_autoneg_tries,
2370 IPATH_AUTONEG_TRIES); 2407 IPATH_AUTONEG_TRIES);
2408 if (!dd->ibdeltainprog) {
2409 dd->ibdeltainprog = 1;
2410 dd->ibsymsnap = ipath_read_creg32(dd,
2411 dd->ipath_cregs->cr_ibsymbolerrcnt);
2412 dd->iblnkerrsnap = ipath_read_creg32(dd,
2413 dd->ipath_cregs->cr_iblinkerrrecovcnt);
2414 }
2371 try_auto_neg(dd); 2415 try_auto_neg(dd);
2372 ret = 1; /* no other IB status change processing */ 2416 ret = 1; /* no other IB status change processing */
2373 } else if ((dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) 2417 } else if ((dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)
@@ -2388,6 +2432,7 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2388 set_speed_fast(dd, 2432 set_speed_fast(dd,
2389 dd->ipath_link_speed_enabled); 2433 dd->ipath_link_speed_enabled);
2390 wake_up(&dd->ipath_autoneg_wait); 2434 wake_up(&dd->ipath_autoneg_wait);
2435 symadj = 1;
2391 } else if (dd->ipath_flags & IPATH_IB_AUTONEG_FAILED) { 2436 } else if (dd->ipath_flags & IPATH_IB_AUTONEG_FAILED) {
2392 /* 2437 /*
2393 * clear autoneg failure flag, and do setup 2438 * clear autoneg failure flag, and do setup
@@ -2403,6 +2448,7 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2403 IBA7220_IBC_IBTA_1_2_MASK; 2448 IBA7220_IBC_IBTA_1_2_MASK;
2404 ipath_write_kreg(dd, 2449 ipath_write_kreg(dd,
2405 IPATH_KREG_OFFSET(IBNCModeCtrl), 0); 2450 IPATH_KREG_OFFSET(IBNCModeCtrl), 0);
2451 symadj = 1;
2406 } 2452 }
2407 } 2453 }
2408 /* 2454 /*
@@ -2416,9 +2462,13 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2416 IB_WIDTH_4X)) == (IB_WIDTH_1X | IB_WIDTH_4X) 2462 IB_WIDTH_4X)) == (IB_WIDTH_1X | IB_WIDTH_4X)
2417 && dd->ipath_link_width_active == IB_WIDTH_1X 2463 && dd->ipath_link_width_active == IB_WIDTH_1X
2418 && dd->ipath_x1_fix_tries < 3) { 2464 && dd->ipath_x1_fix_tries < 3) {
2419 if (++dd->ipath_x1_fix_tries == 3) 2465 if (++dd->ipath_x1_fix_tries == 3) {
2420 dev_info(&dd->pcidev->dev, 2466 dev_info(&dd->pcidev->dev,
2421 "IB link is in 1X mode\n"); 2467 "IB link is in 1X mode\n");
2468 if (!(dd->ipath_flags &
2469 IPATH_IB_AUTONEG_INPROG))
2470 symadj = 1;
2471 }
2422 else { 2472 else {
2423 ipath_cdbg(VERBOSE, "IB 1X in " 2473 ipath_cdbg(VERBOSE, "IB 1X in "
2424 "auto-width, try %u to be " 2474 "auto-width, try %u to be "
@@ -2429,7 +2479,8 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2429 dd->ipath_f_xgxs_reset(dd); 2479 dd->ipath_f_xgxs_reset(dd);
2430 ret = 1; /* skip other processing */ 2480 ret = 1; /* skip other processing */
2431 } 2481 }
2432 } 2482 } else if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG))
2483 symadj = 1;
2433 2484
2434 if (!ret) { 2485 if (!ret) {
2435 dd->delay_mult = rate_to_delay 2486 dd->delay_mult = rate_to_delay
@@ -2440,6 +2491,25 @@ static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
2440 } 2491 }
2441 } 2492 }
2442 2493
2494 if (symadj) {
2495 if (dd->ibdeltainprog) {
2496 dd->ibdeltainprog = 0;
2497 dd->ibsymdelta += ipath_read_creg32(dd,
2498 dd->ipath_cregs->cr_ibsymbolerrcnt) -
2499 dd->ibsymsnap;
2500 dd->iblnkerrdelta += ipath_read_creg32(dd,
2501 dd->ipath_cregs->cr_iblinkerrrecovcnt) -
2502 dd->iblnkerrsnap;
2503 }
2504 } else if (!ibup && !dd->ibdeltainprog
2505 && !(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)) {
2506 dd->ibdeltainprog = 1;
2507 dd->ibsymsnap = ipath_read_creg32(dd,
2508 dd->ipath_cregs->cr_ibsymbolerrcnt);
2509 dd->iblnkerrsnap = ipath_read_creg32(dd,
2510 dd->ipath_cregs->cr_iblinkerrrecovcnt);
2511 }
2512
2443 if (!ret) 2513 if (!ret)
2444 ipath_setup_7220_setextled(dd, ipath_ib_linkstate(dd, ibcs), 2514 ipath_setup_7220_setextled(dd, ipath_ib_linkstate(dd, ibcs),
2445 ltstate); 2515 ltstate);
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 0bd8bcb184a1..aa84153b731b 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -355,6 +355,19 @@ struct ipath_devdata {
355 /* errors masked because they occur too fast */ 355 /* errors masked because they occur too fast */
356 ipath_err_t ipath_maskederrs; 356 ipath_err_t ipath_maskederrs;
357 u64 ipath_lastlinkrecov; /* link recoveries at last ACTIVE */ 357 u64 ipath_lastlinkrecov; /* link recoveries at last ACTIVE */
358 /* these 5 fields are used to establish deltas for IB Symbol
359 * errors and linkrecovery errors. They can be reported on
360 * some chips during link negotiation prior to INIT, and with
361 * DDR when faking DDR negotiations with non-IBTA switches.
362 * The chip counters are adjusted at driver unload if there is
363 * a non-zero delta.
364 */
365 u64 ibdeltainprog;
366 u64 ibsymdelta;
367 u64 ibsymsnap;
368 u64 iblnkerrdelta;
369 u64 iblnkerrsnap;
370
358 /* time in jiffies at which to re-enable maskederrs */ 371 /* time in jiffies at which to re-enable maskederrs */
359 unsigned long ipath_unmasktime; 372 unsigned long ipath_unmasktime;
360 /* count of egrfull errors, combined for all ports */ 373 /* count of egrfull errors, combined for all ports */
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c
index c8e3d65f0de8..f63e143e3292 100644
--- a/drivers/infiniband/hw/ipath/ipath_stats.c
+++ b/drivers/infiniband/hw/ipath/ipath_stats.c
@@ -112,6 +112,14 @@ u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg)
112 dd->ipath_lastrpkts = val; 112 dd->ipath_lastrpkts = val;
113 } 113 }
114 val64 = dd->ipath_rpkts; 114 val64 = dd->ipath_rpkts;
115 } else if (creg == dd->ipath_cregs->cr_ibsymbolerrcnt) {
116 if (dd->ibdeltainprog)
117 val64 -= val64 - dd->ibsymsnap;
118 val64 -= dd->ibsymdelta;
119 } else if (creg == dd->ipath_cregs->cr_iblinkerrrecovcnt) {
120 if (dd->ibdeltainprog)
121 val64 -= val64 - dd->iblnkerrsnap;
122 val64 -= dd->iblnkerrdelta;
115 } else 123 } else
116 val64 = (u64) val; 124 val64 = (u64) val;
117 125