diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.c')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index d20935dc8399..4b4f5bc0e279 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -2922,17 +2922,25 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus, | |||
2922 | { | 2922 | { |
2923 | unsigned int size = lstatus & BD_LENGTH_MASK; | 2923 | unsigned int size = lstatus & BD_LENGTH_MASK; |
2924 | struct page *page = rxb->page; | 2924 | struct page *page = rxb->page; |
2925 | bool last = !!(lstatus & BD_LFLAG(RXBD_LAST)); | ||
2925 | 2926 | ||
2926 | /* Remove the FCS from the packet length */ | 2927 | /* Remove the FCS from the packet length */ |
2927 | if (likely(lstatus & BD_LFLAG(RXBD_LAST))) | 2928 | if (last) |
2928 | size -= ETH_FCS_LEN; | 2929 | size -= ETH_FCS_LEN; |
2929 | 2930 | ||
2930 | if (likely(first)) | 2931 | if (likely(first)) { |
2931 | skb_put(skb, size); | 2932 | skb_put(skb, size); |
2932 | else | 2933 | } else { |
2933 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | 2934 | /* the last fragments' length contains the full frame length */ |
2934 | rxb->page_offset + RXBUF_ALIGNMENT, | 2935 | if (last) |
2935 | size, GFAR_RXB_TRUESIZE); | 2936 | size -= skb->len; |
2937 | |||
2938 | /* in case the last fragment consisted only of the FCS */ | ||
2939 | if (size > 0) | ||
2940 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | ||
2941 | rxb->page_offset + RXBUF_ALIGNMENT, | ||
2942 | size, GFAR_RXB_TRUESIZE); | ||
2943 | } | ||
2936 | 2944 | ||
2937 | /* try reuse page */ | 2945 | /* try reuse page */ |
2938 | if (unlikely(page_count(page) != 1)) | 2946 | if (unlikely(page_count(page) != 1)) |