|
@@ -3850,13 +3850,22 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
|
|
|
|
|
|
length = le16_to_cpu(rx_desc->length);
|
|
|
/* !EOP means multiple descriptors were used to store a single
|
|
|
- * packet, also make sure the frame isn't just CRC only */
|
|
|
- if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
|
|
|
+ * packet, if thats the case we need to toss it. In fact, we
|
|
|
+ * to toss every packet with the EOP bit clear and the next
|
|
|
+ * frame that _does_ have the EOP bit set, as it is by
|
|
|
+ * definition only a frame fragment
|
|
|
+ */
|
|
|
+ if (unlikely(!(status & E1000_RXD_STAT_EOP)))
|
|
|
+ adapter->discarding = true;
|
|
|
+
|
|
|
+ if (adapter->discarding) {
|
|
|
/* All receives must fit into a single buffer */
|
|
|
E1000_DBG("%s: Receive packet consumed multiple"
|
|
|
" buffers\n", netdev->name);
|
|
|
/* recycle */
|
|
|
buffer_info->skb = skb;
|
|
|
+ if (status & E1000_RXD_STAT_EOP)
|
|
|
+ adapter->discarding = false;
|
|
|
goto next_desc;
|
|
|
}
|
|
|
|