1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun====================== 4*4882a593Smuzhiyun USB4 and Thunderbolt 5*4882a593Smuzhiyun====================== 6*4882a593SmuzhiyunUSB4 is the public specification based on Thunderbolt 3 protocol with 7*4882a593Smuzhiyunsome differences at the register level among other things. Connection 8*4882a593Smuzhiyunmanager is an entity running on the host router (host controller) 9*4882a593Smuzhiyunresponsible for enumerating routers and establishing tunnels. A 10*4882a593Smuzhiyunconnection manager can be implemented either in firmware or software. 11*4882a593SmuzhiyunTypically PCs come with a firmware connection manager for Thunderbolt 3 12*4882a593Smuzhiyunand early USB4 capable systems. Apple systems on the other hand use 13*4882a593Smuzhiyunsoftware connection manager and the later USB4 compliant devices follow 14*4882a593Smuzhiyunthe suit. 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunThe Linux Thunderbolt driver supports both and can detect at runtime which 17*4882a593Smuzhiyunconnection manager implementation is to be used. To be on the safe side the 18*4882a593Smuzhiyunsoftware connection manager in Linux also advertises security level 19*4882a593Smuzhiyun``user`` which means PCIe tunneling is disabled by default. The 20*4882a593Smuzhiyundocumentation below applies to both implementations with the exception that 21*4882a593Smuzhiyunthe software connection manager only supports ``user`` security level and 22*4882a593Smuzhiyunis expected to be accompanied with an IOMMU based DMA protection. 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunSecurity levels and how to use them 25*4882a593Smuzhiyun----------------------------------- 26*4882a593SmuzhiyunThe interface presented here is not meant for end users. Instead there 27*4882a593Smuzhiyunshould be a userspace tool that handles all the low-level details, keeps 28*4882a593Smuzhiyuna database of the authorized devices and prompts users for new connections. 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunMore details about the sysfs interface for Thunderbolt devices can be 31*4882a593Smuzhiyunfound in ``Documentation/ABI/testing/sysfs-bus-thunderbolt``. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunThose users who just want to connect any device without any sort of 34*4882a593Smuzhiyunmanual work can add following line to 35*4882a593Smuzhiyun``/etc/udev/rules.d/99-local.rules``:: 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1" 38*4882a593Smuzhiyun 39*4882a593SmuzhiyunThis will authorize all devices automatically when they appear. However, 40*4882a593Smuzhiyunkeep in mind that this bypasses the security levels and makes the system 41*4882a593Smuzhiyunvulnerable to DMA attacks. 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunStarting with Intel Falcon Ridge Thunderbolt controller there are 4 44*4882a593Smuzhiyunsecurity levels available. Intel Titan Ridge added one more security level 45*4882a593Smuzhiyun(usbonly). The reason for these is the fact that the connected devices can 46*4882a593Smuzhiyunbe DMA masters and thus read contents of the host memory without CPU and OS 47*4882a593Smuzhiyunknowing about it. There are ways to prevent this by setting up an IOMMU but 48*4882a593Smuzhiyunit is not always available for various reasons. 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunThe security levels are as follows: 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun none 53*4882a593Smuzhiyun All devices are automatically connected by the firmware. No user 54*4882a593Smuzhiyun approval is needed. In BIOS settings this is typically called 55*4882a593Smuzhiyun *Legacy mode*. 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun user 58*4882a593Smuzhiyun User is asked whether the device is allowed to be connected. 59*4882a593Smuzhiyun Based on the device identification information available through 60*4882a593Smuzhiyun ``/sys/bus/thunderbolt/devices``, the user then can make the decision. 61*4882a593Smuzhiyun In BIOS settings this is typically called *Unique ID*. 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun secure 64*4882a593Smuzhiyun User is asked whether the device is allowed to be connected. In 65*4882a593Smuzhiyun addition to UUID the device (if it supports secure connect) is sent 66*4882a593Smuzhiyun a challenge that should match the expected one based on a random key 67*4882a593Smuzhiyun written to the ``key`` sysfs attribute. In BIOS settings this is 68*4882a593Smuzhiyun typically called *One time saved key*. 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun dponly 71*4882a593Smuzhiyun The firmware automatically creates tunnels for Display Port and 72*4882a593Smuzhiyun USB. No PCIe tunneling is done. In BIOS settings this is 73*4882a593Smuzhiyun typically called *Display Port Only*. 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun usbonly 76*4882a593Smuzhiyun The firmware automatically creates tunnels for the USB controller and 77*4882a593Smuzhiyun Display Port in a dock. All PCIe links downstream of the dock are 78*4882a593Smuzhiyun removed. 79*4882a593Smuzhiyun 80*4882a593SmuzhiyunThe current security level can be read from 81*4882a593Smuzhiyun``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is 82*4882a593Smuzhiyunthe Thunderbolt domain the host controller manages. There is typically 83*4882a593Smuzhiyunone domain per Thunderbolt host controller. 84*4882a593Smuzhiyun 85*4882a593SmuzhiyunIf the security level reads as ``user`` or ``secure`` the connected 86*4882a593Smuzhiyundevice must be authorized by the user before PCIe tunnels are created 87*4882a593Smuzhiyun(e.g the PCIe device appears). 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunEach Thunderbolt device plugged in will appear in sysfs under 90*4882a593Smuzhiyun``/sys/bus/thunderbolt/devices``. The device directory carries 91*4882a593Smuzhiyuninformation that can be used to identify the particular device, 92*4882a593Smuzhiyunincluding its name and UUID. 93*4882a593Smuzhiyun 94*4882a593SmuzhiyunAuthorizing devices when security level is ``user`` or ``secure`` 95*4882a593Smuzhiyun----------------------------------------------------------------- 96*4882a593SmuzhiyunWhen a device is plugged in it will appear in sysfs as follows:: 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/authorized - 0 99*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/device - 0x8004 100*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/device_name - Thunderbolt to FireWire Adapter 101*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/vendor - 0x1 102*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/vendor_name - Apple, Inc. 103*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-1/unique_id - e0376f00-0300-0100-ffff-ffffffffffff 104*4882a593Smuzhiyun 105*4882a593SmuzhiyunThe ``authorized`` attribute reads 0 which means no PCIe tunnels are 106*4882a593Smuzhiyuncreated yet. The user can authorize the device by simply entering:: 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun # echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized 109*4882a593Smuzhiyun 110*4882a593SmuzhiyunThis will create the PCIe tunnels and the device is now connected. 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunIf the device supports secure connect, and the domain security level is 113*4882a593Smuzhiyunset to ``secure``, it has an additional attribute ``key`` which can hold 114*4882a593Smuzhiyuna random 32-byte value used for authorization and challenging the device in 115*4882a593Smuzhiyunfuture connects:: 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/authorized - 0 118*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/device - 0x305 119*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/device_name - AKiTiO Thunder3 PCIe Box 120*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/key - 121*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/vendor - 0x41 122*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/vendor_name - inXtron 123*4882a593Smuzhiyun /sys/bus/thunderbolt/devices/0-3/unique_id - dc010000-0000-8508-a22d-32ca6421cb16 124*4882a593Smuzhiyun 125*4882a593SmuzhiyunNotice the key is empty by default. 126*4882a593Smuzhiyun 127*4882a593SmuzhiyunIf the user does not want to use secure connect they can just ``echo 1`` 128*4882a593Smuzhiyunto the ``authorized`` attribute and the PCIe tunnels will be created in 129*4882a593Smuzhiyunthe same way as in the ``user`` security level. 130*4882a593Smuzhiyun 131*4882a593SmuzhiyunIf the user wants to use secure connect, the first time the device is 132*4882a593Smuzhiyunplugged a key needs to be created and sent to the device:: 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun # key=$(openssl rand -hex 32) 135*4882a593Smuzhiyun # echo $key > /sys/bus/thunderbolt/devices/0-3/key 136*4882a593Smuzhiyun # echo 1 > /sys/bus/thunderbolt/devices/0-3/authorized 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunNow the device is connected (PCIe tunnels are created) and in addition 139*4882a593Smuzhiyunthe key is stored on the device NVM. 140*4882a593Smuzhiyun 141*4882a593SmuzhiyunNext time the device is plugged in the user can verify (challenge) the 142*4882a593Smuzhiyundevice using the same key:: 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun # echo $key > /sys/bus/thunderbolt/devices/0-3/key 145*4882a593Smuzhiyun # echo 2 > /sys/bus/thunderbolt/devices/0-3/authorized 146*4882a593Smuzhiyun 147*4882a593SmuzhiyunIf the challenge the device returns back matches the one we expect based 148*4882a593Smuzhiyunon the key, the device is connected and the PCIe tunnels are created. 149*4882a593SmuzhiyunHowever, if the challenge fails no tunnels are created and error is 150*4882a593Smuzhiyunreturned to the user. 151*4882a593Smuzhiyun 152*4882a593SmuzhiyunIf the user still wants to connect the device they can either approve 153*4882a593Smuzhiyunthe device without a key or write a new key and write 1 to the 154*4882a593Smuzhiyun``authorized`` file to get the new key stored on the device NVM. 155*4882a593Smuzhiyun 156*4882a593SmuzhiyunDMA protection utilizing IOMMU 157*4882a593Smuzhiyun------------------------------ 158*4882a593SmuzhiyunRecent systems from 2018 and forward with Thunderbolt ports may natively 159*4882a593Smuzhiyunsupport IOMMU. This means that Thunderbolt security is handled by an IOMMU 160*4882a593Smuzhiyunso connected devices cannot access memory regions outside of what is 161*4882a593Smuzhiyunallocated for them by drivers. When Linux is running on such system it 162*4882a593Smuzhiyunautomatically enables IOMMU if not enabled by the user already. These 163*4882a593Smuzhiyunsystems can be identified by reading ``1`` from 164*4882a593Smuzhiyun``/sys/bus/thunderbolt/devices/domainX/iommu_dma_protection`` attribute. 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunThe driver does not do anything special in this case but because DMA 167*4882a593Smuzhiyunprotection is handled by the IOMMU, security levels (if set) are 168*4882a593Smuzhiyunredundant. For this reason some systems ship with security level set to 169*4882a593Smuzhiyun``none``. Other systems have security level set to ``user`` in order to 170*4882a593Smuzhiyunsupport downgrade to older OS, so users who want to automatically 171*4882a593Smuzhiyunauthorize devices when IOMMU DMA protection is enabled can use the 172*4882a593Smuzhiyunfollowing ``udev`` rule:: 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun ACTION=="add", SUBSYSTEM=="thunderbolt", ATTRS{iommu_dma_protection}=="1", ATTR{authorized}=="0", ATTR{authorized}="1" 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunUpgrading NVM on Thunderbolt device, host or retimer 177*4882a593Smuzhiyun---------------------------------------------------- 178*4882a593SmuzhiyunSince most of the functionality is handled in firmware running on a 179*4882a593Smuzhiyunhost controller or a device, it is important that the firmware can be 180*4882a593Smuzhiyunupgraded to the latest where possible bugs in it have been fixed. 181*4882a593SmuzhiyunTypically OEMs provide this firmware from their support site. 182*4882a593Smuzhiyun 183*4882a593SmuzhiyunThere is also a central site which has links where to download firmware 184*4882a593Smuzhiyunfor some machines: 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun `Thunderbolt Updates <https://thunderbolttechnology.net/updates>`_ 187*4882a593Smuzhiyun 188*4882a593SmuzhiyunBefore you upgrade firmware on a device, host or retimer, please make 189*4882a593Smuzhiyunsure it is a suitable upgrade. Failing to do that may render the device 190*4882a593Smuzhiyunin a state where it cannot be used properly anymore without special 191*4882a593Smuzhiyuntools! 192*4882a593Smuzhiyun 193*4882a593SmuzhiyunHost NVM upgrade on Apple Macs is not supported. 194*4882a593Smuzhiyun 195*4882a593SmuzhiyunOnce the NVM image has been downloaded, you need to plug in a 196*4882a593SmuzhiyunThunderbolt device so that the host controller appears. It does not 197*4882a593Smuzhiyunmatter which device is connected (unless you are upgrading NVM on a 198*4882a593Smuzhiyundevice - then you need to connect that particular device). 199*4882a593Smuzhiyun 200*4882a593SmuzhiyunNote an OEM-specific method to power the controller up ("force power") may 201*4882a593Smuzhiyunbe available for your system in which case there is no need to plug in a 202*4882a593SmuzhiyunThunderbolt device. 203*4882a593Smuzhiyun 204*4882a593SmuzhiyunAfter that we can write the firmware to the non-active parts of the NVM 205*4882a593Smuzhiyunof the host or device. As an example here is how Intel NUC6i7KYK (Skull 206*4882a593SmuzhiyunCanyon) Thunderbolt controller NVM is upgraded:: 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun # dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-0/nvm_non_active0/nvmem 209*4882a593Smuzhiyun 210*4882a593SmuzhiyunOnce the operation completes we can trigger NVM authentication and 211*4882a593Smuzhiyunupgrade process as follows:: 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun # echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate 214*4882a593Smuzhiyun 215*4882a593SmuzhiyunIf no errors are returned, the host controller shortly disappears. Once 216*4882a593Smuzhiyunit comes back the driver notices it and initiates a full power cycle. 217*4882a593SmuzhiyunAfter a while the host controller appears again and this time it should 218*4882a593Smuzhiyunbe fully functional. 219*4882a593Smuzhiyun 220*4882a593SmuzhiyunWe can verify that the new NVM firmware is active by running the following 221*4882a593Smuzhiyuncommands:: 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun # cat /sys/bus/thunderbolt/devices/0-0/nvm_authenticate 224*4882a593Smuzhiyun 0x0 225*4882a593Smuzhiyun # cat /sys/bus/thunderbolt/devices/0-0/nvm_version 226*4882a593Smuzhiyun 18.0 227*4882a593Smuzhiyun 228*4882a593SmuzhiyunIf ``nvm_authenticate`` contains anything other than 0x0 it is the error 229*4882a593Smuzhiyuncode from the last authentication cycle, which means the authentication 230*4882a593Smuzhiyunof the NVM image failed. 231*4882a593Smuzhiyun 232*4882a593SmuzhiyunNote names of the NVMem devices ``nvm_activeN`` and ``nvm_non_activeN`` 233*4882a593Smuzhiyundepend on the order they are registered in the NVMem subsystem. N in 234*4882a593Smuzhiyunthe name is the identifier added by the NVMem subsystem. 235*4882a593Smuzhiyun 236*4882a593SmuzhiyunUpgrading NVM when host controller is in safe mode 237*4882a593Smuzhiyun-------------------------------------------------- 238*4882a593SmuzhiyunIf the existing NVM is not properly authenticated (or is missing) the 239*4882a593Smuzhiyunhost controller goes into safe mode which means that the only available 240*4882a593Smuzhiyunfunctionality is flashing a new NVM image. When in this mode, reading 241*4882a593Smuzhiyun``nvm_version`` fails with ``ENODATA`` and the device identification 242*4882a593Smuzhiyuninformation is missing. 243*4882a593Smuzhiyun 244*4882a593SmuzhiyunTo recover from this mode, one needs to flash a valid NVM image to the 245*4882a593Smuzhiyunhost controller in the same way it is done in the previous chapter. 246*4882a593Smuzhiyun 247*4882a593SmuzhiyunNetworking over Thunderbolt cable 248*4882a593Smuzhiyun--------------------------------- 249*4882a593SmuzhiyunThunderbolt technology allows software communication between two hosts 250*4882a593Smuzhiyunconnected by a Thunderbolt cable. 251*4882a593Smuzhiyun 252*4882a593SmuzhiyunIt is possible to tunnel any kind of traffic over a Thunderbolt link but 253*4882a593Smuzhiyuncurrently we only support Apple ThunderboltIP protocol. 254*4882a593Smuzhiyun 255*4882a593SmuzhiyunIf the other host is running Windows or macOS, the only thing you need to 256*4882a593Smuzhiyundo is to connect a Thunderbolt cable between the two hosts; the 257*4882a593Smuzhiyun``thunderbolt-net`` driver is loaded automatically. If the other host is 258*4882a593Smuzhiyunalso Linux you should load ``thunderbolt-net`` manually on one host (it 259*4882a593Smuzhiyundoes not matter which one):: 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun # modprobe thunderbolt-net 262*4882a593Smuzhiyun 263*4882a593SmuzhiyunThis triggers module load on the other host automatically. If the driver 264*4882a593Smuzhiyunis built-in to the kernel image, there is no need to do anything. 265*4882a593Smuzhiyun 266*4882a593SmuzhiyunThe driver will create one virtual ethernet interface per Thunderbolt 267*4882a593Smuzhiyunport which are named like ``thunderbolt0`` and so on. From this point 268*4882a593Smuzhiyunyou can either use standard userspace tools like ``ifconfig`` to 269*4882a593Smuzhiyunconfigure the interface or let your GUI handle it automatically. 270*4882a593Smuzhiyun 271*4882a593SmuzhiyunForcing power 272*4882a593Smuzhiyun------------- 273*4882a593SmuzhiyunMany OEMs include a method that can be used to force the power of a 274*4882a593SmuzhiyunThunderbolt controller to an "On" state even if nothing is connected. 275*4882a593SmuzhiyunIf supported by your machine this will be exposed by the WMI bus with 276*4882a593Smuzhiyuna sysfs attribute called "force_power". 277*4882a593Smuzhiyun 278*4882a593SmuzhiyunFor example the intel-wmi-thunderbolt driver exposes this attribute in: 279*4882a593Smuzhiyun /sys/bus/wmi/devices/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun To force the power to on, write 1 to this attribute file. 282*4882a593Smuzhiyun To disable force power, write 0 to this attribute file. 283*4882a593Smuzhiyun 284*4882a593SmuzhiyunNote: it's currently not possible to query the force power state of a platform. 285