return -ETIMEDOUT;
}
+static int tb_port_do_update_credits(struct tb_port *port)
+{
+ u32 nfc_credits;
+ int ret;
+
+ ret = tb_port_read(port, &nfc_credits, TB_CFG_PORT, ADP_CS_4, 1);
+ if (ret)
+ return ret;
+
+ if (nfc_credits != port->config.nfc_credits) {
+ u32 total;
+
+ total = (nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >>
+ ADP_CS_4_TOTAL_BUFFERS_SHIFT;
+
+ tb_port_dbg(port, "total credits changed %u -> %u\n",
+ port->total_credits, total);
+
+ port->config.nfc_credits = nfc_credits;
+ port->total_credits = total;
+ }
+
+ return 0;
+}
+
+/**
+ * tb_port_update_credits() - Re-read port total credits
+ * @port: Port to update
+ *
+ * After the link is bonded (or bonding was disabled) the port total
+ * credits may change, so this function needs to be called to re-read
+ * the credits. Updates also the second lane adapter.
+ */
+int tb_port_update_credits(struct tb_port *port)
+{
+ int ret;
+
+ ret = tb_port_do_update_credits(port);
+ if (ret)
+ return ret;
+ return tb_port_do_update_credits(port->dual_link_port);
+}
+
static int tb_port_start_lane_initialization(struct tb_port *port)
{
int ret;
return ret;
}
+ tb_port_update_credits(down);
+ tb_port_update_credits(up);
tb_switch_update_link_attributes(sw);
tb_sw_dbg(sw, "lane bonding enabled\n");
if (tb_port_wait_for_link_width(down, 1, 100) == -ETIMEDOUT)
tb_sw_warn(sw, "timeout disabling lane bonding\n");
+ tb_port_update_credits(down);
+ tb_port_update_credits(up);
tb_switch_update_link_attributes(sw);
+
tb_sw_dbg(sw, "lane bonding disabled\n");
}
void tb_port_lane_bonding_disable(struct tb_port *port);
int tb_port_wait_for_link_width(struct tb_port *port, int width,
int timeout_msec);
+int tb_port_update_credits(struct tb_port *port);
int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
return ret;
}
+ tb_port_update_credits(port);
tb_xdomain_update_link_attributes(xd);
dev_dbg(&xd->dev, "lane bonding enabled\n");
if (tb_port_wait_for_link_width(port, 1, 100) == -ETIMEDOUT)
tb_port_warn(port, "timeout disabling lane bonding\n");
tb_port_disable(port->dual_link_port);
+ tb_port_update_credits(port);
tb_xdomain_update_link_attributes(xd);
dev_dbg(&xd->dev, "lane bonding disabled\n");