diff options
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6120.c | 61 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba7220.c | 76 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 13 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_stats.c | 8 |
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 | ||
1750 | static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | 1786 | static 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, | |||
1084 | static void ipath_7220_quiet_serdes(struct ipath_devdata *dd) | 1090 | static 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 | ||
2326 | static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | 2363 | static 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 | ||