diff --git a/CHANGELOG.md b/CHANGELOG.md
index d72928879..d34e00bda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@
- Hardware Cursor
- Note cursor images will be static (ie. beachball)
- Quicklook dismiss/expand
+- Add Ethernet Controller detection to build
+- Resolve i210/i225 NIC support on pre-Ivy Macs
## 0.4.2
- Resolve app crashing on some 3rd party SAS/SATA controllers
diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist
index 8b74eeff5..dffedc522 100644
--- a/payloads/Config/config.plist
+++ b/payloads/Config/config.plist
@@ -501,6 +501,24 @@
PlistPath
Contents/Info.plist
+
+ Arch
+ x86_64
+ Comment
+ I210 Ethernet patch
+ Enabled
+
+ MaxKernel
+
+ MinKernel
+ 20.0.0
+ BundlePath
+ CatalinaIntelI210Ethernet.kext
+ ExecutablePath
+ Contents/MacOS/CatalinaIntelI210Ethernet
+ PlistPath
+ Contents/Info.plist
+
Arch
x86_64
diff --git a/payloads/Kexts/Ethernet/CatalinaIntelI210Ethernet-v1.0.0.zip b/payloads/Kexts/Ethernet/CatalinaIntelI210Ethernet-v1.0.0.zip
new file mode 100644
index 000000000..c78f57e45
Binary files /dev/null and b/payloads/Kexts/Ethernet/CatalinaIntelI210Ethernet-v1.0.0.zip differ
diff --git a/resources/build.py b/resources/build.py
index 45c134d1e..bdf0b6411 100644
--- a/resources/build.py
+++ b/resources/build.py
@@ -126,9 +126,6 @@ class BuildOpenCore:
self.constants.cpufriend_path,
lambda: self.model not in ["iMac7,1", "Xserve2,1", "Dortania1,1"] and self.constants.allow_oc_everywhere is False and self.constants.disallow_cpufriend is False and self.constants.serial_settings != "None",
),
- # Ethernet patches
- ("nForceEthernet.kext", self.constants.nforce_version, self.constants.nforce_path, lambda: smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Nvidia"),
- ("MarvelYukonEthernet.kext", self.constants.marvel_version, self.constants.marvel_path, lambda: smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Marvell"),
# Legacy audio
(
"AppleALC.kext",
@@ -190,12 +187,36 @@ class BuildOpenCore:
# Modded RestrictEvents with displaypolicyd blocked to fix dGPU switching
self.enable_kext("RestrictEvents.kext", self.constants.restrictevents_mbp_version, self.constants.restrictevents_mbp_path)
- # Ethernet Patch Sets
- if smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Broadcom":
- if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
- # Required due to Big Sur's BCM5701 requiring VT-x support
- # Applicable for pre-Ivy Bridge models
- self.enable_kext("CatalinaBCM5701Ethernet.kext", self.constants.bcm570_version, self.constants.bcm570_path)
+ if not self.constants.custom_model and self.constants.computer.ethernet:
+ for controller in self.constants.computer.ethernet:
+ if isinstance(controller, device_probe.BroadcomEthernet) and controller.chipset == device_probe.BroadcomEthernet.Chipsets.AppleBCM5701Ethernet:
+ if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
+ # Required due to Big Sur's BCM5701 requiring VT-D support
+ # Applicable for pre-Ivy Bridge models
+ if self.get_kext_by_bundle_path("CatalinaBCM5701Ethernet.kext")["Enabled"] is False:
+ self.enable_kext("CatalinaBCM5701Ethernet.kext", self.constants.bcm570_version, self.constants.bcm570_path)
+ elif isinstance(controller, device_probe.IntelEthernet) and controller.chipset == device_probe.IntelEthernet.Chipsets.AppleIntelI210Ethernet:
+ if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
+ # Apple's IOSkywalkFamily in DriverKit requires VT-D support
+ # Applicable for pre-Ivy Bridge models
+ if self.get_kext_by_bundle_path("CatalinaIntelI210Ethernet.kext")["Enabled"] is False:
+ self.enable_kext("CatalinaIntelI210Ethernet.kext", self.constants.i210_version, self.constants.i210_path)
+ elif isinstance(controller, device_probe.NVIDIAEthernet):
+ if self.get_kext_by_bundle_path("nForceEthernet.kext")["Enabled"] is False:
+ self.enable_kext("nForceEthernet.kext", self.constants.nforce_version, self.constants.nforce_path)
+ elif isinstance(controller, device_probe.Marvell) or isinstance(controller, device_probe.SysKonnect):
+ if self.get_kext_by_bundle_path("MarvelYukonEthernet.kext")["Enabled"] is False:
+ self.enable_kext("MarvelYukonEthernet.kext", self.constants.marvel_version, self.constants.marvel_path)
+ else:
+ if smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Broadcom":
+ if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
+ # Required due to Big Sur's BCM5701 requiring VT-D support
+ # Applicable for pre-Ivy Bridge models
+ self.enable_kext("CatalinaBCM5701Ethernet.kext", self.constants.bcm570_version, self.constants.bcm570_path)
+ elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Nvidia":
+ self.enable_kext("nForceEthernet.kext", self.constants.nforce_version, self.constants.nforce_path)
+ elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Marvell":
+ self.enable_kext("MarvelYukonEthernet.kext", self.constants.marvel_version, self.constants.marvel_path)
# i3 Ivy Bridge iMacs don't support RDRAND
# However for prebuilt, assume they do
diff --git a/resources/constants.py b/resources/constants.py
index 07934f976..9e07e5782 100644
--- a/resources/constants.py
+++ b/resources/constants.py
@@ -57,6 +57,7 @@ class Constants:
## Apple - Dortania Modified
self.bcm570_version = "1.0.2" # CatalinaBCM5701Ethernet
+ self.i210_version = "1.0.0" # CatalinaIntelI210Ethernet
self.corecaptureelcap_version = "1.0.1" # corecaptureElCap
self.io80211elcap_version = "2.0.0" # IO80211ElCap
self.io80211high_sierra_version = "1.0.1" # IO80211HighSierra
@@ -283,6 +284,10 @@ class Constants:
def bcm570_path(self):
return self.payload_kexts_path / Path(f"Ethernet/CatalinaBCM5701Ethernet-v{self.bcm570_version}.zip")
+ @property
+ def i210_path(self):
+ return self.payload_kexts_path / Path(f"Ethernet/CatalinaIntelI210Ethernet-v{self.i210_version}.zip")
+
@property
def marvel_path(self):
return self.payload_kexts_path / Path(f"Ethernet/MarvelYukonEthernet-v{self.marvel_version}.zip")
diff --git a/resources/device_probe.py b/resources/device_probe.py
index bc870a8e5..b6bd64f48 100644
--- a/resources/device_probe.py
+++ b/resources/device_probe.py
@@ -157,6 +157,11 @@ class NVMeController(PCIDevice):
class EthernetController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x020000
+ chipset: enum.Enum = field(init=False)
+
+ def __post_init__(self):
+ self.detect_chipset()
+
@dataclass
class SATAController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x010601
@@ -208,6 +213,18 @@ class NVIDIA(GPU):
else:
self.arch = NVIDIA.Archs.Unknown
+@dataclass
+class NVIDIAEthernet(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x10DE
+
+ class Chipsets(enum.Enum):
+ nForceEthernet = "nForceEthernet"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ # nForce driver matches against Vendor ID, thus making all nForce chipsets supported
+ self.chipset = NVIDIAEthernet.Chipsets.nForceEthernet
@dataclass
class AMD(GPU):
@@ -301,6 +318,27 @@ class Intel(GPU):
else:
self.arch = Intel.Archs.Unknown
+@dataclass
+class IntelEthernet(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x8086
+
+ class Chipsets(enum.Enum):
+ AppleIntel8254XEthernet = "AppleIntel8254XEthernet Supported"
+ AppleIntelI210Ethernet = "AppleIntelI210Ethernet Supported"
+ Intel82574L = "Intel82574L Supported"
+ Unknown = "Unknown"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ if self.device_id in pci_data.intel_ids.AppleIntel8254XEthernet:
+ self.chipset = IntelEthernet.Chipsets.AppleIntel8254XEthernet
+ elif self.device_id in pci_data.intel_ids.AppleIntelI210Ethernet:
+ self.chipset = IntelEthernet.Chipsets.AppleIntelI210Ethernet
+ elif self.device_id in pci_data.intel_ids.Intel82574L:
+ self.chipset = IntelEthernet.Chipsets.Intel82574L
+ else:
+ self.chipset = IntelEthernet.Chipsets.Unknown
@dataclass
class Broadcom(WirelessCard):
@@ -331,6 +369,21 @@ class Broadcom(WirelessCard):
else:
self.chipset = Broadcom.Chipsets.Unknown
+@dataclass
+class BroadcomEthernet(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x14E4
+
+ class Chipsets(enum.Enum):
+ AppleBCM5701Ethernet = "AppleBCM5701Ethernet supported"
+ Unknown = "Unknown"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ if self.device_id in pci_data.broadcom_ids.AppleBCM5701Ethernet:
+ self.chipset = BroadcomEthernet.Chipsets.AppleBCM5701Ethernet
+ else:
+ self.chipset = BroadcomEthernet.Chipsets.Unknown
@dataclass
class Atheros(WirelessCard):
@@ -351,6 +404,56 @@ class Atheros(WirelessCard):
self.chipset = Atheros.Chipsets.Unknown
+@dataclass
+class Aquantia(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x1D6A
+
+ class Chipsets(enum.Enum):
+ # pylint: disable=invalid-name
+ AppleEthernetAquantiaAqtion = "AppleEthernetAquantiaAqtion supported"
+ Unknown = "Unknown"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ if self.device_id in pci_data.aquantia_ids.AppleEthernetAquantiaAqtion:
+ self.chipset = Aquantia.Chipsets.AppleEthernetAquantiaAqtion
+ else:
+ self.chipset = Aquantia.Chipsets.Unknown
+
+@dataclass
+class Marvell(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x11AB
+
+ class Chipsets(enum.Enum):
+ MarvelYukonEthernet = "MarvelYukonEthernet supported"
+ Unknown = "Unknown"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ if self.device_id in pci_data.marvell_ids.MarvelYukonEthernet:
+ self.chipset = Marvell.Chipsets.MarvelYukonEthernet
+ else:
+ self.chipset = Marvell.Chipsets.Unknown
+
+@dataclass
+class SysKonnect(EthernetController):
+ VENDOR_ID: ClassVar[int] = 0x1148
+
+ class Chipsets(enum.Enum):
+ MarvelYukonEthernet = "MarvelYukonEthernet supported"
+ Unknown = "Unknown"
+
+ chipset: Chipsets = field(init=False)
+
+ def detect_chipset(self):
+ if self.device_id in pci_data.syskonnect_ids.MarvelYukonEthernet:
+ self.chipset = SysKonnect.Chipsets.MarvelYukonEthernet
+ else:
+ self.chipset = SysKonnect.Chipsets.Unknown
+
+
@dataclass
class Computer:
real_model: Optional[str] = None
@@ -362,7 +465,7 @@ class Computer:
dgpu: Optional[GPU] = None # Shortcut for GFX0
storage: list[PCIDevice] = field(default_factory=list)
usb_controllers: list[PCIDevice] = field(default_factory=list)
- ethernet: list[PCIDevice] = field(default_factory=list)
+ ethernet: Optional[EthernetController] = field(default_factory=list)
wifi: Optional[WirelessCard] = None
cpu: Optional[CPU] = None
oclp_version: Optional[str] = None
@@ -490,10 +593,15 @@ class Computer:
None,
)[1]
)
- for device in ethernet_controllers:
- self.ethernet.append(EthernetController.from_ioregistry(device))
- ioreg.IOObjectRelease(device)
+ # for device in ethernet_controllers:
+ # self.ethernet.append(EthernetController.from_ioregistry(device))
+ # ioreg.IOObjectRelease(device)
+ for device in ethernet_controllers:
+ vendor: Type[EthernetController] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=EthernetController) # type: ignore
+ if vendor:
+ self.ethernet.append(vendor.from_ioregistry(device)) # type: ignore
+ ioreg.IOObjectRelease(device)
def storage_probe(self):
sata_controllers = ioreg.ioiterator_to_list(