@@ -419,6 +419,7 @@ hns3_get_caps_name(uint32_t caps_id)
} dev_caps[] = {
{ HNS3_CAPS_FD_QUEUE_REGION_B, "fd_queue_region" },
{ HNS3_CAPS_PTP_B, "ptp" },
+ { HNS3_CAPS_SIMPLE_BD_B, "simple_bd" },
{ HNS3_CAPS_TX_PUSH_B, "tx_push" },
{ HNS3_CAPS_PHY_IMP_B, "phy_imp" },
{ HNS3_CAPS_TQP_TXRX_INDEP_B, "tqp_txrx_indep" },
@@ -489,6 +490,8 @@ hns3_parse_capability(struct hns3_hw *hw,
hns3_warn(hw, "ignore PTP capability due to lack of "
"rxd advanced layout capability.");
}
+ if (hns3_get_bit(caps, HNS3_CAPS_SIMPLE_BD_B))
+ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_SIMPLE_BD_B, 1);
if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B))
hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1);
if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B))
@@ -313,6 +313,7 @@ enum HNS3_CAPS_BITS {
*/
HNS3_CAPS_FD_QUEUE_REGION_B = 2,
HNS3_CAPS_PTP_B,
+ HNS3_CAPS_SIMPLE_BD_B = 5,
HNS3_CAPS_TX_PUSH_B = 6,
HNS3_CAPS_PHY_IMP_B = 7,
HNS3_CAPS_TQP_TXRX_INDEP_B,
@@ -96,6 +96,7 @@ hns3_get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
{HNS3_DEV_SUPPORT_TX_PUSH_B, "TX PUSH"},
{HNS3_DEV_SUPPORT_INDEP_TXRX_B, "INDEP TXRX"},
{HNS3_DEV_SUPPORT_STASH_B, "STASH"},
+ {HNS3_DEV_SUPPORT_SIMPLE_BD_B, "SIMPLE BD"},
{HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, "RXD Advanced Layout"},
{HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, "OUTER UDP CKSUM"},
{HNS3_DEV_SUPPORT_RAS_IMP_B, "RAS IMP"},
@@ -886,6 +886,7 @@ enum hns3_dev_cap {
HNS3_DEV_SUPPORT_TX_PUSH_B,
HNS3_DEV_SUPPORT_INDEP_TXRX_B,
HNS3_DEV_SUPPORT_STASH_B,
+ HNS3_DEV_SUPPORT_SIMPLE_BD_B,
HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B,
HNS3_DEV_SUPPORT_RAS_IMP_B,
@@ -3046,6 +3046,10 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
HNS3_PORT_BASE_VLAN_ENABLE;
else
txq->pvid_sw_shift_en = false;
+
+ if (hns3_dev_get_support(hw, SIMPLE_BD))
+ txq->simple_bd_enable = true;
+
txq->max_non_tso_bd_num = hw->max_non_tso_bd_num;
txq->configured = true;
txq->io_base = (void *)((char *)hw->io_base +
@@ -3162,7 +3166,7 @@ hns3_set_tso(struct hns3_desc *desc, uint32_t paylen, struct rte_mbuf *rxm)
return;
desc->tx.type_cs_vlan_tso_len |= rte_cpu_to_le_32(BIT(HNS3_TXD_TSO_B));
- desc->tx.mss = rte_cpu_to_le_16(rxm->tso_segsz);
+ desc->tx.ckst_mss |= rte_cpu_to_le_16(rxm->tso_segsz);
}
static inline void
@@ -3901,6 +3905,50 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
return i;
}
+static inline int
+hns3_handle_simple_bd(struct hns3_tx_queue *txq, struct hns3_desc *desc,
+ struct rte_mbuf *m)
+{
+#define HNS3_TCP_CSUM_OFFSET 16
+#define HNS3_UDP_CSUM_OFFSET 6
+
+ /*
+ * In HIP09, NIC HW support Tx simple BD mode that the HW will
+ * calculate the checksum from the start position of checksum and fill
+ * the checksum result to the offset position without packet type and
+ * header length of L3/L4.
+ * For non-tunneling packet:
+ * - Tx simple BD support for TCP and UDP checksum.
+ * For tunneling packet:
+ * - Tx simple BD support for inner L4 checksum(except sctp checksum).
+ * - Tx simple BD not support the outer checksum and the inner L3
+ * checksum.
+ * - Besides, Tx simple BD is not support for TSO.
+ */
+ if (txq->simple_bd_enable && !(m->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) &&
+ !(m->ol_flags & RTE_MBUF_F_TX_TCP_SEG) &&
+ !(m->ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) &&
+ ((m->ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_TCP_CKSUM ||
+ (m->ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_UDP_CKSUM)) {
+ /* set checksum start and offset, defined in 2 Bytes */
+ hns3_set_field(desc->tx.type_cs_vlan_tso_len,
+ HNS3_TXD_L4_START_M, HNS3_TXD_L4_START_S,
+ (m->l2_len + m->l3_len) >> HNS3_SIMPLE_BD_UNIT);
+ hns3_set_field(desc->tx.ol_type_vlan_len_msec,
+ HNS3_TXD_L4_CKS_OFFSET_M, HNS3_TXD_L4_CKS_OFFSET_S,
+ (m->ol_flags & RTE_MBUF_F_TX_L4_MASK) ==
+ RTE_MBUF_F_TX_TCP_CKSUM ?
+ HNS3_TCP_CSUM_OFFSET >> HNS3_SIMPLE_BD_UNIT :
+ HNS3_UDP_CSUM_OFFSET >> HNS3_SIMPLE_BD_UNIT);
+
+ hns3_set_bit(desc->tx.ckst_mss, HNS3_TXD_CKST_B, 1);
+
+ return 0;
+ }
+
+ return -ENOTSUP;
+}
+
static int
hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
struct rte_mbuf *m)
@@ -3910,6 +3958,8 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
/* Enable checksum offloading */
if (m->ol_flags & HNS3_TX_CKSUM_OFFLOAD_MASK) {
+ if (hns3_handle_simple_bd(txq, desc, m) == 0)
+ return 0;
/* Fill in tunneling parameters if necessary */
if (hns3_parse_tunneling_params(txq, m, tx_desc_id)) {
txq->dfx_stats.unsupported_tunnel_pkt_cnt++;
@@ -134,6 +134,9 @@
#define HNS3_TXD_L4LEN_S 24
#define HNS3_TXD_L4LEN_M (0xffUL << HNS3_TXD_L4LEN_S)
+#define HNS3_TXD_L4_START_S 8
+#define HNS3_TXD_L4_START_M (0xffff << HNS3_TXD_L4_START_S)
+
#define HNS3_TXD_OL3T_S 0
#define HNS3_TXD_OL3T_M (0x3 << HNS3_TXD_OL3T_S)
#define HNS3_TXD_OVLAN_B 2
@@ -141,6 +144,9 @@
#define HNS3_TXD_TUNTYPE_S 4
#define HNS3_TXD_TUNTYPE_M (0xf << HNS3_TXD_TUNTYPE_S)
+#define HNS3_TXD_L4_CKS_OFFSET_S 8
+#define HNS3_TXD_L4_CKS_OFFSET_M (0xffff << HNS3_TXD_L4_CKS_OFFSET_S)
+
#define HNS3_TXD_BDTYPE_S 0
#define HNS3_TXD_BDTYPE_M (0xf << HNS3_TXD_BDTYPE_S)
#define HNS3_TXD_FE_B 4
@@ -157,10 +163,13 @@
#define HNS3_TXD_MSS_S 0
#define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S)
+#define HNS3_TXD_CKST_B 14
+
#define HNS3_TXD_OL4CS_B 22
#define HNS3_L2_LEN_UNIT 1UL
#define HNS3_L3_LEN_UNIT 2UL
#define HNS3_L4_LEN_UNIT 2UL
+#define HNS3_SIMPLE_BD_UNIT 1UL
#define HNS3_TXD_DEFAULT_BDTYPE 0
#define HNS3_TXD_VLD_CMD (0x1 << HNS3_TXD_VLD_B)
@@ -247,7 +256,7 @@ struct hns3_desc {
uint32_t paylen_fd_dop_ol4cs;
uint16_t tp_fe_sc_vld_ra_ri;
- uint16_t mss;
+ uint16_t ckst_mss;
} tx;
struct {
@@ -488,6 +497,7 @@ struct hns3_tx_queue {
*/
uint16_t udp_cksum_mode:1;
+ /* check whether the simple BD mode is supported */
uint16_t simple_bd_enable:1;
uint16_t tx_push_enable:1; /* check whether the tx push is enabled */
/*