summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/switch.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2020-11-10 11:34:07 +0300
committerMika Westerberg <mika.westerberg@linux.intel.com>2020-11-30 14:39:24 +0300
commit661b19473bf3ac0924560f0cbf84c15458b3c8de (patch)
tree32a36bb669b6a4bc3536f3386107a2853a01ec6e /drivers/thunderbolt/switch.c
parent463e48fa544826898791085508459de246fc4c09 (diff)
thunderbolt: Perform USB4 router NVM upgrade in two phases
The currect code expects that the router returns back the status of the NVM authentication immediately. When tested against a real USB4 device what happens is that the router is reset and only after that the result is updated in the ROUTER_CS_26 register status field. This also seems to align better what the spec suggests. For this reason do the same what we already do with the Thunderbolt 3 devices and perform the NVM upgrade in two phases. First start the NVM_AUTH router operation and once the router is added back after the reset read the status in ROUTER_CS_26 and expose it to the userspace accordingly. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/switch.c')
-rw-r--r--drivers/thunderbolt/switch.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index cdfd8cccfe19..a8572f49d3ad 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -2160,6 +2160,7 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
fallthrough;
case 3:
+ case 4:
ret = tb_switch_set_uuid(sw);
if (ret)
return ret;
@@ -2175,6 +2176,22 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
break;
}
+ if (sw->no_nvm_upgrade)
+ return 0;
+
+ if (tb_switch_is_usb4(sw)) {
+ ret = usb4_switch_nvm_authenticate_status(sw, &status);
+ if (ret)
+ return ret;
+
+ if (status) {
+ tb_sw_info(sw, "switch flash authentication failed\n");
+ nvm_set_auth_status(sw, status);
+ }
+
+ return 0;
+ }
+
/* Root switch DMA port requires running firmware */
if (!tb_route(sw) && !tb_switch_is_icm(sw))
return 0;
@@ -2183,9 +2200,6 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
if (!sw->dma_port)
return 0;
- if (sw->no_nvm_upgrade)
- return 0;
-
/*
* If there is status already set then authentication failed
* when the dma_port_flash_update_auth() returned. Power cycling