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 | ||
