From daa6e9e80e1c106bfda3448c726d2d465219e9ab Mon Sep 17 00:00:00 2001 From: jpz4085 Date: Mon, 31 May 2021 20:00:20 -0400 Subject: [PATCH] Update to version 2.5.3d1. --- .../IntelMausiEthernet-Info.plist | 4 +- IntelMausiEthernet/IntelMausiEthernet.cpp | 409 ++++++------------ IntelMausiEthernet/IntelMausiEthernet.h | 33 +- IntelMausiEthernet/IntelMausiHardware.cpp | 220 +++++++--- IntelMausiEthernet/IntelMausiSetup.cpp | 130 ++++-- IntelMausiEthernet/defines.h | 2 + IntelMausiEthernet/ich8lan.h | 17 +- IntelMausiEthernet/regs.h | 3 + 8 files changed, 444 insertions(+), 374 deletions(-) mode change 100644 => 100755 IntelMausiEthernet/IntelMausiEthernet-Info.plist mode change 100644 => 100755 IntelMausiEthernet/IntelMausiEthernet.cpp mode change 100644 => 100755 IntelMausiEthernet/IntelMausiEthernet.h mode change 100644 => 100755 IntelMausiEthernet/IntelMausiHardware.cpp mode change 100644 => 100755 IntelMausiEthernet/IntelMausiSetup.cpp mode change 100644 => 100755 IntelMausiEthernet/defines.h mode change 100644 => 100755 IntelMausiEthernet/ich8lan.h mode change 100644 => 100755 IntelMausiEthernet/regs.h diff --git a/IntelMausiEthernet/IntelMausiEthernet-Info.plist b/IntelMausiEthernet/IntelMausiEthernet-Info.plist old mode 100644 new mode 100755 index 6bfc218..fef7bc0 --- a/IntelMausiEthernet/IntelMausiEthernet-Info.plist +++ b/IntelMausiEthernet/IntelMausiEthernet-Info.plist @@ -32,9 +32,7 @@ enableCSO6 - enableTSO4 - - enableTSO6 + enableWakeOnAddrMatch maxIntrRate10 3000 diff --git a/IntelMausiEthernet/IntelMausiEthernet.cpp b/IntelMausiEthernet/IntelMausiEthernet.cpp old mode 100644 new mode 100755 index 0b1f2ea..5c6e209 --- a/IntelMausiEthernet/IntelMausiEthernet.cpp +++ b/IntelMausiEthernet/IntelMausiEthernet.cpp @@ -21,11 +21,6 @@ #include "IntelMausiEthernet.h" -#pragma mark --- function prototypes --- - -static inline void prepareTSO4(mbuf_t m, UInt32 *mssHeaderSize, UInt32 *payloadSize); -static inline void prepareTSO6(mbuf_t m, UInt32 *mssHeaderSize, UInt32 *payloadSize); - #pragma mark --- private data --- static const struct intelDevice deviceTable[] = { @@ -164,7 +159,6 @@ bool IntelMausi::init(OSDictionary *properties) promiscusMode = false; multicastMode = false; linkUp = false; - linkOpts = 0; polling = false; forceReset = false; eeeMode = 0; @@ -180,8 +174,6 @@ bool IntelMausi::init(OSDictionary *properties) wolCapable = false; wolActive = false; wolPwrOff = true; - enableTSO4 = false; - enableTSO6 = false; enableCSO6 = false; pciPMCtrlOffset = 0; maxLatency = 0; @@ -245,7 +237,7 @@ bool IntelMausi::start(IOService *provider) result = super::start(provider); if (!result) { - IOLog("Ethernet [IntelMausi]: IOEthernetController::start failed.\n"); + IOLog("[IntelMausi]: IOEthernetController::start failed.\n"); goto done; } multicastMode = false; @@ -256,13 +248,13 @@ bool IntelMausi::start(IOService *provider) pciDevice = OSDynamicCast(IOPCIDevice, provider); if (!pciDevice) { - IOLog("Ethernet [IntelMausi]: No provider.\n"); + IOLog("[IntelMausi]: No provider.\n"); goto done; } pciDevice->retain(); if (!pciDevice->open(this)) { - IOLog("Ethernet [IntelMausi]: Failed to open provider.\n"); + IOLog("[IntelMausi]: Failed to open provider.\n"); goto error1; } if (!initPCIConfigSpace(pciDevice)) { @@ -274,32 +266,32 @@ bool IntelMausi::start(IOService *provider) goto error2; } if (!setupMediumDict()) { - IOLog("Ethernet [IntelMausi]: Failed to setup medium dictionary.\n"); + IOLog("[IntelMausi]: Failed to setup medium dictionary.\n"); goto error2; } commandGate = getCommandGate(); if (!commandGate) { - IOLog("Ethernet [IntelMausi]: getCommandGate() failed.\n"); - goto error3; + IOLog("[IntelMausi]: getCommandGate() failed.\n"); + goto error2; } commandGate->retain(); if (!setupDMADescriptors()) { - IOLog("Ethernet [IntelMausi]: Error allocating DMA descriptors.\n"); + IOLog("[IntelMausi]: Error allocating DMA descriptors.\n"); goto error3; } if (!initEventSources(provider)) { - IOLog("Ethernet [IntelMausi]: initEventSources() failed.\n"); + IOLog("[IntelMausi]: initEventSources() failed.\n"); goto error4; } result = attachInterface(reinterpret_cast(&netif)); if (!result) { - IOLog("Ethernet [IntelMausi]: attachInterface() failed.\n"); - goto error3; + IOLog("[IntelMausi]: attachInterface() failed.\n"); + goto error4; } if (pciDevice->getProperty("disable-wol-from-shutdown")) @@ -396,10 +388,10 @@ IOReturn IntelMausi::setPowerState(unsigned long powerStateOrdinal, IOService *p DebugLog("setPowerState() ===>\n"); if (powerStateOrdinal == powerState) { - DebugLog("Ethernet [IntelMausi]: Already in power state %lu.\n", powerStateOrdinal); + DebugLog("[IntelMausi]: Already in power state %lu.\n", powerStateOrdinal); goto done; } - DebugLog("Ethernet [IntelMausi]: switching to power state %lu.\n", powerStateOrdinal); + DebugLog("[IntelMausi]: switching to power state %lu.\n", powerStateOrdinal); if (powerStateOrdinal == kPowerStateOff) commandGate->runAction(setPowerStateSleepAction); @@ -446,12 +438,12 @@ IOReturn IntelMausi::enable(IONetworkInterface *netif) DebugLog("enable() ===>\n"); if (isEnabled) { - DebugLog("Ethernet [IntelMausi]: Interface already enabled.\n"); + DebugLog("[IntelMausi]: Interface already enabled.\n"); result = kIOReturnSuccess; goto done; } if (!pciDevice || pciDevice->isOpen()) { - IOLog("Ethernet [IntelMausi]: Unable to open PCI device.\n"); + IOLog("[IntelMausi]: Unable to open PCI device.\n"); goto done; } pciDevice->open(this); @@ -547,7 +539,7 @@ IOReturn IntelMausi::outputStart(IONetworkInterface *interface, IOOptionBits opt count = 0; if (!(isEnabled && linkUp) || forceReset) { - DebugLog("Ethernet [IntelMausi]: Interface down. Dropping packets.\n"); + DebugLog("[IntelMausi]: Interface down. Dropping packets.\n"); goto done; } while ((txNumFreeDesc >= (kMaxSegs + kTxSpareDescs)) && (interface->dequeueOutputPackets(1, &m, NULL, NULL, NULL) == kIOReturnSuccess)) { @@ -561,88 +553,51 @@ IOReturn IntelMausi::outputStart(IONetworkInterface *interface, IOOptionBits opt tcpConfig = 0; offloadFlags = 0; - if (mbuf_get_tso_requested(m, &offloadFlags, &mss)) { - DebugLog("Ethernet [IntelMausi]: mbuf_get_tso_requested() failed. Dropping packet.\n"); - freePacket(m); - continue; - } /* First prepare the header and the command bits. */ - if (offloadFlags & (MBUF_TSO_IPV4 | MBUF_TSO_IPV6)) { + mbuf_get_csum_requested(m, &offloadFlags, &mss); + + if (offloadFlags & (kChecksumUDPIPv6 | kChecksumTCPIPv6 | kChecksumIP | kChecksumUDP | kChecksumTCP)) { numDescs = 1; - opts = E1000_TXD_CMD_IFCS; + cmd = (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); - if (offloadFlags & MBUF_TSO_IPV4) { - /* Correct the pseudo header checksum and extract the header size. */ - prepareTSO4(m, &mss, &len); - - /* Prepare the context descriptor. */ + if (offloadFlags & kChecksumTCP) { ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); tcpConfig = ((kTCPv4CSumEnd << 16) | (kTCPv4CSumOffset << 8) | kTCPv4CSumStart); - len |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP); + len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP); + mss = 0; - //DebugLog("Ethernet [IntelMausi]: TSO4 mssHeaderLen=0x%08x, payload=0x%08x\n", mss, len); + word2 = (E1000_TXD_OPTS_TXSM | E1000_TXD_OPTS_IXSM); + } else if (offloadFlags & kChecksumUDP) { + ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); + tcpConfig = ((kUDPv4CSumEnd << 16) | (kUDPv4CSumOffset << 8) | kUDPv4CSumStart); + len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP); + mss = 0; - /* Setup the command bits for TSO over IPv4. */ - cmd = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | E1000_TXD_DTYP_D); word2 = (E1000_TXD_OPTS_TXSM | E1000_TXD_OPTS_IXSM); - } else { - /* Correct the pseudo header checksum and extract the header size. */ - prepareTSO6(m, &mss, &len); + } else if (offloadFlags & kChecksumIP) { + ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); + tcpConfig = 0; + mss = 0; + len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP); - /* Prepare the context descriptor. */ + word2 = E1000_TXD_OPTS_IXSM; + } else if (offloadFlags & kChecksumTCPIPv6) { ipConfig = ((kIPv6CSumEnd << 16) | (kIPv6CSumOffset << 8) | kIPv6CSumStart); tcpConfig = ((kTCPv6CSumEnd << 16) | (kTCPv6CSumOffset << 8) | kTCPv6CSumStart); - len |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | E1000_TXD_CMD_TCP); + len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TCP); + mss = 0; - /* Setup the command bits for TSO over IPv6. */ - cmd = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | E1000_TXD_DTYP_D); word2 = E1000_TXD_OPTS_TXSM; - } - } else { - mbuf_get_csum_requested(m, &offloadFlags, &mss); - - if (offloadFlags & (kChecksumUDPIPv6 | kChecksumTCPIPv6 | kChecksumIP | kChecksumUDP | kChecksumTCP)) { - numDescs = 1; - cmd = (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); + } else if (offloadFlags & kChecksumUDPIPv6) { + ipConfig = ((kIPv6CSumEnd << 16) | (kIPv6CSumOffset << 8) | kIPv6CSumStart); + tcpConfig = ((kUDPv6CSumEnd << 16) | (kUDPv6CSumOffset << 8) | kUDPv6CSumStart); + len = E1000_TXD_CMD_DEXT; + mss = 0; - if (offloadFlags & kChecksumTCP) { - ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); - tcpConfig = ((kTCPv4CSumEnd << 16) | (kTCPv4CSumOffset << 8) | kTCPv4CSumStart); - len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP); - mss = 0; - - word2 = (E1000_TXD_OPTS_TXSM | E1000_TXD_OPTS_IXSM); - } else if (offloadFlags & kChecksumUDP) { - ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); - tcpConfig = ((kUDPv4CSumEnd << 16) | (kUDPv4CSumOffset << 8) | kUDPv4CSumStart); - len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP); - mss = 0; - - word2 = (E1000_TXD_OPTS_TXSM | E1000_TXD_OPTS_IXSM); - } else if (offloadFlags & kChecksumIP) { - ipConfig = ((kIPv4CSumEnd << 16) | (kIPv4CSumOffset << 8) | kIPv4CSumStart); - tcpConfig = 0; - mss = 0; - len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_IP); - - word2 = E1000_TXD_OPTS_IXSM; - } else if (offloadFlags & kChecksumTCPIPv6) { - ipConfig = ((kIPv6CSumEnd << 16) | (kIPv6CSumOffset << 8) | kIPv6CSumStart); - tcpConfig = ((kTCPv6CSumEnd << 16) | (kTCPv6CSumOffset << 8) | kTCPv6CSumStart); - len = (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TCP); - mss = 0; - - word2 = E1000_TXD_OPTS_TXSM; - } else if (offloadFlags & kChecksumUDPIPv6) { - ipConfig = ((kIPv6CSumEnd << 16) | (kIPv6CSumOffset << 8) | kIPv6CSumStart); - tcpConfig = ((kUDPv6CSumEnd << 16) | (kUDPv6CSumOffset << 8) | kUDPv6CSumStart); - len = E1000_TXD_CMD_DEXT; - mss = 0; - - word2 = E1000_TXD_OPTS_TXSM; - } + word2 = E1000_TXD_OPTS_TXSM; } } + /* Next get the VLAN tag and command bit. */ if (!mbuf_get_vlan_tag(m, &vlanTag)) { opts |= E1000_TXD_CMD_VLE; @@ -653,7 +608,7 @@ IOReturn IntelMausi::outputStart(IONetworkInterface *interface, IOOptionBits opt numDescs += numSegs; if (!numSegs) { - DebugLog("Ethernet [IntelMausi]: getPhysicalSegmentsWithCoalesce() failed. Dropping packet.\n"); + DebugLog("[IntelMausi]: getPhysicalSegmentsWithCoalesce() failed. Dropping packet.\n"); etherStats->dot3TxExtraEntry.resourceErrors++; freePacket(m); continue; @@ -663,7 +618,7 @@ IOReturn IntelMausi::outputStart(IONetworkInterface *interface, IOOptionBits opt txNextDescIndex = (txNextDescIndex + numDescs) & kTxDescMask; lastSeg = numSegs - 1; - /* Setup the context descriptor for TSO or checksum offload. */ + /* Setup the context descriptor for checksum offload. */ if (offloadFlags) { contDesc = (struct e1000_context_desc *)&txDescArray[index]; @@ -682,58 +637,28 @@ IOReturn IntelMausi::outputStart(IONetworkInterface *interface, IOOptionBits opt ++index &= kTxDescMask; } /* And finally fill in the data descriptors. */ - if (offloadFlags & (MBUF_TSO_IPV4 | MBUF_TSO_IPV6)) { - for (i = 0; i < numSegs; i++) { - desc = &txDescArray[index]; - word1 = (cmd | (txSegments[i].length & 0x000fffff)); - - if (i == 0) { - word1 |= opts; - txBufArray[index].mbuf = NULL; - txBufArray[index].numDescs = 0; - } else if (i == lastSeg) { - word1 |= (E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS); - txBufArray[index].mbuf = m; - txBufArray[index].numDescs = numDescs; - } else { - txBufArray[index].mbuf = NULL; - txBufArray[index].numDescs = 0; - } - -#ifdef DEBUG - txBufArray[index].pad = (UInt32)txSegments[i].length; -#endif - - desc->buffer_addr = OSSwapHostToLittleInt64(txSegments[i].location); - desc->lower.data = OSSwapHostToLittleInt32(word1); - desc->upper.data = OSSwapHostToLittleInt32(word2); - - ++index &= kTxDescMask; + for (i = 0; i < numSegs; i++) { + desc = &txDescArray[index]; + word1 = (cmd | (txSegments[i].length & 0x000fffff)); + + if (i == lastSeg) { + word1 |= opts; + txBufArray[index].mbuf = m; + txBufArray[index].numDescs = numDescs; + } else { + txBufArray[index].mbuf = NULL; + txBufArray[index].numDescs = 0; } - } else { - for (i = 0; i < numSegs; i++) { - desc = &txDescArray[index]; - word1 = (cmd | (txSegments[i].length & 0x000fffff)); - - if (i == lastSeg) { - word1 |= opts; - txBufArray[index].mbuf = m; - txBufArray[index].numDescs = numDescs; - } else { - txBufArray[index].mbuf = NULL; - txBufArray[index].numDescs = 0; - } - + #ifdef DEBUG - txBufArray[index].pad = (UInt32)txSegments[i].length; + txBufArray[index].pad = (UInt32)txSegments[i].length; #endif - - desc->buffer_addr = OSSwapHostToLittleInt64(txSegments[i].location); - desc->lower.data = OSSwapHostToLittleInt32(word1); - desc->upper.data = OSSwapHostToLittleInt32(word2); - - ++index &= kTxDescMask; - } + + desc->buffer_addr = OSSwapHostToLittleInt64(txSegments[i].location); + desc->lower.data = OSSwapHostToLittleInt32(word1); + desc->upper.data = OSSwapHostToLittleInt32(word2); + + ++index &= kTxDescMask; } count++; } @@ -806,7 +731,7 @@ bool IntelMausi::configureInterface(IONetworkInterface *interface) netStats = (IONetworkStats *)data->getBuffer(); if (!netStats) { - IOLog("Ethernet [IntelMausi]: Error getting IONetworkStats\n."); + IOLog("[IntelMausi]: Error getting IONetworkStats\n."); result = false; goto done; } @@ -818,7 +743,7 @@ bool IntelMausi::configureInterface(IONetworkInterface *interface) etherStats = (IOEthernetStats *)data->getBuffer(); if (!etherStats) { - IOLog("Ethernet [IntelMausi]: Error getting IOEthernetStats\n."); + IOLog("[IntelMausi]: Error getting IOEthernetStats\n."); result = false; goto done; } @@ -826,14 +751,14 @@ bool IntelMausi::configureInterface(IONetworkInterface *interface) error = interface->configureOutputPullModel(384, 0, 0, IONetworkInterface::kOutputPacketSchedulingModelNormal); if (error != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: configureOutputPullModel() failed\n."); + IOLog("[IntelMausi]: configureOutputPullModel() failed\n."); result = false; goto done; } error = interface->configureInputPacketPolling(kNumRxDesc, kIONetworkWorkLoopSynchronous); if (error != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: configureInputPacketPolling() failed\n."); + IOLog("[IntelMausi]: configureInputPacketPolling() failed\n."); result = false; goto done; } @@ -877,10 +802,10 @@ IOReturn IntelMausi::setPromiscuousMode(bool active) rxControl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); if (active) { - DebugLog("Ethernet [IntelMausi]: Promiscuous mode enabled.\n"); + DebugLog("[IntelMausi]: Promiscuous mode enabled.\n"); rxControl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); } else { - DebugLog("Ethernet [IntelMausi]: Promiscuous mode disabled.\n"); + DebugLog("[IntelMausi]: Promiscuous mode disabled.\n"); hw->mac.ops.update_mc_addr_list(hw, (UInt8 *)mcAddrList, mcListCount); } intelWriteMem32(E1000_RCTL, rxControl); @@ -982,12 +907,6 @@ UInt32 IntelMausi::getFeatures() const DebugLog("getFeatures() ===>\n"); - if (enableTSO4) - features |= kIONetworkFeatureTSOIPv4; - - if (enableTSO6) - features |= kIONetworkFeatureTSOIPv6; - DebugLog("getFeatures() <===\n"); return features; @@ -1001,7 +920,7 @@ IOReturn IntelMausi::setWakeOnMagicPacket(bool active) if (wolCapable) { wolActive = active; - DebugLog("Ethernet [IntelMausi]: Wake on magic packet %s.\n", active ? "enabled" : "disabled"); + DebugLog("[IntelMausi]: Wake on magic packet %s.\n", active ? "enabled" : "disabled"); result = kIOReturnSuccess; } @@ -1040,8 +959,15 @@ IOReturn IntelMausi::getPacketFilters(const OSSymbol *group, UInt32 *filters) co DebugLog("getPacketFilters() ===>\n"); if ((group == gIOEthernetWakeOnLANFilterGroup) && wolCapable) { - *filters = kIOEthernetWakeOnMagicPacket; - DebugLog("Ethernet [IntelMausi]: kIOEthernetWakeOnMagicPacket added to filters.\n"); + if (enableWoM) { + *filters = (kIOEthernetWakeOnMagicPacket | kIOEthernetWakeOnPacketAddressMatch); + + DebugLog("[IntelMausi]: kIOEthernetWakeOnMagicPacket and kIOEthernetWakeOnPacketAddressMatch added to filters.\n"); + } else { + *filters = kIOEthernetWakeOnMagicPacket; + + DebugLog("[IntelMausi]: kIOEthernetWakeOnMagicPacket added to filters.\n"); + } } else { result = super::getPacketFilters(group, filters); } @@ -1078,7 +1004,7 @@ IOReturn IntelMausi::getHardwareAddress(IOEthernetAddress *addr) DebugLog("getHardwareAddress() ===>\n"); - //IOLog("Ethernet [IntelMausi]: RAH = 0x%x, RAL = 0x%x\n", intelReadMem32(E1000_RAH(0)), intelReadMem32(E1000_RAL(0))); + //IOLog("[IntelMausi]: RAH = 0x%x, RAL = 0x%x\n", intelReadMem32(E1000_RAH(0)), intelReadMem32(E1000_RAL(0))); if (addr) { memcpy(&addr->bytes[0], adapterData.hw.mac.addr, kIOEthernetAddressSize); @@ -1134,7 +1060,7 @@ IOReturn IntelMausi::setMaxPacketSize(UInt32 maxSize) mtu = maxSize - (ETH_HLEN + ETH_FCS_LEN); adapterData.max_frame_size = maxSize; - DebugLog("Ethernet [IntelMausi]: maxSize: %u, mtu: %u\n", maxSize, mtu); + DebugLog("[IntelMausi]: maxSize: %u, mtu: %u\n", maxSize, mtu); /* Force reinitialization. */ setLinkDown(); @@ -1179,7 +1105,7 @@ void IntelMausi::txInterrupt() ++txDirtyIndex &= kTxDescMask; } - //DebugLog("Ethernet [IntelMausi]: txInterrupt oldIndex=%u newIndex=%u\n", oldDirtyIndex, txDirtyDescIndex); + //DebugLog("[IntelMausi]: txInterrupt oldIndex=%u newIndex=%u\n", oldDirtyIndex, txDirtyDescIndex); done: if (txNumFreeDesc > kTxQueueWakeTreshhold) @@ -1207,7 +1133,7 @@ UInt32 IntelMausi::rxInterrupt(IONetworkInterface *interface, uint32_t maxCount, /* Skip bad packet. */ if (status & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { - DebugLog("Ethernet [IntelMausi]: Bad packet.\n"); + DebugLog("[IntelMausi]: Bad packet.\n"); etherStats->dot3StatsEntry.internalMacReceiveErrors++; discardPacketFragment(); goto nextDesc; @@ -1216,7 +1142,7 @@ UInt32 IntelMausi::rxInterrupt(IONetworkInterface *interface, uint32_t maxCount, if (!newPkt) { /* Allocation of a new packet failed so that we must leave the original packet in place. */ - //DebugLog("Ethernet [IntelMausi]: replaceOrCopyPacket() failed.\n"); + //DebugLog("[IntelMausi]: replaceOrCopyPacket() failed.\n"); etherStats->dot3RxExtraEntry.resourceErrors++; discardPacketFragment(); goto nextDesc; @@ -1227,7 +1153,7 @@ UInt32 IntelMausi::rxInterrupt(IONetworkInterface *interface, uint32_t maxCount, n = rxMbufCursor->getPhysicalSegments(bufPkt, &rxSegment, 1); if ((n != 1) || (rxSegment.location & 0x07ff)) { - DebugLog("Ethernet [IntelMausi]: getPhysicalSegments() failed.\n"); + DebugLog("[IntelMausi]: getPhysicalSegments() failed.\n"); etherStats->dot3RxExtraEntry.resourceErrors++; freePacket(bufPkt); discardPacketFragment(); @@ -1325,7 +1251,7 @@ void IntelMausi::checkLinkStatus() /* Now check the link state. */ link = intelCheckLink(&adapterData); - DebugLog("Ethernet [IntelMausi]: checkLinkStatus() returned %u.\n", link); + DebugLog("[IntelMausi]: checkLinkStatus() returned %u.\n", link); if (linkUp) { if (link) { @@ -1377,7 +1303,7 @@ void IntelMausi::interruptOccurred(OSObject *client, IOInterruptEventSource *src etherStats->dot3StatsEntry.internalMacReceiveErrors += (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; etherStats->dot3TxExtraEntry.resets++; - IOLog("Ethernet [IntelMausi]: Uncorrectable ECC error. Reseting chip.\n"); + IOLog("[IntelMausi]: Uncorrectable ECC error. Reseting chip.\n"); intelRestart(); return; } @@ -1451,7 +1377,7 @@ void IntelMausi::setLinkUp() e1000e_check_downshift(hw); if (phy->speed_downgraded) - IOLog("Ethernet [IntelMausi]: Link Speed was downgraded by SmartSpeed\n"); + IOLog("[IntelMausi]: Link Speed was downgraded by SmartSpeed\n"); /* On supported PHYs, check for duplex mismatch only * if link has autonegotiated at 10/100 half @@ -1464,7 +1390,7 @@ void IntelMausi::setLinkUp() e1e_rphy(hw, MII_EXPANSION, &autoneg_exp); if (!(autoneg_exp & EXPANSION_NWAY)) - IOLog("Ethernet [IntelMausi]: Autonegotiated half duplex but link partner cannot autoneg. Try forcing full duplex if link gets many collisions.\n"); + IOLog("[IntelMausi]: Autonegotiated half duplex but link partner cannot autoneg. Try forcing full duplex if link gets many collisions.\n"); } /* Get link speed, duplex and flow-control mode. */ @@ -1589,8 +1515,7 @@ void IntelMausi::setLinkUp() linkUp = true; - setLinkStatus((kIONetworkLinkValid | kIONetworkLinkActive | linkOpts), mediumTable[mediumIndex], mediumSpeed, NULL); - linkOpts = 0; + setLinkStatus((kIONetworkLinkValid | kIONetworkLinkActive), mediumTable[mediumIndex], mediumSpeed, NULL); /* Update poll params according to link speed. */ bzero(&pollParams, sizeof(IONetworkPacketPollingParameters)); @@ -1609,41 +1534,41 @@ void IntelMausi::setLinkUp() pollParams.pollIntervalTime = (adapterData.link_speed == SPEED_1000) ? 170000 : 1000000; /* 170µs / 1ms */ } netif->setPacketPollingParameters(&pollParams, 0); - DebugLog("Ethernet [IntelMausi]: pollIntervalTime: %lluus\n", (pollParams.pollIntervalTime / 1000)); + DebugLog("[IntelMausi]: pollIntervalTime: %lluus\n", (pollParams.pollIntervalTime / 1000)); /* Start output thread, statistics update and watchdog. */ netif->startOutputThread(); - IOLog("Ethernet [IntelMausi]: Link up on en%u, %s, %s, %s%s\n", netif->getUnitNumber(), speedName, duplexName, flowName, eeeName); + IOLog("[IntelMausi]: Link up on en%u, %s, %s, %s%s\n", netif->getUnitNumber(), speedName, duplexName, flowName, eeeName); if (chipType >= board_pch_lpt) setMaxLatency(adapterData.link_speed); - DebugLog("Ethernet [IntelMausi]: CTRL=0x%08x\n", intelReadMem32(E1000_CTRL)); - DebugLog("Ethernet [IntelMausi]: CTRL_EXT=0x%08x\n", intelReadMem32(E1000_CTRL_EXT)); - DebugLog("Ethernet [IntelMausi]: STATUS=0x%08x\n", intelReadMem32(E1000_STATUS)); - DebugLog("Ethernet [IntelMausi]: RCTL=0x%08x\n", intelReadMem32(E1000_RCTL)); - DebugLog("Ethernet [IntelMausi]: PSRCTL=0x%08x\n", intelReadMem32(E1000_PSRCTL)); - DebugLog("Ethernet [IntelMausi]: FCRTL=0x%08x\n", intelReadMem32(E1000_FCRTL)); - DebugLog("Ethernet [IntelMausi]: FCRTH=0x%08x\n", intelReadMem32(E1000_FCRTH)); - DebugLog("Ethernet [IntelMausi]: RDLEN(0)=0x%08x\n", intelReadMem32(E1000_RDLEN(0))); - DebugLog("Ethernet [IntelMausi]: RDTR=0x%08x\n", intelReadMem32(E1000_RDTR)); - DebugLog("Ethernet [IntelMausi]: RADV=0x%08x\n", intelReadMem32(E1000_RADV)); - DebugLog("Ethernet [IntelMausi]: RXCSUM=0x%08x\n", intelReadMem32(E1000_RXCSUM)); - DebugLog("Ethernet [IntelMausi]: RFCTL=0x%08x\n", intelReadMem32(E1000_RFCTL)); - DebugLog("Ethernet [IntelMausi]: RXDCTL(0)=0x%08x\n", intelReadMem32(E1000_RXDCTL(0))); - DebugLog("Ethernet [IntelMausi]: RAL(0)=0x%08x\n", intelReadMem32(E1000_RAL(0))); - DebugLog("Ethernet [IntelMausi]: RAH(0)=0x%08x\n", intelReadMem32(E1000_RAH(0))); - DebugLog("Ethernet [IntelMausi]: MRQC=0x%08x\n", intelReadMem32(E1000_MRQC)); - DebugLog("Ethernet [IntelMausi]: TARC(0)=0x%08x\n", intelReadMem32(E1000_TARC(0))); - DebugLog("Ethernet [IntelMausi]: TARC(1)=0x%08x\n", intelReadMem32(E1000_TARC(1))); - DebugLog("Ethernet [IntelMausi]: TCTL=0x%08x\n", intelReadMem32(E1000_TCTL)); - DebugLog("Ethernet [IntelMausi]: TXDCTL(0)=0x%08x\n", intelReadMem32(E1000_TXDCTL(0))); - DebugLog("Ethernet [IntelMausi]: TXDCTL(1)=0x%08x\n", intelReadMem32(E1000_TXDCTL(1))); - DebugLog("Ethernet [IntelMausi]: TADV=0x%08x\n", intelReadMem32(E1000_TADV)); - DebugLog("Ethernet [IntelMausi]: TIDV=0x%08x\n", intelReadMem32(E1000_TIDV)); - DebugLog("Ethernet [IntelMausi]: MANC=0x%08x\n", intelReadMem32(E1000_MANC)); - DebugLog("Ethernet [IntelMausi]: MANC2H=0x%08x\n", intelReadMem32(E1000_MANC2H)); - DebugLog("Ethernet [IntelMausi]: LTRV=0x%08x\n", intelReadMem32(E1000_LTRV)); + DebugLog("[IntelMausi]: CTRL=0x%08x\n", intelReadMem32(E1000_CTRL)); + DebugLog("[IntelMausi]: CTRL_EXT=0x%08x\n", intelReadMem32(E1000_CTRL_EXT)); + DebugLog("[IntelMausi]: STATUS=0x%08x\n", intelReadMem32(E1000_STATUS)); + DebugLog("[IntelMausi]: RCTL=0x%08x\n", intelReadMem32(E1000_RCTL)); + DebugLog("[IntelMausi]: PSRCTL=0x%08x\n", intelReadMem32(E1000_PSRCTL)); + DebugLog("[IntelMausi]: FCRTL=0x%08x\n", intelReadMem32(E1000_FCRTL)); + DebugLog("[IntelMausi]: FCRTH=0x%08x\n", intelReadMem32(E1000_FCRTH)); + DebugLog("[IntelMausi]: RDLEN(0)=0x%08x\n", intelReadMem32(E1000_RDLEN(0))); + DebugLog("[IntelMausi]: RDTR=0x%08x\n", intelReadMem32(E1000_RDTR)); + DebugLog("[IntelMausi]: RADV=0x%08x\n", intelReadMem32(E1000_RADV)); + DebugLog("[IntelMausi]: RXCSUM=0x%08x\n", intelReadMem32(E1000_RXCSUM)); + DebugLog("[IntelMausi]: RFCTL=0x%08x\n", intelReadMem32(E1000_RFCTL)); + DebugLog("[IntelMausi]: RXDCTL(0)=0x%08x\n", intelReadMem32(E1000_RXDCTL(0))); + DebugLog("[IntelMausi]: RAL(0)=0x%08x\n", intelReadMem32(E1000_RAL(0))); + DebugLog("[IntelMausi]: RAH(0)=0x%08x\n", intelReadMem32(E1000_RAH(0))); + DebugLog("[IntelMausi]: MRQC=0x%08x\n", intelReadMem32(E1000_MRQC)); + DebugLog("[IntelMausi]: TARC(0)=0x%08x\n", intelReadMem32(E1000_TARC(0))); + DebugLog("[IntelMausi]: TARC(1)=0x%08x\n", intelReadMem32(E1000_TARC(1))); + DebugLog("[IntelMausi]: TCTL=0x%08x\n", intelReadMem32(E1000_TCTL)); + DebugLog("[IntelMausi]: TXDCTL(0)=0x%08x\n", intelReadMem32(E1000_TXDCTL(0))); + DebugLog("[IntelMausi]: TXDCTL(1)=0x%08x\n", intelReadMem32(E1000_TXDCTL(1))); + DebugLog("[IntelMausi]: TADV=0x%08x\n", intelReadMem32(E1000_TADV)); + DebugLog("[IntelMausi]: TIDV=0x%08x\n", intelReadMem32(E1000_TIDV)); + DebugLog("[IntelMausi]: MANC=0x%08x\n", intelReadMem32(E1000_MANC)); + DebugLog("[IntelMausi]: MANC2H=0x%08x\n", intelReadMem32(E1000_MANC2H)); + DebugLog("[IntelMausi]: LTRV=0x%08x\n", intelReadMem32(E1000_LTRV)); } void IntelMausi::setLinkDown() @@ -1663,7 +1588,7 @@ void IntelMausi::setLinkDown() clear_bit(__E1000_DOWN, &adapterData.state); intelEnableIRQ(intrMask); - IOLog("Ethernet [IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); + IOLog("[IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); } inline void IntelMausi::intelGetChecksumResult(mbuf_t m, UInt32 status) @@ -1751,8 +1676,6 @@ bool IntelMausi::intelStart() if (adapterData.flags2 & FLAG2_HAS_EEE) hw->dev_spec.ich8lan.eee_disable = false; - linkOpts = 0; - initPCIPowerManagment(pciDevice, ei); /* Explicitly disable IRQ since the NIC can be in any state. */ @@ -1772,7 +1695,7 @@ bool IntelMausi::intelStart() error = ei->get_variants(&adapterData); if (error) { - IOLog("Ethernet [IntelMausi]: Failed to get adapter data with error %d.\n", error); + IOLog("[IntelMausi]: Failed to get adapter data with error %d.\n", error); goto done; } if ((adapterData.flags & FLAG_IS_ICH) && @@ -1789,7 +1712,7 @@ bool IntelMausi::intelStart() hw->phy.ms_type = e1000_ms_hw_default; } if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) - IOLog("Ethernet [IntelMausi]: PHY reset is blocked due to SOL/IDER session.\n"); + IOLog("[IntelMausi]: PHY reset is blocked due to SOL/IDER session.\n"); if (intelEnableMngPassThru(hw)) adapterData.flags |= FLAG_MNG_PT_ENABLED; @@ -1807,7 +1730,7 @@ bool IntelMausi::intelStart() break; if (i == 2) { - IOLog("Ethernet [IntelMausi]: The NVM Checksum Is Not Valid.\n"); + IOLog("[IntelMausi]: The NVM Checksum Is Not Valid.\n"); goto error_eeprom; break; } @@ -1816,10 +1739,10 @@ bool IntelMausi::intelStart() /* copy the MAC address */ if (e1000e_read_mac_addr(hw)) - IOLog("Ethernet [IntelMausi]: NVM Read Error while reading MAC address.\n"); + IOLog("[IntelMausi]: NVM Read Error while reading MAC address.\n"); if (!is_valid_ether_addr(mac->addr)) { - IOLog("Ethernet [IntelMausi]: Invalid MAC Address: %pM\n", mac->addr); + IOLog("[IntelMausi]: Invalid MAC Address: %pM\n", mac->addr); goto error_eeprom; } /* Initialize link parameters. User can change them with ethtool */ @@ -1849,7 +1772,7 @@ bool IntelMausi::intelStart() /* fetch WoL from EEPROM */ if (rval) - DebugLog("Ethernet [IntelMausi]: NVM read error getting WoL initial values: %d\n", rval); + DebugLog("[IntelMausi]: NVM read error getting WoL initial values: %d\n", rval); else if (eepromData & eepromApmeMask) adapterData.eeprom_wol |= E1000_WUFC_MAG; @@ -1871,7 +1794,7 @@ bool IntelMausi::intelStart() rval = e1000_read_nvm(hw, 5, 1, &adapterData.eeprom_vers); if (rval) { - DebugLog("Ethernet [IntelMausi]: NVM read error getting EEPROM version: %d\n", rval); + DebugLog("[IntelMausi]: NVM read error getting EEPROM version: %d\n", rval); adapterData.eeprom_vers = 0; } /* reset the hardware with the new settings */ @@ -1887,7 +1810,7 @@ bool IntelMausi::intelStart() if ((hw->mac.type == e1000_pch_lpt) || (hw->mac.type == e1000_pch_spt)) { intrMask |= E1000_IMS_ECCER; } - IOLog("Ethernet [IntelMausi]: %s (Rev. %u), %02x:%02x:%02x:%02x:%02x:%02x\n", + IOLog("[IntelMausi]: %s (Rev. %u), %02x:%02x:%02x:%02x:%02x:%02x\n", deviceTable[chip].deviceName, pciDeviceData.revision, mac->addr[0], mac->addr[1], mac->addr[2], mac->addr[3], mac->addr[4], mac->addr[5]); result = true; @@ -1909,7 +1832,7 @@ void IntelMausi::timerAction(IOTimerEventSource *timer) struct e1000_hw *hw = &adapterData.hw; if (!linkUp) { - DebugLog("Ethernet [IntelMausi]: Timer fired while link down.\n"); + DebugLog("[IntelMausi]: Timer fired while link down.\n"); goto done; } intelUpdateAdaptive(&adapterData.hw); @@ -2031,43 +1954,43 @@ bool IntelMausi::checkForDeadlock() if (++deadlockWarn >= kTxDeadlockTreshhold) { mbuf_t m = txBufArray[txDirtyIndex].mbuf; UInt32 pktSize; - UInt16 index; #ifdef DEBUG UInt16 i; + UInt16 index; UInt16 stalledIndex = txDirtyIndex; #endif //UInt8 data; - IOLog("Ethernet [IntelMausi]: Tx stalled? Resetting chipset. txDirtyDescIndex=%u, STATUS=0x%08x, TCTL=0x%08x.\n", txDirtyIndex, intelReadMem32(E1000_STATUS), intelReadMem32(E1000_TCTL)); + IOLog("[IntelMausi]: Tx stalled? Resetting chipset. txDirtyDescIndex=%u, STATUS=0x%08x, TCTL=0x%08x.\n", txDirtyIndex, intelReadMem32(E1000_STATUS), intelReadMem32(E1000_TCTL)); #ifdef DEBUG for (i = 0; i < 30; i++) { index = ((stalledIndex - 20 + i) & kTxDescMask); - IOLog("Ethernet [IntelMausi]: desc[%u]: lower=0x%08x, upper=0x%08x, addr=0x%016llx, mbuf=0x%016llx, len=%u.\n", index, txDescArray[index].lower.data, txDescArray[index].upper.data, txDescArray[index].buffer_addr, (UInt64)txBufArray[index].mbuf, txBufArray[index].pad); + IOLog("[IntelMausi]: desc[%u]: lower=0x%08x, upper=0x%08x, addr=0x%016llx, mbuf=0x%016llx, len=%u.\n", index, txDescArray[index].lower.data, txDescArray[index].upper.data, txDescArray[index].buffer_addr, (UInt64)txBufArray[index].mbuf, txBufArray[index].pad); } #endif if (m) { pktSize = (UInt32)mbuf_pkthdr_len(m); - IOLog("Ethernet [IntelMausi]: packet size=%u, header size=%u.\n", pktSize, (UInt32)mbuf_len(m)); + IOLog("[IntelMausi]: packet size=%u, header size=%u.\n", pktSize, (UInt32)mbuf_len(m)); /* #ifdef DEBUG - IOLog("Ethernet [IntelMausi]: MAC-header: "); + IOLog("[IntelMausi]: MAC-header: "); for (i = 0; i < 14; i++) { mbuf_copydata(m, i, 1, &data); IOLog(" 0x%02x", data); } IOLog("\n"); - IOLog("Ethernet [IntelMausi]: IP-header: "); + IOLog("[IntelMausi]: IP-header: "); for (i = 14; i < 34; i++) { mbuf_copydata(m, i, 1, &data); IOLog(" 0x%02x", data); } IOLog("\n"); - IOLog("Ethernet [IntelMausi]: TCP-Header / Data: "); + IOLog("[IntelMausi]: TCP-Header / Data: "); for (i = 34; i < 100; i++) { mbuf_copydata(m, i, 1, &data); IOLog(" 0x%02x", data); @@ -2080,7 +2003,7 @@ bool IntelMausi::checkForDeadlock() intelRestart(); deadlock = true; } else { - DebugLog("Ethernet [IntelMausi]: Check tx ring for progress. txNumFreeDesc=%u\n", txNumFreeDesc); + DebugLog("[IntelMausi]: Check tx ring for progress. txNumFreeDesc=%u\n", txNumFreeDesc); /* Flush pending tx descriptors. */ intelFlushDescriptors(); /* Check the transmitter ring. */ @@ -2091,59 +2014,3 @@ bool IntelMausi::checkForDeadlock() } return deadlock; } - -#pragma mark --- miscellaneous functions --- - -static inline void prepareTSO4(mbuf_t m, UInt32 *mssHeaderSize, UInt32 *payloadSize) -{ - struct iphdr *ipHdr = (struct iphdr *)((UInt8 *)mbuf_data(m) + ETHER_HDR_LEN); - struct tcphdr *tcpHdr = (struct tcphdr *)((UInt8 *)ipHdr + sizeof(struct iphdr)); - UInt16 *addr = (UInt16 *)&ipHdr->saddr; - UInt32 csum32 = 6; - UInt32 plen = (UInt32)mbuf_pkthdr_len(m); - UInt32 hlen = (tcpHdr->th_off << 2) + kMinL4HdrOffsetV4; - - ipHdr->tot_len = 0; - - csum32 += ntohs(*addr++); - csum32 += ntohs(*addr++); - csum32 += ntohs(*addr++); - csum32 += ntohs(*addr); - csum32 += (csum32 >> 16); - tcpHdr->th_sum = htons((UInt16)csum32); - - /* Flush the cache lines in order to enforce writeback. */ - asm volatile ("clflush %0" : "=m" (ipHdr->tot_len)); - asm volatile ("clflush %0" : "=m" (tcpHdr->th_sum)); - - *mssHeaderSize = ((*mssHeaderSize << 16) | (hlen << 8)); - *payloadSize = plen - hlen; -} - -static inline void prepareTSO6(mbuf_t m, UInt32 *mssHeaderSize, UInt32 *payloadSize) -{ - struct ip6_hdr *ip6Hdr = (struct ip6_hdr *)((UInt8 *)mbuf_data(m) + ETHER_HDR_LEN); - struct tcphdr *tcpHdr = (struct tcphdr *)((UInt8 *)ip6Hdr + sizeof(struct ip6_hdr)); - UInt16 *addr = (UInt16 *)&ip6Hdr->ip6_src; - UInt32 csum32 = 6; - UInt32 plen = (UInt32)mbuf_pkthdr_len(m); - UInt32 hlen = (tcpHdr->th_off << 2) + kMinL4HdrOffsetV6; - UInt32 i; - - ip6Hdr->ip6_ctlun.ip6_un1.ip6_un1_plen = 0; - - for (i = 0; i < 16; i++) - csum32 += ntohs(*addr++); - - csum32 += (csum32 >> 16); - tcpHdr->th_sum = htons((UInt16)csum32); - - /* Flush the cache lines in order to enforce writeback. */ - asm volatile ("clflush %0" : "=m" (ip6Hdr->ip6_ctlun.ip6_un1.ip6_un1_plen)); - asm volatile ("clflush %0" : "=m" (tcpHdr->th_sum)); - - *mssHeaderSize = ((*mssHeaderSize << 16) | (hlen << 8)); - *payloadSize = plen - hlen; -} - - diff --git a/IntelMausiEthernet/IntelMausiEthernet.h b/IntelMausiEthernet/IntelMausiEthernet.h old mode 100644 new mode 100755 index 6250e38..c697def --- a/IntelMausiEthernet/IntelMausiEthernet.h +++ b/IntelMausiEthernet/IntelMausiEthernet.h @@ -235,8 +235,7 @@ enum #define kParamName "Driver Parameters" #define kEnableCSO6Name "enableCSO6" -#define kEnableTSO4Name "enableTSO4" -#define kEnableTSO6Name "enableTSO6" +#define kEnableWoMName "enableWakeOnAddrMatch" #define kIntrRate10Name "maxIntrRate10" #define kIntrRate100Name "maxIntrRate100" #define kIntrRate1000Name "maxIntrRate1000" @@ -275,6 +274,27 @@ struct IntelRxDesc { UInt64 status; }; +/* + * Keep alive address data as supported by hardware with a + * maximum of: + * 3 IPv4 addresses + * 4 IPv6 addresses + */ +#define kMaxAddrV4 3 +#define kMaxAddrV6 4 + +#define kLLAPrefix 0xfe800000 +#define kLLAMask 0xffc00000 +#define kULAPrefix 0xfc000000 +#define kULAMask 0xfe000000 + +struct IntelAddrData { + UInt16 ipV6Count; + UInt16 ipV4Count; + struct in6_addr ipV6Addr[kMaxAddrV6]; + UInt32 ipV4Addr[kMaxAddrV4]; +}; + class IntelMausi : public super { @@ -389,7 +409,8 @@ class IntelMausi : public super void intelFlushRxRing(struct e1000_adapter *adapter); void intelFlushDescRings(struct e1000_adapter *adapter); void intelPhyReadStatus(struct e1000_adapter *adapter); - void intelInitPhyWakeup(UInt32 wufc); + void intelInitPhyWakeup(UInt32 wufc, struct IntelAddrData *addrData); + void intelInitMacWakeup(UInt32 wufc, struct IntelAddrData *addrData); void intelSetupAdvForMedium(const IONetworkMedium *medium); void intelFlushLPIC(); void setMaxLatency(UInt32 linkSpeed); @@ -399,6 +420,8 @@ class IntelMausi : public super inline void intelGetChecksumResult(mbuf_t m, UInt32 status); + void getAddressList(struct IntelAddrData *addr); + /* timer action */ void timerAction(IOTimerEventSource *timer); @@ -481,7 +504,6 @@ class IntelMausi : public super UInt8 pcieCapOffset; UInt8 pciPMCtrlOffset; - UInt32 linkOpts; IONetworkPacketPollingParameters pollParams; /* flags */ @@ -496,9 +518,8 @@ class IntelMausi : public super bool wolCapable; bool wolActive; bool wolPwrOff; - bool enableTSO4; - bool enableTSO6; bool enableCSO6; + bool enableWoM; /* mbuf_t arrays */ struct intelTxBufferInfo txBufArray[kNumTxDesc]; diff --git a/IntelMausiEthernet/IntelMausiHardware.cpp b/IntelMausiEthernet/IntelMausiHardware.cpp old mode 100644 new mode 100755 index 0d03900..680fc18 --- a/IntelMausiEthernet/IntelMausiHardware.cpp +++ b/IntelMausiEthernet/IntelMausiHardware.cpp @@ -50,7 +50,7 @@ bool IntelMausi::initPCIConfigSpace(IOPCIDevice *provider) if (maxLatency > kMaxDmaLatency) maxLatency = kMaxDmaLatency; - DebugLog("Ethernet [IntelMausi]: maxSnoop: 0x%04x (%uns), maxNoSnoop: 0x%04x (%uns).\n", pciDeviceData.maxSnoop, lat1, pciDeviceData.maxNoSnoop, lat2); + DebugLog("[IntelMausi]: maxSnoop: 0x%04x (%uns), maxNoSnoop: 0x%04x (%uns).\n", pciDeviceData.maxSnoop, lat1, pciDeviceData.maxNoSnoop, lat2); } /* Get the bus information. */ adapterData.hw.bus.func = pciDevice->getFunctionNumber(); @@ -62,7 +62,7 @@ bool IntelMausi::initPCIConfigSpace(IOPCIDevice *provider) baseMap = provider->mapDeviceMemoryWithRegister(kIOPCIConfigBaseAddress0, kIOMapInhibitCache); if (!baseMap) { - IOLog("Ethernet [IntelMausi]: region #0 not an MMIO resource, aborting.\n"); + IOLog("[IntelMausi]: region #0 not an MMIO resource, aborting.\n"); goto done; } baseAddr = reinterpret_cast(baseMap->getVirtualAddress()); @@ -73,7 +73,7 @@ bool IntelMausi::initPCIConfigSpace(IOPCIDevice *provider) flashMap = provider->mapDeviceMemoryWithRegister(kIOPCIConfigBaseAddress1, kIOMapInhibitCache); if (!flashMap) { - IOLog("Ethernet [IntelMausi]: region #1 not an MMIO resource, aborting.\n"); + IOLog("[IntelMausi]: region #1 not an MMIO resource, aborting.\n"); goto error; } flashAddr = reinterpret_cast(flashMap->getVirtualAddress()); @@ -102,15 +102,15 @@ void IntelMausi::initPCIPowerManagment(IOPCIDevice *provider, const struct e1000 /* Setup power management. */ if (provider->findPCICapability(kIOPCIPowerManagementCapability, &pmCapOffset)) { pmCap = provider->extendedConfigRead16(pmCapOffset + kIOPCIPMCapability); - DebugLog("Ethernet [IntelMausi]: PCI power management capabilities: 0x%x.\n", pmCap); + DebugLog("[IntelMausi]: PCI power management capabilities: 0x%x.\n", pmCap); if (pmCap & (kPCIPMCPMESupportFromD3Cold | kPCIPMCPMESupportFromD3Hot)) { wolCapable = true; - DebugLog("Ethernet [IntelMausi]: PME# from D3 (cold/hot) supported.\n"); + DebugLog("[IntelMausi]: PME# from D3 (cold/hot) supported.\n"); } pciPMCtrlOffset = pmCapOffset + kIOPCIPMControl; } else { - IOLog("Ethernet [IntelMausi]: PCI power management unsupported.\n"); + IOLog("[IntelMausi]: PCI power management unsupported.\n"); } provider->enablePCIPowerManagement(); @@ -118,7 +118,7 @@ void IntelMausi::initPCIPowerManagment(IOPCIDevice *provider, const struct e1000 if (provider->findPCICapability(kIOPCIPCIExpressCapability, &pcieCapOffset)) { pcieLinkCap = provider->extendedConfigRead32(pcieCapOffset + kIOPCIELinkCapability); pcieLinkCtl = provider->extendedConfigRead16(pcieCapOffset + kIOPCIELinkControl); - DebugLog("Ethernet [IntelMausi]: PCIe link capabilities: 0x%08x, link control: 0x%04x.\n", pcieLinkCap, pcieLinkCtl); + DebugLog("[IntelMausi]: PCIe link capabilities: 0x%08x, link control: 0x%04x.\n", pcieLinkCap, pcieLinkCtl); aspmDisable = 0; if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S) @@ -134,9 +134,9 @@ void IntelMausi::initPCIPowerManagment(IOPCIDevice *provider, const struct e1000 pcieLinkCtl = provider->extendedConfigRead16(pcieCapOffset + kIOPCIELinkControl); if (pcieLinkCtl & (kIOPCIELinkCtlASPM | kIOPCIELinkCtlClkReqEn)) - IOLog("Ethernet [IntelMausi]: PCIe ASPM enabled. link control: 0x%04x.\n", pcieLinkCtl); + IOLog("[IntelMausi]: PCIe ASPM enabled. link control: 0x%04x.\n", pcieLinkCtl); else - IOLog("Ethernet [IntelMausi]: PCIe ASPM disabled. link control: 0x%04x.\n", pcieLinkCtl); + IOLog("[IntelMausi]: PCIe ASPM disabled. link control: 0x%04x.\n", pcieLinkCtl); #endif /* DEBUG */ } } @@ -204,7 +204,7 @@ void IntelMausi::intelEEPROMChecks(struct e1000_adapter *adapter) if (!ret_val && (!(buf & (1 << 0)))) { /* Deep Smart Power Down (DSPD) */ - IOLog("Ethernet [IntelMausi]: Warning: detected DSPD enabled in EEPROM.\n"); + IOLog("[IntelMausi]: Warning: detected DSPD enabled in EEPROM.\n"); } } @@ -229,18 +229,33 @@ void IntelMausi::intelEnable() selectedMedium = getSelectedMedium(); if (!selectedMedium) { - DebugLog("Ethernet [IntelMausi]: No medium selected. Falling back to autonegotiation.\n"); + DebugLog("[IntelMausi]: No medium selected. Falling back to autonegotiation.\n"); selectedMedium = mediumTable[MEDIUM_INDEX_AUTO]; setCurrentMedium(selectedMedium); } /* Check if we re waking up from sleep with WoL enabled and still have a valid link. */ - if (!linkOpts || !intelCheckLink(&adapterData)) { - linkOpts = 0; + if (!intelCheckLink(&adapterData)) { setLinkStatus(kIONetworkLinkValid); } polling = false; +#ifdef DEBUG + if (adapterData.flags2 & FLAG2_HAS_PHY_WAKEUP) { + struct e1000_hw *hw = &adapterData.hw; + UInt16 phyData; + + hw->phy.ops.read_reg(hw, BM_WUS, &phyData); + hw->phy.ops.write_reg(hw, BM_WUS, ~0); + + IOLog("[IntelMausi]: WUS=0x%04x\n", phyData); + } else { + IOLog("[IntelMausi]: WUS=0x%08x\n", intelReadMem32(E1000_WUS)); + + intelWriteMem32(E1000_WUS, ~0); + } +#endif + intelSetupAdvForMedium(selectedMedium); e1000_phy_hw_reset(hw); @@ -272,6 +287,7 @@ void IntelMausi::intelEnable() void IntelMausi::intelDisable() { + struct IntelAddrData addrData; struct e1000_hw *hw = &adapterData.hw; UInt32 linkStatus = kIONetworkLinkValid; UInt32 wufc = adapterData.wol; @@ -279,7 +295,6 @@ void IntelMausi::intelDisable() int retval; polling = false; - linkOpts = 0; /* Flush LPIC. */ intelFlushLPIC(); @@ -290,6 +305,9 @@ void IntelMausi::intelDisable() wufc &= ~E1000_WUFC_LNKC; if (wolActive && wufc) { + /* Get interface's IP addresses. */ + getAddressList(&addrData); + intelDown(&adapterData, false); intelSetupRxControl(&adapterData); @@ -322,16 +340,16 @@ void IntelMausi::intelDisable() if (adapterData.flags2 & FLAG2_HAS_PHY_WAKEUP) { /* enable wakeup by the PHY */ - intelInitPhyWakeup(wufc); + intelInitPhyWakeup(wufc, &addrData); + + DebugLog("Ethernet [IntelMausi]: Configure wakeup by PHY.\n"); } else { /* enable wakeup by the MAC */ - intelWriteMem32(E1000_WUFC, wufc); - intelWriteMem32(E1000_WUC, E1000_WUC_PME_EN); + intelInitMacWakeup(wufc, &addrData); + + DebugLog("Ethernet [IntelMausi]: Configure wakeup by MAC.\n"); } - DebugLog("Ethernet [IntelMausi]: WUFC=0x%08x.\n", wufc); - - linkOpts = kIONetworkLinkNoNetworkChange; - linkStatus |= linkOpts; + DebugLog("[IntelMausi]: WUFC=0x%08x.\n", wufc); } else { intelDown(&adapterData, true); intelWriteMem32(E1000_WUC, 0); @@ -377,7 +395,7 @@ void IntelMausi::intelDisable() if (linkUp) { linkUp = false; setLinkStatus(linkStatus); - IOLog("Ethernet [IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); + IOLog("[IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); } } @@ -488,7 +506,7 @@ void IntelMausi::intelSetupRxControl(struct e1000_adapter *adapter) ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); if (ret_val) - DebugLog("Ethernet [IntelMausi]: failed to enable/disable jumbo frame workaround mode.\n"); + DebugLog("[IntelMausi]: failed to enable/disable jumbo frame workaround mode.\n"); } /* Program MC offset vector base */ rctl = intelReadMem32(E1000_RCTL); @@ -634,7 +652,7 @@ void IntelMausi::intelDown(struct e1000_adapter *adapter, bool reset) /* Disable Si errata workaround on PCHx for jumbo frame flow */ if ((hw->mac.type >= e1000_pch2lan) && (mtu > ETH_DATA_LEN) && e1000_lv_jumbo_workaround_ich8lan(hw, false)) - DebugLog("Ethernet [IntelMausi]: failed to disable jumbo frame workaround mode\n"); + DebugLog("[IntelMausi]: failed to disable jumbo frame workaround mode\n"); if (reset) intelReset(adapter); @@ -701,7 +719,7 @@ void IntelMausi::intelInitManageabilityPt(struct e1000_adapter *adapter) } if (!j) - IOLog("Ethernet [IntelMausi]: Unable to create IPMI pass-through filter.\n"); + IOLog("[IntelMausi]: Unable to create IPMI pass-through filter.\n"); break; } intelWriteMem32(E1000_MANC2H, manc2h); @@ -856,7 +874,7 @@ void IntelMausi::intelReset(struct e1000_adapter *adapter) intelWriteMem32(E1000_WUC, 0); if (mac->ops.init_hw(hw)) - IOLog("Ethernet [IntelMausi]: Hardware Error.\n"); + IOLog("[IntelMausi]: Hardware Error.\n"); //e1000_update_mng_vlan(adapter); @@ -881,14 +899,14 @@ void IntelMausi::intelReset(struct e1000_adapter *adapter) adv_addr = I217_EEE_ADVERTISEMENT; break; default: - IOLog("Ethernet [IntelMausi]: Invalid PHY type setting EEE advertisement.\n"); + IOLog("[IntelMausi]: Invalid PHY type setting EEE advertisement.\n"); return; } ret_val = hw->phy.ops.acquire(hw); if (ret_val) { - IOLog("Ethernet [IntelMausi]: EEE advertisement - unable to acquire PHY.\n"); + IOLog("[IntelMausi]: EEE advertisement - unable to acquire PHY.\n"); return; } e1000_write_emi_reg_locked(hw, adv_addr, hw->dev_spec.ich8lan.eee_disable ? 0 : adapter->eee_advert); @@ -964,7 +982,7 @@ void IntelMausi::intelResetAdaptive(struct e1000_hw *hw) struct e1000_mac_info *mac = &hw->mac; if (!mac->adaptive_ifs) { - DebugLog("Ethernet [IntelMausi]: Not in Adaptive IFS mode!\n"); + DebugLog("[IntelMausi]: Not in Adaptive IFS mode!\n"); return; } mac->current_ifs_val = 0; @@ -989,7 +1007,7 @@ void IntelMausi::intelUpdateAdaptive(struct e1000_hw *hw) struct e1000_mac_info *mac = &hw->mac; if (!mac->adaptive_ifs) { - DebugLog("Ethernet [IntelMausi]: Not in Adaptive IFS mode!\n"); + DebugLog("[IntelMausi]: Not in Adaptive IFS mode!\n"); return; } @@ -1092,7 +1110,7 @@ void IntelMausi::intelRestart() /* Also set the link status to down. */ if (linkUp) - IOLog("Ethernet [IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); + IOLog("[IntelMausi]: Link down on en%u\n", netif->getUnitNumber()); setLinkStatus(kIONetworkLinkValid); linkUp = false; @@ -1158,7 +1176,7 @@ void IntelMausi::intelUpdateTxDescTail(UInt32 index) intelWriteMem32(E1000_TCTL, tctl & ~E1000_TCTL_EN); forceReset = true; - IOLog("Ethernet [IntelMausi]: ME firmware caused invalid TDT - resetting.\n"); + IOLog("[IntelMausi]: ME firmware caused invalid TDT - resetting.\n"); } } else { intelWriteMem32(E1000_TDT(0), index); @@ -1179,7 +1197,7 @@ void IntelMausi::intelUpdateRxDescTail(UInt32 index) intelWriteMem32(E1000_RCTL, rctl & ~E1000_RCTL_EN); forceReset = true; - IOLog("Ethernet [IntelMausi]: ME firmware caused invalid RDT - resetting.\n"); + IOLog("[IntelMausi]: ME firmware caused invalid RDT - resetting.\n"); } } @@ -1231,10 +1249,10 @@ void IntelMausi::intelFlushTxRing(struct e1000_adapter *adapter) tdt = intelReadMem32(E1000_TDT(0)); if (tdt != txNextDescIndex) { - IOLog("Ethernet [IntelMausi]: Failed to flush tx descriptor ring.\n"); + IOLog("[IntelMausi]: Failed to flush tx descriptor ring.\n"); goto done; } - DebugLog("Ethernet [IntelMausi]: Flushing tx descriptor ring.\n"); + DebugLog("[IntelMausi]: Flushing tx descriptor ring.\n"); OSAddAtomic(-1, &txNumFreeDesc); desc = &txDescArray[txNextDescIndex++]; @@ -1261,7 +1279,7 @@ void IntelMausi::intelFlushRxRing(struct e1000_adapter *adapter) { UInt32 rctl, rxdctl; - DebugLog("Ethernet [IntelMausi]: Flushing rx descriptor ring.\n"); + DebugLog("[IntelMausi]: Flushing rx descriptor ring.\n"); rctl = intelReadMem32(E1000_RCTL); intelWriteMem32(E1000_RCTL, rctl & ~E1000_RCTL_EN); @@ -1359,7 +1377,7 @@ bool IntelMausi::intelCheckLink(struct e1000_adapter *adapter) if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) && (intelReadMem32(E1000_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) { /* See e1000_kmrn_lock_loss_workaround_ich8lan() */ - IOLog("Ethernet [IntelMausi]: Gigabit has been disabled, downgrading speed.\n"); + IOLog("[IntelMausi]: Gigabit has been disabled, downgrading speed.\n"); } return link_active; } @@ -1387,7 +1405,7 @@ void IntelMausi::intelPhyReadStatus(struct e1000_adapter *adapter) ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus); if (ret_val) - IOLog("Ethernet [IntelMausi]: Error reading PHY register.\n"); + IOLog("[IntelMausi]: Error reading PHY register.\n"); } else { /* Do not read PHY registers if link is not up * Set values to typical power-on defaults @@ -1406,27 +1424,27 @@ void IntelMausi::intelPhyReadStatus(struct e1000_adapter *adapter) } } -void IntelMausi::intelInitPhyWakeup(UInt32 wufc) +void IntelMausi::intelInitPhyWakeup(UInt32 wufc, struct IntelAddrData *addrData) { struct e1000_hw *hw = &adapterData.hw; - u32 i, mac_reg, wuc; - u16 phy_reg, wuc_enable; + UInt32 i, mac_reg, wuc, ad, num; int error; - + UInt16 phy_reg, wuc_enable, av; + /* copy MAC RARs to PHY RARs */ e1000_copy_rx_addrs_to_phy_ich8lan(hw); error = hw->phy.ops.acquire(hw); if (error) { - DebugLog("Ethernet [IntelMausi]: Failed to acquire PHY.\n"); + DebugLog("[IntelMausi]: Failed to acquire PHY.\n"); return; } /* Enable access to wakeup registers on and set page to BM_WUC_PAGE */ error = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable); if (error) { - DebugLog("Ethernet [IntelMausi]: Failed to access PHY wakeup registers.\n"); + DebugLog("[IntelMausi]: Failed to access PHY wakeup registers.\n"); goto release; } /* copy MAC MTA to PHY MTA - only needed for pchlan */ @@ -1439,7 +1457,7 @@ void IntelMausi::intelInitPhyWakeup(UInt32 wufc) } /* configure PHY Rx Control register */ hw->phy.ops.read_reg_page(hw, BM_RCTL, &phy_reg); - mac_reg = er32(RCTL); + mac_reg = intelReadMem32(E1000_RCTL); if (mac_reg & E1000_RCTL_UPE) phy_reg |= BM_RCTL_UPE; @@ -1458,23 +1476,84 @@ void IntelMausi::intelInitPhyWakeup(UInt32 wufc) if (mac_reg & E1000_RCTL_PMCF) phy_reg |= BM_RCTL_PMCF; - mac_reg = er32(CTRL); + mac_reg = intelReadMem32(E1000_CTRL); if (mac_reg & E1000_CTRL_RFCE) phy_reg |= BM_RCTL_RFCE; - hw->phy.ops.write_reg_page(hw, BM_RCTL, phy_reg); - + /* Disable slave access to activate filters */ + phy_reg &= ~BM_RCTL_SAE; + wuc = E1000_WUC_PME_EN; if (wufc & (E1000_WUFC_MAG | E1000_WUFC_LNKC)) wuc |= E1000_WUC_APME; + /* + * Enable wakeup by ARP request and directed IPv4/IPv6 packets. + */ + if (addrData->ipV4Count > 0) + wufc |= (E1000_WUFC_EX | E1000_WUFC_ARP | E1000_WUFC_IP4); + + if (addrData->ipV6Count > 0) + wufc |= (E1000_WUFC_EX | E1000_WUFC_IP6); + /* enable PHY wakeup in MAC register */ - ew32(WUFC, wufc); - ew32(WUC, (E1000_WUC_PHY_WAKE | E1000_WUC_APMPME | E1000_WUC_PME_STATUS | wuc)); + intelWriteMem32(E1000_WUFC, wufc); + intelWriteMem32(E1000_WUC, (E1000_WUC_PHY_WAKE | E1000_WUC_APMPME | E1000_WUC_PME_STATUS | wuc)); - /* configure and enable PHY wakeup in PHY registers */ + /* + * Setup IPv4 and IPv6 wakeup address registers with the + * retrieved address list. + */ + av = 0x0000; + num = (addrData->ipV4Count > kMaxAddrV4) ? kMaxAddrV4 : addrData->ipV4Count; + + for (i = 0; i < num; i++) { + //av |= BIT(i + 1); + ad = addrData->ipV4Addr[i]; + + hw->phy.ops.write_reg_page(hw, BM_IP4AT0(i), (u16)(ad & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_IP4AT1(i), (u16)((ad >> 16) & 0xFFFF)); + } + num = (addrData->ipV6Count > kMaxAddrV6) ? kMaxAddrV6 : addrData->ipV6Count; + + for (i = 0; i < num; i++) { + av |= BIT(7 - i); + + ad = addrData->ipV6Addr[i].s6_addr32[0]; + hw->phy.ops.write_reg_page(hw, BM_IP6AT0(i), (u16)(ad & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_IP6AT1(i), (u16)((ad >> 16) & 0xFFFF)); + + ad = addrData->ipV6Addr[i].s6_addr32[1]; + hw->phy.ops.write_reg_page(hw, BM_IP6AT2(i), (u16)(ad & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_IP6AT3(i), (u16)((ad >> 16) & 0xFFFF)); + + ad = addrData->ipV6Addr[i].s6_addr32[2]; + hw->phy.ops.write_reg_page(hw, BM_IP6AT4(i), (u16)(ad & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_IP6AT5(i), (u16)((ad >> 16) & 0xFFFF)); + + ad = addrData->ipV6Addr[i].s6_addr32[3]; + hw->phy.ops.write_reg_page(hw, BM_IP6AT6(i), (u16)(ad & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_IP6AT7(i), (u16)((ad >> 16) & 0xFFFF)); + } + /* + * Fix address valid mask as bit 15 is a duplicate of bit 7 + * and write to IPAV register. + */ + if (av & BIT(7)) { + av |= BIT(15); + } + hw->phy.ops.write_reg_page(hw, BM_IPAV, av); + DebugLog("[IntelMausi]: PHY IPAV = 0x%04x.\n", av); + DebugLog("[IntelMausi]: PHY WUFC = 0x%04x.\n", wufc); + DebugLog("[IntelMausi]: PHY WUC = 0x%04x.\n", wuc); + + /* Configure PHY rx control */ + DebugLog("[IntelMausi]: PHY RCTL = 0x%04x.\n", phy_reg); + hw->phy.ops.write_reg_page(hw, BM_RCTL, phy_reg); + + /* Configure and enable PHY wakeup in PHY registers */ hw->phy.ops.write_reg_page(hw, BM_WUFC, wufc); hw->phy.ops.write_reg_page(hw, BM_WUC, wuc); @@ -1483,12 +1562,43 @@ void IntelMausi::intelInitPhyWakeup(UInt32 wufc) error = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable); if (error) - DebugLog("Ethernet [IntelMausi]: Failed to set PHY Host Wakeup bit.\n"); + DebugLog("[IntelMausi]: Failed to set PHY Host Wakeup bit.\n"); release: hw->phy.ops.release(hw); } +void IntelMausi::intelInitMacWakeup(UInt32 wufc, struct IntelAddrData *addrData) +{ + UInt32 av, num, i; + + /* Enable wakeup by ARP request and directed IPv4 packets. */ + if (addrData->ipV4Count > 0) + wufc |= (E1000_WUFC_EX | E1000_WUFC_ARP | E1000_WUFC_IP4); + + /* Configure IPv4 wakeup address registers. */ + av = 0; + num = (addrData->ipV4Count > kMaxAddrV4) ? kMaxAddrV4 : addrData->ipV4Count; + + for (i = 0; i < num; i++) { + av |= BIT(i + 1); + intelWriteMem32(E1000_IP4AT(i), addrData->ipV4Addr[i]); + } + + /* Configure IPv6 wakeup address registers. */ + if (addrData->ipV6Count > 0) { + wufc |= (E1000_WUFC_EX | E1000_WUFC_IP6); + av |= BIT(16); + + for (i = 0; i < 4; i++) { + intelWriteMem32(E1000_IP6AT(i), addrData->ipV6Addr[0].s6_addr32[i]); + } + } + intelWriteMem32(E1000_IPAV, av); + intelWriteMem32(E1000_WUFC, wufc); + intelWriteMem32(E1000_WUC, (E1000_WUC_PME_EN | E1000_WUC_PME_STATUS)); +} + void IntelMausi::intelSetupAdvForMedium(const IONetworkMedium *medium) { struct e1000_hw *hw = &adapterData.hw; @@ -1600,7 +1710,7 @@ void IntelMausi::intelFlushLPIC() return; lpic = intelReadMem32(E1000_LPIC); - DebugLog("Ethernet [IntelMausi]: LPIC=0x%08x.\n", lpic); + DebugLog("[IntelMausi]: LPIC=0x%08x.\n", lpic); hw->phy.ops.release(hw); } @@ -1619,7 +1729,7 @@ void IntelMausi::setMaxLatency(UInt32 linkSpeed) requireMaxBusStall(latency); - DebugLog("Ethernet [IntelMausi]: requireMaxBusStall(%uns).\n", latency); + DebugLog("[IntelMausi]: requireMaxBusStall(%uns).\n", latency); } UInt16 IntelMausi::intelSupportsEEE(struct e1000_adapter *adapter) @@ -1678,7 +1788,7 @@ UInt16 IntelMausi::intelSupportsEEE(struct e1000_adapter *adapter) if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) result |= I82579_LPI_CTRL_100_ENABLE; - DebugLog("Ethernet [IntelMausi]: EEE mode = 0x%04x, adv=0x%04x, lpa=0x%04x\n", result, adv, dev_spec->eee_lp_ability); + DebugLog("[IntelMausi]: EEE mode = 0x%04x, adv=0x%04x, lpa=0x%04x\n", result, adv, dev_spec->eee_lp_ability); release: hw->phy.ops.release(hw); diff --git a/IntelMausiEthernet/IntelMausiSetup.cpp b/IntelMausiEthernet/IntelMausiSetup.cpp old mode 100644 new mode 100755 index 3034f97..51428c6 --- a/IntelMausiEthernet/IntelMausiSetup.cpp +++ b/IntelMausiEthernet/IntelMausiSetup.cpp @@ -63,9 +63,8 @@ void IntelMausi::getParams() OSDictionary *params; OSString *versionString; OSNumber *num; - OSBoolean *tso4; - OSBoolean *tso6; OSBoolean *csoV6; + OSBoolean *wom; UInt32 newIntrRate10; UInt32 newIntrRate100; UInt32 newIntrRate1000; @@ -75,21 +74,16 @@ void IntelMausi::getParams() params = OSDynamicCast(OSDictionary, getProperty(kParamName)); if (params) { - tso4 = OSDynamicCast(OSBoolean, params->getObject(kEnableTSO4Name)); - enableTSO4 = (tso4) ? tso4->getValue() : false; - - IOLog("Ethernet [IntelMausi]: TCP/IPv4 segmentation offload %s.\n", enableTSO4 ? onName : offName); - - tso6 = OSDynamicCast(OSBoolean, params->getObject(kEnableTSO6Name)); - enableTSO6 = (tso6) ? tso6->getValue() : false; - - IOLog("Ethernet [IntelMausi]: TCP/IPv6 segmentation offload %s.\n", enableTSO6 ? onName : offName); - csoV6 = OSDynamicCast(OSBoolean, params->getObject(kEnableCSO6Name)); enableCSO6 = (csoV6) ? csoV6->getValue() : false; - IOLog("Ethernet [IntelMausi]: TCP/IPv6 checksum offload %s.\n", enableCSO6 ? onName : offName); + IOLog("[IntelMausi]: TCP/IPv6 checksum offload %s.\n", enableCSO6 ? onName : offName); + wom = OSDynamicCast(OSBoolean, params->getObject(kEnableWoMName)); + enableWoM = (wom) ? wom->getValue() : false; + + IOLog("[IntelMausi]: Wake on address match %s.\n", enableWoM ? onName : offName); + /* Get maximum interrupt rate for 10M. */ num = OSDynamicCast(OSNumber, params->getObject(kIntrRate10Name)); newIntrRate10 = 3000; @@ -201,9 +195,8 @@ void IntelMausi::getParams() } } else { /* Use default values in case of missing config data. */ - enableTSO4 = false; - enableTSO6 = false; enableCSO6 = false; + enableWoM = false; newIntrRate10 = 3000; newIntrRate100 = 5000; newIntrRate1000 = 7000; @@ -218,12 +211,12 @@ void IntelMausi::getParams() rxDelayTime1000 = 0; } - DebugLog("Ethernet [IntelMausi]: rxAbsTime10=%u, rxAbsTime100=%u, rxAbsTime1000=%u, rxDelayTime10=%u, rxDelayTime100=%u, rxDelayTime1000=%u. \n", rxAbsTime10, rxAbsTime100, rxAbsTime1000, rxDelayTime10, rxDelayTime100, rxDelayTime1000); + DebugLog("[IntelMausi]: rxAbsTime10=%u, rxAbsTime100=%u, rxAbsTime1000=%u, rxDelayTime10=%u, rxDelayTime100=%u, rxDelayTime1000=%u. \n", rxAbsTime10, rxAbsTime100, rxAbsTime1000, rxDelayTime10, rxDelayTime100, rxDelayTime1000); if (versionString) - IOLog("Ethernet [IntelMausi]: Version %s using max interrupt rates [%u; %u; %u]. Please don't support tonymacx86.com!\n", versionString->getCStringNoCopy(), newIntrRate10, newIntrRate100, newIntrRate1000); + IOLog("[IntelMausi]: Version %s using max interrupt rates [%u; %u; %u]. Please don't support tonymacx86.com!\n", versionString->getCStringNoCopy(), newIntrRate10, newIntrRate100, newIntrRate1000); else - IOLog("Ethernet [IntelMausi]: Using max interrupt rates [%u; %u; %u. Please don't support tonymacx86.com!\n", intrThrValue10, intrThrValue100, intrThrValue1000); + IOLog("[IntelMausi]: Using max interrupt rates [%u; %u; %u. Please don't support tonymacx86.com!\n", intrThrValue10, intrThrValue100, intrThrValue1000); } bool IntelMausi::setupMediumDict() @@ -267,7 +260,7 @@ bool IntelMausi::setupMediumDict() return result; error1: - IOLog("Ethernet [IntelMausi]: Error creating medium dictionary.\n"); + IOLog("[IntelMausi]: Error creating medium dictionary.\n"); mediumDict->release(); for (i = MEDIUM_INDEX_AUTO; i < MEDIUM_INDEX_COUNT; i++) @@ -287,7 +280,7 @@ bool IntelMausi::initEventSources(IOService *provider) txQueue = reinterpret_cast(getOutputQueue()); if (txQueue == NULL) { - IOLog("Ethernet [IntelMausi]: Failed to get output queue.\n"); + IOLog("[IntelMausi]: Failed to get output queue.\n"); goto done; } txQueue->retain(); @@ -300,12 +293,12 @@ bool IntelMausi::initEventSources(IOService *provider) intrIndex++; } if (msiIndex != -1) { - DebugLog("Ethernet [IntelMausi]: MSI interrupt index: %d\n", msiIndex); + DebugLog("[IntelMausi]: MSI interrupt index: %d\n", msiIndex); interruptSource = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventSource::Action, this, &IntelMausi::interruptOccurred), provider, msiIndex); } if (!interruptSource) { - IOLog("Ethernet [IntelMausi]: MSI interrupt could not be enabled.\n"); + IOLog("[IntelMausi]: MSI interrupt could not be enabled.\n"); goto error1; } workLoop->addEventSource(interruptSource); @@ -313,7 +306,7 @@ bool IntelMausi::initEventSources(IOService *provider) timerSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &IntelMausi::timerAction)); if (!timerSource) { - IOLog("Ethernet [IntelMausi]: Failed to create IOTimerEventSource.\n"); + IOLog("[IntelMausi]: Failed to create IOTimerEventSource.\n"); goto error2; } workLoop->addEventSource(timerSource); @@ -328,7 +321,7 @@ bool IntelMausi::initEventSources(IOService *provider) RELEASE(interruptSource); error1: - IOLog("Ethernet [IntelMausi]: Error initializing event sources.\n"); + IOLog("[IntelMausi]: Error initializing event sources.\n"); txQueue->release(); txQueue = NULL; goto done; @@ -350,11 +343,11 @@ bool IntelMausi::setupDMADescriptors() txBufDesc = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, (kIODirectionInOut | kIOMemoryPhysicallyContiguous | kIOMapInhibitCache), kTxDescSize, 0xFFFFFFFFFFFFF000ULL); if (!txBufDesc) { - IOLog("Ethernet [IntelMausi]: Couldn't alloc txBufDesc.\n"); + IOLog("[IntelMausi]: Couldn't alloc txBufDesc.\n"); goto done; } if (txBufDesc->prepare() != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: txBufDesc->prepare() failed.\n"); + IOLog("[IntelMausi]: txBufDesc->prepare() failed.\n"); goto error1; } txDescArray = (struct e1000_data_desc *)txBufDesc->getBytesNoCopy(); @@ -363,17 +356,17 @@ bool IntelMausi::setupDMADescriptors() txDescDmaCmd = IODMACommand::withSpecification(kIODMACommandOutputHost64, 64, 0, IODMACommand::kMapped, 0, 1); if (!txDescDmaCmd) { - IOLog("Ethernet [IntelMausi]: Couldn't alloc txDescDmaCmd.\n"); + IOLog("[IntelMausi]: Couldn't alloc txDescDmaCmd.\n"); goto error2; } if (txDescDmaCmd->setMemoryDescriptor(txBufDesc) != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: setMemoryDescriptor() failed.\n"); + IOLog("[IntelMausi]: setMemoryDescriptor() failed.\n"); goto error3; } if (txDescDmaCmd->gen64IOVMSegments(&offset, &seg, &numSegs) != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: gen64IOVMSegments() failed.\n"); + IOLog("[IntelMausi]: gen64IOVMSegments() failed.\n"); goto error4; } /* Now get tx ring's physical address. */ @@ -392,7 +385,7 @@ bool IntelMausi::setupDMADescriptors() txMbufCursor = IOMbufNaturalMemoryCursor::withSpecification(0x4000, kMaxSegs); if (!txMbufCursor) { - IOLog("Ethernet [IntelMausi]: Couldn't create txMbufCursor.\n"); + IOLog("[IntelMausi]: Couldn't create txMbufCursor.\n"); goto error4; } @@ -400,12 +393,12 @@ bool IntelMausi::setupDMADescriptors() rxBufDesc = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, (kIODirectionInOut | kIOMemoryPhysicallyContiguous | kIOMapInhibitCache), kRxDescSize, 0xFFFFFFFFFFFFF000ULL); if (!rxBufDesc) { - IOLog("Ethernet [IntelMausi]: Couldn't alloc rxBufDesc.\n"); + IOLog("[IntelMausi]: Couldn't alloc rxBufDesc.\n"); goto error5; } if (rxBufDesc->prepare() != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: rxBufDesc->prepare() failed.\n"); + IOLog("[IntelMausi]: rxBufDesc->prepare() failed.\n"); goto error6; } rxDescArray = (union e1000_rx_desc_extended *)rxBufDesc->getBytesNoCopy(); @@ -414,19 +407,19 @@ bool IntelMausi::setupDMADescriptors() rxDescDmaCmd = IODMACommand::withSpecification(kIODMACommandOutputHost64, 64, 0, IODMACommand::kMapped, 0, 1); if (!rxDescDmaCmd) { - IOLog("Ethernet [IntelMausi]: Couldn't alloc rxDescDmaCmd.\n"); + IOLog("[IntelMausi]: Couldn't alloc rxDescDmaCmd.\n"); goto error7; } if (rxDescDmaCmd->setMemoryDescriptor(rxBufDesc) != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: setMemoryDescriptor() failed.\n"); + IOLog("[IntelMausi]: setMemoryDescriptor() failed.\n"); goto error8; } offset = 0; numSegs = 1; if (rxDescDmaCmd->gen64IOVMSegments(&offset, &seg, &numSegs) != kIOReturnSuccess) { - IOLog("Ethernet [IntelMausi]: gen64IOVMSegments() failed.\n"); + IOLog("[IntelMausi]: gen64IOVMSegments() failed.\n"); goto error9; } /* And the rx ring's physical address too. */ @@ -444,7 +437,7 @@ bool IntelMausi::setupDMADescriptors() rxMbufCursor = IOMbufNaturalMemoryCursor::withSpecification(PAGE_SIZE, 1); if (!rxMbufCursor) { - IOLog("Ethernet [IntelMausi]: Couldn't create rxMbufCursor.\n"); + IOLog("[IntelMausi]: Couldn't create rxMbufCursor.\n"); goto error9; } /* Alloc receive buffers. */ @@ -452,7 +445,7 @@ bool IntelMausi::setupDMADescriptors() m = allocatePacket(kRxBufferPktSize); if (!m) { - IOLog("Ethernet [IntelMausi]: Couldn't alloc receive buffer.\n"); + IOLog("[IntelMausi]: Couldn't alloc receive buffer.\n"); goto error10; } rxBufArray[i].mbuf = m; @@ -460,7 +453,7 @@ bool IntelMausi::setupDMADescriptors() n = rxMbufCursor->getPhysicalSegments(m, &rxSegment, 1); if ((n != 1) || (rxSegment.location & 0x07ff)) { - IOLog("Ethernet [IntelMausi]: getPhysicalSegments() for receive buffer failed.\n"); + IOLog("[IntelMausi]: getPhysicalSegments() for receive buffer failed.\n"); goto error10; } /* We have to keep the physical address of the buffer too @@ -614,3 +607,64 @@ void IntelMausi::discardPacketFragment() rxPacketHead = rxPacketTail = NULL; rxPacketSize = 0; } + +/* + * Retrieve a list of IPv4 and IVv6 addresses of the interface which + * are required by the ARP and IP wakeup filters. As hardware supports + * a maximum of 3 IPv4 and 4 IPv6 addresses, we have to ignore + * excess addresses and limit IPv6 addresses to Link-Local and + * Unique Local Addresses. + */ + +void IntelMausi::getAddressList(struct IntelAddrData *addrData) +{ + ifnet_t interface = netif->getIfnet(); + ifaddr_t *addresses; + ifaddr_t addr; + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + sa_family_t family; + u_int32_t i = 0, prefix; + + addrData->ipV6Count = 0; + addrData->ipV4Count = 0; + + if (enableWoM) { + if (!ifnet_get_address_list(interface, &addresses)) { + while ((addr = addresses[i++]) != NULL) { + family = ifaddr_address_family(addr); + + switch (family) { + case AF_INET: + if (!ifaddr_address(addr, (struct sockaddr *) &addr4, sizeof(struct sockaddr_in))) { + if (addrData->ipV4Count < kMaxAddrV4) { + addrData->ipV4Addr[addrData->ipV4Count++] = addr4.sin_addr.s_addr; + + DebugLog("[IntelMausi]: IPv4 address 0x%08x.\n", OSSwapBigToHostInt32(addr4.sin_addr.s_addr)); + } + } + break; + + case AF_INET6: + if (!ifaddr_address(addr, (struct sockaddr *) &addr6, sizeof(struct sockaddr_in6))) { + prefix = OSSwapBigToHostInt32(addr6.sin6_addr.s6_addr32[0]); + + if ((addrData->ipV6Count < kMaxAddrV6) && (((prefix & kULAMask) == kULAPrefix) || ((prefix & kLLAMask) == kLLAPrefix))) { + addrData->ipV6Addr[addrData->ipV6Count].s6_addr32[0] = addr6.sin6_addr.s6_addr32[0]; + addrData->ipV6Addr[addrData->ipV6Count].s6_addr32[1] = addr6.sin6_addr.s6_addr32[1]; + addrData->ipV6Addr[addrData->ipV6Count].s6_addr32[2] = addr6.sin6_addr.s6_addr32[2]; + addrData->ipV6Addr[addrData->ipV6Count++].s6_addr32[3] = addr6.sin6_addr.s6_addr32[3]; + + DebugLog("[IntelMausi]: IPv6 address 0x%08x 0x%08x 0x%08x 0x%08x.\n", OSSwapBigToHostInt32(addr6.sin6_addr.s6_addr32[0]), OSSwapBigToHostInt32(addr6.sin6_addr.s6_addr32[1]), OSSwapBigToHostInt32(addr6.sin6_addr.s6_addr32[2]), OSSwapBigToHostInt32(addr6.sin6_addr.s6_addr32[3])); + } + } + break; + + default: + break; + } + } + ifnet_free_address_list(addresses); + } + } +} diff --git a/IntelMausiEthernet/defines.h b/IntelMausiEthernet/defines.h old mode 100644 new mode 100755 index afb7ebe..7d92d19 --- a/IntelMausiEthernet/defines.h +++ b/IntelMausiEthernet/defines.h @@ -41,6 +41,8 @@ #define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ #define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ +#define E1000_WUFC_IP4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ +#define E1000_WUFC_IP6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ /* Wake Up Status */ #define E1000_WUS_LNKC E1000_WUFC_LNKC diff --git a/IntelMausiEthernet/ich8lan.h b/IntelMausiEthernet/ich8lan.h old mode 100644 new mode 100755 index 00a36df..a8800e7 --- a/IntelMausiEthernet/ich8lan.h +++ b/IntelMausiEthernet/ich8lan.h @@ -143,8 +143,23 @@ #define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2))) #define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1))) +#define BM_IPAV PHY_REG(BM_WUC_PAGE, 64) +#define BM_PRXC PHY_REG(BM_WUC_PAGE, 70) +#define BM_IP4AT0(_i) (BM_PHY_REG(BM_WUC_PAGE, 82 + (_i << 1))) +#define BM_IP4AT1(_i) (BM_PHY_REG(BM_WUC_PAGE, 83 + (_i << 1))) + +#define BM_IP6AT0(_i) (BM_PHY_REG(BM_WUC_PAGE, 88 + (_i << 3))) +#define BM_IP6AT1(_i) (BM_PHY_REG(BM_WUC_PAGE, 89 + (_i << 3))) +#define BM_IP6AT2(_i) (BM_PHY_REG(BM_WUC_PAGE, 90 + (_i << 3))) +#define BM_IP6AT3(_i) (BM_PHY_REG(BM_WUC_PAGE, 91 + (_i << 3))) +#define BM_IP6AT4(_i) (BM_PHY_REG(BM_WUC_PAGE, 92 + (_i << 3))) +#define BM_IP6AT5(_i) (BM_PHY_REG(BM_WUC_PAGE, 93 + (_i << 3))) +#define BM_IP6AT6(_i) (BM_PHY_REG(BM_WUC_PAGE, 94 + (_i << 3))) +#define BM_IP6AT7(_i) (BM_PHY_REG(BM_WUC_PAGE, 95 + (_i << 3))) + #define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */ -#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ +#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ +#define BM_RCTL_SAE 0x0004 /* Slave Access Enable */ #define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */ #define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */ #define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */ diff --git a/IntelMausiEthernet/regs.h b/IntelMausiEthernet/regs.h old mode 100644 new mode 100755 index 0cb4d36..9e805c6 --- a/IntelMausiEthernet/regs.h +++ b/IntelMausiEthernet/regs.h @@ -214,6 +214,9 @@ #define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ #define E1000_WUS 0x05810 /* Wakeup Status - RO */ #define E1000_MANC 0x05820 /* Management Control - RW */ +#define E1000_IPAV 0x05838 /* IP Address Valid */ +#define E1000_IP4AT(_n) (0x05848 + (_n * 8)) /* IPv4 Address Table */ +#define E1000_IP6AT(_n) (0x05880 + (_n * 4)) /* IPv6 Address Table */ #define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ #define E1000_HOST_IF 0x08800 /* Host Interface */