Lines Matching refs:sw
16 static int tb_eeprom_ctl_write(struct tb_switch *sw, struct tb_eeprom_ctl *ctl) in tb_eeprom_ctl_write() argument
18 return tb_sw_write(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1); in tb_eeprom_ctl_write()
24 static int tb_eeprom_ctl_read(struct tb_switch *sw, struct tb_eeprom_ctl *ctl) in tb_eeprom_ctl_read() argument
26 return tb_sw_read(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1); in tb_eeprom_ctl_read()
40 static int tb_eeprom_active(struct tb_switch *sw, bool enable) in tb_eeprom_active() argument
43 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_active()
48 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
52 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
55 res = tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
59 return tb_eeprom_ctl_write(sw, &ctl); in tb_eeprom_active()
69 static int tb_eeprom_transfer(struct tb_switch *sw, struct tb_eeprom_ctl *ctl, in tb_eeprom_transfer() argument
74 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
79 res = tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
83 res = tb_eeprom_ctl_read(sw, ctl); in tb_eeprom_transfer()
88 return tb_eeprom_ctl_write(sw, ctl); in tb_eeprom_transfer()
94 static int tb_eeprom_out(struct tb_switch *sw, u8 val) in tb_eeprom_out() argument
98 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_out()
103 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_OUT); in tb_eeprom_out()
114 static int tb_eeprom_in(struct tb_switch *sw, u8 *val) in tb_eeprom_in() argument
118 int res = tb_eeprom_ctl_read(sw, &ctl); in tb_eeprom_in()
124 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_IN); in tb_eeprom_in()
135 static int tb_eeprom_read_n(struct tb_switch *sw, u16 offset, u8 *val, in tb_eeprom_read_n() argument
139 res = tb_eeprom_active(sw, true); in tb_eeprom_read_n()
142 res = tb_eeprom_out(sw, 3); in tb_eeprom_read_n()
145 res = tb_eeprom_out(sw, offset >> 8); in tb_eeprom_read_n()
148 res = tb_eeprom_out(sw, offset); in tb_eeprom_read_n()
152 res = tb_eeprom_in(sw, val + i); in tb_eeprom_read_n()
156 return tb_eeprom_active(sw, false); in tb_eeprom_read_n()
243 static int tb_eeprom_get_drom_offset(struct tb_switch *sw, u16 *offset) in tb_eeprom_get_drom_offset() argument
247 if (!sw->cap_plug_events) { in tb_eeprom_get_drom_offset()
248 tb_sw_warn(sw, "no TB_CAP_PLUG_EVENTS, cannot read eeprom\n"); in tb_eeprom_get_drom_offset()
251 res = tb_sw_read(sw, &cap, TB_CFG_SWITCH, sw->cap_plug_events, in tb_eeprom_get_drom_offset()
257 tb_sw_warn(sw, "no NVM\n"); in tb_eeprom_get_drom_offset()
262 tb_sw_warn(sw, "drom offset is larger than 0xffff: %#x\n", in tb_eeprom_get_drom_offset()
276 int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) in tb_drom_read_uid_only() argument
281 int res = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_drom_read_uid_only()
289 res = tb_eeprom_read_n(sw, drom_offset, data, 9); in tb_drom_read_uid_only()
295 tb_sw_warn(sw, "uid crc8 mismatch (expected: %#x, got: %#x)\n", in tb_drom_read_uid_only()
304 static int tb_drom_parse_entry_generic(struct tb_switch *sw, in tb_drom_parse_entry_generic() argument
313 sw->vendor_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
315 if (!sw->vendor_name) in tb_drom_parse_entry_generic()
320 sw->device_name = kstrndup(entry->data, in tb_drom_parse_entry_generic()
322 if (!sw->device_name) in tb_drom_parse_entry_generic()
330 static int tb_drom_parse_entry_port(struct tb_switch *sw, in tb_drom_parse_entry_port() argument
341 if (header->index > sw->config.max_port_number) { in tb_drom_parse_entry_port()
342 dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n"); in tb_drom_parse_entry_port()
346 port = &sw->ports[header->index]; in tb_drom_parse_entry_port()
359 tb_sw_warn(sw, in tb_drom_parse_entry_port()
367 &port->sw->ports[entry->dual_link_port_nr]; in tb_drom_parse_entry_port()
377 static int tb_drom_parse_entries(struct tb_switch *sw) in tb_drom_parse_entries() argument
379 struct tb_drom_header *header = (void *) sw->drom; in tb_drom_parse_entries()
385 struct tb_drom_entry_header *entry = (void *) (sw->drom + pos); in tb_drom_parse_entries()
388 tb_sw_warn(sw, "drom buffer overrun, aborting\n"); in tb_drom_parse_entries()
394 res = tb_drom_parse_entry_generic(sw, entry); in tb_drom_parse_entries()
397 res = tb_drom_parse_entry_port(sw, entry); in tb_drom_parse_entries()
411 static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) in tb_drom_copy_efi() argument
413 struct device *dev = &sw->tb->nhi->pdev->dev; in tb_drom_copy_efi()
420 sw->drom = kmalloc(len, GFP_KERNEL); in tb_drom_copy_efi()
421 if (!sw->drom) in tb_drom_copy_efi()
424 res = device_property_read_u8_array(dev, "ThunderboltDROM", sw->drom, in tb_drom_copy_efi()
429 *size = ((struct tb_drom_header *)sw->drom)->data_len + in tb_drom_copy_efi()
437 kfree(sw->drom); in tb_drom_copy_efi()
438 sw->drom = NULL; in tb_drom_copy_efi()
442 static int tb_drom_copy_nvm(struct tb_switch *sw, u16 *size) in tb_drom_copy_nvm() argument
447 if (!sw->dma_port) in tb_drom_copy_nvm()
450 ret = tb_sw_read(sw, &drom_offset, TB_CFG_SWITCH, in tb_drom_copy_nvm()
451 sw->cap_plug_events + 12, 1); in tb_drom_copy_nvm()
458 ret = dma_port_flash_read(sw->dma_port, drom_offset + 14, size, in tb_drom_copy_nvm()
465 sw->drom = kzalloc(*size, GFP_KERNEL); in tb_drom_copy_nvm()
466 if (!sw->drom) in tb_drom_copy_nvm()
469 ret = dma_port_flash_read(sw->dma_port, drom_offset, sw->drom, *size); in tb_drom_copy_nvm()
477 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_copy_nvm()
481 kfree(sw->drom); in tb_drom_copy_nvm()
482 sw->drom = NULL; in tb_drom_copy_nvm()
489 int tb_drom_read(struct tb_switch *sw) in tb_drom_read() argument
496 if (sw->drom) in tb_drom_read()
499 if (tb_route(sw) == 0) { in tb_drom_read()
504 if (tb_drom_copy_efi(sw, &size) == 0) in tb_drom_read()
508 if (tb_drom_copy_nvm(sw, &size) == 0) in tb_drom_read()
515 tb_drom_read_uid_only(sw, &sw->uid); in tb_drom_read()
517 sw->ports[1].link_nr = 0; in tb_drom_read()
518 sw->ports[2].link_nr = 1; in tb_drom_read()
519 sw->ports[1].dual_link_port = &sw->ports[2]; in tb_drom_read()
520 sw->ports[2].dual_link_port = &sw->ports[1]; in tb_drom_read()
522 sw->ports[3].link_nr = 0; in tb_drom_read()
523 sw->ports[4].link_nr = 1; in tb_drom_read()
524 sw->ports[3].dual_link_port = &sw->ports[4]; in tb_drom_read()
525 sw->ports[4].dual_link_port = &sw->ports[3]; in tb_drom_read()
528 if (sw->config.device_id == PCI_DEVICE_ID_INTEL_LIGHT_RIDGE) in tb_drom_read()
529 sw->ports[5].disabled = true; in tb_drom_read()
534 res = tb_eeprom_get_drom_offset(sw, &drom_offset); in tb_drom_read()
538 res = tb_eeprom_read_n(sw, drom_offset + 14, (u8 *) &size, 2); in tb_drom_read()
543 tb_sw_info(sw, "reading drom (length: %#x)\n", size); in tb_drom_read()
545 tb_sw_warn(sw, "drom too small, aborting\n"); in tb_drom_read()
549 sw->drom = kzalloc(size, GFP_KERNEL); in tb_drom_read()
550 if (!sw->drom) in tb_drom_read()
552 res = tb_eeprom_read_n(sw, drom_offset, sw->drom, size); in tb_drom_read()
557 header = (void *) sw->drom; in tb_drom_read()
560 tb_sw_warn(sw, "drom size mismatch, aborting\n"); in tb_drom_read()
566 tb_sw_warn(sw, in tb_drom_read()
571 if (!sw->uid) in tb_drom_read()
572 sw->uid = header->uid; in tb_drom_read()
573 sw->vendor = header->vendor_id; in tb_drom_read()
574 sw->device = header->model_id; in tb_drom_read()
576 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); in tb_drom_read()
578 tb_sw_warn(sw, in tb_drom_read()
584 tb_sw_warn(sw, "drom device_rom_revision %#x unknown\n", in tb_drom_read()
587 return tb_drom_parse_entries(sw); in tb_drom_read()
589 kfree(sw->drom); in tb_drom_read()
590 sw->drom = NULL; in tb_drom_read()