Received: by 2002:ac0:8c8e:0:0:0:0:0 with SMTP id r14csp595293ima; Wed, 6 Feb 2019 05:23:31 -0800 (PST) X-Google-Smtp-Source: AHgI3IaWxXAUpc5I2nKt9FY4HqL9VbNd7TL1QTlRBH2w+1J2IATGJLG4KocW1Qti4zUfGRL5T41j X-Received: by 2002:a17:902:6e0f:: with SMTP id u15mr10549937plk.175.1549459411014; Wed, 06 Feb 2019 05:23:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549459411; cv=none; d=google.com; s=arc-20160816; b=Rt/vEyMnFSVuCryIDh5V+DoDtXT7FLwtlfi85dOxYj4gk+XurrC51QAnUG/Mj5TeRg 3HQ5WIEvsU7JUDNLCVXjw71QIkOuFemRaUgyzOUO+cTI2DEXwNhxtU6y83xywQ5+ntwe ps/SQdsJTnZHZzVB0wHKkErvwh3kFWLhtmk1MYF3c9urgGlWYoAO45qPlqmLq6fzNSIS 9SYvphbEtJz0AAVFq37Ya+nBp6GGqMWxp5ImlQcceB3N8UVI3duSiyYYeP9ZCwivjYwJ 4Agw0YQq/+Ib9suo/+Ckg6IXA1EXMuEuQzYORXpVFVCPOlPhUjErF70Y71+bTe1Feon5 mPSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=scSwcpvxXYooAnbxYil3yd/SB1U0qouOw7RhYRS9CeA=; b=N9kKY1GvTURcP6qqVgMHepndUAhWfM/bITwGEeZ5zbCINIFQGQbgd7CZdpJYjqByYl JxJr7JSdOFnEVsPQ2k8x4ijSqg9hJzN3Q5xjxskOd/CrDy0eaVgtOgabeGpBHerZOm30 sD83hv9VdxKTKqXhy5YxvLPldi6iROvmaPgV5cvXz2qoPnD6/Rehvuzf1hojkXVuB20D SojmArh0v+nZzIOTEO3GrJ25ZpONd4y/UIilzOvSeUR7lVqL2FFiy9yihGE37pEvZjsj nYTED3qzEBd2jc8Hrw1HKPE5uClKPZK0u92TBN2fL6Ie9bHvY8v0Xzy0mguk6stf84DX ihEQ== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c22si2263040pgb.254.2019.02.06.05.23.15; Wed, 06 Feb 2019 05:23:30 -0800 (PST) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731152AbfBFNWW (ORCPT + 99 others); Wed, 6 Feb 2019 08:22:22 -0500 Received: from mga05.intel.com ([192.55.52.43]:56949 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730057AbfBFNRr (ORCPT ); Wed, 6 Feb 2019 08:17:47 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Feb 2019 05:17:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,340,1544515200"; d="scan'208";a="142036820" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga004.fm.intel.com with ESMTP; 06 Feb 2019 05:17:43 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 041E0642; Wed, 6 Feb 2019 15:17:39 +0200 (EET) From: Mika Westerberg To: linux-kernel@vger.kernel.org Cc: Michael Jamet , Yehezkel Bernat , Andreas Noever , Lukas Wunner , "David S . Miller" , Mika Westerberg , Andy Shevchenko , netdev@vger.kernel.org Subject: [PATCH v2 12/28] thunderbolt: Add functions for allocating and releasing hop IDs Date: Wed, 6 Feb 2019 16:17:22 +0300 Message-Id: <20190206131738.43696-13-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190206131738.43696-1-mika.westerberg@linux.intel.com> References: <20190206131738.43696-1-mika.westerberg@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Each port has a separate path configuration space that is used for finding the next hop (switch) in the path. Hop ID is an index to this configuration space and hop IDs 0 - 7 are reserved. In order to get next available hop ID for each direction we provide two pairs of helper functions that can be used to allocate and release hop IDs for a given port. While there remove obsolete TODO comment. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/switch.c | 87 +++++++++++++++++++++++++++++++++++- drivers/thunderbolt/tb.h | 8 ++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index b20af050ce9a..320f64ebe8b8 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -601,11 +601,88 @@ static int tb_init_port(struct tb_port *port) tb_dump_port(port->sw->tb, &port->config); - /* TODO: Read dual link port, DP port and more from EEPROM. */ + /* Control port does not need Hop ID allocation */ + if (port->port) { + ida_init(&port->in_hopids); + ida_init(&port->out_hopids); + } + return 0; } +static int tb_port_alloc_hopid(struct tb_port *port, bool in, int min_hopid, + int max_hopid) +{ + int port_max_hopid; + struct ida *ida; + + if (in) { + port_max_hopid = port->config.max_in_hop_id; + ida = &port->in_hopids; + } else { + port_max_hopid = port->config.max_out_hop_id; + ida = &port->out_hopids; + } + + /* Hop IDs 0-7 are reserved */ + if (min_hopid < 8) + min_hopid = 8; + + if (max_hopid < 0 || max_hopid > port_max_hopid) + max_hopid = port_max_hopid; + + return ida_simple_get(ida, min_hopid, max_hopid + 1, GFP_KERNEL); +} + +/** + * tb_port_alloc_in_hopid() - Allocate input hop ID from port + * @port: Port to allocate hop ID for + * @min_hopid: Minimum acceptable input hop ID + * @max_hopid: Maximum acceptable input hop ID + * + * Return: Hop ID between @min_hopid and @max_hopid or negative errno in + * case of error. + */ +int tb_port_alloc_in_hopid(struct tb_port *port, int min_hopid, int max_hopid) +{ + return tb_port_alloc_hopid(port, true, min_hopid, max_hopid); +} + +/** + * tb_port_alloc_out_hopid() - Allocate output hop ID from port + * @port: Port to allocate hop ID for + * @min_hopid: Minimum acceptable output hop ID + * @max_hopid: Maximum acceptable output hop ID + * + * Return: Hop ID between @min_hopid and @max_hopid or negative errno in + * case of error. + */ +int tb_port_alloc_out_hopid(struct tb_port *port, int min_hopid, int max_hopid) +{ + return tb_port_alloc_hopid(port, false, min_hopid, max_hopid); +} + +/** + * tb_port_release_in_hopid() - Release allocated input hop ID from port + * @port: Port whose hop ID to release + * @hopid: Hop ID to release + */ +void tb_port_release_in_hopid(struct tb_port *port, int hopid) +{ + ida_simple_remove(&port->in_hopids, hopid); +} + +/** + * tb_port_release_out_hopid() - Release allocated output hop ID from port + * @port: Port whose hop ID to release + * @hopid: Hop ID to release + */ +void tb_port_release_out_hopid(struct tb_port *port, int hopid) +{ + ida_simple_remove(&port->out_hopids, hopid); +} + /** * tb_pci_port_enable() - Enable PCIe adapter port * @port: PCIe port to enable @@ -1080,9 +1157,17 @@ static const struct attribute_group *switch_groups[] = { static void tb_switch_release(struct device *dev) { struct tb_switch *sw = tb_to_switch(dev); + int i; dma_port_free(sw->dma_port); + for (i = 1; i <= sw->config.max_port_number; i++) { + if (!sw->ports[i].disabled) { + ida_destroy(&sw->ports[i].in_hopids); + ida_destroy(&sw->ports[i].out_hopids); + } + } + kfree(sw->uuid); kfree(sw->device_name); kfree(sw->vendor_name); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index a13d1cd53bc3..bfa1cee193fd 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -130,6 +130,8 @@ 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. + * @in_hopids: Currently allocated input hopids + * @out_hopids: Currently allocated output hopids */ struct tb_port { struct tb_regs_port_header config; @@ -142,6 +144,8 @@ struct tb_port { bool disabled; struct tb_port *dual_link_port; u8 link_nr:1; + struct ida in_hopids; + struct ida out_hopids; }; /** @@ -439,6 +443,10 @@ static inline struct tb_switch *tb_to_switch(struct device *dev) 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); +int tb_port_alloc_in_hopid(struct tb_port *port, int hopid, int max_hopid); +void tb_port_release_in_hopid(struct tb_port *port, int hopid); +int tb_port_alloc_out_hopid(struct tb_port *port, int hopid, int max_hopid); +void tb_port_release_out_hopid(struct tb_port *port, int hopid); int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec); int tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap); -- 2.20.1