From: Bjorn Helgaas <helgaas@kernel.org>
To: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
edumazet@google.com, andrew+netdev@lunn.ch,
netdev@vger.kernel.org, Phani R Burra <phani.r.burra@intel.com>,
larysa.zaremba@intel.com, przemyslaw.kitszel@intel.com,
aleksander.lobakin@intel.com, sridhar.samudrala@intel.com,
anjali.singhai@intel.com, michal.swiatkowski@linux.intel.com,
maciej.fijalkowski@intel.com, emil.s.tantilov@intel.com,
madhu.chittim@intel.com, joshua.a.hay@intel.com,
jacob.e.keller@intel.com, jayaprakash.shanmugam@intel.com,
jiri@resnulli.us, horms@kernel.org, corbet@lwn.net,
richardcochran@gmail.com, linux-doc@vger.kernel.org,
bhelgaas@google.com, linux-pci@vger.kernel.org,
Bharath R <bharath.r@intel.com>,
Samuel Salin <Samuel.salin@intel.com>,
Aleksandr Loktionov <aleksandr.loktionov@intel.com>,
Philipp Stanner <phasta@kernel.org>
Subject: Re: [PATCH net-next v3 02/14] libie: add PCI device initialization helpers to libie
Date: Mon, 18 May 2026 16:54:41 -0500 [thread overview]
Message-ID: <20260518215441.GA640516@bhelgaas> (raw)
In-Reply-To: <20260515224443.2772147-3-anthony.l.nguyen@intel.com>
[+cc Philipp]
On Fri, May 15, 2026 at 03:44:26PM -0700, Tony Nguyen wrote:
> From: Phani R Burra <phani.r.burra@intel.com>
>
> Add support functions for drivers to configure PCI functionality and access
> MMIO space.
This looks kind of like what pcim_iomap_range() does, i.e., a way to
ioremap (BAR-idx, offset, size) pieces of PCI BARs. That sounds like
useful functionality.
Is there something Intel-specific or even ethernet-specific about
this? If devm_* and pcim_* don't do what you need, maybe they should
be extended or this could be made generic so any drivers could use it?
This looks like a mix of managed (pcim_enable_device(),
pcim_request_region()), and unmanaged (ioremap(), iounmap()) things.
I haven't looked at how all this is used, but it's pretty easy to get
things wrong when mixing models.
> +++ b/drivers/net/ethernet/intel/libie/pci.c
> @@ -0,0 +1,208 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (C) 2025 Intel Corporation */
> +
> +#include <linux/intel/libie/pci.h>
> +
> +/**
> + * libie_find_mmio_region - find MMIO region containing a range
> + * @mmio_list: list that contains MMIO region info
> + * @offset: range start offset
> + * @size: range size
> + * @bar_idx: BAR index containing the range to search
> + *
> + * Return: pointer to a MMIO region overlapping with the range in any way or
> + * NULL if no such region is mapped.
> + */
> +static struct libie_pci_mmio_region *
> +libie_find_mmio_region(const struct list_head *mmio_list,
> + resource_size_t offset, resource_size_t size,
> + int bar_idx)
> +{
> + resource_size_t end_offset = offset + size;
> + struct libie_pci_mmio_region *mr;
> +
> + list_for_each_entry(mr, mmio_list, list) {
> + resource_size_t mr_end = mr->offset + mr->size;
> + resource_size_t mr_start = mr->offset;
> +
> + if (mr->bar_idx != bar_idx)
> + continue;
> + if (offset < mr_end && end_offset > mr_start)
> + return mr;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + * __libie_pci_get_mmio_addr - get the MMIO virtual address
> + * @mmio_info: contains list of MMIO regions
> + * @offset: register offset to find
> + * @num_args: number of additional arguments present
> + *
> + * This function finds the virtual address of a register offset by iterating
> + * 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 = 0;
> + va_list args;
> +
> + if (num_args) {
> + va_start(args, num_args);
> + bar_idx = va_arg(args, int);
> + va_end(args);
> + }
> +
> + list_for_each_entry(mr, &mmio_info->mmio_list, list)
> + if (bar_idx == mr->bar_idx && offset >= mr->offset &&
> + offset < mr->offset + mr->size) {
> + offset -= 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 = mmio_info->pdev;
> + struct libie_pci_mmio_region *mr;
> + resource_size_t pa;
> + void __iomem *va;
> + int bar_idx = 0;
> + va_list args;
> +
> + if (num_args) {
> + va_start(args, num_args);
> + bar_idx = va_arg(args, int);
> + va_end(args);
> + }
> +
> + if (offset + size > pci_resource_len(pdev, bar_idx))
> + return false;
> +
> + mr = libie_find_mmio_region(&mmio_info->mmio_list, offset, size,
> + bar_idx);
> + if (mr) {
> + pci_warn(pdev,
> + "Mapping of BAR%u (offset=%llu, size=%llu) intersecting region (offset=%llu, size=%llu) already exists\n",
> + bar_idx, (unsigned long long)mr->offset,
> + (unsigned long long)mr->size,
> + (unsigned long long)offset, (unsigned long long)size);
> + return mr->offset <= offset &&
> + mr->offset + mr->size >= offset + size;
> + }
> +
> + pa = pci_resource_start(pdev, bar_idx) + offset;
> + va = ioremap(pa, size);
> + if (!va) {
> + pci_err(pdev, "Failed to map BAR%u region\n", bar_idx);
> + return false;
> + }
> +
> + mr = kvzalloc_obj(*mr);
> + if (!mr) {
> + iounmap(va);
> + return false;
> + }
> +
> + mr->addr = va;
> + mr->offset = offset;
> + mr->size = size;
> + mr->bar_idx = 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_fltr_regs - unmap selected PCI device MMIO regions
> + * @mmio_info: contains list of MMIO regions to unmap
> + * @fltr: returns true, if region is to be unmapped
> + */
> +void libie_pci_unmap_fltr_regs(struct libie_mmio_info *mmio_info,
> + bool (*fltr)(struct libie_mmio_info *mmio_info,
> + struct libie_pci_mmio_region *reg))
> +{
> + struct libie_pci_mmio_region *mr, *tmp;
> +
> + list_for_each_entry_safe(mr, tmp, &mmio_info->mmio_list, list) {
> + if (!fltr(mmio_info, mr))
> + continue;
> + iounmap(mr->addr);
> + list_del(&mr->list);
> + kvfree(mr);
> + }
> +}
> +EXPORT_SYMBOL_NS_GPL(libie_pci_unmap_fltr_regs, "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);
> + kvfree(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 = pcim_enable_device(pdev);
> + if (err)
> + return err;
> +
> + for (int bar = 0; bar < PCI_STD_NUM_BARS; bar++)
> + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
> + err = pcim_request_region(pdev, bar, pci_name(pdev));
> + if (err)
> + return err;
> + }
> +
> + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> + if (err)
> + return err;
> +
> + pci_set_master(pdev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(libie_pci_init_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/pci.h
> new file mode 100644
> index 000000000000..effd072c55c8
> --- /dev/null
> +++ b/include/linux/intel/libie/pci.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright (C) 2025 Intel Corporation */
> +
> +#ifndef __LIBIE_PCI_H
> +#define __LIBIE_PCI_H
> +
> +#include <linux/pci.h>
> +
> +/**
> + * 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 offset,
> + int num_args, ...);
> +void libie_pci_unmap_all_mmio_regions(struct libie_mmio_info *mmio_info);
> +void libie_pci_unmap_fltr_regs(struct libie_mmio_info *mmio_info,
> + bool (*fltr)(struct libie_mmio_info *mmio_info,
> + struct libie_pci_mmio_region *reg));
> +int libie_pci_init_dev(struct pci_dev *pdev);
> +
> +#endif /* __LIBIE_PCI_H */
> --
> 2.47.1
>
next prev parent reply other threads:[~2026-05-18 21:54 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-15 22:44 [PATCH net-next v3 00/14][pull request] Introduce iXD driver Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 01/14] virtchnl: create 'include/linux/intel' and move necessary header files Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 02/14] libie: add PCI device initialization helpers to libie Tony Nguyen
2026-05-18 6:46 ` Larysa Zaremba
2026-05-18 21:54 ` Bjorn Helgaas [this message]
2026-05-19 8:20 ` Philipp Stanner
2026-05-19 10:03 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 03/14] libeth: allow to create fill queues without NAPI Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 04/14] libie: add control queue support Tony Nguyen
2026-05-18 7:02 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 05/14] libie: add bookkeeping support for control queue messages Tony Nguyen
2026-05-18 7:24 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 06/14] idpf: remove 'vport_params_reqd' field Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 07/14] idpf: refactor idpf to use libie_pci APIs Tony Nguyen
2026-05-18 7:40 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 08/14] idpf: refactor idpf to use libie control queues Tony Nguyen
2026-05-18 8:01 ` Larysa Zaremba
2026-05-18 10:14 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 09/14] idpf: make mbx_task queueing and cancelling more consistent Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 10/14] idpf: print a debug message and bail in case of non-event ctlq message Tony Nguyen
2026-05-15 22:44 ` [PATCH net-next v3 11/14] ixd: add basic driver framework for Intel(R) Control Plane Function Tony Nguyen
2026-05-18 8:32 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 12/14] ixd: add reset checks and initialize the mailbox Tony Nguyen
2026-05-18 9:12 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 13/14] ixd: add the core initialization Tony Nguyen
2026-05-18 10:01 ` Larysa Zaremba
2026-05-18 10:10 ` Larysa Zaremba
2026-05-15 22:44 ` [PATCH net-next v3 14/14] ixd: add devlink support Tony Nguyen
2026-05-18 10:11 ` Larysa Zaremba
2026-05-18 10:23 ` [PATCH net-next v3 00/14][pull request] Introduce iXD driver Larysa Zaremba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518215441.GA640516@bhelgaas \
--to=helgaas@kernel.org \
--cc=Samuel.salin@intel.com \
--cc=aleksander.lobakin@intel.com \
--cc=aleksandr.loktionov@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anjali.singhai@intel.com \
--cc=anthony.l.nguyen@intel.com \
--cc=bharath.r@intel.com \
--cc=bhelgaas@google.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=emil.s.tantilov@intel.com \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=jayaprakash.shanmugam@intel.com \
--cc=jiri@resnulli.us \
--cc=joshua.a.hay@intel.com \
--cc=kuba@kernel.org \
--cc=larysa.zaremba@intel.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=madhu.chittim@intel.com \
--cc=michal.swiatkowski@linux.intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=phani.r.burra@intel.com \
--cc=phasta@kernel.org \
--cc=przemyslaw.kitszel@intel.com \
--cc=richardcochran@gmail.com \
--cc=sridhar.samudrala@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox