Skip to content

Commit

Permalink
thunderbolt: Update port credits after bonding is enabled/disabled
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
westeri committed Jun 1, 2021
1 parent 56ad3ae commit 69fea37
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
48 changes: 48 additions & 0 deletions drivers/thunderbolt/switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,49 @@ int tb_port_wait_for_link_width(struct tb_port *port, int width,
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;
Expand Down Expand Up @@ -2494,6 +2537,8 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw)
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");
Expand Down Expand Up @@ -2531,7 +2576,10 @@ void tb_switch_lane_bonding_disable(struct tb_switch *sw)
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");
}

Expand Down
1 change: 1 addition & 0 deletions drivers/thunderbolt/tb.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,7 @@ int tb_port_lane_bonding_enable(struct tb_port *port);
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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/thunderbolt/xdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,7 @@ int tb_xdomain_lane_bonding_enable(struct tb_xdomain *xd)
return ret;
}

tb_port_update_credits(port);
tb_xdomain_update_link_attributes(xd);

dev_dbg(&xd->dev, "lane bonding enabled\n");
Expand All @@ -1557,6 +1558,7 @@ void tb_xdomain_lane_bonding_disable(struct tb_xdomain *xd)
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");
Expand Down

0 comments on commit 69fea37

Please sign in to comment.