Commit f0342e75 authored by Mika Westerberg's avatar Mika Westerberg

thunderbolt: Do not allocate switch if depth is greater than 6

Maximum depth in Thunderbolt topology is 6 so make sure it is not
possible to allocate switches that exceed the depth limit.

While at it update tb_switch_alloc() to use upper/lower_32_bits()
following tb_switch_alloc_safe_mode().
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 09f11b6c
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#define ICM_TIMEOUT 5000 /* ms */ #define ICM_TIMEOUT 5000 /* ms */
#define ICM_APPROVE_TIMEOUT 10000 /* ms */ #define ICM_APPROVE_TIMEOUT 10000 /* ms */
#define ICM_MAX_LINK 4 #define ICM_MAX_LINK 4
#define ICM_MAX_DEPTH 6
/** /**
* struct icm - Internal connection manager private data * struct icm - Internal connection manager private data
...@@ -714,7 +713,7 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) ...@@ -714,7 +713,7 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
ICM_LINK_INFO_DEPTH_SHIFT; ICM_LINK_INFO_DEPTH_SHIFT;
if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) { if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth); tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
return; return;
} }
...@@ -744,7 +743,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) ...@@ -744,7 +743,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
ICM_LINK_INFO_DEPTH_SHIFT; ICM_LINK_INFO_DEPTH_SHIFT;
if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) { if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth); tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
return; return;
} }
......
...@@ -1130,10 +1130,16 @@ static int tb_switch_get_generation(struct tb_switch *sw) ...@@ -1130,10 +1130,16 @@ static int tb_switch_get_generation(struct tb_switch *sw)
struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
u64 route) u64 route)
{ {
int i;
int cap;
struct tb_switch *sw; struct tb_switch *sw;
int upstream_port = tb_cfg_get_upstream_port(tb->ctl, route); int upstream_port;
int i, cap, depth;
/* Make sure we do not exceed maximum topology limit */
depth = tb_route_length(route);
if (depth > TB_SWITCH_MAX_DEPTH)
return NULL;
upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
if (upstream_port < 0) if (upstream_port < 0)
return NULL; return NULL;
...@@ -1150,9 +1156,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, ...@@ -1150,9 +1156,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
/* configure switch */ /* configure switch */
sw->config.upstream_port_number = upstream_port; sw->config.upstream_port_number = upstream_port;
sw->config.depth = tb_route_length(route); sw->config.depth = depth;
sw->config.route_lo = route; sw->config.route_hi = upper_32_bits(route);
sw->config.route_hi = route >> 32; sw->config.route_lo = lower_32_bits(route);
sw->config.enabled = 0; sw->config.enabled = 0;
/* initialize ports */ /* initialize ports */
......
...@@ -43,6 +43,7 @@ struct tb_switch_nvm { ...@@ -43,6 +43,7 @@ struct tb_switch_nvm {
}; };
#define TB_SWITCH_KEY_SIZE 32 #define TB_SWITCH_KEY_SIZE 32
#define TB_SWITCH_MAX_DEPTH 6
/** /**
* struct tb_switch - a thunderbolt switch * struct tb_switch - a thunderbolt switch
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment