xref: /OK3568_Linux_fs/kernel/Documentation/admin-guide/thunderbolt.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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