Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1656243 > unrolled thread

[PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

Started byMika Westerberg <mika.westerberg@linux.intel.com>
First post2017-06-02 16:10 +0200
Last post2017-06-06 08:50 +0200
Articles 12 on this page of 52 — 7 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 05/27] thunderbolt: Add MSI-X support Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 07/27] thunderbolt: Allow passing NULL to tb_ctl_free() Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 18/27] thunderbolt: Rework control channel to be more reliable Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 27/27] MAINTAINERS: Add maintainers for Thunderbolt driver Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 25/27] thunderbolt: Add support for host and device NVM firmware upgrade Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 01/27] thunderbolt: Use const buffer pointer in write operations Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 22/27] thunderbolt: Add support for DMA configuration based mailbox Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 06/27] thunderbolt: Rework capability handling Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
      Re: [PATCH v3 06/27] thunderbolt: Rework capability handling Lukas Wunner <lukas@wunner.de> - 2017-06-04 16:00 +0200
        Re: [PATCH v3 06/27] thunderbolt: Rework capability handling Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-04 17:10 +0200
          Re: [PATCH v3 06/27] thunderbolt: Rework capability handling Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-04 17:10 +0200
            Re: [PATCH v3 06/27] thunderbolt: Rework capability handling Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-06-04 20:20 +0200
              Re: [PATCH v3 06/27] thunderbolt: Rework capability handling Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 08:50 +0200
    [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
      Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Lukas Wunner <lukas@wunner.de> - 2017-06-05 10:20 +0200
        Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 11:40 +0200
          Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Lukas Wunner <lukas@wunner.de> - 2017-06-05 14:10 +0200
            Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 15:00 +0200
              Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 15:40 +0200
                Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Lukas Wunner <lukas@wunner.de> - 2017-06-05 15:50 +0200
                  Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 16:00 +0200
                Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Andy Shevchenko <andriy.shevchenko@linux.intel.com> - 2017-06-05 16:30 +0200
                  Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 16:50 +0200
                  Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-05 17:30 +0200
                    Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 17:50 +0200
                      RE: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs <Mario.Limonciello@dell.com> - 2017-06-05 18:00 +0200
                        Re: [PATCH v3 19/27] thunderbolt: Add new Thunderbolt PCI IDs Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 19:00 +0200
    [PATCH v3 17/27] thunderbolt: Let the connection manager handle all notifications Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 04/27] thunderbolt: Do not warn about newer DROM versions Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 16/27] thunderbolt: Expose make_header() to other files Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 26/27] thunderbolt: Add documentation how Thunderbolt bus can be used Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
      Re: [PATCH v3 26/27] thunderbolt: Add documentation how Thunderbolt  bus can be used Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-03 16:20 +0200
    [PATCH v3 10/27] thunderbolt: Fail switch adding operation if reading DROM fails Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 03/27] thunderbolt: Do not try to read UID if DROM offset is read as 0 Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 20/27] thunderbolt: Add support for NHI mailbox Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:10 +0200
    [PATCH v3 08/27] thunderbolt: Introduce thunderbolt bus and connection manager Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
      Re: [PATCH v3 08/27] thunderbolt: Introduce thunderbolt bus and  connection manager Andreas Noever <andreas.noever@gmail.com> - 2017-06-05 17:20 +0200
    [PATCH v3 02/27] thunderbolt: No need to read UID of the root switch on resume Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
    [PATCH v3 14/27] thunderbolt: Move control channel messages to tb_msgs.h Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
    [PATCH v3 13/27] thunderbolt: Read vendor and device name from DROM Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
    [PATCH v3 11/27] thunderbolt: Do not fail if DROM data CRC32 is invalid Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
    [PATCH v3 09/27] thunderbolt: Convert switch to a device Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
      Re: [PATCH v3 09/27] thunderbolt: Convert switch to a device Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-03 16:20 +0200
    [PATCH v3 21/27] thunderbolt: Store Thunderbolt generation in the switch structure Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-02 16:20 +0200
    Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Andy Shevchenko <andriy.shevchenko@linux.intel.com> - 2017-06-02 20:10 +0200
    Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-03 16:20 +0200
      Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 09:20 +0200
        Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade Andreas Noever <andreas.noever@gmail.com> - 2017-06-05 19:10 +0200
          Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-05 21:50 +0200
          Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-06 08:10 +0200
            Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware  upgrade Mika Westerberg <mika.westerberg@linux.intel.com> - 2017-06-06 08:50 +0200

Page 3 of 3 — ← Prev page 1 2 [3]


#1656271 — [PATCH v3 13/27] thunderbolt: Read vendor and device name from DROM

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-02 16:20 +0200
Subject[PATCH v3 13/27] thunderbolt: Read vendor and device name from DROM
Message-ID<tNVAK-2ht-15@gated-at.bofh.it>
In reply to#1656243
The device DROM contains name of the vendor and device among other
things. Extract this information and expose it to the userspace via two
new attributes.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Michael Jamet <michael.jamet@intel.com>
---
 Documentation/ABI/testing/sysfs-bus-thunderbolt | 14 +++++++++++
 drivers/thunderbolt/eeprom.c                    | 32 +++++++++++++++++++++++++
 drivers/thunderbolt/switch.c                    | 22 +++++++++++++++++
 drivers/thunderbolt/tb.h                        |  4 ++++
 4 files changed, 72 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt
index 9f1bd0086938..29a516f53d2c 100644
--- a/Documentation/ABI/testing/sysfs-bus-thunderbolt
+++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt
@@ -5,6 +5,13 @@ Contact:	thunderbolt-software@lists.01.org
 Description:	This attribute contains id of this device extracted from
 		the device DROM.
 
+What:		/sys/bus/thunderbolt/devices/.../device_name
+Date:		Sep 2017
+KernelVersion:	4.13
+Contact:	thunderbolt-software@lists.01.org
+Description:	This attribute contains name of this device extracted from
+		the device DROM.
+
 What:		/sys/bus/thunderbolt/devices/.../vendor
 Date:		Sep 2017
 KernelVersion:	4.13
@@ -12,6 +19,13 @@ Contact:	thunderbolt-software@lists.01.org
 Description:	This attribute contains vendor id of this device extracted
 		from the device DROM.
 
+What:		/sys/bus/thunderbolt/devices/.../vendor_name
+Date:		Sep 2017
+KernelVersion:	4.13
+Contact:	thunderbolt-software@lists.01.org
+Description:	This attribute contains vendor name of this device extracted
+		from the device DROM.
+
 What:		/sys/bus/thunderbolt/devices/.../unique_id
 Date:		Sep 2017
 KernelVersion:	4.13
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index 5c7d80a109b1..d40a5f07fc4c 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -204,6 +204,11 @@ struct tb_drom_entry_header {
 	enum tb_drom_entry_type type:1;
 } __packed;
 
