Lines Matching refs:sw
18 static int tb_eeprom_ctl_write(struct tb_switch *sw, struct tb_eeprom_ctl *ctl) in tb_eeprom_ctl_write() argument
20 return tb_sw_write(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + ROUTER_CS_4, 1); in tb_eeprom_ctl_write()
26 static int tb_eeprom_ctl_read(struct tb_switch *sw, struct tb_eeprom_ctl *ctl) in tb_eeprom_ctl_read() argument
28 return tb_sw_read(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + ROUTER_CS_4, 1); in tb_eeprom_ctl_read()
42 static int tb_eeprom_active(struct tb_switch *sw, bool enable) in tb_eeprom_active() argument
45 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_active()
50 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
54 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
57 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
61 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
71 static int tb_eeprom_transfer(struct tb_switch *sw, struct tb_eeprom_ctl *ctl, in tb_eeprom_transfer() argument
76 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
81 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
85 res = tb_eeprom_ctl_read(sw, ctl); in tb_eeprom_transfer()
90 return tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
96 static int tb_eeprom_out(struct tb_switch *sw, u8 val) in tb_eeprom_out() argument
100 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_out()
105 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_OUT); in tb_eeprom_out()
116 static int tb_eeprom_in(struct tb_switch *sw, u8 *val) in tb_eeprom_in() argument
120 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_in()
126 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_IN); in tb_eeprom_in()
137 static int tb_eeprom_get_drom_offset(struct tb_switch *sw, u16 *offset) in tb_eeprom_get_drom_offset() argument
142 if (!sw->cap_plug_events) { in tb_eeprom_get_drom_offset()
143 tb_sw_warn(sw, "no TB_CAP_PLUG_EVENTS, cannot read eeprom\n"); in tb_eeprom_get_drom_offset()
146 res = tb_sw_read(sw, &cap, TB_CFG_SWITCH, sw->cap_plug_events, in tb_eeprom_get_drom_offset()
152 tb_sw_warn(sw, "no NVM\n"); in tb_eeprom_get_drom_offset()
157 tb_sw_warn(sw, "drom offset is larger than 0xffff: %#x\n", in tb_eeprom_get_drom_offset()
168 static int tb_eeprom_read_n(struct tb_switch *sw, u16 offset, u8 *val, in tb_eeprom_read_n() argument
174 res = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_eeprom_read_n()
180 res = tb_eeprom_active(sw, true); in tb_eeprom_read_n()
183 res = tb_eeprom_out(sw, 3); in tb_eeprom_read_n()
186 res = tb_eeprom_out(sw, offset >> 8); in tb_eeprom_read_n()
189 res = tb_eeprom_out(sw, offset); in tb_eeprom_read_n()
193 res = tb_eeprom_in(sw, val + i); in tb_eeprom_read_n()
197 return tb_eeprom_active(sw, false); in tb_eeprom_read_n()
302 int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) in tb_drom_read_uid_only() argument
309 res = tb_eeprom_read_n(sw, 0, data, 9); in tb_drom_read_uid_only()
315 tb_sw_warn(sw, "uid crc8 mismatch (expected: %#x, got: %#x)\n", in tb_drom_read_uid_only()
324 static int tb_drom_parse_entry_generic(struct tb_switch *sw, in tb_drom_parse_entry_generic() argument
333 sw->vendor_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
335 if (!sw->vendor_name) in tb_drom_parse_entry_generic()
340 sw->device_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
342 if (!sw->device_name) in tb_drom_parse_entry_generic()
349 if (!sw->vendor && !sw->device) { in tb_drom_parse_entry_generic()
350 sw->vendor = desc->idVendor; in tb_drom_parse_entry_generic()
351 sw->device = desc->idProduct; in tb_drom_parse_entry_generic()
360 static int tb_drom_parse_entry_port(struct tb_switch *sw, in tb_drom_parse_entry_port() argument
371 if (header->index > sw->config.max_port_number) { in tb_drom_parse_entry_port()
372 dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n"); in tb_drom_parse_entry_port()
376 port = &sw->ports[header->index]; in tb_drom_parse_entry_port()
389 tb_sw_warn(sw, in tb_drom_parse_entry_port()
397 &port->sw->ports[entry->dual_link_port_nr]; in tb_drom_parse_entry_port()
407 static int tb_drom_parse_entries(struct tb_switch *sw, size_t header_size) in tb_drom_parse_entries() argument
409 struct tb_drom_header *header = (void *) sw->drom; in tb_drom_parse_entries()
415 struct tb_drom_entry_header *entry = (void *) (sw->drom + pos); in tb_drom_parse_entries()
418 tb_sw_warn(sw, "DROM buffer overrun\n"); in tb_drom_parse_entries()
424 res = tb_drom_parse_entry_generic(sw, entry); in tb_drom_parse_entries()
427 res = tb_drom_parse_entry_port(sw, entry); in tb_drom_parse_entries()
441 static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) in tb_drom_copy_efi() argument
443 struct device *dev = &sw->tb->nhi->pdev->dev; in tb_drom_copy_efi()
450 sw->drom = kmalloc(len, GFP_KERNEL); in tb_drom_copy_efi()
451 if (!sw->drom) in tb_drom_copy_efi()
454 res = device_property_read_u8_array(dev, "ThunderboltDROM", sw->drom, in tb_drom_copy_efi()
459 *size = ((struct tb_drom_header *)sw->drom)->data_len + in tb_drom_copy_efi()
467 kfree(sw->drom); in tb_drom_copy_efi()
468 sw->drom = NULL; in tb_drom_copy_efi()
472 static int tb_drom_copy_nvm(struct tb_switch *sw, u16 *size) in tb_drom_copy_nvm() argument
477 if (!sw->dma_port) in tb_drom_copy_nvm()
480 ret = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_drom_copy_nvm()
487 ret = dma_port_flash_read(sw->dma_port, drom_offset + 14, size, in tb_drom_copy_nvm()
494 sw->drom = kzalloc(*size, GFP_KERNEL); in tb_drom_copy_nvm()
495 if (!sw->drom) in tb_drom_copy_nvm()
498 ret = dma_port_flash_read(sw->dma_port, drom_offset, sw->drom, *size); in tb_drom_copy_nvm()
506 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_copy_nvm()
510 kfree(sw->drom); in tb_drom_copy_nvm()
511 sw->drom = NULL; in tb_drom_copy_nvm()
515 static int usb4_copy_drom(struct tb_switch *sw, u16 *size) in usb4_copy_drom() argument
519 ret = usb4_switch_drom_read(sw, 14, size, sizeof(*size)); in usb4_copy_drom()
525 sw->drom = kzalloc(*size, GFP_KERNEL); in usb4_copy_drom()
526 if (!sw->drom) in usb4_copy_drom()
529 ret = usb4_switch_drom_read(sw, 0, sw->drom, *size); in usb4_copy_drom()
531 kfree(sw->drom); in usb4_copy_drom()
532 sw->drom = NULL; in usb4_copy_drom()
538 static int tb_drom_bit_bang(struct tb_switch *sw, u16 *size) in tb_drom_bit_bang() argument
542 ret = tb_eeprom_read_n(sw, 14, (u8 *)size, 2); in tb_drom_bit_bang()
549 tb_sw_dbg(sw, "reading DROM (length: %#x)\n", *size); in tb_drom_bit_bang()
551 tb_sw_warn(sw, "DROM too small, aborting\n"); in tb_drom_bit_bang()
555 sw->drom = kzalloc(*size, GFP_KERNEL); in tb_drom_bit_bang()
556 if (!sw->drom) in tb_drom_bit_bang()
559 ret = tb_eeprom_read_n(sw, 0, sw->drom, *size); in tb_drom_bit_bang()
566 kfree(sw->drom); in tb_drom_bit_bang()
567 sw->drom = NULL; in tb_drom_bit_bang()
571 static int tb_drom_parse_v1(struct tb_switch *sw) in tb_drom_parse_v1() argument
574 (const struct tb_drom_header *)sw->drom; in tb_drom_parse_v1()
579 tb_sw_warn(sw, in tb_drom_parse_v1()
584 if (!sw->uid) in tb_drom_parse_v1()
585 sw->uid = header->uid; in tb_drom_parse_v1()
586 sw->vendor = header->vendor_id; in tb_drom_parse_v1()
587 sw->device = header->model_id; in tb_drom_parse_v1()
589 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); in tb_drom_parse_v1()
591 tb_sw_warn(sw, in tb_drom_parse_v1()
596 return tb_drom_parse_entries(sw, TB_DROM_HEADER_SIZE); in tb_drom_parse_v1()
599 static int usb4_drom_parse(struct tb_switch *sw) in usb4_drom_parse() argument
602 (const struct tb_drom_header *)sw->drom; in usb4_drom_parse()
605 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); in usb4_drom_parse()
607 tb_sw_warn(sw, in usb4_drom_parse()
612 return tb_drom_parse_entries(sw, USB4_DROM_HEADER_SIZE); in usb4_drom_parse()
615 static int tb_drom_parse(struct tb_switch *sw, u16 size) in tb_drom_parse() argument
617 const struct tb_drom_header *header = (const void *)sw->drom; in tb_drom_parse()
621 tb_sw_warn(sw, "DROM size mismatch\n"); in tb_drom_parse()
626 tb_sw_dbg(sw, "DROM version: %d\n", header->device_rom_revision); in tb_drom_parse()
630 ret = usb4_drom_parse(sw); in tb_drom_parse()
633 tb_sw_warn(sw, "DROM device_rom_revision %#x unknown\n", in tb_drom_parse()
637 ret = tb_drom_parse_v1(sw); in tb_drom_parse()
642 tb_sw_warn(sw, "parsing DROM failed\n"); in tb_drom_parse()
649 kfree(sw->drom); in tb_drom_parse()
650 sw->drom = NULL; in tb_drom_parse()
655 static int tb_drom_host_read(struct tb_switch *sw) in tb_drom_host_read() argument
659 if (tb_switch_is_usb4(sw)) { in tb_drom_host_read()
660 usb4_switch_read_uid(sw, &sw->uid); in tb_drom_host_read()
661 if (!usb4_copy_drom(sw, &size)) in tb_drom_host_read()
662 return tb_drom_parse(sw, size); in tb_drom_host_read()
664 if (!tb_drom_copy_efi(sw, &size)) in tb_drom_host_read()
665 return tb_drom_parse(sw, size); in tb_drom_host_read()
667 if (!tb_drom_copy_nvm(sw, &size)) in tb_drom_host_read()
668 return tb_drom_parse(sw, size); in tb_drom_host_read()
670 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_host_read()
676 static int tb_drom_device_read(struct tb_switch *sw) in tb_drom_device_read() argument
681 if (tb_switch_is_usb4(sw)) { in tb_drom_device_read()
682 usb4_switch_read_uid(sw, &sw->uid); in tb_drom_device_read()
683 ret = usb4_copy_drom(sw, &size); in tb_drom_device_read()
685 ret = tb_drom_bit_bang(sw, &size); in tb_drom_device_read()
691 return tb_drom_parse(sw, size); in tb_drom_device_read()
704 int tb_drom_read(struct tb_switch *sw) in tb_drom_read() argument
706 if (sw->drom) in tb_drom_read()
709 if (!tb_route(sw)) in tb_drom_read()
710 return tb_drom_host_read(sw); in tb_drom_read()
711 return tb_drom_device_read(sw); in tb_drom_read()