* [PATCH v31 1/5] sfc: add cxl support
2026-06-30 15:13 [PATCH v31 0/5] Type2 device basic support alejandro.lucero-palau
@ 2026-06-30 15:13 ` alejandro.lucero-palau
2026-06-30 15:13 ` [PATCH v31 2/5] sfc: Map cxl regs alejandro.lucero-palau
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: alejandro.lucero-palau @ 2026-06-30 15:13 UTC (permalink / raw)
To: linux-cxl, djbw, dave.jiang, kuba
Cc: Alejandro Lucero, Jonathan Cameron, Edward Cree, Alison Schofield,
Dan Williams
From: Alejandro Lucero <alucerop@amd.com>
Add CXL initialization based on new CXL API for accel drivers and make
it dependent on kernel CXL configuration.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/net/ethernet/sfc/Kconfig | 9 +++++
drivers/net/ethernet/sfc/Makefile | 1 +
drivers/net/ethernet/sfc/efx.c | 16 ++++++++-
drivers/net/ethernet/sfc/efx_cxl.c | 50 +++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 29 ++++++++++++++++
drivers/net/ethernet/sfc/net_driver.h | 8 +++++
6 files changed, 112 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.c
create mode 100644 drivers/net/ethernet/sfc/efx_cxl.h
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index c4c43434f314..979f2801e2a8 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -66,6 +66,15 @@ config SFC_MCDI_LOGGING
Driver-Interface) commands and responses, allowing debugging of
driver/firmware interaction. The tracing is actually enabled by
a sysfs file 'mcdi_logging' under the PCI device.
+config SFC_CXL
+ bool "Solarflare SFC9100-family CXL support"
+ depends on SFC && CXL_BUS >= SFC
+ default SFC
+ help
+ This enables SFC CXL support if the kernel is configuring CXL for
+ using CTPIO with CXL.mem. The SFC device with CXL support and
+ with a CXL-aware firmware can be used for minimizing latencies
+ when sending through CTPIO.
source "drivers/net/ethernet/sfc/falcon/Kconfig"
source "drivers/net/ethernet/sfc/siena/Kconfig"
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index d99039ec468d..bb0f1891cde6 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -13,6 +13,7 @@ sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
mae.o tc.o tc_bindings.o tc_counters.o \
tc_encap_actions.o tc_conntrack.o
+sfc-$(CONFIG_SFC_CXL) += efx_cxl.o
obj-$(CONFIG_SFC) += sfc.o
obj-$(CONFIG_SFC_FALCON) += falcon/
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 8f136a11d396..61cbb6cfc360 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -34,6 +34,7 @@
#include "selftest.h"
#include "sriov.h"
#include "efx_devlink.h"
+#include "efx_cxl.h"
#include "mcdi_port_common.h"
#include "mcdi_pcol.h"
@@ -981,12 +982,14 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_pci_remove_main(efx);
efx_fini_io(efx);
+
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+
pci_dbg(efx->pci_dev, "shutdown successful\n");
efx_fini_devlink_and_unlock(efx);
efx_fini_struct(efx);
free_netdev(efx->net_dev);
- probe_data = container_of(efx, struct efx_probe_data, efx);
kfree(probe_data);
};
@@ -1190,6 +1193,17 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail2;
+ /* A successful cxl initialization implies a CXL region created to be
+ * used for PIO buffers. If there is no CXL support legacy PIO buffers
+ * defined at specific PCI BAR regions will be used. If there is CXL
+ * support and the cxl initialization fails, the driver probe fails.
+ */
+ rc = efx_cxl_init(probe_data);
+ if (rc) {
+ pci_err(pci_dev, "CXL initialization failed with error %d\n", rc);
+ goto fail3;
+ }
+
rc = efx_pci_probe_post_io(efx);
if (rc) {
/* On failure, retry once immediately.
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
new file mode 100644
index 000000000000..be252af972ab
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ *
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2025, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/pci.h>
+
+#include "net_driver.h"
+#include "efx_cxl.h"
+
+#define EFX_CTPIO_BUFFER_SIZE SZ_256M
+
+int efx_cxl_init(struct efx_probe_data *probe_data)
+{
+ struct efx_nic *efx = &probe_data->efx;
+ struct pci_dev *pci_dev = efx->pci_dev;
+ struct efx_cxl *cxl;
+ u16 dvsec;
+
+ /* Is the device configured with and using CXL? */
+ if (!pcie_is_cxl(pci_dev))
+ return 0;
+
+ dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
+ PCI_DVSEC_CXL_DEVICE);
+ if (!dvsec) {
+ pci_info(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability not found\n");
+ return 0;
+ }
+
+ pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
+
+ /* Create a cxl_dev_state embedded in the cxl struct using cxl core api
+ * specifying no mbox available.
+ */
+ cxl = devm_cxl_dev_state_create(&pci_dev->dev, CXL_DEVTYPE_DEVMEM,
+ pci_get_dsn(pci_dev), dvsec,
+ struct efx_cxl, cxlds, false);
+
+ if (!cxl)
+ return -ENOMEM;
+
+ probe_data->cxl = cxl;
+
+ return 0;
+}
+
+MODULE_IMPORT_NS("CXL");
diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
new file mode 100644
index 000000000000..04e46278464d
--- /dev/null
+++ b/drivers/net/ethernet/sfc/efx_cxl.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for AMD network controllers and boards
+ * Copyright (C) 2025, Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_CXL_H
+#define EFX_CXL_H
+
+#ifdef CONFIG_SFC_CXL
+
+#include <cxl/cxl.h>
+
+struct efx_probe_data;
+
+struct efx_cxl {
+ struct cxl_dev_state cxlds;
+ struct cxl_memdev *cxlmd;
+};
+
+int efx_cxl_init(struct efx_probe_data *probe_data);
+#else
+static inline int efx_cxl_init(struct efx_probe_data *probe_data) { return 0; }
+#endif
+#endif
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index b98c259f672d..563e6a6e85f1 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1197,14 +1197,22 @@ struct efx_nic {
atomic_t n_rx_noskb_drops;
};
+#ifdef CONFIG_SFC_CXL
+struct efx_cxl;
+#endif
+
/**
* struct efx_probe_data - State after hardware probe
* @pci_dev: The PCI device
* @efx: Efx NIC details
+ * @cxl: details of related cxl objects
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
struct efx_nic efx;
+#ifdef CONFIG_SFC_CXL
+ struct efx_cxl *cxl;
+#endif
};
static inline struct efx_nic *efx_netdev_priv(struct net_device *dev)
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v31 2/5] sfc: Map cxl regs
2026-06-30 15:13 [PATCH v31 0/5] Type2 device basic support alejandro.lucero-palau
2026-06-30 15:13 ` [PATCH v31 1/5] sfc: add cxl support alejandro.lucero-palau
@ 2026-06-30 15:13 ` alejandro.lucero-palau
2026-06-30 14:39 ` sashiko-bot
2026-06-30 15:13 ` [PATCH v31 3/5] sfc: Initialize cxl dpa alejandro.lucero-palau
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: alejandro.lucero-palau @ 2026-06-30 15:13 UTC (permalink / raw)
To: linux-cxl, djbw, dave.jiang, kuba
Cc: Alejandro Lucero, Dan Williams, Jonathan Cameron, Ben Cheatham,
Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Use cxl core functions for discovering and mapping CXL device registers.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index be252af972ab..704b0ebae937 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -7,6 +7,8 @@
#include <linux/pci.h>
+#include <cxl/cxl.h>
+#include <cxl/pci.h>
#include "net_driver.h"
#include "efx_cxl.h"
@@ -18,6 +20,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
struct pci_dev *pci_dev = efx->pci_dev;
struct efx_cxl *cxl;
u16 dvsec;
+ int rc;
/* Is the device configured with and using CXL? */
if (!pcie_is_cxl(pci_dev))
@@ -42,6 +45,29 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
if (!cxl)
return -ENOMEM;
+ rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
+ &cxl->cxlds.reg_map);
+ if (rc) {
+ pci_err(pci_dev, "No component registers\n");
+ return rc;
+ }
+
+ if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
+ pci_err(pci_dev, "Expected HDM component register not found\n");
+ return -ENODEV;
+ }
+
+ if (!cxl->cxlds.reg_map.component_map.ras.valid) {
+ pci_err(pci_dev, "Expected RAS component register not found\n");
+ return -ENODEV;
+ }
+
+ /* Set media ready explicitly as there are neither mailbox for checking
+ * this state nor the CXL register involved, both not mandatory for
+ * type2.
+ */
+ cxl->cxlds.media_ready = true;
+
probe_data->cxl = cxl;
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v31 2/5] sfc: Map cxl regs
2026-06-30 15:13 ` [PATCH v31 2/5] sfc: Map cxl regs alejandro.lucero-palau
@ 2026-06-30 14:39 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-30 14:39 UTC (permalink / raw)
To: alejandro.lucero-palau; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The commit adds `#include <cxl/pci.h>`, but `include/cxl/pci.h` does not exist in the kernel tree, resulting in a fatal compilation error.
--
commit fd1792aaa5cf6782d5137f23ed3db63b260303d5
Author: Alejandro Lucero <alucerop@amd.com>
sfc: Map cxl regs
This commit introduces CXL core functions to the SFC driver for discovering
and mapping CXL device registers. It sets up the component registers and
verifies the presence of HDM and RAS capabilities.
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index be252af972ab3..704b0ebae9374 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -7,6 +7,8 @@
>
> #include <linux/pci.h>
>
> +#include <cxl/cxl.h>
> +#include <cxl/pci.h>
[Severity: Low]
Is this the correct header path? The cxl/pci.h file doesn't appear to exist
in the kernel tree. The cxl_pci_setup_regs() function and the
CXL_REGLOC_RBI_COMPONENT enum seem to be defined in drivers/cxl/cxlpci.h,
which is internal to the CXL subsystem and not exposed to other drivers.
Will this cause a build failure when compiling the sfc driver?
[ ... ]
> @@ -42,6 +45,29 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> if (!cxl)
> return -ENOMEM;
>
> + rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
> + &cxl->cxlds.reg_map);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260630151346.31201-1-alejandro.lucero-palau@amd.com?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v31 3/5] sfc: Initialize cxl dpa
2026-06-30 15:13 [PATCH v31 0/5] Type2 device basic support alejandro.lucero-palau
2026-06-30 15:13 ` [PATCH v31 1/5] sfc: add cxl support alejandro.lucero-palau
2026-06-30 15:13 ` [PATCH v31 2/5] sfc: Map cxl regs alejandro.lucero-palau
@ 2026-06-30 15:13 ` alejandro.lucero-palau
2026-06-30 14:52 ` sashiko-bot
2026-06-30 15:13 ` [PATCH v31 4/5] sfc: obtain and map cxl range using devm_cxl_probe_mem alejandro.lucero-palau
2026-06-30 15:13 ` [PATCH v31 5/5] sfc: support pio mapping based on cxl alejandro.lucero-palau
4 siblings, 1 reply; 10+ messages in thread
From: alejandro.lucero-palau @ 2026-06-30 15:13 UTC (permalink / raw)
To: linux-cxl, djbw, dave.jiang, kuba
Cc: Alejandro Lucero, Dan Williams, Ben Cheatham, Jonathan Cameron,
Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Use cxl_set_capacity() for DPA initialization as no mailbox is
available.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/net/ethernet/sfc/efx_cxl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 704b0ebae937..18b535b3ea40 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -68,6 +68,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
*/
cxl->cxlds.media_ready = true;
+ if (cxl_set_capacity(&cxl->cxlds, EFX_CTPIO_BUFFER_SIZE)) {
+ pci_err(pci_dev, "dpa capacity setup failed\n");
+ return -ENODEV;
+ }
+
probe_data->cxl = cxl;
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v31 3/5] sfc: Initialize cxl dpa
2026-06-30 15:13 ` [PATCH v31 3/5] sfc: Initialize cxl dpa alejandro.lucero-palau
@ 2026-06-30 14:52 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-30 14:52 UTC (permalink / raw)
To: alejandro.lucero-palau; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] The patch adds a call to an undefined function `cxl_set_capacity()`, which will cause a build failure.
- [Low] The file includes `<cxl/pci.h>` which does not exist in the source tree, causing a build failure.
--
commit 658adf5bd8fde62f9bb534a3960bfeef69a61055
Author: Alejandro Lucero <alucerop@amd.com>
sfc: Initialize cxl dpa
Use cxl_set_capacity() for DPA initialization as no mailbox is
available.
> diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
> index 704b0ebae9374..18b535b3ea405 100644
> --- a/drivers/net/ethernet/sfc/efx_cxl.c
> +++ b/drivers/net/ethernet/sfc/efx_cxl.c
> @@ -68,6 +68,11 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
> */
> cxl->cxlds.media_ready = true;
>
> + if (cxl_set_capacity(&cxl->cxlds, EFX_CTPIO_BUFFER_SIZE)) {
[Severity: Low]
Are we calling an undefined function here? cxl_set_capacity() is neither
declared nor defined anywhere in the kernel source tree, which causes a build
failure.
> + pci_err(pci_dev, "dpa capacity setup failed\n");
> + return -ENODEV;
> + }
> +
> probe_data->cxl = cxl;
>
> return 0;
[Severity: Low]
Is there a missing header file in this file? It includes <cxl/pci.h> which
does not exist in the kernel tree, causing a fatal compilation error:
drivers/net/ethernet/sfc/efx_cxl.c:
...
#include <linux/pci.h>
#include <cxl/cxl.h>
#include <cxl/pci.h>
#include "net_driver.h"
...
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260630151346.31201-1-alejandro.lucero-palau@amd.com?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v31 4/5] sfc: obtain and map cxl range using devm_cxl_probe_mem
2026-06-30 15:13 [PATCH v31 0/5] Type2 device basic support alejandro.lucero-palau
` (2 preceding siblings ...)
2026-06-30 15:13 ` [PATCH v31 3/5] sfc: Initialize cxl dpa alejandro.lucero-palau
@ 2026-06-30 15:13 ` alejandro.lucero-palau
2026-06-30 15:04 ` sashiko-bot
2026-06-30 15:13 ` [PATCH v31 5/5] sfc: support pio mapping based on cxl alejandro.lucero-palau
4 siblings, 1 reply; 10+ messages in thread
From: alejandro.lucero-palau @ 2026-06-30 15:13 UTC (permalink / raw)
To: linux-cxl, djbw, dave.jiang, kuba; +Cc: Alejandro Lucero, Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
Use core API for safely obtain the CXL range linked to an HDM committed
by the BIOS. Map such a range for being used as the ctpio buffer.
A potential user space action through sysfs unbinding or core cxl
modules remove will trigger sfc driver device detachment, with that case
not racing with this mapping as this is done during driver probe and
therefore protected with device lock against those user space actions.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/net/ethernet/sfc/efx.c | 2 ++
drivers/net/ethernet/sfc/efx_cxl.c | 23 +++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_cxl.h | 3 +++
3 files changed, 28 insertions(+)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 61cbb6cfc360..3806cd3dd7f4 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -984,6 +984,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_fini_io(efx);
probe_data = container_of(efx, struct efx_probe_data, efx);
+ efx_cxl_exit(probe_data);
pci_dbg(efx->pci_dev, "shutdown successful\n");
@@ -1242,6 +1243,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
return 0;
fail3:
+ efx_cxl_exit(probe_data);
efx_fini_io(efx);
fail2:
efx_fini_struct(efx);
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 18b535b3ea40..3e7c950f83e9 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -18,6 +18,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
{
struct efx_nic *efx = &probe_data->efx;
struct pci_dev *pci_dev = efx->pci_dev;
+ struct range cxl_pio_range;
struct efx_cxl *cxl;
u16 dvsec;
int rc;
@@ -73,9 +74,31 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
return -ENODEV;
}
+ cxl->cxlmd = devm_cxl_probe_mem(&cxl->cxlds, &cxl_pio_range);
+ if (IS_ERR(cxl->cxlmd)) {
+ pci_err(pci_dev, "CXL accel memdev creation failed\n");
+ return PTR_ERR(cxl->cxlmd);
+ }
+
+ cxl->ctpio_cxl = ioremap_wc(cxl_pio_range.start,
+ range_len(&cxl_pio_range));
+ if (!cxl->ctpio_cxl) {
+ pci_err(pci_dev, "CXL ioremap region (%pra) failed\n",
+ &cxl_pio_range);
+ return -ENOMEM;
+ }
+
probe_data->cxl = cxl;
return 0;
}
+void efx_cxl_exit(struct efx_probe_data *probe_data)
+{
+ if (!probe_data->cxl)
+ return;
+
+ iounmap(probe_data->cxl->ctpio_cxl);
+}
+
MODULE_IMPORT_NS("CXL");
diff --git a/drivers/net/ethernet/sfc/efx_cxl.h b/drivers/net/ethernet/sfc/efx_cxl.h
index 04e46278464d..3e2705cb063f 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.h
+++ b/drivers/net/ethernet/sfc/efx_cxl.h
@@ -20,10 +20,13 @@ struct efx_probe_data;
struct efx_cxl {
struct cxl_dev_state cxlds;
struct cxl_memdev *cxlmd;
+ void __iomem *ctpio_cxl;
};
int efx_cxl_init(struct efx_probe_data *probe_data);
+void efx_cxl_exit(struct efx_probe_data *probe_data);
#else
static inline int efx_cxl_init(struct efx_probe_data *probe_data) { return 0; }
+static inline void efx_cxl_exit(struct efx_probe_data *probe_data) {}
#endif
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v31 4/5] sfc: obtain and map cxl range using devm_cxl_probe_mem
2026-06-30 15:13 ` [PATCH v31 4/5] sfc: obtain and map cxl range using devm_cxl_probe_mem alejandro.lucero-palau
@ 2026-06-30 15:04 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-30 15:04 UTC (permalink / raw)
To: alejandro.lucero-palau; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Inverted teardown order unmaps write-combining memory and cleans up devm CXL resources after the PCI device is disabled.
--
commit 8a6ea64dcd83c4ec06b3116375770f0f9dce6ca6
Author: Alejandro Lucero <alucerop@amd.com>
Subject: sfc: obtain and map cxl range using devm_cxl_probe_mem
This commit uses the core CXL API to safely obtain and map the CXL range
linked to an HDM committed by the BIOS. The mapped range is used as the ctpio
buffer.
> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
> index 61cbb6cfc3602..3806cd3dd7f48 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -984,6 +984,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
> efx_fini_io(efx);
>
> probe_data = container_of(efx, struct efx_probe_data, efx);
> + efx_cxl_exit(probe_data);
[Severity: High]
Does this sequence unmap the Write-Combining memory after the PCI device is
disabled?
In efx_pci_remove(), efx_fini_io() is called first, which calls
pci_disable_device(). Then efx_cxl_exit() calls iounmap() on the ctpio_cxl
mapping.
If a CPU write-combining buffer flush occurs during iounmap() on a disabled
device, could it trigger a fatal PCIe error (Master Abort) and a kernel panic?
Also, since devm_cxl_probe_mem() and devm_cxl_dev_state_create() are used
during initialization, devres will clean up these resources after
efx_pci_remove() returns. Does this mean the devm cleanup also accesses the
device after it has been disabled?
>
> pci_dbg(efx->pci_dev, "shutdown successful\n");
>
[ ... ]
> @@ -1242,6 +1243,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
> return 0;
>
> fail3:
> + efx_cxl_exit(probe_data);
> efx_fini_io(efx);
[Severity: High]
Does this error path cause devm-managed CXL resources to be cleaned up on a
disabled device?
While efx_cxl_exit() correctly unmaps the region before efx_fini_io()
disables the device here, the devm-managed resources (like the CXL accel
memdev) will be destroyed by devres after efx_pci_probe() returns.
By the time devres runs, efx_fini_io() has already called pci_disable_device(),
so the devm cleanup will happen with the PCI device already disabled.
> fail2:
> efx_fini_struct(efx);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260630151346.31201-1-alejandro.lucero-palau@amd.com?part=4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v31 5/5] sfc: support pio mapping based on cxl
2026-06-30 15:13 [PATCH v31 0/5] Type2 device basic support alejandro.lucero-palau
` (3 preceding siblings ...)
2026-06-30 15:13 ` [PATCH v31 4/5] sfc: obtain and map cxl range using devm_cxl_probe_mem alejandro.lucero-palau
@ 2026-06-30 15:13 ` alejandro.lucero-palau
2026-06-30 15:22 ` sashiko-bot
4 siblings, 1 reply; 10+ messages in thread
From: alejandro.lucero-palau @ 2026-06-30 15:13 UTC (permalink / raw)
To: linux-cxl, djbw, dave.jiang, kuba; +Cc: Alejandro Lucero, Edward Cree
From: Alejandro Lucero <alucerop@amd.com>
A PIO buffer is a region of device memory to which the driver can write a
packet for TX, with the device handling the transmit doorbell without
requiring a DMA for getting the packet data, which helps reducing latency
in certain exchanges. With CXL mem protocol this latency can be lowered
further.
With a device supporting CXL and successfully initialised, use the cxl
region to map the memory range and use this mapping for PIO buffers.
Signed-off-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Acked-by: Edward Cree <ecree.xilinx@gmail.com>
---
drivers/net/ethernet/sfc/ef10.c | 41 ++++++++++++++++++++++-----
drivers/net/ethernet/sfc/efx_cxl.c | 1 +
drivers/net/ethernet/sfc/net_driver.h | 2 ++
drivers/net/ethernet/sfc/nic.h | 3 ++
4 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 7e04f115bbaa..73bc064929f6 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -24,6 +24,7 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <net/udp_tunnel.h>
+#include "efx_cxl.h"
/* Hardware control for EF10 architecture including 'Huntington'. */
@@ -106,7 +107,7 @@ static int efx_ef10_get_vf_index(struct efx_nic *efx)
static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
{
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
struct efx_ef10_nic_data *nic_data = efx->nic_data;
size_t outlen;
int rc;
@@ -177,6 +178,12 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
efx->num_mac_stats);
}
+ if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
+ nic_data->datapath_caps3 = 0;
+ else
+ nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_V7_OUT_FLAGS3);
+
return 0;
}
@@ -1140,6 +1147,9 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
unsigned int channel_vis, pio_write_vi_base, max_vis;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int uc_mem_map_size, wc_mem_map_size;
+#ifdef CONFIG_SFC_CXL
+ struct efx_probe_data *probe_data;
+#endif
void __iomem *membase;
int rc;
@@ -1263,8 +1273,23 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
iounmap(efx->membase);
efx->membase = membase;
- /* Set up the WC mapping if needed */
- if (wc_mem_map_size) {
+ if (!wc_mem_map_size)
+ goto skip_pio;
+
+ /* Set up the WC mapping */
+
+#ifdef CONFIG_SFC_CXL
+ probe_data = container_of(efx, struct efx_probe_data, efx);
+ if ((nic_data->datapath_caps3 &
+ (1 << MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_LBN)) &&
+ probe_data->cxl_pio_initialised) {
+ /* Using PIO through CXL mapping */
+ nic_data->pio_write_base = probe_data->cxl->ctpio_cxl;
+ nic_data->pio_write_vi_base = pio_write_vi_base;
+ } else
+#endif
+ {
+ /* Using legacy PIO BAR mapping */
nic_data->wc_membase = ioremap_wc(efx->membase_phys +
uc_mem_map_size,
wc_mem_map_size);
@@ -1279,12 +1304,14 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
nic_data->wc_membase +
(pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF -
uc_mem_map_size);
-
- rc = efx_ef10_link_piobufs(efx);
- if (rc)
- efx_ef10_free_piobufs(efx);
}
+ rc = efx_ef10_link_piobufs(efx);
+ if (rc)
+ efx_ef10_free_piobufs(efx);
+
+skip_pio:
+
netif_dbg(efx, probe, efx->net_dev,
"memory BAR at %pa (virtual %p+%x UC, %p+%x WC)\n",
&efx->membase_phys, efx->membase, uc_mem_map_size,
diff --git a/drivers/net/ethernet/sfc/efx_cxl.c b/drivers/net/ethernet/sfc/efx_cxl.c
index 3e7c950f83e9..348d7404cd7a 100644
--- a/drivers/net/ethernet/sfc/efx_cxl.c
+++ b/drivers/net/ethernet/sfc/efx_cxl.c
@@ -88,6 +88,7 @@ int efx_cxl_init(struct efx_probe_data *probe_data)
return -ENOMEM;
}
+ probe_data->cxl_pio_initialised = true;
probe_data->cxl = cxl;
return 0;
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 563e6a6e85f1..3964b2c56609 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1206,12 +1206,14 @@ struct efx_cxl;
* @pci_dev: The PCI device
* @efx: Efx NIC details
* @cxl: details of related cxl objects
+ * @cxl_pio_initialised: cxl initialization outcome.
*/
struct efx_probe_data {
struct pci_dev *pci_dev;
struct efx_nic efx;
#ifdef CONFIG_SFC_CXL
struct efx_cxl *cxl;
+ bool cxl_pio_initialised;
#endif
};
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index ec3b2df43b68..7480f9995dfb 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -152,6 +152,8 @@ enum {
* %MC_CMD_GET_CAPABILITIES response)
* @datapath_caps2: Further Capabilities of datapath firmware (FLAGS2 field of
* %MC_CMD_GET_CAPABILITIES response)
+ * @datapath_caps3: Further Capabilities of datapath firmware (FLAGS3 field of
+ * %MC_CMD_GET_CAPABILITIES response)
* @rx_dpcpu_fw_id: Firmware ID of the RxDPCPU
* @tx_dpcpu_fw_id: Firmware ID of the TxDPCPU
* @must_probe_vswitching: Flag: vswitching has yet to be setup after MC reboot
@@ -187,6 +189,7 @@ struct efx_ef10_nic_data {
bool must_check_datapath_caps;
u32 datapath_caps;
u32 datapath_caps2;
+ u32 datapath_caps3;
unsigned int rx_dpcpu_fw_id;
unsigned int tx_dpcpu_fw_id;
bool must_probe_vswitching;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v31 5/5] sfc: support pio mapping based on cxl
2026-06-30 15:13 ` [PATCH v31 5/5] sfc: support pio mapping based on cxl alejandro.lucero-palau
@ 2026-06-30 15:22 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-30 15:22 UTC (permalink / raw)
To: alejandro.lucero-palau; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] Missing VI base and PIO register offsets in CXL PIO mapping, leading to hardware register corruption
--
commit 125e7b168b7494938907570e29acc3c906cb9a0a
Author: Alejandro Lucero <alucerop@amd.com>
sfc: support pio mapping based on cxl
This patch adds support for mapping PIO buffers using CXL memory if the device
supports it and is successfully initialized. Using CXL for the PIO buffer region
can help further reduce latency during TX packet exchanges.
> diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
> index 7e04f115bbaaa..73bc064929f63 100644
> --- a/drivers/net/ethernet/sfc/ef10.c
> +++ b/drivers/net/ethernet/sfc/ef10.c
[ ... ]
> @@ -1263,8 +1273,23 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
> iounmap(efx->membase);
> efx->membase = membase;
>
> - /* Set up the WC mapping if needed */
> - if (wc_mem_map_size) {
> + if (!wc_mem_map_size)
> + goto skip_pio;
> +
> + /* Set up the WC mapping */
> +
> +#ifdef CONFIG_SFC_CXL
> + probe_data = container_of(efx, struct efx_probe_data, efx);
> + if ((nic_data->datapath_caps3 &
> + (1 << MC_CMD_GET_CAPABILITIES_V7_OUT_CXL_CONFIG_ENABLE_LBN)) &&
> + probe_data->cxl_pio_initialised) {
> + /* Using PIO through CXL mapping */
> + nic_data->pio_write_base = probe_data->cxl->ctpio_cxl;
[Severity: Critical]
Does this assignment miss the required hardware offsets for the VI base and PIO
buffer register?
In the legacy PIO BAR mapping path just below, the base is calculated with
these offsets:
pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF - uc_mem_map_size
When efx_ef10_link_piobufs() sets up the TX queue, it computes the pointer
using this base:
tx_queue->piobuf =
nic_data->pio_write_base +
index * efx->vi_stride + offset;
Without adding the VI base and PIO register offsets to the CXL mapping,
will the calculated pointer target the doorbell registers at offset 0
(e.g., ER_DZ_EVQ_RPTR, ER_DZ_TX_DESC_UPD) instead of the PIO buffers,
causing packet data writes to corrupt hardware state?
> + nic_data->pio_write_vi_base = pio_write_vi_base;
> + } else
> +#endif
> + {
> + /* Using legacy PIO BAR mapping */
> nic_data->wc_membase = ioremap_wc(efx->membase_phys +
> uc_mem_map_size,
> wc_mem_map_size);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260630151346.31201-1-alejandro.lucero-palau@amd.com?part=5
^ permalink raw reply [flat|nested] 10+ messages in thread