+struct tb_drom_entry_generic {
+	struct tb_drom_entry_header header;
+	u8 data[0];
+} __packed;
+
 struct tb_drom_entry_port {
 	/* BYTES 0-1 */
 	struct tb_drom_entry_header header;
@@ -295,6 +300,32 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid)
 	return 0;
 }
 
+static int tb_drom_parse_entry_generic(struct tb_switch *sw,
+		struct tb_drom_entry_header *header)
+{
+	const struct tb_drom_entry_generic *entry =
+		(const struct tb_drom_entry_generic *)header;
+
+	switch (header->index) {
+	case 1:
+		/* Length includes 2 bytes header so remove it before copy */
+		sw->vendor_name = kstrndup(entry->data,
+			header->len - sizeof(*header), GFP_KERNEL);
+		if (!sw->vendor_name)
+			return -ENOMEM;
+		break;
+
+	case 2:
+		sw->device_name = kstrndup(entry->data,
+			header->len - sizeof(*header), GFP_KERNEL);
+		if (!sw->device_name)
+			return -ENOMEM;
+		break;
+	}
+
+	return 0;
+}
+
 static int tb_drom_parse_entry_port(struct tb_switch *sw,
 				    struct tb_drom_entry_header *header)
 {
@@ -350,6 +381,7 @@ static int tb_drom_parse_entries(struct tb_switch *sw)
 
 		switch (entry->type) {
 		case TB_DROM_ENTRY_GENERIC:
+			res = tb_drom_parse_entry_generic(sw, entry);
 			break;
 		case TB_DROM_ENTRY_PORT:
 			res = tb_drom_parse_entry_port(sw, entry);
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 0ce8b600a23f..0a592ccb7923 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -319,6 +319,15 @@ static ssize_t device_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(device);
 
+static ssize_t
+device_name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct tb_switch *sw = tb_to_switch(dev);
+
+	return sprintf(buf, "%s\n", sw->device_name ? sw->device_name : "");
+}
+static DEVICE_ATTR_RO(device_name);
+
 static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
 			   char *buf)
 {
@@ -328,6 +337,15 @@ static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(vendor);
 
+static ssize_t
+vendor_name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct tb_switch *sw = tb_to_switch(dev);
+
+	return sprintf(buf, "%s\n", sw->vendor_name ? sw->vendor_name : "");
+}
+static DEVICE_ATTR_RO(vendor_name);
+
 static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
 			      char *buf)
 {
@@ -339,7 +357,9 @@ static DEVICE_ATTR_RO(unique_id);
 
 static struct attribute *switch_attrs[] = {
 	&dev_attr_device.attr,
+	&dev_attr_device_name.attr,
 	&dev_attr_vendor.attr,
+	&dev_attr_vendor_name.attr,
 	&dev_attr_unique_id.attr,
 	NULL,
 };
@@ -358,6 +378,8 @@ static void tb_switch_release(struct device *dev)
 	struct tb_switch *sw = tb_to_switch(dev);
 
 	kfree(sw->uuid);
+	kfree(sw->device_name);
+	kfree(sw->vendor_name);
 	kfree(sw->ports);
 	kfree(sw->drom);
 	kfree(sw);
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 350c3f21924e..5e66dce53c65 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -23,6 +23,8 @@
  * @uuid: UUID of the switch (or %NULL if not supported)
  * @vendor: Vendor ID of the switch
  * @device: Device ID of the switch
+ * @vendor_name: Name of the vendor (or %NULL if not known)
+ * @device_name: Name of the device (or %NULL if not known)
  * @cap_plug_events: Offset to the plug events capability (%0 if not found)
  * @is_unplugged: The switch is going away
  * @drom: DROM of the switch (%NULL if not found)
@@ -36,6 +38,8 @@ struct tb_switch {
 	uuid_be *uuid;
 	u16 vendor;
 	u16 device;
+	const char *vendor_name;
+	const char *device_name;
 	int cap_plug_events;
 	bool is_unplugged;
 	u8 *drom;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1656272 — [PATCH v3 11/27] thunderbolt: Do not fail if DROM data CRC32 is invalid

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-02 16:20 +0200
Subject[PATCH v3 11/27] thunderbolt: Do not fail if DROM data CRC32 is invalid
Message-ID<tNVAK-2ht-13@gated-at.bofh.it>
In reply to#1656243
There are devices out there where CRC32 of the DROM is not correct. One
reason for this is that the ICM firmware does not validate it and it
seems that neither does the Apple driver. To be able to support such
devices we continue parsing the DROM contents regardless of whether
CRC32 failed or not. We still keep the warning there.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Michael Jamet <michael.jamet@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/thunderbolt/eeprom.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index 7e485e3ef27e..e2c1f8a45522 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -485,9 +485,8 @@ int tb_drom_read(struct tb_switch *sw)
 	crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len);
 	if (crc != header->data_crc32) {
 		tb_sw_warn(sw,
-			"drom data crc32 mismatch (expected: %#x, got: %#x), aborting\n",
+			"drom data crc32 mismatch (expected: %#x, got: %#x), continuing\n",
 			header->data_crc32, crc);
-		goto err;
 	}
 
 	if (header->device_rom_revision > 2)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1656273 — [PATCH v3 09/27] thunderbolt: Convert switch to a device

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-02 16:20 +0200
Subject[PATCH v3 09/27] thunderbolt: Convert switch to a device
Message-ID<tNVAL-2ht-25@gated-at.bofh.it>
In reply to#1656243
Thunderbolt domain consists of switches that are connected to each
other, forming a bus. This will convert each switch into a real Linux
device structure and adds them to the domain. The advantage here is
that we get all the goodies from the driver core, like reference
counting and sysfs hierarchy for free.

Also expose device identification information to the userspace via new
sysfs attributes.

In order to support internal connection manager (ICM) we separate switch
configuration into its own function (tb_switch_configure()) which is
only called by the existing native connection manager implementation
used on Macs.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Michael Jamet <michael.jamet@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 Documentation/ABI/testing/sysfs-bus-thunderbolt |  22 ++
 drivers/thunderbolt/eeprom.c                    |   2 +
 drivers/thunderbolt/switch.c                    | 261 +++++++++++++++++++-----
 drivers/thunderbolt/tb.c                        |  40 +++-
 drivers/thunderbolt/tb.h                        |  45 +++-
 5 files changed, 303 insertions(+), 67 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-thunderbolt

diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt
new file mode 100644
index 000000000000..9f1bd0086938
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt
@@ -0,0 +1,22 @@
+What:		/sys/bus/thunderbolt/devices/.../device
+Date:		Sep 2017
+KernelVersion:	4.13
+Contact:	thunderbolt-software@lists.01.org
+Description:	This attribute contains id of this device extracted from
+		the device DROM.
+
+What:		/sys/bus/thunderbolt/devices/.../vendor
+Date:		Sep 2017
+KernelVersion:	4.13
+Contact:	thunderbolt-software@lists.01.org
+Description:	This attribute contains vendor id of this device extracted
+		from the device DROM.
+
+What:		/sys/bus/thunderbolt/devices/.../unique_id
+Date:		Sep 2017
+KernelVersion:	4.13
+Contact:	thunderbolt-software@lists.01.org
+Description:	This attribute contains unique_id string of this device.
+		This is either read from hardware registers (UUID on
+		newer hardware) or based on UID from the device DROM.
+		Can be used to uniquely identify particular device.
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index eb2179c98b09..7e485e3ef27e 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -479,6 +479,8 @@ int tb_drom_read(struct tb_switch *sw)
 		goto err;
 	}
 	sw->uid = header->uid;
