#define HNS3_UNLIMIT_PROMISC_MODE 0
#define HNS3_LIMIT_PROMISC_MODE 1
+#define HNS3_SPECIAL_PORT_SW_CKSUM_MODE 0
+#define HNS3_SPECIAL_PORT_HW_CKSUM_MODE 1
+
#define HNS3_UC_MACADDR_NUM 128
#define HNS3_VF_UC_MACADDR_NUM 48
#define HNS3_MC_MACADDR_NUM 128
uint8_t drop_stats_mode;
uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */
+ /*
+ * udp checksum mode.
+ * value range:
+ * HNS3_SPECIAL_PORT_HW_CKSUM_MODE/HNS3_SPECIAL_PORT_SW_CKSUM_MODE
+ *
+ * - HNS3_SPECIAL_PORT_SW_CKSUM_MODE
+ * In this mode, HW can not do checksum for special UDP port like
+ * 4789, 4790, 6081 for non-tunnel UDP packets and UDP tunnel
+ * packets without the PKT_TX_TUNEL_MASK in the mbuf. So, PMD need
+ * do the checksum for these packets to avoid a checksum error.
+ *
+ * - HNS3_SPECIAL_PORT_HW_CKSUM_MODE
+ * In this mode, HW does not have the preceding problems and can
+ * directly calculate the checksum of these UDP packets.
+ */
+ uint8_t udp_cksum_mode;
struct hns3_port_base_vlan_config port_base_vlan_cfg;
/*
#include <rte_bus_pci.h>
#include <rte_common.h>
#include <rte_cycles.h>
+#include <rte_geneve.h>
#include <rte_vxlan.h>
#include <ethdev_driver.h>
#include <rte_io.h>
HNS3_RING_TX_TAIL_REG);
txq->min_tx_pkt_len = hw->min_tx_pkt_len;
txq->tso_mode = hw->tso_mode;
+ txq->udp_cksum_mode = hw->udp_cksum_mode;
memset(&txq->basic_stats, 0, sizeof(struct hns3_tx_basic_stats));
memset(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats));
}
#endif
+static uint16_t
+hns3_udp_cksum_help(struct rte_mbuf *m)
+{
+ uint64_t ol_flags = m->ol_flags;
+ uint16_t cksum = 0;
+ uint32_t l4_len;
+
+ if (ol_flags & PKT_TX_IPV4) {
+ struct rte_ipv4_hdr *ipv4_hdr = rte_pktmbuf_mtod_offset(m,
+ struct rte_ipv4_hdr *, m->l2_len);
+ l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - m->l3_len;
+ } else {
+ struct rte_ipv6_hdr *ipv6_hdr = rte_pktmbuf_mtod_offset(m,
+ struct rte_ipv6_hdr *, m->l2_len);
+ l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
+ }
+
+ rte_raw_cksum_mbuf(m, m->l2_len + m->l3_len, l4_len, &cksum);
+
+ cksum = ~cksum;
+ /*
+ * RFC 768:If the computed checksum is zero for UDP, it is transmitted
+ * as all ones
+ */
+ if (cksum == 0)
+ cksum = 0xffff;
+
+ return (uint16_t)cksum;
+}
+
+static bool
+hns3_validate_tunnel_cksum(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m)
+{
+ uint64_t ol_flags = m->ol_flags;
+ struct rte_udp_hdr *udp_hdr;
+ uint16_t dst_port;
+
+ if (tx_queue->udp_cksum_mode == HNS3_SPECIAL_PORT_HW_CKSUM_MODE ||
+ ol_flags & PKT_TX_TUNNEL_MASK ||
+ (ol_flags & PKT_TX_L4_MASK) != PKT_TX_UDP_CKSUM)
+ return true;
+ /*
+ * A UDP packet with the same dst_port as VXLAN\VXLAN_GPE\GENEVE will
+ * be recognized as a tunnel packet in HW. In this case, if UDP CKSUM
+ * offload is set and the tunnel mask has not been set, the CKSUM will
+ * be wrong since the header length is wrong and driver should complete
+ * the CKSUM to avoid CKSUM error.
+ */
+ udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
+ m->l2_len + m->l3_len);
+ dst_port = rte_be_to_cpu_16(udp_hdr->dst_port);
+ switch (dst_port) {
+ case RTE_VXLAN_DEFAULT_PORT:
+ case RTE_VXLAN_GPE_DEFAULT_PORT:
+ case RTE_GENEVE_DEFAULT_PORT:
+ udp_hdr->dgram_cksum = hns3_udp_cksum_help(m);
+ m->ol_flags = ol_flags & ~PKT_TX_L4_MASK;
+ return false;
+ default:
+ return true;
+ }
+}
+
static int
hns3_prep_pkt_proc(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m)
{
return ret;
}
+ if (!hns3_validate_tunnel_cksum(tx_queue, m))
+ return 0;
+
hns3_outer_header_cksum_prepare(m);
return 0;
* not need to recalculate it.
*/
uint8_t tso_mode;
+ /*
+ * udp checksum mode.
+ * value range:
+ * HNS3_SPECIAL_PORT_HW_CKSUM_MODE/HNS3_SPECIAL_PORT_SW_CKSUM_MODE
+ *
+ * - HNS3_SPECIAL_PORT_SW_CKSUM_MODE
+ * In this mode, HW can not do checksum for special UDP port like
+ * 4789, 4790, 6081 for non-tunnel UDP packets and UDP tunnel
+ * packets without the PKT_TX_TUNEL_MASK in the mbuf. So, PMD need
+ * do the checksum for these packets to avoid a checksum error.
+ *
+ * - HNS3_SPECIAL_PORT_HW_CKSUM_MODE
+ * In this mode, HW does not have the preceding problems and can
+ * directly calculate the checksum of these UDP packets.
+ */
+ uint8_t udp_cksum_mode;
/*
* The minimum length of the packet supported by hardware in the Tx
* direction.