thunderbolt: Changes for v6.10 merge window
This includes following USB4/Thunderbolt changes for the v6.10 merge window: - Enable NVM firmare upgrade on Intel Maple Ridge Thunderbolt 4 controller - Improve USB3 tunnel bandwidth calculation - Improve sideband access - Minor cleanups and fixes. All these have been in linux-next with no reported issues. -----BEGIN PGP SIGNATURE----- iQJUBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAmY9p68gHG1pa2Eud2Vz dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKAncQ/7BHfSiGFgAxo0 COALJ0sChaYBT7qOfnf6QVJv6jPV1pfRx21FrTwjbwQXGZVT+Q2QmMK66TvHviO2 5pCeJdpdphMpUR5ZQE1USY4Ig3DW3TBmDEx2HxtdOzl7ot60eVQNpcnrrp+wWJNO ha1tWnDt2mTVsZoASDReztdZCZbZXS0zW3ODdfXMqaeRxI+/IwvmfmRo5YvL6qBG ChdMHTMKEgPSvZY918fMVoJi46ugOiTJgXfk4X7fmGeRIMUPpcU5k6hk9TDxK9bV L2Xi930AhSACzTNto+mLEyfdNeErkot2V4Yhx5OVaKPpLdjOjN6p1Lrh5GkcgP+F mGG1as793JZX7VyBDrIhWp2wglELqQcZKTlmQJkuXPXyDCfLWeJTaqKDx9z1de4s w0ltpS5cgDyeCRNLTTmY5ARq+CyUVMb/tE687ZkqWrrxYRaMfsHCZe0pupZgPVKA OzH9ItC1xlDf7ErpiZI6whOeTunJ9pBRvhQmx2m5MYq+Gcs/kC/EH0NMO6nTjLz5 7bbTiih7WMgJUFR953dUbC/LqAo0Xg5V2dSlSU+rAJWQ4ocOVRasCK3jxp9StMzf bdaJZbD7mDR5BT/xVhMYDYZnZiG2huwPag6L1OXyRSVPl1RLJpznIu3TvcqcunLN MQPZKiW3S3tGPYlRmAhxmi+M2nwdbP4= =fiCC -----END PGP SIGNATURE----- Merge tag 'thunderbolt-for-v6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next Mika writes: thunderbolt: Changes for v6.10 merge window This includes following USB4/Thunderbolt changes for the v6.10 merge window: - Enable NVM firmare upgrade on Intel Maple Ridge Thunderbolt 4 controller - Improve USB3 tunnel bandwidth calculation - Improve sideband access - Minor cleanups and fixes. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Correct trace output of firmware connection manager packets thunderbolt: Fix kernel-doc for tb_tunnel_alloc_dp() thunderbolt: Fix uninitialized variable in tb_tunnel_alloc_usb3() thunderbolt: There are only 5 basic router registers in pre-USB4 routers thunderbolt: No need to loop over all retimers if access fails thunderbolt: Increase sideband access polling delay thunderbolt: Get rid of TB_CFG_PKG_PREPARE_TO_SLEEP thunderbolt: Use correct error code with ERROR_NOT_SUPPORTED thunderbolt: Allow USB3 bandwidth to be lower than maximum supported thunderbolt: Fix calculation of consumed USB3 bandwidth on a path thunderbolt: Enable NVM upgrade support on Intel Maple Ridge
This commit is contained in:
commit
e4306116b5
@ -1346,7 +1346,7 @@ static int switch_basic_regs_show(struct tb_switch *sw, struct seq_file *s)
|
||||
if (tb_switch_is_usb4(sw))
|
||||
dwords = ARRAY_SIZE(data);
|
||||
else
|
||||
dwords = 7;
|
||||
dwords = 5;
|
||||
|
||||
ret = tb_sw_read(sw, data, TB_CFG_SWITCH, 0, dwords);
|
||||
if (ret)
|
||||
|
@ -2532,6 +2532,7 @@ struct tb *icm_probe(struct tb_nhi *nhi)
|
||||
|
||||
case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI:
|
||||
case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI:
|
||||
icm->can_upgrade_nvm = true;
|
||||
icm->is_supported = icm_tgl_is_supported;
|
||||
icm->get_mode = icm_ar_get_mode;
|
||||
icm->driver_ready = icm_tr_driver_ready;
|
||||
|
@ -199,8 +199,10 @@ static void tb_retimer_nvm_authenticate_status(struct tb_port *port, u32 *status
|
||||
* If the retimer has it set, store it for the new retimer
|
||||
* device instance.
|
||||
*/
|
||||
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
|
||||
usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]);
|
||||
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
|
||||
if (usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
|
||||
@ -234,8 +236,10 @@ static void tb_retimer_unset_inbound_sbtx(struct tb_port *port)
|
||||
|
||||
tb_port_dbg(port, "disabling sideband transactions\n");
|
||||
|
||||
for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--)
|
||||
usb4_port_retimer_unset_inbound_sbtx(port, i);
|
||||
for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--) {
|
||||
if (usb4_port_retimer_unset_inbound_sbtx(port, i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t nvm_authenticate_store(struct device *dev,
|
||||
|
@ -498,8 +498,9 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb,
|
||||
* @consumed_down: Consumed downstream bandwidth (Mb/s)
|
||||
*
|
||||
* Calculates consumed USB3 and PCIe bandwidth at @port between path
|
||||
* from @src_port to @dst_port. Does not take tunnel starting from
|
||||
* @src_port and ending from @src_port into account.
|
||||
* from @src_port to @dst_port. Does not take USB3 tunnel starting from
|
||||
* @src_port and ending on @src_port into account because that bandwidth is
|
||||
* already included in as part of the "first hop" USB3 tunnel.
|
||||
*/
|
||||
static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb,
|
||||
struct tb_port *src_port,
|
||||
@ -514,8 +515,8 @@ static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb,
|
||||
*consumed_up = *consumed_down = 0;
|
||||
|
||||
tunnel = tb_find_first_usb3_tunnel(tb, src_port, dst_port);
|
||||
if (tunnel && tunnel->src_port != src_port &&
|
||||
tunnel->dst_port != dst_port) {
|
||||
if (tunnel && !tb_port_is_usb3_down(src_port) &&
|
||||
!tb_port_is_usb3_up(dst_port)) {
|
||||
int ret;
|
||||
|
||||
ret = tb_tunnel_consumed_bandwidth(tunnel, consumed_up,
|
||||
|
@ -98,12 +98,6 @@ struct cfg_reset_pkg {
|
||||
struct tb_cfg_header header;
|
||||
} __packed;
|
||||
|
||||
/* TB_CFG_PKG_PREPARE_TO_SLEEP */
|
||||
struct cfg_pts_pkg {
|
||||
struct tb_cfg_header header;
|
||||
u32 data;
|
||||
} __packed;
|
||||
|
||||
/* ICM messages */
|
||||
|
||||
enum icm_pkg_code {
|
||||
|
@ -87,23 +87,32 @@ static inline const char *show_data(struct trace_seq *p, u8 type,
|
||||
const char *prefix = "";
|
||||
int i;
|
||||
|
||||
show_route(p, data);
|
||||
|
||||
switch (type) {
|
||||
case TB_CFG_PKG_READ:
|
||||
case TB_CFG_PKG_WRITE:
|
||||
show_route(p, data);
|
||||
show_data_read_write(p, data);
|
||||
break;
|
||||
|
||||
case TB_CFG_PKG_ERROR:
|
||||
show_route(p, data);
|
||||
show_data_error(p, data);
|
||||
break;
|
||||
|
||||
case TB_CFG_PKG_EVENT:
|
||||
show_route(p, data);
|
||||
show_data_event(p, data);
|
||||
break;
|
||||
|
||||
case TB_CFG_PKG_ICM_EVENT:
|
||||
case TB_CFG_PKG_ICM_CMD:
|
||||
case TB_CFG_PKG_ICM_RESP:
|
||||
/* ICM messages always target the host router */
|
||||
trace_seq_puts(p, "route=0, ");
|
||||
break;
|
||||
|
||||
default:
|
||||
show_route(p, data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1435,10 +1435,10 @@ err_free:
|
||||
* @in: DP in adapter port
|
||||
* @out: DP out adapter port
|
||||
* @link_nr: Preferred lane adapter when the link is not bonded
|
||||
* @max_up: Maximum available upstream bandwidth for the DP tunnel (%0
|
||||
* if not limited)
|
||||
* @max_down: Maximum available downstream bandwidth for the DP tunnel
|
||||
* (%0 if not limited)
|
||||
* @max_up: Maximum available upstream bandwidth for the DP tunnel.
|
||||
* %0 if no available bandwidth.
|
||||
* @max_down: Maximum available downstream bandwidth for the DP tunnel.
|
||||
* %0 if no available bandwidth.
|
||||
*
|
||||
* Allocates a tunnel between @in and @out that is capable of tunneling
|
||||
* Display Port traffic.
|
||||
@ -2048,10 +2048,10 @@ err_free:
|
||||
* @tb: Pointer to the domain structure
|
||||
* @up: USB3 upstream adapter port
|
||||
* @down: USB3 downstream adapter port
|
||||
* @max_up: Maximum available upstream bandwidth for the USB3 tunnel (%0
|
||||
* if not limited).
|
||||
* @max_down: Maximum available downstream bandwidth for the USB3 tunnel
|
||||
* (%0 if not limited).
|
||||
* @max_up: Maximum available upstream bandwidth for the USB3 tunnel.
|
||||
* %0 if no available bandwidth.
|
||||
* @max_down: Maximum available downstream bandwidth for the USB3 tunnel.
|
||||
* %0 if no available bandwidth.
|
||||
*
|
||||
* Allocate an USB3 tunnel. The ports must be of type @TB_TYPE_USB3_UP and
|
||||
* @TB_TYPE_USB3_DOWN.
|
||||
@ -2066,24 +2066,19 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
|
||||
struct tb_path *path;
|
||||
int max_rate = 0;
|
||||
|
||||
if (!tb_route(down->sw) && (max_up > 0 || max_down > 0)) {
|
||||
/*
|
||||
* Check that we have enough bandwidth available for the new
|
||||
* USB3 tunnel.
|
||||
* For USB3 isochronous transfers, we allow bandwidth which is
|
||||
* not higher than 90% of maximum supported bandwidth by USB3
|
||||
* adapters.
|
||||
*/
|
||||
if (max_up > 0 || max_down > 0) {
|
||||
max_rate = tb_usb3_max_link_rate(down, up);
|
||||
if (max_rate < 0)
|
||||
return NULL;
|
||||
|
||||
/* Only 90% can be allocated for USB3 isochronous transfers */
|
||||
max_rate = max_rate * 90 / 100;
|
||||
tb_port_dbg(up, "required bandwidth for USB3 tunnel %d Mb/s\n",
|
||||
tb_port_dbg(up, "maximum required bandwidth for USB3 tunnel %d Mb/s\n",
|
||||
max_rate);
|
||||
|
||||
if (max_rate > max_up || max_rate > max_down) {
|
||||
tb_port_warn(up, "not enough bandwidth for USB3 tunnel\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
tunnel = tb_tunnel_alloc(tb, 2, TB_TUNNEL_USB3);
|
||||
@ -2115,8 +2110,8 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
|
||||
tunnel->paths[TB_USB3_PATH_UP] = path;
|
||||
|
||||
if (!tb_route(down->sw)) {
|
||||
tunnel->allocated_up = max_rate;
|
||||
tunnel->allocated_down = max_rate;
|
||||
tunnel->allocated_up = min(max_rate, max_up);
|
||||
tunnel->allocated_down = min(max_rate, max_down);
|
||||
|
||||
tunnel->init = tb_usb3_init;
|
||||
tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth;
|
||||
|
@ -52,6 +52,10 @@ enum usb4_ba_index {
|
||||
#define USB4_BA_VALUE_MASK GENMASK(31, 16)
|
||||
#define USB4_BA_VALUE_SHIFT 16
|
||||
|
||||
/* Delays in us used with usb4_port_wait_for_bit() */
|
||||
#define USB4_PORT_DELAY 50
|
||||
#define USB4_PORT_SB_DELAY 5000
|
||||
|
||||
static int usb4_native_switch_op(struct tb_switch *sw, u16 opcode,
|
||||
u32 *metadata, u8 *status,
|
||||
const void *tx_data, size_t tx_dwords,
|
||||
@ -1245,7 +1249,7 @@ void usb4_port_unconfigure_xdomain(struct tb_port *port)
|
||||
}
|
||||
|
||||
static int usb4_port_wait_for_bit(struct tb_port *port, u32 offset, u32 bit,
|
||||
u32 value, int timeout_msec)
|
||||
u32 value, int timeout_msec, unsigned long delay_usec)
|
||||
{
|
||||
ktime_t timeout = ktime_add_ms(ktime_get(), timeout_msec);
|
||||
|
||||
@ -1260,7 +1264,7 @@ static int usb4_port_wait_for_bit(struct tb_port *port, u32 offset, u32 bit,
|
||||
if ((val & bit) == value)
|
||||
return 0;
|
||||
|
||||
usleep_range(50, 100);
|
||||
fsleep(delay_usec);
|
||||
} while (ktime_before(ktime_get(), timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
@ -1308,7 +1312,7 @@ static int usb4_port_sb_read(struct tb_port *port, enum usb4_sb_target target,
|
||||
return ret;
|
||||
|
||||
ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_1,
|
||||
PORT_CS_1_PND, 0, 500);
|
||||
PORT_CS_1_PND, 0, 500, USB4_PORT_SB_DELAY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1355,7 +1359,7 @@ static int usb4_port_sb_write(struct tb_port *port, enum usb4_sb_target target,
|
||||
return ret;
|
||||
|
||||
ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_1,
|
||||
PORT_CS_1_PND, 0, 500);
|
||||
PORT_CS_1_PND, 0, 500, USB4_PORT_SB_DELAY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1410,6 +1414,8 @@ static int usb4_port_sb_op(struct tb_port *port, enum usb4_sb_target target,
|
||||
|
||||
if (val != opcode)
|
||||
return usb4_port_sb_opcode_err_to_errno(val);
|
||||
|
||||
fsleep(USB4_PORT_SB_DELAY);
|
||||
} while (ktime_before(ktime_get(), timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
@ -1591,13 +1597,14 @@ int usb4_port_asym_start(struct tb_port *port)
|
||||
* port started the symmetry transition.
|
||||
*/
|
||||
ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_19,
|
||||
PORT_CS_19_START_ASYM, 0, 1000);
|
||||
PORT_CS_19_START_ASYM, 0, 1000,
|
||||
USB4_PORT_DELAY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Then wait for the transtion to be completed */
|
||||
return usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_18,
|
||||
PORT_CS_18_TIP, 0, 5000);
|
||||
PORT_CS_18_TIP, 0, 5000, USB4_PORT_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2123,7 +2130,8 @@ static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)
|
||||
*/
|
||||
val &= ADP_USB3_CS_2_CMR;
|
||||
return usb4_port_wait_for_bit(port, port->cap_adap + ADP_USB3_CS_1,
|
||||
ADP_USB3_CS_1_HCA, val, 1500);
|
||||
ADP_USB3_CS_1_HCA, val, 1500,
|
||||
USB4_PORT_DELAY);
|
||||
}
|
||||
|
||||
static inline int usb4_usb3_port_set_cm_request(struct tb_port *port)
|
||||
|
@ -250,7 +250,7 @@ static int tb_xdp_handle_error(const struct tb_xdp_error_response *res)
|
||||
case ERROR_UNKNOWN_DOMAIN:
|
||||
return -EIO;
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
case ERROR_NOT_READY:
|
||||
return -EAGAIN;
|
||||
default:
|
||||
|
@ -33,7 +33,6 @@ enum tb_cfg_pkg_type {
|
||||
TB_CFG_PKG_ICM_EVENT = 10,
|
||||
TB_CFG_PKG_ICM_CMD = 11,
|
||||
TB_CFG_PKG_ICM_RESP = 12,
|
||||
TB_CFG_PKG_PREPARE_TO_SLEEP = 13,
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user