Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2050678imm; Sun, 9 Sep 2018 14:46:50 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZl12WzO8e7GPXvAPyi28hoif/rQLMpHmGoCHnpdEgDtVT4sWExYAr73w0N3k2jqQh49evu X-Received: by 2002:a63:ca09:: with SMTP id n9-v6mr19326860pgi.287.1536529610226; Sun, 09 Sep 2018 14:46:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536529610; cv=none; d=google.com; s=arc-20160816; b=qk9774mmtjULLsLG9JAtR3bwf67f9aeixdGnP8mA8QDpqDr0LFtoZWD6jwhey1+1mu HPpFzJpgZuHfFcVLeab+8yjoQpobVvMYckg1IorItvNRubkj56eTuC2ouow5UtT58Zfs VSQyAobPQG9l4jfv/vOzgHYObZ8YTER1UJFCBb2Yu7FmDj/Dz9m917GTmokupExUEnPF Mhp7g7wUX5gHuWSF/pAdwAcczAq5fU7hjEGyTsUKmlbspxszyitib7/iQeM0dKx7U9Jw cy6i8uEb/YUi1z957ujl2LjMvzvYmR2QC6TFGNRGJrg++AiMDaHlG5LOG5XA4IiII0JY M7Wg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:date:from:references :in-reply-to:message-id; bh=vg74kmBXR5ulVz8ZzyYtix3vZKYlOzmXsXvDcAHpcDU=; b=S4MezvKiO40clYO+gAtiDgo08czl6iz8nPeYxHd6QjeIgut81oRxQo683uAsoQUZ2I 7UmC8YvTP72hzocTjgY2Dk2gSii8RFjzgFWMnK8pONWN93p5w07VsIyFmvOXriVa64vO i/e1hWzkSDf3Ohy7juICnUf7DVgGtvbQsC/sWfsmIkh7tb8xcV/hhy212vOdnb9AFd72 Gkj7T4EwIDeiZ6ErErRtdSlxdlpAGrEM0K2FCcNoaHYu9EEbqoNQb65MsEdNiAzhvC12 VwEJ/BPw3uu8mK723DNqIZSzItNJq6GpBkuMmcUChKJ7vWhH9WycD5q1DBjjUv4LwW8m dhpQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j8-v6si13632364pll.493.2018.09.09.14.46.18; Sun, 09 Sep 2018 14:46:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726912AbeIJCfa (ORCPT + 99 others); Sun, 9 Sep 2018 22:35:30 -0400 Received: from bmailout2.hostsharing.net ([83.223.90.240]:51335 "EHLO bmailout2.hostsharing.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726767AbeIJCfa (ORCPT ); Sun, 9 Sep 2018 22:35:30 -0400 Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "COMODO RSA Domain Validation Secure Server CA" (not verified)) by bmailout2.hostsharing.net (Postfix) with ESMTPS id C73C82800B3CC; Sun, 9 Sep 2018 23:44:23 +0200 (CEST) Received: by h08.hostsharing.net (Postfix, from userid 100393) id 7C1B2E542; Sun, 9 Sep 2018 23:44:23 +0200 (CEST) Message-Id: <756f7148bc106d80d2e43273edd6dc8c48c1b87b.1536517047.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Sun, 9 Sep 2018 23:42:01 +0200 Subject: [PATCH 2/5] thunderbolt: Obtain PCI slot number from DROM To: Andreas Noever , Mika Westerberg , Michael Jamet , Yehezkel Bernat Cc: Stephen Hemminger , linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The port numbers of PCIe adapters on a CIO switch and the slot numbers of their corresponding PCI devices don't necessarily match up in ascending order. E.g. Light Ridge in host mode (MacBookPro9,1) mixes them up like this: switch port 7 == pci slot 4 (PCIe downstream port) switch port 8 == pci slot 5 (PCIe downstream port) switch port 9 == pci slot 6 (PCIe downstream port) switch port 10 == pci slot 3 (PCIe downstream port) Light Ridge in endpoint mode (Sonnet Echo Express): switch port 7 == pci slot 4 (PCIe downstream port) switch port 8 == pci slot 5 (PCIe downstream port) switch port 9 (PCIe downstream port, disabled in DROM) switch port 10 == pci slot 0 (PCIe upstream port, pci slot 3 in DROM) Obtain the slot number used by a switch port from the DROM and store it in struct tb_port. This will allow us to correlate PCI devices with Thunderbolt ports. For space efficiency, use a union in struct tb_port to store attributes that are specific to certain port types. Attributes specific to TB_TYPE_PORT could be moved into a separate struct within the union. The slot number occupies 3 bits in the third byte of PCI DROM entries. The purpose of the remaining 5 bits is unknown (function number?). Downstream port entries have 3 bytes, upstream port entries 11 bytes. The slot number in upstream port entries is not that of the port itself (which is always zero), but that of the PCI endpoint device built into the Thunderbolt product. In the case of the Sonnet Echo Express, the upstream port specifies slot 3, which is used by a PLX switch. The purpose of the additional 8 bytes present on upstream ports is unknown (number of PCIe lanes, priority requirements, direct tunnel to the host desired?). Examples: 01 00 64 00 00 00 00 00 (Sonnet Echo Express, PLX switch) 01 40 0a 00 00 00 00 00 (Apple Gigabit Ethernet Adapter, BCM957762) Signed-off-by: Lukas Wunner --- drivers/thunderbolt/eeprom.c | 21 +++++++++++++++++++++ drivers/thunderbolt/switch.c | 14 +++++++++++++- drivers/thunderbolt/tb.h | 9 +++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index 3e8caf22c294..ce6e037fdb39 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -236,6 +236,15 @@ struct tb_drom_entry_port { u8 unknown4:2; } __packed; +struct tb_drom_entry_pci { + /* BYTES 0-1 */ + struct tb_drom_entry_header header; + /* BYTE 2 */ + u8 unknown:5; + u8 slot:3; + /* BYTES 3-10 are only present on PCIe upstream ports */ +} __packed; + /** * tb_eeprom_get_drom_offset - get drom offset within eeprom @@ -365,6 +374,18 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw, if (entry->has_dual_link_port) port->dual_link_port = &port->sw->ports[entry->dual_link_port_nr]; + } else if (type == TB_TYPE_PCIE_UP || type == TB_TYPE_PCIE_DOWN) { + struct tb_drom_entry_pci *entry = (void *) header; + if (header->len < sizeof(*entry)) { + tb_sw_warn(sw, + "port entry has size %#x (expected %#zx+)\n", + header->len, sizeof(struct tb_drom_entry_pci)); + return -EIO; + } + port->pci.devfn = PCI_DEVFN(entry->slot, 0); + memcpy(port->pci.unknown, header + 1, + min(header->len - sizeof(struct tb_drom_entry_header), + sizeof(port->pci.unknown))); } return 0; } diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 7442bc4c6433..54fd42250935 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -577,6 +577,7 @@ int tb_port_clear_counter(struct tb_port *port, int counter) */ static int tb_init_port(struct tb_port *port) { + struct tb *tb = port->sw->tb; int res; int cap; @@ -594,9 +595,20 @@ static int tb_init_port(struct tb_port *port) tb_port_WARN(port, "non switch port without a PHY\n"); } - tb_dump_port(port->sw->tb, &port->config); + tb_dump_port(tb, &port->config); /* TODO: Read dual link port, DP port and more from EEPROM. */ + switch (port->config.type) { + case TB_TYPE_PCIE_UP: + case TB_TYPE_PCIE_DOWN: + tb_info(tb, " PCI slot: %02x.0\n", PCI_SLOT(port->pci.devfn)); + tb_info(tb, " PCI unknown data: %*ph\n", + (int)sizeof(port->pci.unknown), port->pci.unknown); + break; + default: + break; + } + return 0; } diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 5067d69d0501..755183f0b257 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -125,6 +125,9 @@ struct tb_switch { * @dual_link_port: If the switch is connected using two ports, points * to the other port. * @link_nr: Is this primary or secondary port on the dual_link. + * @pci: Data specific to PCIe adapters + * @pci.devfn: PCI slot/function according to DROM + * @pci.unknown: Unknown data in DROM (to be reverse-engineered) */ struct tb_port { struct tb_regs_port_header config; @@ -136,6 +139,12 @@ struct tb_port { bool disabled; struct tb_port *dual_link_port; u8 link_nr:1; + union { + struct { + u8 devfn; + u8 unknown[9]; + } pci; + }; }; /** -- 2.18.0