net: hns3: refactor function hns3_fill_skb_desc to simplify code

The function hns3_fill_skb_desc is hard to read, this patch
extract 2 functions and add new a struct data to simplify the
code and Improve readability.

Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Peng Li 2021-12-02 16:35:56 +08:00 committed by David S. Miller
parent e6d72f6ac2
commit a1cfb24d01

View file

@ -1544,16 +1544,29 @@ static bool hns3_check_hw_tx_csum(struct sk_buff *skb)
return true;
}
static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
struct sk_buff *skb, struct hns3_desc *desc,
struct hns3_desc_cb *desc_cb)
struct hns3_desc_param {
u32 paylen_ol4cs;
u32 ol_type_vlan_len_msec;
u32 type_cs_vlan_tso;
u16 mss_hw_csum;
u16 inner_vtag;
u16 out_vtag;
};
static void hns3_init_desc_data(struct sk_buff *skb, struct hns3_desc_param *pa)
{
pa->paylen_ol4cs = skb->len;
pa->ol_type_vlan_len_msec = 0;
pa->type_cs_vlan_tso = 0;
pa->mss_hw_csum = 0;
pa->inner_vtag = 0;
pa->out_vtag = 0;
}
static int hns3_handle_vlan_info(struct hns3_enet_ring *ring,
struct sk_buff *skb,
struct hns3_desc_param *param)
{
u32 ol_type_vlan_len_msec = 0;
u32 paylen_ol4cs = skb->len;
u32 type_cs_vlan_tso = 0;
u16 mss_hw_csum = 0;
u16 inner_vtag = 0;
u16 out_vtag = 0;
int ret;
ret = hns3_handle_vtags(ring, skb);
@ -1561,67 +1574,93 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
hns3_ring_stats_update(ring, tx_vlan_err);
return ret;
} else if (ret == HNS3_INNER_VLAN_TAG) {
inner_vtag = skb_vlan_tag_get(skb);
inner_vtag |= (skb->priority << VLAN_PRIO_SHIFT) &
param->inner_vtag = skb_vlan_tag_get(skb);
param->inner_vtag |= (skb->priority << VLAN_PRIO_SHIFT) &
VLAN_PRIO_MASK;
hns3_set_field(type_cs_vlan_tso, HNS3_TXD_VLAN_B, 1);
hns3_set_field(param->type_cs_vlan_tso, HNS3_TXD_VLAN_B, 1);
} else if (ret == HNS3_OUTER_VLAN_TAG) {
out_vtag = skb_vlan_tag_get(skb);
out_vtag |= (skb->priority << VLAN_PRIO_SHIFT) &
param->out_vtag = skb_vlan_tag_get(skb);
param->out_vtag |= (skb->priority << VLAN_PRIO_SHIFT) &
VLAN_PRIO_MASK;
hns3_set_field(ol_type_vlan_len_msec, HNS3_TXD_OVLAN_B,
hns3_set_field(param->ol_type_vlan_len_msec, HNS3_TXD_OVLAN_B,
1);
}
return 0;
}
static int hns3_handle_csum_partial(struct hns3_enet_ring *ring,
struct sk_buff *skb,
struct hns3_desc_cb *desc_cb,
struct hns3_desc_param *param)
{
u8 ol4_proto, il4_proto;
int ret;
if (hns3_check_hw_tx_csum(skb)) {
/* set checksum start and offset, defined in 2 Bytes */
hns3_set_field(param->type_cs_vlan_tso, HNS3_TXD_CSUM_START_S,
skb_checksum_start_offset(skb) >> 1);
hns3_set_field(param->ol_type_vlan_len_msec,
HNS3_TXD_CSUM_OFFSET_S,
skb->csum_offset >> 1);
param->mss_hw_csum |= BIT(HNS3_TXD_HW_CS_B);
return 0;
}
skb_reset_mac_len(skb);
ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_l4_proto_err);
return ret;
}
ret = hns3_set_l2l3l4(skb, ol4_proto, il4_proto,
&param->type_cs_vlan_tso,
&param->ol_type_vlan_len_msec);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_l2l3l4_err);
return ret;
}
ret = hns3_set_tso(skb, &param->paylen_ol4cs, &param->mss_hw_csum,
&param->type_cs_vlan_tso, &desc_cb->send_bytes);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_tso_err);
return ret;
}
return 0;
}
static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
struct sk_buff *skb, struct hns3_desc *desc,
struct hns3_desc_cb *desc_cb)
{
struct hns3_desc_param param;
u8 fd_op;
int ret;
hns3_init_desc_data(skb, &param);
ret = hns3_handle_vlan_info(ring, skb, &param);
if (unlikely(ret < 0))
return ret;
desc_cb->send_bytes = skb->len;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 ol4_proto, il4_proto;
if (hns3_check_hw_tx_csum(skb)) {
/* set checksum start and offset, defined in 2 Bytes */
hns3_set_field(type_cs_vlan_tso, HNS3_TXD_CSUM_START_S,
skb_checksum_start_offset(skb) >> 1);
hns3_set_field(ol_type_vlan_len_msec,
HNS3_TXD_CSUM_OFFSET_S,
skb->csum_offset >> 1);
mss_hw_csum |= BIT(HNS3_TXD_HW_CS_B);
goto out_hw_tx_csum;
}
skb_reset_mac_len(skb);
ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_l4_proto_err);
ret = hns3_handle_csum_partial(ring, skb, desc_cb, &param);
if (ret)
return ret;
}
ret = hns3_set_l2l3l4(skb, ol4_proto, il4_proto,
&type_cs_vlan_tso,
&ol_type_vlan_len_msec);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_l2l3l4_err);
return ret;
}
ret = hns3_set_tso(skb, &paylen_ol4cs, &mss_hw_csum,
&type_cs_vlan_tso, &desc_cb->send_bytes);
if (unlikely(ret < 0)) {
hns3_ring_stats_update(ring, tx_tso_err);
return ret;
}
}
out_hw_tx_csum:
/* Set txbd */
desc->tx.ol_type_vlan_len_msec =
cpu_to_le32(ol_type_vlan_len_msec);
desc->tx.type_cs_vlan_tso_len = cpu_to_le32(type_cs_vlan_tso);
desc->tx.paylen_ol4cs = cpu_to_le32(paylen_ol4cs);
desc->tx.mss_hw_csum = cpu_to_le16(mss_hw_csum);
desc->tx.vlan_tag = cpu_to_le16(inner_vtag);
desc->tx.outer_vlan_tag = cpu_to_le16(out_vtag);
cpu_to_le32(param.ol_type_vlan_len_msec);
desc->tx.type_cs_vlan_tso_len = cpu_to_le32(param.type_cs_vlan_tso);
desc->tx.paylen_ol4cs = cpu_to_le32(param.paylen_ol4cs);
desc->tx.mss_hw_csum = cpu_to_le16(param.mss_hw_csum);
desc->tx.vlan_tag = cpu_to_le16(param.inner_vtag);
desc->tx.outer_vlan_tag = cpu_to_le16(param.out_vtag);
return 0;
}