diff options
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index ac06b01fe934..e280013afa63 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -1820,7 +1820,6 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, struct page *page, *head_page; struct dpaa_bp *dpaa_bp; void *vaddr, *sg_vaddr; - int frag_off, frag_len; struct sk_buff *skb; dma_addr_t sg_addr; int page_offset; @@ -1863,6 +1862,11 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, * on Tx, if extra headers are added. */ WARN_ON(fd_off != priv->rx_headroom); + /* The offset to data start within the buffer holding + * the SGT should always be equal to the offset to data + * start within the first buffer holding the frame. + */ + WARN_ON_ONCE(fd_off != qm_sg_entry_get_off(&sgt[i])); skb_reserve(skb, fd_off); skb_put(skb, qm_sg_entry_get_len(&sgt[i])); } else { @@ -1876,21 +1880,23 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, page = virt_to_page(sg_vaddr); head_page = virt_to_head_page(sg_vaddr); - /* Compute offset in (possibly tail) page */ + /* Compute offset of sg_vaddr in (possibly tail) page */ page_offset = ((unsigned long)sg_vaddr & (PAGE_SIZE - 1)) + (page_address(page) - page_address(head_page)); - /* page_offset only refers to the beginning of sgt[i]; - * but the buffer itself may have an internal offset. + + /* Non-initial SGT entries should not have a buffer + * offset. */ - frag_off = qm_sg_entry_get_off(&sgt[i]) + page_offset; - frag_len = qm_sg_entry_get_len(&sgt[i]); + WARN_ON_ONCE(qm_sg_entry_get_off(&sgt[i])); + /* skb_add_rx_frag() does no checking on the page; if * we pass it a tail page, we'll end up with - * bad page accounting and eventually with segafults. + * bad page accounting and eventually with segfaults. */ - skb_add_rx_frag(skb, i - 1, head_page, frag_off, - frag_len, dpaa_bp->size); + skb_add_rx_frag(skb, i - 1, head_page, page_offset, + qm_sg_entry_get_len(&sgt[i]), + dpaa_bp->size); } /* Update the pool count for the current {cpu x bpool} */ |