net/hns3: add TSO pseudo header calculation compatibility

In kunpeng 920, when process pkts which need TSO, the network driver
need to erase the L4 len value of the TCP TSO pseudo header and
recalculate the pseudo header checksum. kunpeng930 support not need
to erase the L4 len value of the TCP TSO pseudo header.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
This commit is contained in:
Wei Hu (Xavier) 2020-09-22 20:03:17 +08:00 committed by Ferruh Yigit
parent da17b003f3
commit dd1e461182
5 changed files with 92 additions and 32 deletions

View File

@ -2916,6 +2916,7 @@ hns3_get_capability(struct hns3_hw *hw)
hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
hw->intr.coalesce_mode = HNS3_INTR_COALESCE_NON_QL;
hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM;
hw->vlan_mode = HNS3_SW_SHIFT_AND_DISCARD_MODE;
hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN;
return 0;
@ -2932,6 +2933,7 @@ hns3_get_capability(struct hns3_hw *hw)
hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_ALL;
hw->intr.coalesce_mode = HNS3_INTR_COALESCE_QL;
hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US;
hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM;
hw->vlan_mode = HNS3_HW_SHIFT_AND_DISCARD_MODE;
hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN;

View File

@ -416,6 +416,9 @@ struct hns3_queue_intr {
uint8_t gl_unit;
};
#define HNS3_TSO_SW_CAL_PSEUDO_H_CSUM 0
#define HNS3_TSO_HW_CAL_PSEUDO_H_CSUM 1
struct hns3_hw {
struct rte_eth_dev_data *data;
void *io_base;
@ -476,7 +479,23 @@ struct hns3_hw {
uint32_t min_tx_pkt_len;
struct hns3_queue_intr intr;
/*
* tso mode.
* value range:
* HNS3_TSO_SW_CAL_PSEUDO_H_CSUM/HNS3_TSO_HW_CAL_PSEUDO_H_CSUM
*
* - HNS3_TSO_SW_CAL_PSEUDO_H_CSUM
* In this mode, because of the hardware constraint, network driver
* software need erase the L4 len value of the TCP pseudo header
* and recalculate the TCP pseudo header checksum of packets that
* need TSO.
*
* - HNS3_TSO_HW_CAL_PSEUDO_H_CSUM
* In this mode, hardware support recalculate the TCP pseudo header
* checksum of packets that need TSO, so network driver software
* not need to recalculate it.
*/
uint8_t tso_mode;
/*
* vlan mode.
* value range:

View File

@ -1165,6 +1165,7 @@ hns3vf_get_capability(struct hns3_hw *hw)
hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
hw->intr.coalesce_mode = HNS3_INTR_COALESCE_NON_QL;
hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM;
hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN;
return 0;
}
@ -1180,6 +1181,7 @@ hns3vf_get_capability(struct hns3_hw *hw)
hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_ALL;
hw->intr.coalesce_mode = HNS3_INTR_COALESCE_QL;
hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US;
hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM;
hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN;
return 0;

View File

@ -2188,6 +2188,7 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
txq->io_tail_reg = (volatile void *)((char *)txq->io_base +
HNS3_RING_TX_TAIL_REG);
txq->min_tx_pkt_len = hw->min_tx_pkt_len;
txq->tso_mode = hw->tso_mode;
txq->over_length_pkt_cnt = 0;
txq->exceed_limit_bd_pkt_cnt = 0;
txq->exceed_limit_bd_reassem_fail = 0;
@ -2858,47 +2859,66 @@ hns3_vld_vlan_chk(struct hns3_tx_queue *txq, struct rte_mbuf *m)
}
#endif
static int
hns3_prep_pkt_proc(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m)
{
int ret;
#ifdef RTE_LIBRTE_ETHDEV_DEBUG
ret = rte_validate_tx_offload(m);
if (ret != 0) {
rte_errno = -ret;
return ret;
}
ret = hns3_vld_vlan_chk(tx_queue, m);
if (ret != 0) {
rte_errno = EINVAL;
return ret;
}
#endif
if (hns3_pkt_is_tso(m)) {
if (hns3_pkt_need_linearized(m, m->nb_segs,
tx_queue->max_non_tso_bd_num) ||
hns3_check_tso_pkt_valid(m)) {
rte_errno = EINVAL;
return -EINVAL;
}
if (tx_queue->tso_mode != HNS3_TSO_SW_CAL_PSEUDO_H_CSUM) {
/*
* (tso mode != HNS3_TSO_SW_CAL_PSEUDO_H_CSUM) means
* hardware support recalculate the TCP pseudo header
* checksum of packets that need TSO, so network driver
* software not need to recalculate it.
*/
hns3_outer_header_cksum_prepare(m);
return 0;
}
}
ret = rte_net_intel_cksum_prepare(m);
if (ret != 0) {
rte_errno = -ret;
return ret;
}
hns3_outer_header_cksum_prepare(m);
return 0;
}
uint16_t
hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
struct hns3_tx_queue *txq;
struct rte_mbuf *m;
uint16_t i;
int ret;
txq = (struct hns3_tx_queue *)tx_queue;
for (i = 0; i < nb_pkts; i++) {
m = tx_pkts[i];
if (hns3_pkt_is_tso(m) &&
(hns3_pkt_need_linearized(m, m->nb_segs,
txq->max_non_tso_bd_num) ||
hns3_check_tso_pkt_valid(m))) {
rte_errno = EINVAL;
if (hns3_prep_pkt_proc(tx_queue, m))
return i;
}
#ifdef RTE_LIBRTE_ETHDEV_DEBUG
ret = rte_validate_tx_offload(m);
if (ret != 0) {
rte_errno = -ret;
return i;
}
if (hns3_vld_vlan_chk(txq, m)) {
rte_errno = EINVAL;
return i;
}
#endif
ret = rte_net_intel_cksum_prepare(m);
if (ret != 0) {
rte_errno = -ret;
return i;
}
hns3_outer_header_cksum_prepare(m);
}
return i;

View File

@ -366,6 +366,23 @@ struct hns3_tx_queue {
uint16_t tx_rs_thresh;
struct rte_mbuf **free;
/*
* tso mode.
* value range:
* HNS3_TSO_SW_CAL_PSEUDO_H_CSUM/HNS3_TSO_HW_CAL_PSEUDO_H_CSUM
*
* - HNS3_TSO_SW_CAL_PSEUDO_H_CSUM
* In this mode, because of the hardware constraint, network driver
* software need erase the L4 len value of the TCP pseudo header
* and recalculate the TCP pseudo header checksum of packets that
* need TSO.
*
* - HNS3_TSO_HW_CAL_PSEUDO_H_CSUM
* In this mode, hardware support recalculate the TCP pseudo header
* checksum of packets that need TSO, so network driver software
* not need to recalculate it.
*/
uint8_t tso_mode;
/*
* The minimum length of the packet supported by hardware in the Tx
* direction.