Lines Matching refs:sw

17 static int tb_eeprom_ctl_write(struct tb_switch *sw, struct tb_eeprom_ctl *ctl)  in tb_eeprom_ctl_write()  argument
19 return tb_sw_write(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1); in tb_eeprom_ctl_write()
25 static int tb_eeprom_ctl_read(struct tb_switch *sw, struct tb_eeprom_ctl *ctl) in tb_eeprom_ctl_read() argument
27 return tb_sw_read(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1); in tb_eeprom_ctl_read()
41 static int tb_eeprom_active(struct tb_switch *sw, bool enable) in tb_eeprom_active() argument
44 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_active()
49 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
53 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
56 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
60 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
70 static int tb_eeprom_transfer(struct tb_switch *sw, struct tb_eeprom_ctl *ctl, in tb_eeprom_transfer() argument
75 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
80 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
84 res = tb_eeprom_ctl_read(sw, ctl); in tb_eeprom_transfer()
89 return tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
95 static int tb_eeprom_out(struct tb_switch *sw, u8 val) in tb_eeprom_out() argument
99 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_out()
104 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_OUT); in tb_eeprom_out()
115 static int tb_eeprom_in(struct tb_switch *sw, u8 *val) in tb_eeprom_in() argument
119 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_in()
125 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_IN); in tb_eeprom_in()
136 static int tb_eeprom_read_n(struct tb_switch *sw, u16 offset, u8 *val, in tb_eeprom_read_n() argument
140 res = tb_eeprom_active(sw, true); in tb_eeprom_read_n()
143 res = tb_eeprom_out(sw, 3); in tb_eeprom_read_n()
146 res = tb_eeprom_out(sw, offset >> 8); in tb_eeprom_read_n()
149 res = tb_eeprom_out(sw, offset); in tb_eeprom_read_n()
153 res = tb_eeprom_in(sw, val + i); in tb_eeprom_read_n()
157 return tb_eeprom_active(sw, false); in tb_eeprom_read_n()
244 static int tb_eeprom_get_drom_offset(struct tb_switch *sw, u16 *offset) in tb_eeprom_get_drom_offset() argument
248 if (!sw->cap_plug_events) { in tb_eeprom_get_drom_offset()
249 tb_sw_warn(sw, "no TB_CAP_PLUG_EVENTS, cannot read eeprom\n"); in tb_eeprom_get_drom_offset()
252 res = tb_sw_read(sw, &cap, TB_CFG_SWITCH, sw->cap_plug_events, in tb_eeprom_get_drom_offset()
258 tb_sw_warn(sw, "no NVM\n"); in tb_eeprom_get_drom_offset()
263 tb_sw_warn(sw, "drom offset is larger than 0xffff: %#x\n", in tb_eeprom_get_drom_offset()
277 int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) in tb_drom_read_uid_only() argument
282 int res = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_drom_read_uid_only()
290 res = tb_eeprom_read_n(sw, drom_offset, data, 9); in tb_drom_read_uid_only()
296 tb_sw_warn(sw, "uid crc8 mismatch (expected: %#x, got: %#x)\n", in tb_drom_read_uid_only()
305 static int tb_drom_parse_entry_generic(struct tb_switch *sw, in tb_drom_parse_entry_generic() argument
314 sw->vendor_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
316 if (!sw->vendor_name) in tb_drom_parse_entry_generic()
321 sw->device_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
323 if (!sw->device_name) in tb_drom_parse_entry_generic()
331 static int tb_drom_parse_entry_port(struct tb_switch *sw, in tb_drom_parse_entry_port() argument
342 if (header->index > sw->config.max_port_number) { in tb_drom_parse_entry_port()
343 dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n"); in tb_drom_parse_entry_port()
347 port = &sw->ports[header->index]; in tb_drom_parse_entry_port()
360 tb_sw_warn(sw, in tb_drom_parse_entry_port()
368 &port->sw->ports[entry->dual_link_port_nr]; in tb_drom_parse_entry_port()
378 static int tb_drom_parse_entries(struct tb_switch *sw) in tb_drom_parse_entries() argument
380 struct tb_drom_header *header = (void *) sw->drom; in tb_drom_parse_entries()
386 struct tb_drom_entry_header *entry = (void *) (sw->drom + pos); in tb_drom_parse_entries()
389 tb_sw_warn(sw, "drom buffer overrun, aborting\n"); in tb_drom_parse_entries()
395 res = tb_drom_parse_entry_generic(sw, entry); in tb_drom_parse_entries()
398 res = tb_drom_parse_entry_port(sw, entry); in tb_drom_parse_entries()
412 static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) in tb_drom_copy_efi() argument
414 struct device *dev = &sw->tb->nhi->pdev->dev; in tb_drom_copy_efi()
421 sw->drom = kmalloc(len, GFP_KERNEL); in tb_drom_copy_efi()
422 if (!sw->drom) in tb_drom_copy_efi()
425 res = device_property_read_u8_array(dev, "ThunderboltDROM", sw->drom, in tb_drom_copy_efi()
430 *size = ((struct tb_drom_header *)sw->drom)->data_len + in tb_drom_copy_efi()
438 kfree(sw->drom); in tb_drom_copy_efi()
439 sw->drom = NULL; in tb_drom_copy_efi()
443 static int tb_drom_copy_nvm(struct tb_switch *sw, u16 *size) in tb_drom_copy_nvm() argument
448 if (!sw->dma_port) in tb_drom_copy_nvm()
451 ret = tb_sw_read(sw, &drom_offset, TB_CFG_SWITCH, in tb_drom_copy_nvm()
452 sw->cap_plug_events + 12, 1); in tb_drom_copy_nvm()
459 ret = dma_port_flash_read(sw->dma_port, drom_offset + 14, size, in tb_drom_copy_nvm()
466 sw->drom = kzalloc(*size, GFP_KERNEL); in tb_drom_copy_nvm()
467 if (!sw->drom) in tb_drom_copy_nvm()
470 ret = dma_port_flash_read(sw->dma_port, drom_offset, sw->drom, *size); in tb_drom_copy_nvm()
478 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_copy_nvm()
482 kfree(sw->drom); in tb_drom_copy_nvm()
483 sw->drom = NULL; in tb_drom_copy_nvm()
490 int tb_drom_read(struct tb_switch *sw) in tb_drom_read() argument
497 if (sw->drom) in tb_drom_read()
500 if (tb_route(sw) == 0) { in tb_drom_read()
505 if (tb_drom_copy_efi(sw, &size) == 0) in tb_drom_read()
509 if (tb_drom_copy_nvm(sw, &size) == 0) in tb_drom_read()
516 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_read()
518 sw->ports[1].link_nr = 0; in tb_drom_read()
519 sw->ports[2].link_nr = 1; in tb_drom_read()
520 sw->ports[1].dual_link_port = &sw->ports[2]; in tb_drom_read()
521 sw->ports[2].dual_link_port = &sw->ports[1]; in tb_drom_read()
523 sw->ports[3].link_nr = 0; in tb_drom_read()
524 sw->ports[4].link_nr = 1; in tb_drom_read()
525 sw->ports[3].dual_link_port = &sw->ports[4]; in tb_drom_read()
526 sw->ports[4].dual_link_port = &sw->ports[3]; in tb_drom_read()
531 res = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_drom_read()
535 res = tb_eeprom_read_n(sw, drom_offset + 14, (u8 *) &size, 2); in tb_drom_read()
540 tb_sw_dbg(sw, "reading drom (length: %#x)\n", size); in tb_drom_read()
542 tb_sw_warn(sw, "drom too small, aborting\n"); in tb_drom_read()
546 sw->drom = kzalloc(size, GFP_KERNEL); in tb_drom_read()
547 if (!sw->drom) in tb_drom_read()
549 res = tb_eeprom_read_n(sw, drom_offset, sw->drom, size); in tb_drom_read()
554 header = (void *) sw->drom; in tb_drom_read()
557 tb_sw_warn(sw, "drom size mismatch, aborting\n"); in tb_drom_read()
563 tb_sw_warn(sw, in tb_drom_read()
568 if (!sw->uid) in tb_drom_read()
569 sw->uid = header->uid; in tb_drom_read()
570 sw->vendor = header->vendor_id; in tb_drom_read()
571 sw->device = header->model_id; in tb_drom_read()
573 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); in tb_drom_read()
575 tb_sw_warn(sw, in tb_drom_read()
581 tb_sw_warn(sw, "drom device_rom_revision %#x unknown\n", in tb_drom_read()
584 return tb_drom_parse_entries(sw); in tb_drom_read()
586 kfree(sw->drom); in tb_drom_read()
587 sw->drom = NULL; in tb_drom_read()