+	sw->vendor = header->vendor_id;
+	sw->device = header->model_id;
 
 	crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len);
 	if (crc != header->data_crc32) {
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index c02079424d0e..5cd854dedeea 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -281,6 +281,9 @@ static int tb_plug_events_active(struct tb_switch *sw, bool active)
 	u32 data;
 	int res;
 
+	if (!sw->config.enabled)
+		return 0;
+
 	sw->config.plug_events_delay = 0xff;
 	res = tb_sw_write(sw, ((u32 *) &sw->config) + 4, TB_CFG_SWITCH, 4, 1);
 	if (res)
@@ -307,36 +310,79 @@ static int tb_plug_events_active(struct tb_switch *sw, bool active)
 			   sw->cap_plug_events + 1, 1);
 }
 
+static ssize_t device_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct tb_switch *sw = tb_to_switch(dev);
 
-/**
- * tb_switch_free() - free a tb_switch and all downstream switches
- */
-void tb_switch_free(struct tb_switch *sw)
+	return sprintf(buf, "%#x\n", sw->device);
+}
+static DEVICE_ATTR_RO(device);
+
+static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
-	int i;
-	/* port 0 is the switch itself and never has a remote */
-	for (i = 1; i <= sw->config.max_port_number; i++) {
-		if (tb_is_upstream_port(&sw->ports[i]))
-			continue;
-		if (sw->ports[i].remote)
-			tb_switch_free(sw->ports[i].remote->sw);
-		sw->ports[i].remote = NULL;
-	}
+	struct tb_switch *sw = tb_to_switch(dev);
 
-	if (!sw->is_unplugged)
-		tb_plug_events_active(sw, false);
+	return sprintf(buf, "%#x\n", sw->vendor);
+}
+static DEVICE_ATTR_RO(vendor);
+
+static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
+			      char *buf)
+{
+	struct tb_switch *sw = tb_to_switch(dev);
+
+	return sprintf(buf, "%pUb\n", sw->uuid);
+}
+static DEVICE_ATTR_RO(unique_id);
+
+static struct attribute *switch_attrs[] = {
+	&dev_attr_device.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_unique_id.attr,
+	NULL,
+};
+
+static struct attribute_group switch_group = {
+	.attrs = switch_attrs,
+};
 
+static const struct attribute_group *switch_groups[] = {
+	&switch_group,
+	NULL,
+};
+
+static void tb_switch_release(struct device *dev)
+{
+	struct tb_switch *sw = tb_to_switch(dev);
+
+	kfree(sw->uuid);
 	kfree(sw->ports);
 	kfree(sw->drom);
 	kfree(sw);
 }
 
+struct device_type tb_switch_type = {
+	.name = "thunderbolt_device",
+	.release = tb_switch_release,
+};
+
 /**
- * tb_switch_alloc() - allocate and initialize a switch
+ * tb_switch_alloc() - allocate a switch
+ * @tb: Pointer to the owning domain
+ * @parent: Parent device for this switch
+ * @route: Route string for this switch
  *
- * Return: Returns a NULL on failure.
+ * Allocates and initializes a switch. Will not upload configuration to
+ * the switch. For that you need to call tb_switch_configure()
+ * separately. The returned switch should be released by calling
+ * tb_switch_put().
+ *
+ * Return: Pointer to the allocated switch or %NULL in case of failure
  */
-struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
+struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
+				  u64 route)
 {
 	int i;
 	int cap;
@@ -351,11 +397,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
 
 	sw->tb = tb;
 	if (tb_cfg_read(tb->ctl, &sw->config, route, 0, TB_CFG_SWITCH, 0, 5))
-		goto err;
-	tb_info(tb,
-		"initializing Switch at %#llx (depth: %d, up port: %d)\n",
-		route, tb_route_length(route), upstream_port);
-	tb_info(tb, "old switch config:\n");
+		goto err_free_sw_ports;
+
+	tb_info(tb, "current switch config:\n");
 	tb_dump_switch(tb, &sw->config);
 
 	/* configure switch */
@@ -363,30 +407,13 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
 	sw->config.depth = tb_route_length(route);
 	sw->config.route_lo = route;
 	sw->config.route_hi = route >> 32;
-	sw->config.enabled = 1;
-	/* from here on we may use the tb_sw_* functions & macros */
-
-	if (sw->config.vendor_id != 0x8086)
-		tb_sw_warn(sw, "unknown switch vendor id %#x\n",
-			   sw->config.vendor_id);
-
-	if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE &&
-	    sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C &&
-	    sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE &&
-	    sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE &&
-	    sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE)
-		tb_sw_warn(sw, "unsupported switch device id %#x\n",
-			   sw->config.device_id);
-
-	/* upload configuration */
-	if (tb_sw_write(sw, 1 + (u32 *) &sw->config, TB_CFG_SWITCH, 1, 3))
-		goto err;
+	sw->config.enabled = 0;
 
 	/* initialize ports */
 	sw->ports = kcalloc(sw->config.max_port_number + 1, sizeof(*sw->ports),
 				GFP_KERNEL);
 	if (!sw->ports)
