From nobody Mon Feb 9 10:12:44 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F94622FE10; Thu, 24 Apr 2025 11:32:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745494381; cv=none; b=J+bNKlLLGDRfHAUG+PP6sAOSX+tOgIBcUviPWKpHWT/HwPvf4/382fdLtwNVYo+MFM/a+4RIq4a8VkGCrbwR6s9F2f3Q6Pwf765JuMK18M/c4ZmOB9m9fzm8MuX2N1oQalL3qr5GvD72zLRuL9EEAsJVy8KjMIFE8gHnKr/hp+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745494381; c=relaxed/simple; bh=ogiyY7kHnh0pueYLXUNE67oNvtCbuEEXeD1/CzRXW2Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ts2uRVTh8IurZxLxF1NeXCmnM3VivYCG9DULG27o2+DbVntIrHUjPe7QNId6F8x+YFBBIH5N7La4o0JbQjhN5D+ZEq2HDcFg1OmJJzkKepVCLPS1Cw0VrP/LhwAeS1aK8oglLbQZXxnCDT88zLqm57z5yhA79wnHWKel+pvRnuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=AMW+kWAC; arc=none smtp.client-ip=192.198.163.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="AMW+kWAC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1745494379; x=1777030379; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ogiyY7kHnh0pueYLXUNE67oNvtCbuEEXeD1/CzRXW2Q=; b=AMW+kWACTPFWaUnywTfPCC0TlnRZArU4r4Jq4wSz5Sx7INURNSio8WQr 6DZNC5i97wro/xh6kbcE0tsBTtySu9Q+AdjDNU3pDXbjGpEHj9USIx7L7 POtxzlL5DAx2QyGqUW2H5bqZZavUOGSgTaQHPrrO+c58xifwpxQEM3+iL KhBUw/KVgtM7Cazw1lwVK7ysNuwIkR13UnH4pxbNWLnRUtammFoS/QfME mZfQOkl6In30FKnE/MgTNROvpErlucUleyYO7wlqZh0tQyyb4L5HFm9pv m3R7YP9fZXT7Ss6hkL7VeCyEy3qC2WIqRV7IUTD5Q/DulaW0dtyBZeU09 Q==; X-CSE-ConnectionGUID: G5CZV/e2T+CuU4PG8CwFwA== X-CSE-MsgGUID: rbvn99DHQG2I/ptD5E0MWg== X-IronPort-AV: E=McAfee;i="6700,10204,11412"; a="57771183" X-IronPort-AV: E=Sophos;i="6.15,235,1739865600"; d="scan'208";a="57771183" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2025 04:32:58 -0700 X-CSE-ConnectionGUID: 3pcKGHaBQUadhcvs23knXw== X-CSE-MsgGUID: KV9CMfp7T2eHDNwmz7X57g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.15,235,1739865600"; d="scan'208";a="137389377" Received: from irvmail002.ir.intel.com ([10.43.11.120]) by fmviesa005.fm.intel.com with ESMTP; 24 Apr 2025 04:32:52 -0700 Received: from mglak.igk.intel.com (mglak.igk.intel.com [10.237.112.146]) by irvmail002.ir.intel.com (Postfix) with ESMTP id 2C19D33EA4; Thu, 24 Apr 2025 12:32:49 +0100 (IST) From: Larysa Zaremba To: intel-wired-lan@lists.osuosl.org, Tony Nguyen Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jonathan Corbet , Przemek Kitszel , Jiri Pirko , Tatyana Nikolova , Andrew Lunn , Alexander Lobakin , Michael Ellerman , Maciej Fijalkowski , Lee Trager , Madhavan Srinivasan , Larysa Zaremba , Sridhar Samudrala , Jacob Keller , Michal Swiatkowski , Mateusz Polchlopek , Ahmed Zaki , netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, "Karlsson, Magnus" , Emil Tantilov , Madhu Chittim , Josh Hay , Milena Olech , pavan.kumar.linga@intel.com, "Singhai, Anjali" , Phani R Burra Subject: [PATCH iwl-next v2 03/14] libie: add PCI device initialization helpers to libie Date: Thu, 24 Apr 2025 13:32:26 +0200 Message-ID: <20250424113241.10061-4-larysa.zaremba@intel.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250424113241.10061-1-larysa.zaremba@intel.com> References: <20250424113241.10061-1-larysa.zaremba@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Phani R Burra Add memory related support functions for drivers to access MMIO space and allocate/free dma buffers. Reviewed-by: Maciej Fijalkowski Signed-off-by: Phani R Burra Co-developed-by: Victor Raj Signed-off-by: Victor Raj Co-developed-by: Sridhar Samudrala Signed-off-by: Sridhar Samudrala Co-developed-by: Pavan Kumar Linga Signed-off-by: Pavan Kumar Linga Co-developed-by: Larysa Zaremba Signed-off-by: Larysa Zaremba --- drivers/net/ethernet/intel/libie/Kconfig | 6 + drivers/net/ethernet/intel/libie/Makefile | 4 + drivers/net/ethernet/intel/libie/pci.c | 184 ++++++++++++++++++++++ include/linux/intel/libie/pci.h | 54 +++++++ 4 files changed, 248 insertions(+) create mode 100644 drivers/net/ethernet/intel/libie/pci.c create mode 100644 include/linux/intel/libie/pci.h diff --git a/drivers/net/ethernet/intel/libie/Kconfig b/drivers/net/etherne= t/intel/libie/Kconfig index 33aff6bc8f81..20fa45feb946 100644 --- a/drivers/net/ethernet/intel/libie/Kconfig +++ b/drivers/net/ethernet/intel/libie/Kconfig @@ -8,3 +8,9 @@ config LIBIE libie (Intel Ethernet library) is a common library built on top of libeth and containing vendor-specific routines shared between several Intel Ethernet drivers. + +config LIBIE_PCI + tristate + help + Helper functions for management of PCI resources belonging + to networking devices. diff --git a/drivers/net/ethernet/intel/libie/Makefile b/drivers/net/ethern= et/intel/libie/Makefile index ffd27fab916a..c20aeea1f67c 100644 --- a/drivers/net/ethernet/intel/libie/Makefile +++ b/drivers/net/ethernet/intel/libie/Makefile @@ -4,3 +4,7 @@ obj-$(CONFIG_LIBIE) +=3D libie.o =20 libie-y :=3D rx.o + +obj-$(CONFIG_LIBIE_PCI) +=3D libie_pci.o + +libie_pci-y :=3D pci.o diff --git a/drivers/net/ethernet/intel/libie/pci.c b/drivers/net/ethernet/= intel/libie/pci.c new file mode 100644 index 000000000000..727ce7b200a5 --- /dev/null +++ b/drivers/net/ethernet/intel/libie/pci.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (C) 2025 Intel Corporation */ + +#include + +/** + * libie_find_mmio_region - find if MMIO region is present in the list + * @mmio_list: list that contains MMIO region info + * @offset: MMIO region start offset + * @bar_idx: BAR index where the offset to search + * + * Return: MMIO region pointer or NULL if the region info is not present. + */ +static struct libie_pci_mmio_region * +libie_find_mmio_region(const struct list_head *mmio_list, + resource_size_t offset, int bar_idx) +{ + struct libie_pci_mmio_region *mr; + + list_for_each_entry(mr, mmio_list, list) + if (mr->bar_idx =3D=3D bar_idx && mr->offset =3D=3D offset) + return mr; + + return NULL; +} + +/** + * __libie_pci_get_mmio_addr - get the MMIO virtual address + * @mmio_info: contains list of MMIO regions + * @offset: register offset of find + * @num_args: number of additional arguments present + * + * This function finds the virtual address of a register offset by iterati= ng + * through the non-linear MMIO regions that are mapped by the driver. + * + * Return: valid MMIO virtual address or NULL. + */ +void __iomem *__libie_pci_get_mmio_addr(struct libie_mmio_info *mmio_info, + resource_size_t offset, + int num_args, ...) +{ + struct libie_pci_mmio_region *mr; + int bar_idx =3D 0; + va_list args; + + if (num_args) { + va_start(args, num_args); + bar_idx =3D va_arg(args, int); + va_end(args); + } + + list_for_each_entry(mr, &mmio_info->mmio_list, list) + if (bar_idx =3D=3D mr->bar_idx && offset >=3D mr->offset && + offset < mr->offset + mr->size) { + offset -=3D mr->offset; + + return mr->addr + offset; + } + + return NULL; +} +EXPORT_SYMBOL_NS_GPL(__libie_pci_get_mmio_addr, "LIBIE_PCI"); + +/** + * __libie_pci_map_mmio_region - map PCI device MMIO region + * @mmio_info: struct to store the mapped MMIO region + * @offset: MMIO region start offset + * @size: MMIO region size + * @num_args: number of additional arguments present + * + * Return: true on success, false on memory map failure. + */ +bool __libie_pci_map_mmio_region(struct libie_mmio_info *mmio_info, + resource_size_t offset, + resource_size_t size, int num_args, ...) +{ + struct pci_dev *pdev =3D mmio_info->pdev; + struct libie_pci_mmio_region *mr; + resource_size_t pa; + void __iomem *va; + int bar_idx =3D 0; + va_list args; + + if (num_args) { + va_start(args, num_args); + bar_idx =3D va_arg(args, int); + va_end(args); + } + + mr =3D libie_find_mmio_region(&mmio_info->mmio_list, offset, bar_idx); + if (mr) { + pci_warn(pdev, "Mapping of BAR%u with offset %llu already exists\n", + bar_idx, (unsigned long long)offset); + return true; + } + + pa =3D pci_resource_start(pdev, bar_idx) + offset; + va =3D ioremap(pa, size); + if (!va) { + pci_err(pdev, "Failed to allocate BAR%u region\n", bar_idx); + return false; + } + + mr =3D kvzalloc(sizeof(*mr), GFP_KERNEL); + if (!mr) { + iounmap(va); + return false; + } + + mr->addr =3D va; + mr->offset =3D offset; + mr->size =3D size; + mr->bar_idx =3D bar_idx; + + list_add_tail(&mr->list, &mmio_info->mmio_list); + + return true; +} +EXPORT_SYMBOL_NS_GPL(__libie_pci_map_mmio_region, "LIBIE_PCI"); + +/** + * libie_pci_unmap_all_mmio_regions - unmap all PCI device MMIO regions + * @mmio_info: contains list of MMIO regions to unmap + */ +void libie_pci_unmap_all_mmio_regions(struct libie_mmio_info *mmio_info) +{ + struct libie_pci_mmio_region *mr, *tmp; + + list_for_each_entry_safe(mr, tmp, &mmio_info->mmio_list, list) { + iounmap(mr->addr); + list_del(&mr->list); + kfree(mr); + } +} +EXPORT_SYMBOL_NS_GPL(libie_pci_unmap_all_mmio_regions, "LIBIE_PCI"); + +/** + * libie_pci_init_dev - enable and reserve PCI regions of the device + * @pdev: PCI device information + * + * Return: %0 on success, -%errno on failure. + */ +int libie_pci_init_dev(struct pci_dev *pdev) +{ + int err; + + err =3D pci_enable_device(pdev); + if (err) + return err; + + err =3D pci_request_mem_regions(pdev, pci_name(pdev)); + if (err) + goto disable_dev; + + err =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (err) + goto rel_regions; + + pci_set_master(pdev); + + return 0; + +rel_regions: + pci_release_regions(pdev); +disable_dev: + pci_disable_device(pdev); + + return err; +} +EXPORT_SYMBOL_NS_GPL(libie_pci_init_dev, "LIBIE_PCI"); + +/** + * libie_pci_deinit_dev - disable and release the PCI regions of the device + * @pdev: PCI device information + */ +void libie_pci_deinit_dev(struct pci_dev *pdev) +{ + pci_disable_device(pdev); + pci_release_regions(pdev); +} +EXPORT_SYMBOL_NS_GPL(libie_pci_deinit_dev, "LIBIE_PCI"); + +MODULE_DESCRIPTION("Common Ethernet PCI library"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/intel/libie/pci.h b/include/linux/intel/libie/pc= i.h new file mode 100644 index 000000000000..4601205adc22 --- /dev/null +++ b/include/linux/intel/libie/pci.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2025 Intel Corporation */ + +#ifndef __LIBIE_PCI_H +#define __LIBIE_PCI_H + +#include + +/** + * struct libie_pci_mmio_region - structure for MMIO region info + * @list: used to add a MMIO region to the list of MMIO regions in + * libie_mmio_info + * @addr: virtual address of MMIO region start + * @offset: start offset of the MMIO region + * @size: size of the MMIO region + * @bar_idx: BAR index to which the MMIO region belongs to + */ +struct libie_pci_mmio_region { + struct list_head list; + void __iomem *addr; + resource_size_t offset; + resource_size_t size; + u16 bar_idx; +}; + +/** + * struct libie_mmio_info - contains list of MMIO regions + * @pdev: PCI device pointer + * @mmio_list: list of MMIO regions + */ +struct libie_mmio_info { + struct pci_dev *pdev; + struct list_head mmio_list; +}; + +#define libie_pci_map_mmio_region(mmio_info, offset, size, ...) \ + __libie_pci_map_mmio_region(mmio_info, offset, size, \ + COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__) + +#define libie_pci_get_mmio_addr(mmio_info, offset, ...) \ + __libie_pci_get_mmio_addr(mmio_info, offset, \ + COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__) + +bool __libie_pci_map_mmio_region(struct libie_mmio_info *mmio_info, + resource_size_t offset, resource_size_t size, + int num_args, ...); +void __iomem *__libie_pci_get_mmio_addr(struct libie_mmio_info *mmio_info, + resource_size_t region_offset, + int num_args, ...); +void libie_pci_unmap_all_mmio_regions(struct libie_mmio_info *mmio_info); +int libie_pci_init_dev(struct pci_dev *pdev); +void libie_pci_deinit_dev(struct pci_dev *pdev); + +#endif /* __LIBIE_PCI_H */ --=20 2.47.0