aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_iba7220.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_iba7220.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba7220.c76
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,
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);