aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFuyun Liang <liangfuyun1@huawei.com>2018-10-16 07:58:50 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-16 13:09:59 -0400
commit1e8a7977d09ffb487f7327f1e10df48e5294aaa5 (patch)
treeb58ab8639fe3b3feeeefa83fbc9d8579b6d6df82
parent5188f218fc860da15755bfa5cc357baf2114d586 (diff)
net: hns3: add handling for big TX fragment
This patch unifies big tx fragment handling for tso and non-tso case. Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 288d5277f377..3fb8e483a945 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -985,10 +985,13 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
985 u32 ol_type_vlan_len_msec = 0; 985 u32 ol_type_vlan_len_msec = 0;
986 u16 bdtp_fe_sc_vld_ra_ri = 0; 986 u16 bdtp_fe_sc_vld_ra_ri = 0;
987 struct skb_frag_struct *frag; 987 struct skb_frag_struct *frag;
988 unsigned int frag_buf_num;
988 u32 type_cs_vlan_tso = 0; 989 u32 type_cs_vlan_tso = 0;
989 struct sk_buff *skb; 990 struct sk_buff *skb;
990 u16 inner_vtag = 0; 991 u16 inner_vtag = 0;
991 u16 out_vtag = 0; 992 u16 out_vtag = 0;
993 unsigned int k;
994 int sizeoflast;
992 u32 paylen = 0; 995 u32 paylen = 0;
993 dma_addr_t dma; 996 dma_addr_t dma;
994 u16 mss = 0; 997 u16 mss = 0;
@@ -996,16 +999,6 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
996 u8 il4_proto; 999 u8 il4_proto;
997 int ret; 1000 int ret;
998 1001
999 /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */
1000 desc_cb->priv = priv;
1001 desc_cb->length = size;
1002 desc_cb->type = type;
1003
1004 /* now, fill the descriptor */
1005 desc->tx.send_size = cpu_to_le16((u16)size);
1006 hns3_set_txbd_baseinfo(&bdtp_fe_sc_vld_ra_ri, frag_end);
1007 desc->tx.bdtp_fe_sc_vld_ra_ri = cpu_to_le16(bdtp_fe_sc_vld_ra_ri);
1008
1009 if (type == DESC_TYPE_SKB) { 1002 if (type == DESC_TYPE_SKB) {
1010 skb = (struct sk_buff *)priv; 1003 skb = (struct sk_buff *)priv;
1011 paylen = skb->len; 1004 paylen = skb->len;
@@ -1058,11 +1051,35 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
1058 return -ENOMEM; 1051 return -ENOMEM;
1059 } 1052 }
1060 1053
1061 desc_cb->dma = dma; 1054 frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
1062 desc->addr = cpu_to_le64(dma); 1055 sizeoflast = size % HNS3_MAX_BD_SIZE;
1056 sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;
1057
1058 /* When frag size is bigger than hardware limit, split this frag */
1059 for (k = 0; k < frag_buf_num; k++) {
1060 /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */
1061 desc_cb->priv = priv;
1062 desc_cb->length = (k == frag_buf_num - 1) ?
1063 sizeoflast : HNS3_MAX_BD_SIZE;
1064 desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k;
1065 desc_cb->type = (type == DESC_TYPE_SKB && !k) ?
1066 DESC_TYPE_SKB : DESC_TYPE_PAGE;
1067
1068 /* now, fill the descriptor */
1069 desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k);
1070 desc->tx.send_size = cpu_to_le16((u16)desc_cb->length);
1071 hns3_set_txbd_baseinfo(&bdtp_fe_sc_vld_ra_ri,
1072 frag_end && (k == frag_buf_num - 1) ?
1073 1 : 0);
1074 desc->tx.bdtp_fe_sc_vld_ra_ri =
1075 cpu_to_le16(bdtp_fe_sc_vld_ra_ri);
1076
1077 /* move ring pointer to next.*/
1078 ring_ptr_move_fw(ring, next_to_use);
1063 1079
1064 /* move ring pointer to next.*/ 1080 desc_cb = &ring->desc_cb[ring->next_to_use];
1065 ring_ptr_move_fw(ring, next_to_use); 1081 desc = &ring->desc[ring->next_to_use];
1082 }
1066 1083
1067 return 0; 1084 return 0;
1068} 1085}