AN-2613: Implementing Wake-on-LAN Using the ADIN1320
Introduction
The ADIN1320 is a low-power, single port Gigabit Ethernet PHY designed to support a wide range of industrial and embedded networking applications. As power efficiency becomes increasingly important in connected systems, many devices are required to remain available on the network while minimizing energy consumption during periods of inactivity. To address this requirement, the ADIN1320 supports several power saving features, including Wake-on-LAN (WoL), which enables systems to remain in a low-power state until network activity triggers a wake-up event.
WoL is a widely adopted networking feature that allows a remote device to reactivate a suspended system by transmitting a specially formatted network packet known as a magic packet. By leveraging WoL, system designers can significantly reduce overall power consumption while maintaining remote accessibility for management, diagnostics, software updates, and other network based functions. This capability is particularly valuable in industrial automation equipment, edge computing platforms, building control systems, and embedded devices that spend extended periods in standby mode.
The ADIN1320 implements hardware based WoL detection, allowing the PHY to monitor network traffic independently while the host processor or MAC remains in a reduced power state. Upon detection of a valid wake event, such as a matching magic packet or a configured link status change, the device can generate a dedicated wake signal or interrupt, enabling rapid system recovery without continuous processor activity. This architecture helps minimize standby power consumption while maintaining reliable network responsiveness.
This application note describes the WoL functionality available in the ADIN1320, including wake signal generation, magic packet filtering, interrupt routing, and event monitoring. It also provides guidance on configuring the required hardware registers and demonstrates how to generate magic packets using the Python-based Scapy packet manipulation framework. By following the procedures outlined in this document, engineers can efficiently implement and validate WoL functionality in embedded Ethernet systems based on the ADIN1320.
WOL on ADIN1320
The WoL allows the ADIN1320 to detect specific network packets called magic packets and generate a wake signal to alert external station management software. Once detected, the wake signal can be routed to dedicated pins or trigger interrupts, waking up external devices such as the MAC or host processor from low-power states. The feature is enabled by setting the GE_WOL_EN bit in the GE_WOL_EN register (0xFF79). All relevant WoL registers must be configured before enabling this bit.
By default, WoL functionality monitors packets from copper PHY. However, users can switch monitoring to fiber PHY by setting the GE_WOL_2_PHY_SD_SEL bit in the GE_WOL_SYS_CNTRL register (0xFF78). Only one PHY can be monitored at a time.
Wake Signal Behavior
The wake signal is level-sensitive and active high by default. Users can invert the signal by enabling the GE_WOL_WAKE_INV_EN bit in the GE_WOL_SYS_CNTRL register. Additionally, pulse-based signaling can be configured through the GE_WOL_SIG_CNTRL register (0xFF7B) by setting the GE_WOL_PUL_EN bit. The pulse length is programmable via the GE_WOL_PUL_LENM_1 field.
The wake signal can be routed to various output pins, including INT_N, LED_0 through LED_3, via corresponding I/O override control registers. This makes integration flexible depending on system layout and GPIO availability.
Routing WOL Events to INT_N
In addition to generating a wake signal, the ADIN1320 can propagate WoL events via its interrupt system. This enables integration with host interrupt lines (such as INT_N) for wake detection without polling. To configure WoL events to trigger the INT_N output, the following register settings must be applied:
#Configure INT_N function Comms ETH.mdiowrite22 (PHY ADDR, 0x0018, 0x0005) #Configure INT_N to include Wol Signal Comms ETH.mdiowrite45 (PHY ADDR, 0x1EFF1D, 0x008E)
Once configured, you can verify and clear the relevant interrupt flags by reading IRQ_STATUS and GE_IRQ_LAT. Details of the WoL wake signal can be read from GE_WOL_STAT.
Magic Packet Structure and Detection
The magic packet comprises six 0xFF bytes and 16 repetitions of the target MAC address. Optionally, a SecureOn key, which is normally comprised of six bytes, can follow. To enable magic packet filtering, the station MAC address must be programmed into the GE_WOL_STA_0_AD_01, GE_WOL_STA_0_AD_23, and GE_WOL_STA_0_AD_45 registers.
The GE_MGC_0_CNTRL register (0xFF80) configures magic packet filter behavior. Here, users can enable CRC checks (GE_MGC_0_CRC_CHK_EN), length checks (GE_MGC_0_LEN_CHK_EN), SecureOn key checks (GE_MGC_0_KEY_CHK_EN), and define whether a 4-byte or 6-byte SecureOn key is used (GE_MGC_0_KEY_4BY_EN). Additionally, the filter can be enabled to match broadcast, multicast, unicast, or the programmed station MAC address.
The SecureOn key, if used, must be programmed into GE_MGC_0_KEY_01, GE_MGC_0_KEY_23, and GE_MGC_0_KEY_45. Note that if the GE_MGC_0_KEY_4BY_EN bit is set, only the first four bytes are used.
Wake Events and Status Monitoring
The WoL wake events can be caused by magic packet matches or link status changes. Link status change wake-ups are enabled by the GE_WOL_LS_CHG_WAKE_EN bit in the GE_WOL_WAKE_CNTRL register (0xFF7A). SecureOn key errors can also trigger wake events when GE_WOL_KEY_ERR_WAKE_EN is set.
The GE_WOL_STAT register (0xFF85) provides status flags that indicate the cause of the last wake event. This includes magic packet matches (GE_MGC_0_FRM_MATCH), SecureOn key errors (GE_MGC_0_KEY_ERR), and link status changes (GE_WOL_LS_CHG). These bits are self clearing on read, making them useful for event logging and diagnostics.
In addition, the GE_IRQ_LAT register (0xFF1E) includes a dedicated interrupt status bit for WoL events, allowing independent monitoring even when WoL specific interrupts are not enabled.
Configuring the ADIN1320 for WOL
To configure the WoL, refer to the following steps:
- Program the station MAC address into GE_WOL_STA_0_AD_01, GE_WOL_STA_0_AD_23, and GE_WOL_STA_0_AD_45.
- Configure magic packet filtering via GE_MGC_0_CNTRL. Enable matching options and CRC/key/length checking as required.
- Program the SecureOn key (if used) into GE_MGC_0_KEY_01, GE_MGC_0_KEY_23, and GE_MGC_0_KEY_45.
- Configure wake signal behavior via GE_WOL_SYS_CNTRL and GE_WOL_SIG_CNTRL.
- Enable WoL filtering and behavior using GE_WOL_WAKE_CNTRL.
- Enable Wol functionality by setting GE_WOL_EN in GE_WOL_EN.
- Route wake signal to the desired output pin using the pin override control registers.
After configuration, the device monitors the selected PHY for a magic packet matching the programmed criteria and generates a wake event accordingly. Refer to the ADIN1320 data sheet for details of these registers.
Note on Energy Efficient Ethernet (EEE)
Although the WoL is not dependent on EEE, it is worth noting that the ADIN1320 supports EEE as defined by the IEEE 802.3az standard. EEE allows the PHY to reduce power consumption during periods of low traffic by entering a low power idle (LPI) mode.
Note that EEE configuration is not part of the ADIN1320 WoL setup described above, but it can be used on the ADIN1320 to further reduce PHY power consumption during idle link activity.
Generating a Magic Packet With Scapy (Python)
To test WoL functionality, the Python library Scapy can be utilized to send a magic packet. The following Python code demonstrates how to construct and send a compliant magic packet to a target MAC address, with the option to include a SecureOn key.
# Check if IPv6 is enabled and reachable on the interface
def check_ipv6_ready (interface):
try:
#Attempt to ping the IPv6 loopback address or a known address
response = os.system(f"ping -6 -n 1::1")
if response == 0:
print (f"IPv6 is ready on (interface).")
return True
else:
print (f"IPv6 is not ready on (interface).")
return False
except Exception as e:
print (f"Error checking IPv6 readiness: (e)")
return False
#Check if Ethernet (MAC address) is available on the interface
def check_ethernet_ready (interface):
try:
src_mac = get_if_hwaddr(interface)
if src_mac:
print (f"Ethernet (MAC address) is ready on (interface).")
return True
else:
print (f"Ethernet is not ready on (interface .")
return False
except Exception as e:
print (f"Error checking Ethernet readiness: (e)")
return False
# Convert MAC address string to bytes
def mac_to_bytes (mac):
return b''.join(struct.pack(">B", int (byte, 16)) for byte in mac.split(':'))
# Create WoL magic packet with a 6-byte secure key
def create_magic_packet_with_key(target_mac, secure_key=None):
# Magic Packet: 6 sync bytes + 16 repetitions of the MAC address
sync_bytes = b'\xFF' * 6
target_mac_bytes = mac_to_bytes (target_mac)
magic_packet = sync_bytes + target_mac_bytes * 16
if secure_key:
#Ensure the secure key is exactly 6 bytes
if len(secure_key) != 6:
raise ValueError ("Secure key must be exactly 6 bytes long.")
magic_packet += secure_key # Append secure key to the Magic Packet
return magic_packet
# Send the Magic Packet with optional password in specified mode (ethernet, ipv4, ipv6)
def send_magic_packet (target_mac, interface="Ethernet 3", mode="ethernet", secure_key=None):
# Ensure IPv6 and Ethernet are ready before sending the packet
if mode == "ipv6" and not check_ipv6_ready (interface):
print("IPv6 is not ready. Exiting.")
return
if not check_ethernet_ready (interface):
print ("Ethernet is not ready. Exiting.")
return
# Create the Magic Packet with optional secure key
magic_packet = create_magic_packet_with_key(target_mac, secure_key)
src_mac = get_if_hwaddr (interface)
if mode == "ethernet":
frame = Ether (dst="ff:ff:ff:ff:ff:ff", src=src_mac) / Raw (load=magic_packet)
sendp (frame, iface=interface, verbose=True)
print (f"Magic Packet with secure key sent over Ethernet (L2) via (interface).")
elif mode == "ipv4":
packet = IP(dst="255.255.255.255") / UDP (sport=9, dport=9) / Raw (load=magic_packet)
sendp (Ether (dst="ff:ff:ff:ff:ff:ff", src=src_mac) / packet, iface=interface, verbose=True)
print (f"Magic Packet with secure key sent over IPv4 UDP broadcast via (interface).")
elif mode == "ipv6": #Other way to send it ether
packet = IPv6 (dst="ff02::1") / UDP (sport=32767, dport=9) / Raw (load=magic_packet)
sendp (Ether (dst="ff:ff:ff:ff:ff:ff", src=src_mac) / packet, iface=interface, verbose=True)
print (f"Magic Packet with secure key sent over IPv6 multicast via (interface).")
else:
raise ValueError ("Invalid mode. Choose 'ethernet', 'ipv4', or 'ipv6'.")
# === MAIN EXECUTION ===
if __name__ == "__main__":
target_mac = "00:01:02:03:04:05" # Replace with the target MAC address
interface = "Ethernet 3" # Use the actual name or check with `get_windows_if_list()`
# You can set this mode to "ethernet", "ipv4", or "ipv6"
mode = "ethernet" # Change this to the mode you want to test: "ethernet", "ipv4", "ipv6"
secure_key = b'\x00\x00\x00\x00\x00\x00\x01' # 6-byte secure key (in bytes)
# Send the Magic Packet in the selected mode
send_magic_packet (target_mac, interface, mode, secure_key)
Conclusion
The WoL capability of the ADIN1320 offers a powerful tool for enabling energy efficient systems with responsive remote wake-up functionality. Properly configuring the hardware registers and crafting the magic packet correctly ensures reliable operation. By combining this with tools like Scapy, engineers can quickly prototype, validate, and deploy WoL in embedded applications and networked systems.