-		goto err;
+		goto err_free_sw_ports;
 
 	for (i = 0; i <= sw->config.max_port_number; i++) {
 		/* minimum setup for tb_find_cap and tb_drom_read to work */
@@ -397,35 +424,161 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
 	cap = tb_switch_find_vsec_cap(sw, TB_VSEC_CAP_PLUG_EVENTS);
 	if (cap < 0) {
 		tb_sw_warn(sw, "cannot find TB_VSEC_CAP_PLUG_EVENTS aborting\n");
-		goto err;
+		goto err_free_sw_ports;
 	}
 	sw->cap_plug_events = cap;
 
+	device_initialize(&sw->dev);
+	sw->dev.parent = parent;
+	sw->dev.bus = &tb_bus_type;
+	sw->dev.type = &tb_switch_type;
+	sw->dev.groups = switch_groups;
+	dev_set_name(&sw->dev, "%u-%llx", tb->index, tb_route(sw));
+
+	return sw;
+
+err_free_sw_ports:
+	kfree(sw->ports);
+	kfree(sw);
+
+	return NULL;
+}
+
+/**
+ * tb_switch_configure() - Uploads configuration to the switch
+ * @sw: Switch to configure
+ *
+ * Call this function before the switch is added to the system. It will
+ * upload configuration to the switch and makes it available for the
+ * connection manager to use.
+ *
+ * Return: %0 in case of success and negative errno in case of failure
+ */
+int tb_switch_configure(struct tb_switch *sw)
+{
+	struct tb *tb = sw->tb;
+	u64 route;
+	int ret;
+
+	route = tb_route(sw);
+	tb_info(tb,
+		"initializing Switch at %#llx (depth: %d, up port: %d)\n",
+		route, tb_route_length(route), sw->config.upstream_port_number);
+
+	if (sw->config.vendor_id != PCI_VENDOR_ID_INTEL)
+		tb_sw_warn(sw, "unknown switch vendor id %#x\n",
+			   sw->config.vendor_id);
+
+	if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE &&
+	    sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C &&
+	    sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE &&
+	    sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE &&
+	    sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE)
+		tb_sw_warn(sw, "unsupported switch device id %#x\n",
+			   sw->config.device_id);
+
+	sw->config.enabled = 1;
+
+	/* upload configuration */
+	ret = tb_sw_write(sw, 1 + (u32 *)&sw->config, TB_CFG_SWITCH, 1, 3);
+	if (ret)
+		return ret;
+
+	return tb_plug_events_active(sw, true);
+}
+
+static void tb_switch_set_uuid(struct tb_switch *sw)
+{
+	u32 uuid[4];
+	int cap;
+
+	if (sw->uuid)
+		return;
+
+	/*
+	 * The newer controllers include fused UUID as part of link
+	 * controller specific registers
+	 */
+	cap = tb_switch_find_vsec_cap(sw, TB_VSEC_CAP_LINK_CONTROLLER);
+	if (cap > 0) {
+		tb_sw_read(sw, uuid, TB_CFG_SWITCH, cap + 3, 4);
+	} else {
+		/*
+		 * ICM generates UUID based on UID and fills the upper
+		 * two words with ones. This is not strictly following
+		 * UUID format but we want to be compatible with it so
+		 * we do the same here.
+		 */
+		uuid[0] = sw->uid & 0xffffffff;
+		uuid[1] = (sw->uid >> 32) & 0xffffffff;
+		uuid[2] = 0xffffffff;
+		uuid[3] = 0xffffffff;
+	}
+
+	sw->uuid = kmemdup(uuid, sizeof(uuid), GFP_KERNEL);
+}
+
+/**
+ * tb_switch_add() - Add a switch to the domain
+ * @sw: Switch to add
+ *
+ * This is the last step in adding switch to the domain. It will read
+ * identification information from DROM and initializes ports so that
+ * they can be used to connect other switches. The switch will be
+ * exposed to the userspace when this function successfully returns. To
+ * remove and release the switch, call tb_switch_remove().
+ *
+ * Return: %0 in case of success and negative errno in case of failure
+ */
+int tb_switch_add(struct tb_switch *sw)
+{
+	int i, ret;
+
 	/* read drom */
 	if (tb_drom_read(sw))
 		tb_sw_warn(sw, "tb_eeprom_read_rom failed, continuing\n");
 	tb_sw_info(sw, "uid: %#llx\n", sw->uid);
 
+	tb_switch_set_uuid(sw);
+
 	for (i = 0; i <= sw->config.max_port_number; i++) {
 		if (sw->ports[i].disabled) {
 			tb_port_info(&sw->ports[i], "disabled by eeprom\n");
 			continue;
 		}
-		if (tb_init_port(&sw->ports[i]))
-			goto err;
+		ret = tb_init_port(&sw->ports[i]);
+		if (ret)
+			return ret;
 	}
 
-	/* TODO: I2C, IECS, link controller */
+	return device_add(&sw->dev);
+}
 
