1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt driver - eeprom access
5 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
6 * Copyright (C) 2018, Intel Corporation
9 #include <linux/crc32.h>
10 #include <linux/delay.h>
11 #include <linux/property.h>
12 #include <linux/slab.h>
16 * tb_eeprom_ctl_write() - write control word
18 static int tb_eeprom_ctl_write(struct tb_switch
*sw
, struct tb_eeprom_ctl
*ctl
)
20 return tb_sw_write(sw
, ctl
, TB_CFG_SWITCH
, sw
->cap_plug_events
+ ROUTER_CS_4
, 1);
24 * tb_eeprom_ctl_write() - read control word
26 static int tb_eeprom_ctl_read(struct tb_switch
*sw
, struct tb_eeprom_ctl
*ctl
)
28 return tb_sw_read(sw
, ctl
, TB_CFG_SWITCH
, sw
->cap_plug_events
+ ROUTER_CS_4
, 1);
31 enum tb_eeprom_transfer
{
37 * tb_eeprom_active - enable rom access
39 * WARNING: Always disable access after usage. Otherwise the controller will
42 static int tb_eeprom_active(struct tb_switch
*sw
, bool enable
)
44 struct tb_eeprom_ctl ctl
;
45 int res
= tb_eeprom_ctl_read(sw
, &ctl
);
49 ctl
.bit_banging_enable
= 1;
50 res
= tb_eeprom_ctl_write(sw
, &ctl
);
54 return tb_eeprom_ctl_write(sw
, &ctl
);
57 res
= tb_eeprom_ctl_write(sw
, &ctl
);
60 ctl
.bit_banging_enable
= 0;
61 return tb_eeprom_ctl_write(sw
, &ctl
);
66 * tb_eeprom_transfer - transfer one bit
68 * If TB_EEPROM_IN is passed, then the bit can be retrieved from ctl->fl_do.
69 * If TB_EEPROM_OUT is passed, then ctl->fl_di will be written.
71 static int tb_eeprom_transfer(struct tb_switch
*sw
, struct tb_eeprom_ctl
*ctl
,
72 enum tb_eeprom_transfer direction
)
75 if (direction
== TB_EEPROM_OUT
) {
76 res
= tb_eeprom_ctl_write(sw
, ctl
);
81 res
= tb_eeprom_ctl_write(sw
, ctl
);
84 if (direction
== TB_EEPROM_IN
) {
85 res
= tb_eeprom_ctl_read(sw
, ctl
);
90 return tb_eeprom_ctl_write(sw
, ctl
);
94 * tb_eeprom_out - write one byte to the bus
96 static int tb_eeprom_out(struct tb_switch
*sw
, u8 val
)
98 struct tb_eeprom_ctl ctl
;
100 int res
= tb_eeprom_ctl_read(sw
, &ctl
);
103 for (i
= 0; i
< 8; i
++) {
104 ctl
.fl_di
= val
& 0x80;
105 res
= tb_eeprom_transfer(sw
, &ctl
, TB_EEPROM_OUT
);
114 * tb_eeprom_in - read one byte from the bus
116 static int tb_eeprom_in(struct tb_switch
*sw
, u8
*val
)
118 struct tb_eeprom_ctl ctl
;
120 int res
= tb_eeprom_ctl_read(sw
, &ctl
);
124 for (i
= 0; i
< 8; i
++) {
126 res
= tb_eeprom_transfer(sw
, &ctl
, TB_EEPROM_IN
);
135 * tb_eeprom_get_drom_offset - get drom offset within eeprom
137 static int tb_eeprom_get_drom_offset(struct tb_switch
*sw
, u16
*offset
)
139 struct tb_cap_plug_events cap
;
142 if (!sw
->cap_plug_events
) {
143 tb_sw_warn(sw
, "no TB_CAP_PLUG_EVENTS, cannot read eeprom\n");
146 res
= tb_sw_read(sw
, &cap
, TB_CFG_SWITCH
, sw
->cap_plug_events
,
151 if (!cap
.eeprom_ctl
.present
|| cap
.eeprom_ctl
.not_present
) {
152 tb_sw_warn(sw
, "no NVM\n");
156 if (cap
.drom_offset
> 0xffff) {
157 tb_sw_warn(sw
, "drom offset is larger than 0xffff: %#x\n",
161 *offset
= cap
.drom_offset
;
166 * tb_eeprom_read_n - read count bytes from offset into val
168 static int tb_eeprom_read_n(struct tb_switch
*sw
, u16 offset
, u8
*val
,
174 res
= tb_eeprom_get_drom_offset(sw
, &drom_offset
);
178 offset
+= drom_offset
;
180 res
= tb_eeprom_active(sw
, true);
183 res
= tb_eeprom_out(sw
, 3);
186 res
= tb_eeprom_out(sw
, offset
>> 8);
189 res
= tb_eeprom_out(sw
, offset
);
192 for (i
= 0; i
< count
; i
++) {
193 res
= tb_eeprom_in(sw
, val
+ i
);
197 return tb_eeprom_active(sw
, false);
200 static u8
tb_crc8(u8
*data
, int len
)
204 for (i
= 0; i
< len
; i
++) {
206 for (j
= 0; j
< 8; j
++)
207 val
= (val
<< 1) ^ ((val
& 0x80) ? 7 : 0);
212 static u32
tb_crc32(void *data
, size_t len
)
214 return ~__crc32c_le(~0, data
, len
);
217 #define TB_DROM_DATA_START 13
218 #define TB_DROM_HEADER_SIZE 22
219 #define USB4_DROM_HEADER_SIZE 16
221 struct tb_drom_header
{
223 u8 uid_crc8
; /* checksum for uid */
227 u32 data_crc32
; /* checksum for data_len bytes starting at byte 13 */
229 u8 device_rom_revision
; /* should be <= 1 */
232 /* BYTES 16-21 - Only for TBT DROM, nonexistent in USB4 DROM */
239 enum tb_drom_entry_type
{
240 /* force unsigned to prevent "one-bit signed bitfield" warning */
241 TB_DROM_ENTRY_GENERIC
= 0U,
245 struct tb_drom_entry_header
{
248 bool port_disabled
:1; /* only valid if type is TB_DROM_ENTRY_PORT */
249 enum tb_drom_entry_type type
:1;
252 struct tb_drom_entry_generic
{
253 struct tb_drom_entry_header header
;
257 struct tb_drom_entry_port
{
259 struct tb_drom_entry_header header
;
261 u8 dual_link_port_rid
:4;
264 bool has_dual_link_port
:1;
267 u8 dual_link_port_nr
:6;
270 /* BYTES 4 - 5 TODO decode */
275 /* BYTES 6-7, TODO: verify (find hardware that has these set) */
278 bool has_peer_port
:1;
283 /* USB4 product descriptor */
284 struct tb_drom_entry_desc
{
285 struct tb_drom_entry_header header
;
289 u16 bcdProductFWRevision
;
291 u8 productHWRevision
;
295 * tb_drom_read_uid_only() - Read UID directly from DROM
296 * @sw: Router whose UID to read
297 * @uid: UID is placed here
299 * Does not use the cached copy in sw->drom. Used during resume to check switch
302 int tb_drom_read_uid_only(struct tb_switch
*sw
, u64
*uid
)
309 res
= tb_eeprom_read_n(sw
, 0, data
, 9);
313 crc
= tb_crc8(data
+ 1, 8);
314 if (crc
!= data
[0]) {
315 tb_sw_warn(sw
, "uid crc8 mismatch (expected: %#x, got: %#x)\n",
320 *uid
= *(u64
*)(data
+1);
324 static int tb_drom_parse_entry_generic(struct tb_switch
*sw
,
325 struct tb_drom_entry_header
*header
)
327 const struct tb_drom_entry_generic
*entry
=
328 (const struct tb_drom_entry_generic
*)header
;
330 switch (header
->index
) {
332 /* Length includes 2 bytes header so remove it before copy */
333 sw
->vendor_name
= kstrndup(entry
->data
,
334 header
->len
- sizeof(*header
), GFP_KERNEL
);
335 if (!sw
->vendor_name
)
340 sw
->device_name
= kstrndup(entry
->data
,
341 header
->len
- sizeof(*header
), GFP_KERNEL
);
342 if (!sw
->device_name
)
346 const struct tb_drom_entry_desc
*desc
=
347 (const struct tb_drom_entry_desc
*)entry
;
349 if (!sw
->vendor
&& !sw
->device
) {
350 sw
->vendor
= desc
->idVendor
;
351 sw
->device
= desc
->idProduct
;
360 static int tb_drom_parse_entry_port(struct tb_switch
*sw
,
361 struct tb_drom_entry_header
*header
)
363 struct tb_port
*port
;
365 enum tb_port_type type
;
368 * Some DROMs list more ports than the controller actually has
369 * so we skip those but allow the parser to continue.
371 if (header
->index
> sw
->config
.max_port_number
) {
372 dev_info_once(&sw
->dev
, "ignoring unnecessary extra entries in DROM\n");
376 port
= &sw
->ports
[header
->index
];
377 port
->disabled
= header
->port_disabled
;
381 res
= tb_port_read(port
, &type
, TB_CFG_PORT
, 2, 1);
386 if (type
== TB_TYPE_PORT
) {
387 struct tb_drom_entry_port
*entry
= (void *) header
;
388 if (header
->len
!= sizeof(*entry
)) {
390 "port entry has size %#x (expected %#zx)\n",
391 header
->len
, sizeof(struct tb_drom_entry_port
));
394 port
->link_nr
= entry
->link_nr
;
395 if (entry
->has_dual_link_port
)
396 port
->dual_link_port
=
397 &port
->sw
->ports
[entry
->dual_link_port_nr
];
403 * tb_drom_parse_entries - parse the linked list of drom entries
405 * Drom must have been copied to sw->drom.
407 static int tb_drom_parse_entries(struct tb_switch
*sw
, size_t header_size
)
409 struct tb_drom_header
*header
= (void *) sw
->drom
;
410 u16 pos
= header_size
;
411 u16 drom_size
= header
->data_len
+ TB_DROM_DATA_START
;
414 while (pos
< drom_size
) {
415 struct tb_drom_entry_header
*entry
= (void *) (sw
->drom
+ pos
);
416 if (pos
+ 1 == drom_size
|| pos
+ entry
->len
> drom_size
418 tb_sw_warn(sw
, "DROM buffer overrun\n");
422 switch (entry
->type
) {
423 case TB_DROM_ENTRY_GENERIC
:
424 res
= tb_drom_parse_entry_generic(sw
, entry
);
426 case TB_DROM_ENTRY_PORT
:
427 res
= tb_drom_parse_entry_port(sw
, entry
);
439 * tb_drom_copy_efi - copy drom supplied by EFI to sw->drom if present
441 static int tb_drom_copy_efi(struct tb_switch
*sw
, u16
*size
)
443 struct device
*dev
= &sw
->tb
->nhi
->pdev
->dev
;
446 len
= device_property_count_u8(dev
, "ThunderboltDROM");
447 if (len
< 0 || len
< sizeof(struct tb_drom_header
))
450 sw
->drom
= kmalloc(len
, GFP_KERNEL
);
454 res
= device_property_read_u8_array(dev
, "ThunderboltDROM", sw
->drom
,
459 *size
= ((struct tb_drom_header
*)sw
->drom
)->data_len
+
472 static int tb_drom_copy_nvm(struct tb_switch
*sw
, u16
*size
)
480 ret
= tb_eeprom_get_drom_offset(sw
, &drom_offset
);
487 ret
= dma_port_flash_read(sw
->dma_port
, drom_offset
+ 14, size
,
492 /* Size includes CRC8 + UID + CRC32 */
494 sw
->drom
= kzalloc(*size
, GFP_KERNEL
);
498 ret
= dma_port_flash_read(sw
->dma_port
, drom_offset
, sw
->drom
, *size
);
503 * Read UID from the minimal DROM because the one in NVM is just
506 tb_drom_read_uid_only(sw
, &sw
->uid
);
515 static int usb4_copy_drom(struct tb_switch
*sw
, u16
*size
)
519 ret
= usb4_switch_drom_read(sw
, 14, size
, sizeof(*size
));
523 /* Size includes CRC8 + UID + CRC32 */
525 sw
->drom
= kzalloc(*size
, GFP_KERNEL
);
529 ret
= usb4_switch_drom_read(sw
, 0, sw
->drom
, *size
);
538 static int tb_drom_bit_bang(struct tb_switch
*sw
, u16
*size
)
542 ret
= tb_eeprom_read_n(sw
, 14, (u8
*)size
, 2);
547 *size
+= TB_DROM_DATA_START
;
549 tb_sw_dbg(sw
, "reading DROM (length: %#x)\n", *size
);
550 if (*size
< sizeof(struct tb_drom_header
)) {
551 tb_sw_warn(sw
, "DROM too small, aborting\n");
555 sw
->drom
= kzalloc(*size
, GFP_KERNEL
);
559 ret
= tb_eeprom_read_n(sw
, 0, sw
->drom
, *size
);
571 static int tb_drom_parse_v1(struct tb_switch
*sw
)
573 const struct tb_drom_header
*header
=
574 (const struct tb_drom_header
*)sw
->drom
;
577 crc
= tb_crc8((u8
*) &header
->uid
, 8);
578 if (crc
!= header
->uid_crc8
) {
580 "DROM UID CRC8 mismatch (expected: %#x, got: %#x)\n",
581 header
->uid_crc8
, crc
);
585 sw
->uid
= header
->uid
;
586 sw
->vendor
= header
->vendor_id
;
587 sw
->device
= header
->model_id
;
589 crc
= tb_crc32(sw
->drom
+ TB_DROM_DATA_START
, header
->data_len
);
590 if (crc
!= header
->data_crc32
) {
592 "DROM data CRC32 mismatch (expected: %#x, got: %#x), continuing\n",
593 header
->data_crc32
, crc
);
596 return tb_drom_parse_entries(sw
, TB_DROM_HEADER_SIZE
);
599 static int usb4_drom_parse(struct tb_switch
*sw
)
601 const struct tb_drom_header
*header
=
602 (const struct tb_drom_header
*)sw
->drom
;
605 crc
= tb_crc32(sw
->drom
+ TB_DROM_DATA_START
, header
->data_len
);
606 if (crc
!= header
->data_crc32
) {
608 "DROM data CRC32 mismatch (expected: %#x, got: %#x), continuing\n",
609 header
->data_crc32
, crc
);
612 return tb_drom_parse_entries(sw
, USB4_DROM_HEADER_SIZE
);
615 static int tb_drom_parse(struct tb_switch
*sw
, u16 size
)
617 const struct tb_drom_header
*header
= (const void *)sw
->drom
;
620 if (header
->data_len
+ TB_DROM_DATA_START
!= size
) {
621 tb_sw_warn(sw
, "DROM size mismatch\n");
626 tb_sw_dbg(sw
, "DROM version: %d\n", header
->device_rom_revision
);
628 switch (header
->device_rom_revision
) {
630 ret
= usb4_drom_parse(sw
);
633 tb_sw_warn(sw
, "DROM device_rom_revision %#x unknown\n",
634 header
->device_rom_revision
);
637 ret
= tb_drom_parse_v1(sw
);
642 tb_sw_warn(sw
, "parsing DROM failed\n");
655 static int tb_drom_host_read(struct tb_switch
*sw
)
659 if (tb_switch_is_usb4(sw
)) {
660 usb4_switch_read_uid(sw
, &sw
->uid
);
661 if (!usb4_copy_drom(sw
, &size
))
662 return tb_drom_parse(sw
, size
);
664 if (!tb_drom_copy_efi(sw
, &size
))
665 return tb_drom_parse(sw
, size
);
667 if (!tb_drom_copy_nvm(sw
, &size
))
668 return tb_drom_parse(sw
, size
);
670 tb_drom_read_uid_only(sw
, &sw
->uid
);
676 static int tb_drom_device_read(struct tb_switch
*sw
)
681 if (tb_switch_is_usb4(sw
)) {
682 usb4_switch_read_uid(sw
, &sw
->uid
);
683 ret
= usb4_copy_drom(sw
, &size
);
685 ret
= tb_drom_bit_bang(sw
, &size
);
691 return tb_drom_parse(sw
, size
);
695 * tb_drom_read() - Copy DROM to sw->drom and parse it
696 * @sw: Router whose DROM to read and parse
698 * This function reads router DROM and if successful parses the entries and
699 * populates the fields in @sw accordingly. Can be called for any router
702 * Returns %0 in case of success and negative errno otherwise.
704 int tb_drom_read(struct tb_switch
*sw
)
710 return tb_drom_host_read(sw
);
711 return tb_drom_device_read(sw
);