1 /*
2  * Copyright (c) 2025 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/drivers/pcie/pcie.h>
10 #include <zephyr/drivers/ethernet/eth_intel_plat.h>
11 
12 #include <zephyr/logging/log.h>
13 LOG_MODULE_REGISTER(intel_eth_plat, CONFIG_ETHERNET_LOG_LEVEL);
14 
15 #define DT_DRV_COMPAT intel_eth_plat
16 
17 /* Device id supported in igc */
18 enum i226_sku {
19 	INTEL_IGC_I226_LMVP = 0x5503,
20 	INTEL_IGC_I226_LM = 0x125B,
21 	INTEL_IGC_I226_V = 0x125C,
22 	INTEL_IGC_I226_IT = 0x125D,
23 	INTEL_IGC_I226_BLANK_NVM = 0x125F,
24 };
25 
26 struct intel_eth_plat_cfg {
27 	struct pcie_dev *pcie;
28 };
29 
30 struct intel_eth_plat_data {
31 	DEVICE_MMIO_RAM;
32 	mm_reg_t base;
33 };
34 
eth_intel_get_pcie_bdf(const struct device * dev)35 uint32_t eth_intel_get_pcie_bdf(const struct device *dev)
36 {
37 	const struct intel_eth_plat_cfg *cfg = dev->config;
38 
39 	return cfg->pcie->bdf;
40 }
41 
eth_intel_validate_sku(const struct device * dev)42 static int eth_intel_validate_sku(const struct device *dev)
43 {
44 	const struct intel_eth_plat_cfg *cfg = dev->config;
45 	pcie_id_t pcie_id = cfg->pcie->id;
46 
47 	switch (PCIE_ID_TO_DEV(pcie_id)) {
48 	case INTEL_IGC_I226_LMVP:
49 	case INTEL_IGC_I226_LM:
50 	case INTEL_IGC_I226_V:
51 	case INTEL_IGC_I226_IT:
52 		return 0;
53 	case INTEL_IGC_I226_BLANK_NVM:
54 	default:
55 		break;
56 	}
57 
58 	LOG_ERR("SKU validation failed & pcie_id is %x", pcie_id);
59 
60 	return -EIO;
61 }
62 
intel_eth_plat_init(const struct device * dev)63 static int intel_eth_plat_init(const struct device *dev)
64 {
65 	const struct intel_eth_plat_cfg *cfg = dev->config;
66 	struct pcie_bar mbar;
67 	int ret;
68 
69 	ret = eth_intel_validate_sku(dev);
70 	if (ret < 0) {
71 		return ret;
72 	}
73 
74 	if (cfg->pcie->bdf == PCIE_BDF_NONE || !pcie_probe_mbar(cfg->pcie->bdf, 0, &mbar)) {
75 		LOG_ERR("Cannot get mbar");
76 		return -ENOENT;
77 	}
78 
79 	pcie_set_cmd(cfg->pcie->bdf, PCIE_CONF_CMDSTAT_MEM | PCIE_CONF_CMDSTAT_MASTER, true);
80 
81 	device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE);
82 
83 	return 0;
84 }
85 
86 #define INTEL_ETH_PLAT_INIT(n)                                                                     \
87 	DEVICE_PCIE_INST_DECLARE(n);                                                               \
88 	static struct intel_eth_plat_data plat_data_##n;                                           \
89 	static const struct intel_eth_plat_cfg plat_cfg_##n = {                                    \
90 		DEVICE_PCIE_INST_INIT(n, pcie),                                                    \
91 	};                                                                                         \
92 	DEVICE_DT_INST_DEFINE(n, intel_eth_plat_init, NULL, &plat_data_##n, &plat_cfg_##n,         \
93 			      POST_KERNEL, CONFIG_PCIE_INIT_PRIORITY, NULL);
94 
95 DT_INST_FOREACH_STATUS_OKAY(INTEL_ETH_PLAT_INIT)
96