-	if (tb_plug_events_active(sw, true))
-		goto err;
+/**
+ * tb_switch_remove() - Remove and release a switch
+ * @sw: Switch to remove
+ *
+ * This will remove the switch from the domain and release it after last
+ * reference count drops to zero. If there are switches connected below
+ * this switch, they will be removed as well.
+ */
+void tb_switch_remove(struct tb_switch *sw)
+{
+	int i;
 
-	return sw;
-err:
-	kfree(sw->ports);
-	kfree(sw->drom);
-	kfree(sw);
-	return NULL;
+	/* port 0 is the switch itself and never has a remote */
+	for (i = 1; i <= sw->config.max_port_number; i++) {
+		if (tb_is_upstream_port(&sw->ports[i]))
+			continue;
+		if (sw->ports[i].remote)
+			tb_switch_remove(sw->ports[i].remote->sw);
+		sw->ports[i].remote = NULL;
+	}
+
+	if (!sw->is_unplugged)
+		tb_plug_events_active(sw, false);
+
+	device_unregister(&sw->dev);
 }
 
 /**
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 9f00a0f28d53..94ecac012428 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -61,9 +61,21 @@ static void tb_scan_port(struct tb_port *port)
 		tb_port_WARN(port, "port already has a remote!\n");
 		return;
 	}
-	sw = tb_switch_alloc(port->sw->tb, tb_downstream_route(port));
+	sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
+			     tb_downstream_route(port));
 	if (!sw)
 		return;
+
+	if (tb_switch_configure(sw)) {
+		tb_switch_put(sw);
+		return;
+	}
+
+	if (tb_switch_add(sw)) {
+		tb_switch_put(sw);
+		return;
+	}
+
 	port->remote = tb_upstream_port(sw);
 	tb_upstream_port(sw)->remote = port;
 	tb_scan_switch(sw);
@@ -100,7 +112,7 @@ static void tb_free_unplugged_children(struct tb_switch *sw)
 		if (!port->remote)
 			continue;
 		if (port->remote->sw->is_unplugged) {
-			tb_switch_free(port->remote->sw);
+			tb_switch_remove(port->remote->sw);
 			port->remote = NULL;
 		} else {
 			tb_free_unplugged_children(port->remote->sw);
@@ -266,7 +278,7 @@ static void tb_handle_hotplug(struct work_struct *work)
 			tb_port_info(port, "unplugged\n");
 			tb_sw_set_unplugged(port->remote->sw);
 			tb_free_invalid_tunnels(tb);
-			tb_switch_free(port->remote->sw);
+			tb_switch_remove(port->remote->sw);
 			port->remote = NULL;
 		} else {
 			tb_port_info(port,
@@ -325,22 +337,32 @@ static void tb_stop(struct tb *tb)
 		tb_pci_deactivate(tunnel);
 		tb_pci_free(tunnel);
 	}
-
-	if (tb->root_switch)
-		tb_switch_free(tb->root_switch);
-	tb->root_switch = NULL;
-
+	tb_switch_remove(tb->root_switch);
 	tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */
 }
 
 static int tb_start(struct tb *tb)
 {
 	struct tb_cm *tcm = tb_priv(tb);
+	int ret;
 
-	tb->root_switch = tb_switch_alloc(tb, 0);
+	tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
 	if (!tb->root_switch)
 		return -ENOMEM;
 
+	ret = tb_switch_configure(tb->root_switch);
+	if (ret) {
+		tb_switch_put(tb->root_switch);
+		return ret;
+	}
+
+	/* Announce the switch to the world */
+	ret = tb_switch_add(tb->root_switch);
+	if (ret) {
+		tb_switch_put(tb->root_switch);
+		return ret;
+	}
+
 	/* Full scan to discover devices added before the driver was loaded. */
 	tb_scan_switch(tb->root_switch);
 	tb_activate_pcie_devices(tb);
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index ce9db64e3333..350c3f21924e 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -8,20 +8,36 @@
 #define TB_H_
 
 #include <linux/pci.h>
+#include <linux/uuid.h>
 
 #include "tb_regs.h"
 #include "ctl.h"
 
 /**
  * struct tb_switch - a thunderbolt switch
+ * @dev: Device for the switch
+ * @config: Switch configuration
+ * @ports: Ports in this switch
+ * @tb: Pointer to the domain the switch belongs to
+ * @uid: Unique ID of the switch
+ * @uuid: UUID of the switch (or %NULL if not supported)
+ * @vendor: Vendor ID of the switch
+ * @device: Device ID of the switch
+ * @cap_plug_events: Offset to the plug events capability (%0 if not found)
+ * @is_unplugged: The switch is going away
+ * @drom: DROM of the switch (%NULL if not found)
  */
 struct tb_switch {
+	struct device dev;
 	struct tb_regs_switch_header config;
 	struct tb_port *ports;
 	struct tb *tb;
 	u64 uid;
-	int cap_plug_events; /* offset, zero if not found */
-	bool is_unplugged; /* unplugged, will go away */
+	uuid_be *uuid;
+	u16 vendor;
+	u16 device;
+	int cap_plug_events;
+	bool is_unplugged;
 	u8 *drom;
 };
 
@@ -242,6 +258,7 @@ struct tb *tb_probe(struct tb_nhi *nhi);
 
 extern struct bus_type tb_bus_type;
 extern struct device_type tb_domain_type;
+extern struct device_type tb_switch_type;
 
 int tb_domain_init(void);
 void tb_domain_exit(void);
@@ -257,14 +274,34 @@ static inline void tb_domain_put(struct tb *tb)
 	put_device(&tb->dev);
 }
 
-struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route);
-void tb_switch_free(struct tb_switch *sw);
+struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
+				  u64 route);
+int tb_switch_configure(struct tb_switch *sw);
+int tb_switch_add(struct tb_switch *sw);
+void tb_switch_remove(struct tb_switch *sw);
 void tb_switch_suspend(struct tb_switch *sw);
 int tb_switch_resume(struct tb_switch *sw);
 int tb_switch_reset(struct tb *tb, u64 route);
 void tb_sw_set_unplugged(struct tb_switch *sw);
 struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
 
+static inline void tb_switch_put(struct tb_switch *sw)
+{
+	put_device(&sw->dev);
+}
+
+static inline bool tb_is_switch(const struct device *dev)
+{
+	return dev->type == &tb_switch_type;
+}
+
+static inline struct tb_switch *tb_to_switch(struct device *dev)
+{
+	if (tb_is_switch(dev))
+		return container_of(dev, struct tb_switch, dev);
+	return NULL;
+}
+
 int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged);
 int tb_port_add_nfc_credits(struct tb_port *port, int credits);
 int tb_port_clear_counter(struct tb_port *port, int counter);
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1656831 — Re: [PATCH v3 09/27] thunderbolt: Convert switch to a device

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2017-06-03 16:20 +0200
SubjectRe: [PATCH v3 09/27] thunderbolt: Convert switch to a device
Message-ID<tOi4i-850-21@gated-at.bofh.it>
In reply to#1656273
On Fri, Jun 02, 2017 at 05:05:06PM +0300, Mika Westerberg wrote:
> Thunderbolt domain consists of switches that are connected to each
> other, forming a bus. This will convert each switch into a real Linux
> device structure and adds them to the domain. The advantage here is
> that we get all the goodies from the driver core, like reference
> counting and sysfs hierarchy for free.
> 
> Also expose device identification information to the userspace via new
> sysfs attributes.
> 
> In order to support internal connection manager (ICM) we separate switch
> configuration into its own function (tb_switch_configure()) which is
> only called by the existing native connection manager implementation
> used on Macs.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
> Reviewed-by: Michael Jamet <michael.jamet@intel.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  Documentation/ABI/testing/sysfs-bus-thunderbolt |  22 ++
>  drivers/thunderbolt/eeprom.c                    |   2 +
>  drivers/thunderbolt/switch.c                    | 261 +++++++++++++++++++-----
>  drivers/thunderbolt/tb.c                        |  40 +++-
>  drivers/thunderbolt/tb.h                        |  45 +++-
>  5 files changed, 303 insertions(+), 67 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-thunderbolt

For the driver model type changes, looks good to me, nice job:

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

[toc] | [prev] | [next] | [standalone]


#1656275 — [PATCH v3 21/27] thunderbolt: Store Thunderbolt generation in the switch structure

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-02 16:20 +0200
Subject[PATCH v3 21/27] thunderbolt: Store Thunderbolt generation in the switch structure
Message-ID<tNVAL-2ht-31@gated-at.bofh.it>
In reply to#1656243
In some cases it is useful to know what is the Thunderbolt generation
the switch supports. This introduces a new field to struct switch that
stores the generation of the switch based on the device ID. Unknown
switches (there should be none) are assumed to be first generation to be
on the safe side.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Michael Jamet <michael.jamet@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/thunderbolt/switch.c | 55 ++++++++++++++++++++++++++++++--------------
 drivers/thunderbolt/tb.h     |  2 ++
 2 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 8006577590ed..56b99ad2099d 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -390,6 +390,42 @@ struct device_type tb_switch_type = {
 	.release = tb_switch_release,
 };
 
