diff options
Diffstat (limited to 'drivers/net/phy/dp83640.c')
-rw-r--r-- | drivers/net/phy/dp83640.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 185b03c08e16..cae3b3b3ea3c 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -20,6 +20,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/crc32.h> #include <linux/ethtool.h> #include <linux/kernel.h> #include <linux/list.h> @@ -787,9 +788,12 @@ static int decode_evnt(struct dp83640_private *dp83640, return parsed; } +#define DP83640_PACKET_HASH_OFFSET 20 +#define DP83640_PACKET_HASH_LEN 10 + static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts) { - u16 *seqid; + u16 *seqid, hash; unsigned int offset = 0; u8 *msgtype, *data = skb_mac_header(skb); @@ -819,11 +823,19 @@ static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts) msgtype = data + offset + OFF_PTP_CONTROL; else msgtype = data + offset; + if (rxts->msgtype != (*msgtype & 0xf)) + return 0; seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); + if (rxts->seqid != ntohs(*seqid)) + return 0; + + hash = ether_crc(DP83640_PACKET_HASH_LEN, + data + offset + DP83640_PACKET_HASH_OFFSET) >> 20; + if (rxts->hash != hash) + return 0; - return rxts->msgtype == (*msgtype & 0xf) && - rxts->seqid == ntohs(*seqid); + return 1; } static void decode_rxts(struct dp83640_private *dp83640, |