From: Yunsheng Lin linyunsheng@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
------------------------------------
when the fraglist skb headlen is larger than zero, current code still handle the fraglist skb linear data as frag data, which may cause tx error.
This patch adds a new DESC_TYPE_FRAGLIST_SKB type to handle the mapping and unmapping of the fraglist skb linear data buffer.
Signed-off-by: Yunsheng Lin linyunsheng@huawei.com Reviewed-by: Peng Li lipeng321@huawei.com Reviewed-by: Weiwei Deng dengweiwei@huawei.com Reviewed-by: Zhaohui Zhong zhongzhaohui@huawei.com Reviewed-by: Junxing Chen chenjunxin1@huawei.com Reviewed-by: Zhong Zhaohui zhongzhaohui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index c5ee51d..f795bfd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -81,6 +81,7 @@
enum hns_desc_type { DESC_TYPE_SKB, + DESC_TYPE_FRAGLIST_SKB, DESC_TYPE_PAGE, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index eb24440..b63355a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1109,6 +1109,10 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, return ret;
dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); + } else if (type == DESC_TYPE_FRAGLIST_SKB) { + struct sk_buff *skb = (struct sk_buff *)priv; + + dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); } else { frag = (struct skb_frag_struct *)priv; dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE); @@ -1452,7 +1456,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) goto out;
skb_walk_frags(skb, frag_skb) { - ret = hns3_fill_skb_to_desc(ring, frag_skb, DESC_TYPE_PAGE); + ret = hns3_fill_skb_to_desc(ring, frag_skb, + DESC_TYPE_FRAGLIST_SKB); if (unlikely(ret < 0)) goto fill_err;
@@ -2408,7 +2413,7 @@ static int hns3_map_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb) static void hns3_unmap_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb) { - if (cb->type == DESC_TYPE_SKB) + if (cb->type == DESC_TYPE_SKB || cb->type == DESC_TYPE_FRAGLIST_SKB) dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length, ring_to_dma_dir(ring)); else if (cb->length)