+static int tb_switch_get_generation(struct tb_switch *sw)
+{
+	switch (sw->config.device_id) {
+	case PCI_DEVICE_ID_INTEL_LIGHT_RIDGE:
+	case PCI_DEVICE_ID_INTEL_EAGLE_RIDGE:
+	case PCI_DEVICE_ID_INTEL_LIGHT_PEAK:
+	case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C:
+	case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
+	case PCI_DEVICE_ID_INTEL_PORT_RIDGE:
+	case PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE:
+		return 1;
+
+	case PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE:
+		return 2;
+
+	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
+	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
+		return 3;
+
+	default:
+		/*
+		 * For unknown switches assume generation to be 1 to be
+		 * on the safe side.
+		 */
+		tb_sw_warn(sw, "unsupported switch device id %#x\n",
+			   sw->config.device_id);
+		return 1;
+	}
+}
+
 /**
  * tb_switch_alloc() - allocate a switch
  * @tb: Pointer to the owning domain
@@ -443,6 +479,8 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
 		sw->ports[i].port = i;
 	}
 
+	sw->generation = tb_switch_get_generation(sw);
+
 	cap = tb_switch_find_vsec_cap(sw, TB_VSEC_CAP_PLUG_EVENTS);
 	if (cap < 0) {
 		tb_sw_warn(sw, "cannot find TB_VSEC_CAP_PLUG_EVENTS aborting\n");
@@ -491,23 +529,6 @@ int tb_switch_configure(struct tb_switch *sw)
 		tb_sw_warn(sw, "unknown switch vendor id %#x\n",
 			   sw->config.vendor_id);
 
-	switch (sw->config.device_id) {
-	case PCI_DEVICE_ID_INTEL_LIGHT_RIDGE:
-	case PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C:
-	case PCI_DEVICE_ID_INTEL_PORT_RIDGE:
-	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE:
-	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE:
-	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE:
-	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:
-	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
-	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
-		break;
-
-	default:
-		tb_sw_warn(sw, "unsupported switch device id %#x\n",
-			   sw->config.device_id);
-	}
-
 	sw->config.enabled = 1;
 
 	/* upload configuration */
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 0be989069941..b3cda7605619 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -25,6 +25,7 @@
  * @device: Device ID of the switch
  * @vendor_name: Name of the vendor (or %NULL if not known)
  * @device_name: Name of the device (or %NULL if not known)
+ * @generation: Switch Thunderbolt generation
  * @cap_plug_events: Offset to the plug events capability (%0 if not found)
  * @is_unplugged: The switch is going away
  * @drom: DROM of the switch (%NULL if not found)
