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 + 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 + 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()
287 int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) in tb_drom_read_uid_only() argument
294 res = tb_eeprom_read_n(sw, 0, data, 9); in tb_drom_read_uid_only()
300 tb_sw_warn(sw, "uid crc8 mismatch (expected: %#x, got: %#x)\n", in tb_drom_read_uid_only()
309 static int tb_drom_parse_entry_generic(struct tb_switch *sw, in tb_drom_parse_entry_generic() argument
318 sw->vendor_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
320 if (!sw->vendor_name) in tb_drom_parse_entry_generic()
325 sw->device_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
327 if (!sw->device_name) in tb_drom_parse_entry_generic()
335 static int tb_drom_parse_entry_port(struct tb_switch *sw, in tb_drom_parse_entry_port() argument
346 if (header->index > sw->config.max_port_number) { in tb_drom_parse_entry_port()
347 dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n"); in tb_drom_parse_entry_port()
351 port = &sw->ports[header->index]; in tb_drom_parse_entry_port()
364 tb_sw_warn(sw, in tb_drom_parse_entry_port()
372 &port->sw->ports[entry->dual_link_port_nr]; in tb_drom_parse_entry_port()
382 static int tb_drom_parse_entries(struct tb_switch *sw) in tb_drom_parse_entries() argument
384 struct tb_drom_header *header = (void *) sw->drom; in tb_drom_parse_entries()
390 struct tb_drom_entry_header *entry = (void *) (sw->drom + pos); in tb_drom_parse_entries()
393 tb_sw_warn(sw, "DROM buffer overrun\n"); in tb_drom_parse_entries()
399 res = tb_drom_parse_entry_generic(sw, entry); in tb_drom_parse_entries()
402 res = tb_drom_parse_entry_port(sw, entry); in tb_drom_parse_entries()
416 static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) in tb_drom_copy_efi() argument
418 struct device *dev = &sw->tb->nhi->pdev->dev; in tb_drom_copy_efi()
425 sw->drom = kmalloc(len, GFP_KERNEL); in tb_drom_copy_efi()
426 if (!sw->drom) in tb_drom_copy_efi()
429 res = device_property_read_u8_array(dev, "ThunderboltDROM", sw->drom, in tb_drom_copy_efi()
434 *size = ((struct tb_drom_header *)sw->drom)->data_len + in tb_drom_copy_efi()
442 kfree(sw->drom); in tb_drom_copy_efi()
443 sw->drom = NULL; in tb_drom_copy_efi()
447 static int tb_drom_copy_nvm(struct tb_switch *sw, u16 *size) in tb_drom_copy_nvm() argument
452 if (!sw->dma_port) in tb_drom_copy_nvm()
455 ret = tb_sw_read(sw, &drom_offset, TB_CFG_SWITCH, in tb_drom_copy_nvm()
456 sw->cap_plug_events + 12, 1); in tb_drom_copy_nvm()
463 ret = dma_port_flash_read(sw->dma_port, drom_offset + 14, size, in tb_drom_copy_nvm()
470 sw->drom = kzalloc(*size, GFP_KERNEL); in tb_drom_copy_nvm()
471 if (!sw->drom) in tb_drom_copy_nvm()
474 ret = dma_port_flash_read(sw->dma_port, drom_offset, sw->drom, *size); in tb_drom_copy_nvm()
482 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_copy_nvm()
486 kfree(sw->drom); in tb_drom_copy_nvm()
487 sw->drom = NULL; in tb_drom_copy_nvm()
491 static int usb4_copy_host_drom(struct tb_switch *sw, u16 *size) in usb4_copy_host_drom() argument
495 ret = usb4_switch_drom_read(sw, 14, size, sizeof(*size)); in usb4_copy_host_drom()
501 sw->drom = kzalloc(*size, GFP_KERNEL); in usb4_copy_host_drom()
502 if (!sw->drom) in usb4_copy_host_drom()
505 ret = usb4_switch_drom_read(sw, 0, sw->drom, *size); in usb4_copy_host_drom()
507 kfree(sw->drom); in usb4_copy_host_drom()
508 sw->drom = NULL; in usb4_copy_host_drom()
514 static int tb_drom_read_n(struct tb_switch *sw, u16 offset, u8 *val, in tb_drom_read_n() argument
517 if (tb_switch_is_usb4(sw)) in tb_drom_read_n()
518 return usb4_switch_drom_read(sw, offset, val, count); in tb_drom_read_n()
519 return tb_eeprom_read_n(sw, offset, val, count); in tb_drom_read_n()
525 int tb_drom_read(struct tb_switch *sw) in tb_drom_read() argument
532 if (sw->drom) in tb_drom_read()
535 if (tb_route(sw) == 0) { in tb_drom_read()
540 if (tb_drom_copy_efi(sw, &size) == 0) in tb_drom_read()
544 if (tb_drom_copy_nvm(sw, &size) == 0) in tb_drom_read()
551 if (tb_switch_is_usb4(sw)) { in tb_drom_read()
552 usb4_switch_read_uid(sw, &sw->uid); in tb_drom_read()
553 if (!usb4_copy_host_drom(sw, &size)) in tb_drom_read()
561 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_read()
567 res = tb_drom_read_n(sw, 14, (u8 *) &size, 2); in tb_drom_read()
572 tb_sw_dbg(sw, "reading drom (length: %#x)\n", size); in tb_drom_read()
574 tb_sw_warn(sw, "drom too small, aborting\n"); in tb_drom_read()
578 sw->drom = kzalloc(size, GFP_KERNEL); in tb_drom_read()
579 if (!sw->drom) in tb_drom_read()
581 res = tb_drom_read_n(sw, 0, sw->drom, size); in tb_drom_read()
586 header = (void *) sw->drom; in tb_drom_read()
589 tb_sw_warn(sw, "drom size mismatch, aborting\n"); in tb_drom_read()
595 tb_sw_warn(sw, in tb_drom_read()
600 if (!sw->uid) in tb_drom_read()
601 sw->uid = header->uid; in tb_drom_read()
602 sw->vendor = header->vendor_id; in tb_drom_read()
603 sw->device = header->model_id; in tb_drom_read()
604 tb_check_quirks(sw); in tb_drom_read()
606 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); in tb_drom_read()
608 tb_sw_warn(sw, in tb_drom_read()
614 tb_sw_warn(sw, "drom device_rom_revision %#x unknown\n", in tb_drom_read()
617 res = tb_drom_parse_entries(sw); in tb_drom_read()
620 tb_sw_warn(sw, "parsing DROM failed, retrying\n"); in tb_drom_read()
622 res = tb_drom_read_n(sw, 0, sw->drom, size); in tb_drom_read()
629 kfree(sw->drom); in tb_drom_read()
630 sw->drom = NULL; in tb_drom_read()