diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_iba7220.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba7220.c | 76 |
1 files changed, 73 insertions, 3 deletions
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); |