xref: /linux/drivers/net/ethernet/sfc/efx_cxl.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1a3fc56b1SAlejandro Lucero // SPDX-License-Identifier: GPL-2.0-only
2a3fc56b1SAlejandro Lucero /****************************************************************************
3a3fc56b1SAlejandro Lucero  *
4a3fc56b1SAlejandro Lucero  * Driver for AMD network controllers and boards
5a3fc56b1SAlejandro Lucero  * Copyright (C) 2025, Advanced Micro Devices, Inc.
6a3fc56b1SAlejandro Lucero  */
7a3fc56b1SAlejandro Lucero 
8a3fc56b1SAlejandro Lucero #include <linux/pci.h>
9a3fc56b1SAlejandro Lucero 
1008699796SAlejandro Lucero #include <cxl/cxl.h>
1108699796SAlejandro Lucero #include <cxl/pci.h>
12a3fc56b1SAlejandro Lucero #include "net_driver.h"
13a3fc56b1SAlejandro Lucero #include "efx_cxl.h"
14a3fc56b1SAlejandro Lucero 
15a3fc56b1SAlejandro Lucero #define EFX_CTPIO_BUFFER_SIZE	SZ_256M
16a3fc56b1SAlejandro Lucero 
efx_cxl_init(struct efx_probe_data * probe_data)17a3fc56b1SAlejandro Lucero int efx_cxl_init(struct efx_probe_data *probe_data)
18a3fc56b1SAlejandro Lucero {
19a3fc56b1SAlejandro Lucero 	struct efx_nic *efx = &probe_data->efx;
20a3fc56b1SAlejandro Lucero 	struct pci_dev *pci_dev = efx->pci_dev;
210418860eSAlejandro Lucero 	struct range cxl_pio_range;
22a3fc56b1SAlejandro Lucero 	struct efx_cxl *cxl;
23a3fc56b1SAlejandro Lucero 	u16 dvsec;
2408699796SAlejandro Lucero 	int rc;
25a3fc56b1SAlejandro Lucero 
26a3fc56b1SAlejandro Lucero 	/* Is the device configured with and using CXL? */
27a3fc56b1SAlejandro Lucero 	if (!pcie_is_cxl(pci_dev))
28a3fc56b1SAlejandro Lucero 		return 0;
29a3fc56b1SAlejandro Lucero 
30a3fc56b1SAlejandro Lucero 	dvsec = pci_find_dvsec_capability(pci_dev, PCI_VENDOR_ID_CXL,
31a3fc56b1SAlejandro Lucero 					  PCI_DVSEC_CXL_DEVICE);
32a3fc56b1SAlejandro Lucero 	if (!dvsec) {
33a3fc56b1SAlejandro Lucero 		pci_info(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability not found\n");
34a3fc56b1SAlejandro Lucero 		return 0;
35a3fc56b1SAlejandro Lucero 	}
36a3fc56b1SAlejandro Lucero 
37a3fc56b1SAlejandro Lucero 	pci_dbg(pci_dev, "CXL_DVSEC_PCIE_DEVICE capability found\n");
38a3fc56b1SAlejandro Lucero 
39a3fc56b1SAlejandro Lucero 	/* Create a cxl_dev_state embedded in the cxl struct using cxl core api
40a3fc56b1SAlejandro Lucero 	 * specifying no mbox available.
41a3fc56b1SAlejandro Lucero 	 */
42a3fc56b1SAlejandro Lucero 	cxl = devm_cxl_dev_state_create(&pci_dev->dev, CXL_DEVTYPE_DEVMEM,
43a3fc56b1SAlejandro Lucero 					pci_get_dsn(pci_dev), dvsec,
44a3fc56b1SAlejandro Lucero 					struct efx_cxl, cxlds, false);
45a3fc56b1SAlejandro Lucero 
46a3fc56b1SAlejandro Lucero 	if (!cxl)
47a3fc56b1SAlejandro Lucero 		return -ENOMEM;
48a3fc56b1SAlejandro Lucero 
4908699796SAlejandro Lucero 	rc = cxl_pci_setup_regs(pci_dev, CXL_REGLOC_RBI_COMPONENT,
5008699796SAlejandro Lucero 				&cxl->cxlds.reg_map);
5108699796SAlejandro Lucero 	if (rc) {
5208699796SAlejandro Lucero 		pci_err(pci_dev, "No component registers\n");
5308699796SAlejandro Lucero 		return rc;
5408699796SAlejandro Lucero 	}
5508699796SAlejandro Lucero 
5608699796SAlejandro Lucero 	if (!cxl->cxlds.reg_map.component_map.hdm_decoder.valid) {
5708699796SAlejandro Lucero 		pci_err(pci_dev, "Expected HDM component register not found\n");
5808699796SAlejandro Lucero 		return -ENODEV;
5908699796SAlejandro Lucero 	}
6008699796SAlejandro Lucero 
6108699796SAlejandro Lucero 	if (!cxl->cxlds.reg_map.component_map.ras.valid) {
6208699796SAlejandro Lucero 		pci_err(pci_dev, "Expected RAS component register not found\n");
6308699796SAlejandro Lucero 		return -ENODEV;
6408699796SAlejandro Lucero 	}
6508699796SAlejandro Lucero 
6608699796SAlejandro Lucero 	/* Set media ready explicitly as there are neither mailbox for checking
6708699796SAlejandro Lucero 	 * this state nor the CXL register involved, both not mandatory for
6808699796SAlejandro Lucero 	 * type2.
6908699796SAlejandro Lucero 	 */
7008699796SAlejandro Lucero 	cxl->cxlds.media_ready = true;
7108699796SAlejandro Lucero 
72230284c1SAlejandro Lucero 	if (cxl_set_capacity(&cxl->cxlds, EFX_CTPIO_BUFFER_SIZE)) {
73230284c1SAlejandro Lucero 		pci_err(pci_dev, "dpa capacity setup failed\n");
74230284c1SAlejandro Lucero 		return -ENODEV;
75230284c1SAlejandro Lucero 	}
76230284c1SAlejandro Lucero 
770418860eSAlejandro Lucero 	cxl->cxlmd = devm_cxl_probe_mem(&cxl->cxlds, &cxl_pio_range);
780418860eSAlejandro Lucero 	if (IS_ERR(cxl->cxlmd)) {
790418860eSAlejandro Lucero 		pci_err(pci_dev, "CXL accel memdev creation failed\n");
800418860eSAlejandro Lucero 		return PTR_ERR(cxl->cxlmd);
810418860eSAlejandro Lucero 	}
820418860eSAlejandro Lucero 
830418860eSAlejandro Lucero 	cxl->ctpio_cxl = ioremap_wc(cxl_pio_range.start,
840418860eSAlejandro Lucero 				    range_len(&cxl_pio_range));
850418860eSAlejandro Lucero 	if (!cxl->ctpio_cxl) {
860418860eSAlejandro Lucero 		pci_err(pci_dev, "CXL ioremap region (%pra) failed\n",
870418860eSAlejandro Lucero 			&cxl_pio_range);
880418860eSAlejandro Lucero 		return -ENOMEM;
890418860eSAlejandro Lucero 	}
900418860eSAlejandro Lucero 
91*bd6550bcSAlejandro Lucero 	probe_data->cxl_pio_initialised = true;
92a3fc56b1SAlejandro Lucero 	probe_data->cxl = cxl;
93a3fc56b1SAlejandro Lucero 
94a3fc56b1SAlejandro Lucero 	return 0;
95a3fc56b1SAlejandro Lucero }
96a3fc56b1SAlejandro Lucero 
efx_cxl_exit(struct efx_probe_data * probe_data)970418860eSAlejandro Lucero void efx_cxl_exit(struct efx_probe_data *probe_data)
980418860eSAlejandro Lucero {
990418860eSAlejandro Lucero 	if (!probe_data->cxl)
1000418860eSAlejandro Lucero 		return;
1010418860eSAlejandro Lucero 
1020418860eSAlejandro Lucero 	iounmap(probe_data->cxl->ctpio_cxl);
1030418860eSAlejandro Lucero }
1040418860eSAlejandro Lucero 
105a3fc56b1SAlejandro Lucero MODULE_IMPORT_NS("CXL");
106