Wake-on-LAN flex filters
Subsystems (3)
RFC 1/1 Wake-on-LAN flex filters
Most modern Ethernet hardware supports flexible filters for wake-on-LAN, probably because it's a requirement for certification with Another Operating System.
This patch implements this feature on e1000 via Ethtool. The kernel portion of this code is fairly well polished, but the changes to the tool are extremely hacky and ugly. Don't bother to comment on that portion; if people want this feature either Jeff or I will redo it correctly.
To create a filter:
# ethtool -F <interface> <filter number> <filter>
where <filter number> can be from 0 - 3 (at least for e1000), and where filter is a string of hex digits describing what the filtered frame should look like. Each byte MUST be represented by two hex digits, and no whitespace is allowed. If a particular byte should be ignored by the filter, represent it with "xx".
For example:
# ethtool -F eth0 1 00xxxxxxxx11223344567890xx
To show a filter:
# ethtool -f <interface> <filter num>
To enable WOL filters (after setting one):
# ethtool -s <interface> wol f
Please review and comment, and thanks.
Kernel patch is inline, ethtool patch is attached.
-Mitch
include/linux/ethtool.h +16 -0
@@ -53,6 +53,17 @@ struct ethtool_wolinfo {__u32 supported;__u32 wolopts;__u8 sopass[SOPASS_MAX ];/* SecureOn(tm) password */ +__u32 n_filters; +}; + +#define WOL_FILTER_MAX 256 +#define WOL_FILTER_IGNORE 0x100 +/* wake-on-lan flexible filters */ +struct ethtool_wol_filter { +__u32 cmd; +__u32 index; +__u32 len; +__u16 mask_val[0 ]; };/* for passing single values */
@@ -372,6 +383,8 @@ struct ethtool_ops {void (*complete)(struct net_device *);u32 (*get_ufo)(struct net_device *);int (*set_ufo)(struct net_device *,u32 ); +int (*get_wol_filter)(struct net_device *,struct ethtool_wol_filter *,u16 *); + int (*set_wol_filter)(struct net_device *, struct ethtool_wol_filter *, u16 *); };#endif /* __KERNEL__ */
@@ -413,6 +426,8 @@ struct ethtool_ops {#define ETHTOOL_SUFO 0x00000022/* Set UFO enable (ethtool_value) */ #define ETHTOOL_GGSO 0x00000023/* Get GSO enable (ethtool_value) */ #define ETHTOOL_SGSO 0x00000024/* Set GSO enable (ethtool_value) */ +#define ETHTOOL_GWOLFILTER 0x00000025/* Get WOL flex filter */ +#define ETHTOOL_SWOLFILTER 0x00000026/* Set WOL flex filter */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET
@@ -497,5 +512,6 @@ struct ethtool_ops {#define WAKE_ARP (1 << 4)#define WAKE_MAGIC (1 << 5)#define WAKE_MAGICSECURE (1 << 6)/* only meaningful if WAKE_MAGIC */ +#define WAKE_FILTER (1 << 7)#endif /* _LINUX_ETHTOOL_H */
net/core/ethtool.c +63 -0
75 lines not on this page · raw message
drivers/net/e1000/e1000_ethtool.c +103 -0
131 lines not on this page · raw message
drivers/net/e1000/e1000.h +1 -0
@@ -343,6 +343,7 @@ struct e1000_adapter {#endif boolean_t smart_power_down;/* phy smart power down */ unsigned long flags; +uint32_t wol_filters; };enum e1000_state_t {
ethtool.c +151 -0
217 lines not on this page · raw message
ethtool-copy.h +13 -0
@@ -52,9 +52,19 @@ struct ethtool_wolinfo {u32 cmd;u32 supported;u32 wolopts; +u32 n_filters;u8 sopass[SOPASS_MAX ];/* SecureOn(tm) password */ }; +#define WOL_FILTER_MAX 256 +/* wake-on-lan flexible filters */ +struct ethtool_wol_filter { +u32 cmd; +u32 index; +u32 len; +u16 mask_val[0 ]; +}; +/* for passing single values */ struct ethtool_value {u32 cmd;
@@ -285,6 +295,8 @@ struct ethtool_stats {#define ETHTOOL_STSO 0x0000001f/* Set TSO enable (ethtool_value) */ #define ETHTOOL_GUFO 0x00000021/* Get UFO enable (ethtool_value) */ #define ETHTOOL_SUFO 0x00000022/* Set UFO enable (ethtool_value) */ +#define ETHTOOL_GWOLFILTER 0x00000025/* Get WOL flex filter */ +#define ETHTOOL_SWOLFILTER 0x00000026/* Set WOL flex filter */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET
@@ -364,5 +376,6 @@ struct ethtool_stats {#define WAKE_ARP (1 << 4)#define WAKE_MAGIC (1 << 5)#define WAKE_MAGICSECURE (1 << 6)/* only meaningful if WAKE_MAGIC */ +#define WAKE_FILTER (1 << 7)#endif /* _LINUX_ETHTOOL_H */