Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thunderbolt: Update port credits after bonding is enabled/disabled

Once lane bonding has been enabled (or disabled) both lane adapters may
update their total credits accordingly. For this reason re-read the port
credits after lane bonding has been enabled or disabled.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

+51
+48
drivers/thunderbolt/switch.c
··· 1099 1099 return -ETIMEDOUT; 1100 1100 } 1101 1101 1102 + static int tb_port_do_update_credits(struct tb_port *port) 1103 + { 1104 + u32 nfc_credits; 1105 + int ret; 1106 + 1107 + ret = tb_port_read(port, &nfc_credits, TB_CFG_PORT, ADP_CS_4, 1); 1108 + if (ret) 1109 + return ret; 1110 + 1111 + if (nfc_credits != port->config.nfc_credits) { 1112 + u32 total; 1113 + 1114 + total = (nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >> 1115 + ADP_CS_4_TOTAL_BUFFERS_SHIFT; 1116 + 1117 + tb_port_dbg(port, "total credits changed %u -> %u\n", 1118 + port->total_credits, total); 1119 + 1120 + port->config.nfc_credits = nfc_credits; 1121 + port->total_credits = total; 1122 + } 1123 + 1124 + return 0; 1125 + } 1126 + 1127 + /** 1128 + * tb_port_update_credits() - Re-read port total credits 1129 + * @port: Port to update 1130 + * 1131 + * After the link is bonded (or bonding was disabled) the port total 1132 + * credits may change, so this function needs to be called to re-read 1133 + * the credits. Updates also the second lane adapter. 1134 + */ 1135 + int tb_port_update_credits(struct tb_port *port) 1136 + { 1137 + int ret; 1138 + 1139 + ret = tb_port_do_update_credits(port); 1140 + if (ret) 1141 + return ret; 1142 + return tb_port_do_update_credits(port->dual_link_port); 1143 + } 1144 + 1102 1145 static int tb_port_start_lane_initialization(struct tb_port *port) 1103 1146 { 1104 1147 int ret; ··· 2537 2494 return ret; 2538 2495 } 2539 2496 2497 + tb_port_update_credits(down); 2498 + tb_port_update_credits(up); 2540 2499 tb_switch_update_link_attributes(sw); 2541 2500 2542 2501 tb_sw_dbg(sw, "lane bonding enabled\n"); ··· 2576 2531 if (tb_port_wait_for_link_width(down, 1, 100) == -ETIMEDOUT) 2577 2532 tb_sw_warn(sw, "timeout disabling lane bonding\n"); 2578 2533 2534 + tb_port_update_credits(down); 2535 + tb_port_update_credits(up); 2579 2536 tb_switch_update_link_attributes(sw); 2537 + 2580 2538 tb_sw_dbg(sw, "lane bonding disabled\n"); 2581 2539 } 2582 2540
+1
drivers/thunderbolt/tb.h
··· 906 906 void tb_port_lane_bonding_disable(struct tb_port *port); 907 907 int tb_port_wait_for_link_width(struct tb_port *port, int width, 908 908 int timeout_msec); 909 + int tb_port_update_credits(struct tb_port *port); 909 910 910 911 int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec); 911 912 int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
+2
drivers/thunderbolt/xdomain.c
··· 1533 1533 return ret; 1534 1534 } 1535 1535 1536 + tb_port_update_credits(port); 1536 1537 tb_xdomain_update_link_attributes(xd); 1537 1538 1538 1539 dev_dbg(&xd->dev, "lane bonding enabled\n"); ··· 1558 1557 if (tb_port_wait_for_link_width(port, 1, 100) == -ETIMEDOUT) 1559 1558 tb_port_warn(port, "timeout disabling lane bonding\n"); 1560 1559 tb_port_disable(port->dual_link_port); 1560 + tb_port_update_credits(port); 1561 1561 tb_xdomain_update_link_attributes(xd); 1562 1562 1563 1563 dev_dbg(&xd->dev, "lane bonding disabled\n");