|
@@ -2932,7 +2932,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id)
|
|
static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
|
|
static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
|
|
struct sk_buff *skb, bool first)
|
|
struct sk_buff *skb, bool first)
|
|
{
|
|
{
|
|
- unsigned int size = lstatus & BD_LENGTH_MASK;
|
|
|
|
|
|
+ int size = lstatus & BD_LENGTH_MASK;
|
|
struct page *page = rxb->page;
|
|
struct page *page = rxb->page;
|
|
bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));
|
|
bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));
|
|
|
|
|
|
@@ -2947,11 +2947,16 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
|
|
if (last)
|
|
if (last)
|
|
size -= skb->len;
|
|
size -= skb->len;
|
|
|
|
|
|
- /* in case the last fragment consisted only of the FCS */
|
|
|
|
|
|
+ /* Add the last fragment if it contains something other than
|
|
|
|
+ * the FCS, otherwise drop it and trim off any part of the FCS
|
|
|
|
+ * that was already received.
|
|
|
|
+ */
|
|
if (size > 0)
|
|
if (size > 0)
|
|
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
|
|
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
|
|
rxb->page_offset + RXBUF_ALIGNMENT,
|
|
rxb->page_offset + RXBUF_ALIGNMENT,
|
|
size, GFAR_RXB_TRUESIZE);
|
|
size, GFAR_RXB_TRUESIZE);
|
|
|
|
+ else if (size < 0)
|
|
|
|
+ pskb_trim(skb, skb->len + size);
|
|
}
|
|
}
|
|
|
|
|
|
/* try reuse page */
|
|
/* try reuse page */
|