@@ -40,6 +41,7 @@ struct tb_switch {
 	u16 device;
 	const char *vendor_name;
 	const char *device_name;
+	unsigned int generation;
 	int cap_plug_events;
 	bool is_unplugged;
 	u8 *drom;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1656440 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Date2017-06-02 20:10 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tNZbk-4Ci-7@gated-at.bofh.it>
In reply to#1656243
On Fri, 2017-06-02 at 17:04 +0300, Mika Westerberg wrote:
> Hi,
> 
> This is a third version of the patch series adding support for
> Thunderbolt
> security levels and NVM firmware upgrade. PCs running Intel Falcon
> Ridge or
> newer need these in order to connect devices if the security level is
> set
> to "user(SL1) or secure(SL2)" from BIOS.
> 
> The security levels were added to to prevent DMA attacks when PCIe is
> tunneled over Thunderbolt fabric where IOMMU is not available or
> cannot be
> enabled for different reasons.
> 
> This series converts the Thunderbolt driver to a Linux bus and makes
> each
> Thunderbolt device (aka Thunderbolt switch or router or endpoint) a
> Linux
> device which is connected to that bus addressed by their routing
> string
> (this is the addressing Thunderbolt uses).
> 
> With these patches the user can authorize devices using sysfs
> attributes
> like (following USB):
> 
>   # echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized
> 
> If the BIOS security level is set to "secure" and the device supports
> secure connect on the first connect the device is uploaded a random
> key:
> 
>   # key=$(openssl rand -hex 32)
>   # echo $key > /sys/bus/thunderbolt/devices/0-1/key
>   # echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized
> 
> Next time the device is plugged in the user can verify (challenge) the
> device using the same key:
> 
>   # echo $key > /sys/bus/thunderbolt/devices/0-1/key
>   # echo 2 > /sys/bus/thunderbolt/devices/0-1/authorized
> 
> The device identification information is found below each device sysfs
> node and includes following attributes:
> 
>   device	- Device ID
>   device_name	- Name of the device
>   vendor	- Vendor ID
>   vendor_name	- Name of the vendor
>   unique_id	- Unique ID string identifying this particular
> device
> 
> In addition these patches add support for upgrading NVM firmware
> running on
> a host or device by running something like:
> 
>   # dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-
> 0/nvm_non_active0/nvmem
>   # echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
> 
> More information how to use the Thunderbolt bus can be found in patch
> [26/27].
> 
> Where Internal Connection Manager (ICM) firmware is available and
> usable,
> we use it in the driver. This also includes newer Apple Macbooks with
> Alpine Ridge. For older Macbooks the driver works as before but in
> addition
> the Thunderbolt bus is available there as well (including possibility
> to
> upgrade NVM firmware of connected devices).
> 
> Note for Macs the Linux native PCIe hotplug support does not work well
> with
> the Thunderbolt PCIe topologies where there is need to put all
> available
> resources to the PCIe downstream port where the PCIe chain is
> extended.
> This is something we need to fix. In the mean time is a way to work it
> around by passing "pci=hpbussize=10,hpmemsize=2M" or so to the kernel
> command line.
> 
> Regarding Christoph's UUID series here [1], they now include the
> existing
> types for backwards compatibility so this series compiles and works
> fine
> with them. We will convert the Thunderbolt driver to use these new
> types
> once that series hits mainline.
> 
> Andreas and Lukas, do you have any comments or concerns regarding this
> series?
> 
> We are currently porting Amir's network driver on top of the
> Thunderbolt
> bus.
> 
> The previous version (v2) can be found in [2].
> 
> [1] http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/uu
> id-types
> [2] https://lwn.net/Articles/723935/
> 

Awesome work, Mika!

Have no more to comment.

> Changes from the previos version (v2):
> 
> [PATCH v2 03/27] thunderbolt: Do not try to read UID if DROM offset is
> read as 0
>   - Add Suggested-by Andreas
> 
> [PATCH v2 07/27] thunderbolt: Allow passing NULL to tb_ctl_free()
>   - Add Suggested-by Andy
> 
> [PATCH v2 09/27] thunderbolt: Convert switch to a device
>   - Rework comment regarding UUID to mention that it is not strictly
>     following rules of UUID format.
>   - Update Documentation/ABI/testing/sysfs-bus-thunderbolt unique_id
>     attribute description accordingly.
> 
> [PATCH v2 12/27] thunderbolt: Refactor and fix parsing of port drom
> entries
>   - Add Reviewed-by Andy
> 
> [PATCH v2 13/27] thunderbolt: Read vendor and device name from DROM
>   - Use ksrtndup() instead and drop parse_name()
> 
> [PATCH v2 21/27] thunderbolt: Store Thunderbolt generation in the
> switch structure
>   - Make the unknown switch defaulting to generation 1 more explicit
>   - Add Reviewed-by Andy
> 
> [PATCH v2 24/27] thunderbolt: Add support for Internal Connection
> Manager (ICM)
>   - Allow secure connect only when BIOS setting is in "secure
>     connect/SL2" to follow what Windows does.
> 
> [PATCH v2 25/27] thunderbolt: Add support for host and device NVM
> firmware upgrade
>   - Add check for sw->nvm in nvm_authenticate_store() to prevent NULL
>     pointer dereference when NVMem devices are not yet added.
> 
> [PATCH v2 26/27] thunderbolt: Add documentation how Thunderbolt bus
> can be used
>   - Update documentation to mention that secure connect is only
>     available when the BIOS setting is in "secure connect/SL2".
> 
> Lukas Wunner (1):
>   thunderbolt: Refactor and fix parsing of port drom entries
> 
> Mika Westerberg (26):
>   thunderbolt: Use const buffer pointer in write operations
>   thunderbolt: No need to read UID of the root switch on resume
>   thunderbolt: Do not try to read UID if DROM offset is read as 0
>   thunderbolt: Do not warn about newer DROM versions
>   thunderbolt: Add MSI-X support
>   thunderbolt: Rework capability handling
>   thunderbolt: Allow passing NULL to tb_ctl_free()
>   thunderbolt: Introduce thunderbolt bus and connection manager
>   thunderbolt: Convert switch to a device
>   thunderbolt: Fail switch adding operation if reading DROM fails
>   thunderbolt: Do not fail if DROM data CRC32 is invalid
>   thunderbolt: Read vendor and device name from DROM
>   thunderbolt: Move control channel messages to tb_msgs.h
>   thunderbolt: Expose get_route() to other files
>   thunderbolt: Expose make_header() to other files
>   thunderbolt: Let the connection manager handle all notifications
>   thunderbolt: Rework control channel to be more reliable
>   thunderbolt: Add new Thunderbolt PCI IDs
>   thunderbolt: Add support for NHI mailbox
>   thunderbolt: Store Thunderbolt generation in the switch structure
>   thunderbolt: Add support for DMA configuration based mailbox
>   thunderbolt: Do not touch the hardware if the NHI is gone on resume
>   thunderbolt: Add support for Internal Connection Manager (ICM)
>   thunderbolt: Add support for host and device NVM firmware upgrade
>   thunderbolt: Add documentation how Thunderbolt bus can be used
>   MAINTAINERS: Add maintainers for Thunderbolt driver
> 
>  Documentation/ABI/testing/sysfs-bus-thunderbolt |  110 +++
>  Documentation/admin-guide/index.rst             |    1 +
>  Documentation/admin-guide/thunderbolt.rst       |  199 ++++
>  MAINTAINERS                                     |    3 +
>  drivers/thunderbolt/Kconfig                     |   13 +-
>  drivers/thunderbolt/Makefile                    |    2 +-
>  drivers/thunderbolt/cap.c                       |  169 ++--
>  drivers/thunderbolt/ctl.c                       |  665 +++++++++----
>  drivers/thunderbolt/ctl.h                       |  105 +-
>  drivers/thunderbolt/dma_port.c                  |  524 ++++++++++
>  drivers/thunderbolt/dma_port.h                  |   34 +
>  drivers/thunderbolt/domain.c                    |  455 +++++++++
>  drivers/thunderbolt/eeprom.c                    |  119 ++-
>  drivers/thunderbolt/icm.c                       | 1089
> +++++++++++++++++++++
>  drivers/thunderbolt/nhi.c                       |  306 +++++-
>  drivers/thunderbolt/nhi.h                       |   93 +-
>  drivers/thunderbolt/nhi_regs.h                  |   27 +
>  drivers/thunderbolt/switch.c                    | 1178
> +++++++++++++++++++++--
>  drivers/thunderbolt/tb.c                        |  237 +++--
>  drivers/thunderbolt/tb.h                        |  251 ++++-
>  drivers/thunderbolt/tb_msgs.h                   |  260 +++++
>  drivers/thunderbolt/tb_regs.h                   |   50 +-
>  drivers/thunderbolt/tunnel_pci.c                |   17 +-
>  23 files changed, 5323 insertions(+), 584 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-thunderbolt
>  create mode 100644 Documentation/admin-guide/thunderbolt.rst
>  create mode 100644 drivers/thunderbolt/dma_port.c
>  create mode 100644 drivers/thunderbolt/dma_port.h
>  create mode 100644 drivers/thunderbolt/domain.c
>  create mode 100644 drivers/thunderbolt/icm.c
>  create mode 100644 drivers/thunderbolt/tb_msgs.h
> 

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

[toc] | [prev] | [next] | [standalone]


#1656837 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2017-06-03 16:20 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tOi4j-850-51@gated-at.bofh.it>
In reply to#1656243
On Fri, Jun 02, 2017 at 05:04:57PM +0300, Mika Westerberg wrote:
> Hi,
> 
> This is a third version of the patch series adding support for Thunderbolt
> security levels and NVM firmware upgrade. PCs running Intel Falcon Ridge or
> newer need these in order to connect devices if the security level is set
> to "user(SL1) or secure(SL2)" from BIOS.

All looks good to me, very nice work.

I don't know what tree it should go in through, but if Andreas wants me
to take it, I will if I can get his signed-off-by.

thanks,

greg k-h

[toc] | [prev] | [next] | [standalone]


#1657320 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-05 09:20 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tOUsV-8gF-9@gated-at.bofh.it>
In reply to#1656837
On Sat, Jun 03, 2017 at 06:17:04PM +0900, Greg Kroah-Hartman wrote:
> On Fri, Jun 02, 2017 at 05:04:57PM +0300, Mika Westerberg wrote:
> > Hi,
> > 
> > This is a third version of the patch series adding support for Thunderbolt
> > security levels and NVM firmware upgrade. PCs running Intel Falcon Ridge or
> > newer need these in order to connect devices if the security level is set
> > to "user(SL1) or secure(SL2)" from BIOS.
> 
> All looks good to me, very nice work.

Thanks!

> I don't know what tree it should go in through, but if Andreas wants me
> to take it, I will if I can get his signed-off-by.

That would be perfect.

Andreas, do you have any objections?

I will prepare another version where I've fixed the VSEC vs. VSE thing
in the capability rework patch.

[toc] | [prev] | [next] | [standalone]


#1657956

FromAndreas Noever <andreas.noever@gmail.com>
Date2017-06-05 19:10 +0200
Message-ID<tP3FW-5Hz-73@gated-at.bofh.it>
In reply to#1657320
On Mon, Jun 5, 2017 at 9:18 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Sat, Jun 03, 2017 at 06:17:04PM +0900, Greg Kroah-Hartman wrote:
>> On Fri, Jun 02, 2017 at 05:04:57PM +0300, Mika Westerberg wrote:
>> > Hi,
>> >
>> > This is a third version of the patch series adding support for Thunderbolt
>> > security levels and NVM firmware upgrade. PCs running Intel Falcon Ridge or
>> > newer need these in order to connect devices if the security level is set
>> > to "user(SL1) or secure(SL2)" from BIOS.
>>
>> All looks good to me, very nice work.
>
> Thanks!
>
>> I don't know what tree it should go in through, but if Andreas wants me
>> to take it, I will if I can get his signed-off-by.
>
> That would be perfect.
>
> Andreas, do you have any objections?
No, Thanks a lot.

Signed-off-by: Andreas Noever <andreas.noever@gmail.com>

Greg, can you take this through your tree?



Mika, I have a quick question regarding the pci side of things (your
"pci=hpbussize=10,hpmemsize=2M" workaround). Does that work for nested
hotplug or just on the first level? Back when I was having a look at
enabling chaining in the native driver I could not get pci to properly
assign bus numbers to nested bridges. It always ran out of bus number
after one level (irregardless of hpbussize). Has the pci behaviour
changed or does the ICM somehow preconfigure the bridges before
handing them of to linux?

Cheers
Andreas


> I will prepare another version where I've fixed the VSEC vs. VSE thing
> in the capability rework patch.

[toc] | [prev] | [next] | [standalone]


#1658113 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-05 21:50 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tP6aK-76s-9@gated-at.bofh.it>
In reply to#1657956
On Mon, Jun 05, 2017 at 07:01:10PM +0200, Andreas Noever wrote:
> On Mon, Jun 5, 2017 at 9:18 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Sat, Jun 03, 2017 at 06:17:04PM +0900, Greg Kroah-Hartman wrote:
> >> On Fri, Jun 02, 2017 at 05:04:57PM +0300, Mika Westerberg wrote:
> >> > Hi,
> >> >
> >> > This is a third version of the patch series adding support for Thunderbolt
> >> > security levels and NVM firmware upgrade. PCs running Intel Falcon Ridge or
> >> > newer need these in order to connect devices if the security level is set
> >> > to "user(SL1) or secure(SL2)" from BIOS.
> >>
> >> All looks good to me, very nice work.
> >
> > Thanks!
> >
> >> I don't know what tree it should go in through, but if Andreas wants me
> >> to take it, I will if I can get his signed-off-by.
> >
> > That would be perfect.
> >
> > Andreas, do you have any objections?
> No, Thanks a lot.
> 
> Signed-off-by: Andreas Noever <andreas.noever@gmail.com>

Thanks!

> Greg, can you take this through your tree?
> 
> 
> 
> Mika, I have a quick question regarding the pci side of things (your
> "pci=hpbussize=10,hpmemsize=2M" workaround). Does that work for nested
> hotplug or just on the first level? Back when I was having a look at
> enabling chaining in the native driver I could not get pci to properly
> assign bus numbers to nested bridges. It always ran out of bus number
> after one level (irregardless of hpbussize). Has the pci behaviour
> changed or does the ICM somehow preconfigure the bridges before
> handing them of to linux?

I don't think ICM does any preconfiguration when native PCIe hotplug is
used. For PCs we typically use BIOS assisted ACPI hotplug and the SMI
handler configures the bridges before it notifies the OS.

In case of native PCIe hotplug, it still runs out of bus space, that's
why it is workaround. It works to some depth though, because it adds 10
to all bridges that it finds when the scan is done. When next device is
added you have that 10 which it then allocates to bridges downstream.

Anyway it should be fixed properly and it is on my todo list once I get
still missing parts finished. Unless someone else fixes it first, that
is ;-)

