Skip to content

Commit

Permalink
Version 2.5.3d1 - Problem with lost IPv6 addresses after wakeup solve…
Browse files Browse the repository at this point in the history
…d. Wakeup on address match implemented (disabled by default).)
  • Loading branch information
Mieze committed Oct 23, 2020
1 parent e1bbddb commit 2600494
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 25 deletions.
12 changes: 9 additions & 3 deletions IntelMausiEthernet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
D3CB5B6C1A4394A800A37FAA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1150;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = "Laura Müller";
};
buildConfigurationList = D3CB5B6F1A4394A800A37FAA /* Build configuration list for PBXProject "IntelMausiEthernet" */;
Expand Down Expand Up @@ -313,6 +313,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
Expand Down Expand Up @@ -368,6 +369,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
Expand Down Expand Up @@ -415,6 +417,9 @@
D3F318C01AB3B0E300DA9D9A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_DEADCODE_DEADSTORES = NO;
CLANG_ANALYZER_DIVIDE_BY_ZERO = NO;
CLANG_ANALYZER_NULL_DEREFERENCE = NO;
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
CLANG_ENABLE_MODULES = NO;
Expand All @@ -430,9 +435,10 @@
INFOPLIST_FILE = "IntelMausiEthernet/IntelMausiEthernet-Info.plist";
MARKETING_VERSION = $MODULE_VERSION;
MODULE_NAME = com.insanelymac.IntelMausiEthernet;
MODULE_VERSION = 2.5.2d0;
MODULE_VERSION = 2.5.3d1;
PRODUCT_BUNDLE_IDENTIFIER = "com.insanelymac.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = IntelMausiEthernet;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
WRAPPER_EXTENSION = kext;
};
Expand All @@ -456,7 +462,7 @@
INFOPLIST_FILE = "IntelMausiEthernet/IntelMausiEthernet-Info.plist";
MARKETING_VERSION = $MODULE_VERSION;
MODULE_NAME = com.insanelymac.IntelMausiEthernet;
MODULE_VERSION = 2.5.2d0;
MODULE_VERSION = 2.5.3d1;
PRODUCT_BUNDLE_IDENTIFIER = "com.insanelymac.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = IntelMausiEthernet;
SDKROOT = macosx;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1150"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1150"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 2 additions & 0 deletions IntelMausiEthernet/IntelMausiEthernet-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
<dict>
<key>enableCSO6</key>
<true/>
<key>enableWakeOnAddrMatch</key>
<false/>
<key>maxIntrRate10</key>
<integer>3000</integer>
<key>maxIntrRate100</key>
Expand Down
11 changes: 9 additions & 2 deletions IntelMausiEthernet/IntelMausiEthernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,15 @@ IOReturn IntelMausi::getPacketFilters(const OSSymbol *group, UInt32 *filters) co
DebugLog("getPacketFilters() ===>\n");

if ((group == gIOEthernetWakeOnLANFilterGroup) && wolCapable) {
*filters = kIOEthernetWakeOnMagicPacket;
DebugLog("[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);
}
Expand Down
30 changes: 27 additions & 3 deletions IntelMausiEthernet/IntelMausiEthernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
{

Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -490,6 +513,7 @@ class IntelMausi : public super
bool wolCapable;
bool wolActive;
bool enableCSO6;
bool enableWoM;

/* mbuf_t arrays */
struct intelTxBufferInfo txBufArray[kNumTxDesc];
Expand Down
143 changes: 129 additions & 14 deletions IntelMausiEthernet/IntelMausiHardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,22 @@ void IntelMausi::intelEnable()
}
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);
Expand Down Expand Up @@ -271,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;
Expand All @@ -288,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);

Expand Down Expand Up @@ -320,11 +340,14 @@ 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("[IntelMausi]: WUFC=0x%08x.\n", wufc);
} else {
Expand Down Expand Up @@ -1401,13 +1424,13 @@ 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);

Expand All @@ -1434,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;
Expand All @@ -1453,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));

/*
* Setup IPv4 and IPv6 wakeup address registers with the
* retrieved address list.
*/
av = 0x0000;
num = (addrData->ipV4Count > kMaxAddrV4) ? kMaxAddrV4 : addrData->ipV4Count;

/* configure and enable PHY wakeup in PHY registers */
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);

Expand All @@ -1484,6 +1568,37 @@ void IntelMausi::intelInitPhyWakeup(UInt32 wufc)
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;
Expand Down
Loading

0 comments on commit 2600494

Please sign in to comment.