}
 
 static int decode_evnt(struct dp83640_private *dp83640,
-                      void *data, u16 ests)
+                      void *data, int len, u16 ests)
 {
        struct phy_txts *phy_txts;
        struct ptp_clock_event event;
        int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK;
        u16 ext_status = 0;
 
+       /* calculate length of the event timestamp status message */
+       if (ests & MULT_EVNT)
+               parsed = (words + 2) * sizeof(u16);
+       else
+               parsed = (words + 1) * sizeof(u16);
+
+       /* check if enough data is available */
+       if (len < parsed)
+               return len;
+
        if (ests & MULT_EVNT) {
                ext_status = *(u16 *) data;
                data += sizeof(ext_status);
                dp83640->edata.ns_lo = phy_txts->ns_lo;
        }
 
-       if (ext_status) {
-               parsed = words + 2;
-       } else {
-               parsed = words + 1;
+       if (!ext_status) {
                i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT;
                ext_status = exts_chan_to_edata(i);
        }
                }
        }
 
-       return parsed * sizeof(u16);
+       return parsed;
 }
 
 static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
                        decode_txts(dp83640, phy_txts);
                        size = sizeof(*phy_txts);
 
-               } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) {
+               } else if (PSF_EVNT == type) {
 
-                       size = decode_evnt(dp83640, ptr, ests);
+                       size = decode_evnt(dp83640, ptr, len, ests);
 
                } else {
                        size = 0;