One solution that I've been thinking is to introduce some sort of
resource allocation policies to root ports depending what is connected
to them, and in case of Thunderbolt we follow the BIOS assisted hotplug
way so that we assign the remaining resources to the downstream port
where the chain is extended (this can be figured out from the registers,
I think).

There is also another PCI/ACPI related issue that Mario reported where
we execute _INI() methods before the initial PCI scan on boot when
Thunderbolt device is connected causing Linux to accidentally find the
upstream port of the Thunderbolt host controller before it is configured
properly by the BIOS ACPI hotplug handler. I've discussed this with
Rafael and he has an idea how we could fix it but it probably requires
some changes to ACPICA first. Also on my todo list :)

[toc] | [prev] | [next] | [standalone]


#1658364 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2017-06-06 08:10 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tPfQJ-4Zi-1@gated-at.bofh.it>
In reply to#1657956
On Mon, Jun 05, 2017 at 07:01:10PM +0200, Andreas Noever wrote:
> On Mon, Jun 5, 2017 at 9:18 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Sat, Jun 03, 2017 at 06:17:04PM +0900, Greg Kroah-Hartman wrote:
> >> On Fri, Jun 02, 2017 at 05:04:57PM +0300, Mika Westerberg wrote:
> >> > Hi,
> >> >
> >> > This is a third version of the patch series adding support for Thunderbolt
> >> > security levels and NVM firmware upgrade. PCs running Intel Falcon Ridge or
> >> > newer need these in order to connect devices if the security level is set
> >> > to "user(SL1) or secure(SL2)" from BIOS.
> >>
> >> All looks good to me, very nice work.
> >
> > Thanks!
> >
> >> I don't know what tree it should go in through, but if Andreas wants me
> >> to take it, I will if I can get his signed-off-by.
> >
> > That would be perfect.
> >
> > Andreas, do you have any objections?
> No, Thanks a lot.
> 
> Signed-off-by: Andreas Noever <andreas.noever@gmail.com>
> 
> Greg, can you take this through your tree?

Sure, but wasn't there going to be a new version of this series, or
should I just take this one as-is and follow-up patches will happen?
It's up to both of you, either is fine with me.

thanks,

greg k-h

[toc] | [prev] | [next] | [standalone]


#1658398 — Re: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade

FromMika Westerberg <mika.westerberg@linux.intel.com>
Date2017-06-06 08:50 +0200
SubjectRe: [PATCH v3 00/27] Thunderbolt security levels and NVM firmware upgrade
Message-ID<tPgts-5bP-9@gated-at.bofh.it>
In reply to#1658364
On Tue, Jun 06, 2017 at 08:03:29AM +0200, Greg Kroah-Hartman wrote:
> Sure, but wasn't there going to be a new version of this series, or
> should I just take this one as-is and follow-up patches will happen?
> It's up to both of you, either is fine with me.

I will send an updated version (v4) of the series later today.

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | linux.kernel


csiph-web