Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp995269pxj; Thu, 17 Jun 2021 19:38:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw9dhXqYnHGvj4FJGIGwDuVXcGzgKmLWygC+KnbCFw8tyylSYrLmXTqHzPywShw1QxgKAeU X-Received: by 2002:a92:190f:: with SMTP id 15mr5408395ilz.45.1623983922911; Thu, 17 Jun 2021 19:38:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623983922; cv=none; d=google.com; s=arc-20160816; b=vlP2v4XKT5zJ6jFwrJ4rBY1iJFs/5Sak2yX5K8ICrbAY03qxZc+PQUkjccdmhrp0tL gNqHcDJM/+twXj3cuOwq+8RXz7FRCBwTalcB+m07DbD1jSZpi3OGt4poIS5IrDaTAycK nMVEF3WyOxMF2lXHCCJJIU9gV8Gq4QRfaQjcFKD3V9vVFuo+vrOmnbdhTyKz/Ly/eFv3 0kdfy3D3Biw2aQG+avyvW49DkmUqa0CV9vEcFkGVrCwznMXO+8D5TWgHJpfrfzhn59mW f1khJStNpqcKs8jsUwb3GjeZ0JkeZVc6talRzD0hG2ywhOscDXSry+wXa4J4zv9yzr25 2a/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=4LjzKMabbFaHFvJqoMThk7rMKBB+/+KCFQudw012Z8I=; b=T4P+AVdT2SPlElKzg/sGv/34lVAk9gLvmPNjenlvfUpJHzXxVTSi6cc4BVsW4aKde9 HfIIxvG6HCFUiWtoCquUcQaSOuwyOJqxhqPMMU77++iMlnNa/nRXbF5sobM90JTDLAAE /8wHt1hvfHPNcb9ayX+Khlfq+xzkyiKIu2u0LgqgIpinEu3w/5XWaRs1lpDRpK9D5kMM 2OQY8y554oQdI4GsDB9RKV+AK9Uq+cM3XF+OhHA3t6HAkL0y1WMpS3sf8Vbt9357J+cK MS9/WZ8uN+t+vw5IRyhrDtj1E/d8OL4EPvPmrxcUblbmYyKO++x4j423/RkVrougzzRn HmgA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id e3si7063250iom.57.2021.06.17.19.38.31; Thu, 17 Jun 2021 19:38:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S231759AbhFQV56 (ORCPT + 99 others); Thu, 17 Jun 2021 17:57:58 -0400 Received: from mga07.intel.com ([134.134.136.100]:16700 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231474AbhFQV5u (ORCPT ); Thu, 17 Jun 2021 17:57:50 -0400 IronPort-SDR: NEeFg25bXG5PX5/vKnnK3CEvjCseNoh2eQ7phqAo89Rn09asn76q24fSKuhYXwizUK0aIbxP9D +HH4K/B8hthw== X-IronPort-AV: E=McAfee;i="6200,9189,10018"; a="270304155" X-IronPort-AV: E=Sophos;i="5.83,281,1616482800"; d="scan'208";a="270304155" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 14:55:41 -0700 IronPort-SDR: 6ZHkDpGlx3WOn7uW+LShkGAYsoxClCtz1c8DC6jJ2sPs1sryqVMZoFaktpayaobN/Dsw27577J AsJSvaZ63O1A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,281,1616482800"; d="scan'208";a="488810897" Received: from linux.intel.com ([10.54.29.200]) by fmsmga002.fm.intel.com with ESMTP; 17 Jun 2021 14:55:41 -0700 Received: from debox1-desk2.jf.intel.com (debox1-desk2.jf.intel.com [10.54.75.16]) by linux.intel.com (Postfix) with ESMTP id EC13C580224; Thu, 17 Jun 2021 14:55:40 -0700 (PDT) From: "David E. Box" To: lee.jones@linaro.org, david.e.box@linux.intel.com, hdegoede@redhat.com, mgross@linux.intel.com, bhelgaas@google.com Cc: linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-pci@vger.kernel.org Subject: [PATCH 4/4] MFD: intel-extended-cap: Add support for PCIe VSEC structures Date: Thu, 17 Jun 2021 14:54:08 -0700 Message-Id: <20210617215408.1412409-5-david.e.box@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210617215408.1412409-1-david.e.box@linux.intel.com> References: <20210617215408.1412409-1-david.e.box@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adds support for discovering Intel extended capability features from Vendor Specific Extended Capability (VSEC) registers in PCIe config space. While doing so place the existing DVSEC and new VSEC code in separate functions. Signed-off-by: David E. Box --- drivers/mfd/intel_extended_caps.c | 159 ++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 50 deletions(-) diff --git a/drivers/mfd/intel_extended_caps.c b/drivers/mfd/intel_extended_caps.c index 89cf1ae6f65b..9b60defda856 100644 --- a/drivers/mfd/intel_extended_caps.c +++ b/drivers/mfd/intel_extended_caps.c @@ -105,7 +105,7 @@ static int intel_ext_cap_add_dev(struct pci_dev *pdev, struct intel_ext_cap_head header->offset >>= 3; /* - * The DVSEC contains the starting offset and count for a block of + * The DVSEC/VSEC contains the starting offset and count for a block of * discovery tables, each providing access to monitoring facilities for * a section of the device. Create a resource list of these tables to * provide to the driver. @@ -124,11 +124,112 @@ static int intel_ext_cap_add_dev(struct pci_dev *pdev, struct intel_ext_cap_head return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); } +static bool intel_ext_cap_walk_dvsec(struct pci_dev *pdev, unsigned long quirks) +{ + int count = 0; + int pos = 0; + + do { + struct intel_ext_cap_header header; + u32 table, hdr; + u16 vid; + int ret; + + pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC); + if (!pos) + break; + + pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER1, &hdr); + vid = PCI_DVSEC_HEADER1_VID(hdr); + if (vid != PCI_VENDOR_ID_INTEL) + continue; + + /* Support only revision 1 */ + header.rev = PCI_DVSEC_HEADER1_REV(hdr); + if (header.rev != 1) { + dev_warn(&pdev->dev, "Unsupported DVSEC revision %d\n", + header.rev); + continue; + } + + header.length = PCI_DVSEC_HEADER1_LEN(hdr); + + pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, + &header.num_entries); + pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, + &header.entry_size); + pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, + &table); + + header.tbir = INTEL_DVSEC_TABLE_BAR(table); + header.offset = INTEL_DVSEC_TABLE_OFFSET(table); + + pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr); + header.id = PCI_DVSEC_HEADER2_ID(hdr); + + ret = intel_ext_cap_add_dev(pdev, &header, quirks); + if (ret) + continue; + + count++; + } while (true); + + return count; +} + +static bool intel_ext_cap_walk_vsec(struct pci_dev *pdev, unsigned long quirks) +{ + int count = 0; + int pos = 0; + + do { + struct intel_ext_cap_header header; + u32 table, hdr; + int ret; + + pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_VNDR); + if (!pos) + break; + + pci_read_config_dword(pdev, pos + PCI_VNDR_HEADER, &hdr); + + /* Support only revision 1 */ + header.rev = PCI_VNDR_HEADER_REV(hdr); + if (header.rev != 1) { + dev_warn(&pdev->dev, "Unsupported VSEC revision %d\n", + header.rev); + continue; + } + + header.id = PCI_VNDR_HEADER_ID(hdr); + header.length = PCI_VNDR_HEADER_LEN(hdr); + + /* entry, size, and table offset are the same as DVSEC */ + pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, + &header.num_entries); + pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, + &header.entry_size); + pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, + &table); + + header.tbir = INTEL_DVSEC_TABLE_BAR(table); + header.offset = INTEL_DVSEC_TABLE_OFFSET(table); + + ret = intel_ext_cap_add_dev(pdev, &header, quirks); + if (ret) + continue; + + count++; + } while (true); + + return count; +} + int intel_ext_cap_probe(struct pci_dev *pdev, struct intel_ext_cap_platform_info *info) { unsigned long quirks = 0; - bool found_devices = false; - int ret, pos; + int device_count = 0; + int ret; if (info) quirks = info->quirks; @@ -144,59 +245,17 @@ int intel_ext_cap_probe(struct pci_dev *pdev, struct intel_ext_cap_platform_info "Failed to add device for DVSEC id %d\n", (*header)->id); else - found_devices = true; + device_count++; header++; } - } else { - /* Find DVSEC features */ - pos = 0; - do { - struct intel_ext_cap_header header; - u32 table, hdr; - u16 vid; - - pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC); - if (!pos) - break; - - pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER1, &hdr); - vid = PCI_DVSEC_HEADER1_VID(hdr); - if (vid != PCI_VENDOR_ID_INTEL) - continue; - - /* Support only revision 1 */ - header.rev = PCI_DVSEC_HEADER1_REV(hdr); - if (header.rev != 1) { - dev_warn(&pdev->dev, "Unsupported DVSEC revision %d\n", - header.rev); - continue; - } - - header.length = PCI_DVSEC_HEADER1_LEN(hdr); - - pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, - &header.num_entries); - pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, - &header.entry_size); - pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, - &table); - - header.tbir = INTEL_DVSEC_TABLE_BAR(table); - header.offset = INTEL_DVSEC_TABLE_OFFSET(table); - - pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr); - header.id = PCI_DVSEC_HEADER2_ID(hdr); - - ret = intel_ext_cap_add_dev(pdev, &header, quirks); - if (ret) - continue; - found_devices = true; - } while (true); + } else { + device_count += intel_ext_cap_walk_dvsec(pdev, quirks); + device_count += intel_ext_cap_walk_vsec(pdev, quirks); } - if (!found_devices) + if (!device_count) return -ENODEV; return 0; -- 2.25.1