X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_rxtx_vec_neon.c;h=c541f537c7787f5e975280853f957bd7e4297e9b;hb=f17c5d7abd91a4c70a8ca82f885e2f930980d22d;hp=4d6f057e7332ef0a4dbcfb6a7cbb0b3b5c42bd1a;hpb=f1657f97e4753efc77a331bb8aecb4f21869d7f7;p=dpdk.git diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c index 4d6f057e73..c541f537c7 100644 --- a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c +++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c @@ -3,7 +3,7 @@ */ #include -#include +#include #include #include @@ -83,16 +83,19 @@ ixgbe_rxq_rearm(struct ixgbe_rx_queue *rxq) static inline void desc_to_olflags_v(uint8x16x2_t sterr_tmp1, uint8x16x2_t sterr_tmp2, - uint8x16_t staterr, uint8_t vlan_flags, struct rte_mbuf **rx_pkts) + uint8x16_t staterr, uint8_t vlan_flags, uint16_t udp_p_flag, + struct rte_mbuf **rx_pkts) { - uint8x16_t ptype; - uint8x16_t vtag; + uint16_t udp_p_flag_hi; + uint8x16_t ptype, udp_csum_skip; + uint32x4_t temp_udp_csum_skip = {0, 0, 0, 0}; + uint8x16_t vtag_lo, vtag_hi, vtag; uint8x16_t temp_csum; uint32x4_t csum = {0, 0, 0, 0}; union { - uint8_t e[4]; - uint32_t word; + uint16_t e[4]; + uint64_t word; } vol; const uint8x16_t rsstype_msk = { @@ -119,19 +122,51 @@ desc_to_olflags_v(uint8x16x2_t sterr_tmp1, uint8x16x2_t sterr_tmp2, (IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE) >> 24}; /* map vlan present (0x8), IPE (0x2), L4E (0x1) to ol_flags */ - const uint8x16_t vlan_csum_map = { - 0, - PKT_RX_L4_CKSUM_BAD, + const uint8x16_t vlan_csum_map_lo = { + PKT_RX_IP_CKSUM_GOOD, + PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD, PKT_RX_IP_CKSUM_BAD, PKT_RX_IP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD, 0, 0, 0, 0, - vlan_flags, - vlan_flags | PKT_RX_L4_CKSUM_BAD, + vlan_flags | PKT_RX_IP_CKSUM_GOOD, + vlan_flags | PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD, vlan_flags | PKT_RX_IP_CKSUM_BAD, vlan_flags | PKT_RX_IP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD, 0, 0, 0, 0}; + const uint8x16_t vlan_csum_map_hi = { + PKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t), 0, + PKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t), 0, + 0, 0, 0, 0, + PKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t), 0, + PKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t), 0, + 0, 0, 0, 0}; + + /* change mask from 0x200(IXGBE_RXDADV_PKTTYPE_UDP) to 0x2 */ + udp_p_flag_hi = udp_p_flag >> 8; + + /* mask everything except UDP header present if specified */ + const uint8x16_t udp_hdr_p_msk = { + 0, 0, 0, 0, + udp_p_flag_hi, udp_p_flag_hi, udp_p_flag_hi, udp_p_flag_hi, + 0, 0, 0, 0, + 0, 0, 0, 0}; + + const uint8x16_t udp_csum_bad_shuf = { + 0xFF, ~(uint8_t)PKT_RX_L4_CKSUM_BAD, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}; + ptype = vzipq_u8(sterr_tmp1.val[0], sterr_tmp2.val[0]).val[0]; + + /* save the UDP header present information */ + udp_csum_skip = vandq_u8(ptype, udp_hdr_p_msk); + + /* move UDP header present information to low 32bits */ + temp_udp_csum_skip = vcopyq_laneq_u32(temp_udp_csum_skip, 0, + vreinterpretq_u32_u8(udp_csum_skip), 1); + ptype = vandq_u8(ptype, rsstype_msk); ptype = vqtbl1q_u8(rss_flags, ptype); @@ -150,11 +185,25 @@ desc_to_olflags_v(uint8x16x2_t sterr_tmp1, uint8x16x2_t sterr_tmp2, csum = vsetq_lane_u32(vgetq_lane_u32(vreinterpretq_u32_u8(temp_csum), 3), csum, 0); vtag = vorrq_u8(vreinterpretq_u8_u32(csum), vtag); - /* convert VP, IPE, L4E to ol_flags */ - vtag = vqtbl1q_u8(vlan_csum_map, vtag); - vtag = vorrq_u8(ptype, vtag); + /* convert L4 checksum correct type to vtag_hi */ + vtag_hi = vqtbl1q_u8(vlan_csum_map_hi, vtag); + vtag_hi = vshrq_n_u8(vtag_hi, 7); + + /* convert VP, IPE, L4E to vtag_lo */ + vtag_lo = vqtbl1q_u8(vlan_csum_map_lo, vtag); + vtag_lo = vorrq_u8(ptype, vtag_lo); - vol.word = vgetq_lane_u32(vreinterpretq_u32_u8(vtag), 0); + /* convert the UDP header present 0x2 to 0x1 for aligning with each + * PKT_RX_L4_CKSUM_BAD value in low byte of 8 bits word ol_flag in + * vtag_lo (4x8). Then mask out the bad checksum value by shuffle and + * bit-mask. + */ + udp_csum_skip = vshrq_n_u8(vreinterpretq_u8_u32(temp_udp_csum_skip), 1); + udp_csum_skip = vqtbl1q_u8(udp_csum_bad_shuf, udp_csum_skip); + vtag_lo = vandq_u8(vtag_lo, udp_csum_skip); + + vtag = vzipq_u8(vtag_lo, vtag_hi).val[0]; + vol.word = vgetq_lane_u64(vreinterpretq_u64_u8(vtag), 0); rx_pkts[0]->ol_flags = vol.e[0]; rx_pkts[1]->ol_flags = vol.e[1]; @@ -254,6 +303,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, uint16x8_t crc_adjust = {0, 0, rxq->crc_len, 0, rxq->crc_len, 0, 0, 0}; uint8_t vlan_flags; + uint16_t udp_p_flag = 0; /* Rx Descriptor UDP header present */ /* nb_pkts has to be floor-aligned to RTE_IXGBE_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_IXGBE_DESCS_PER_LOOP); @@ -278,6 +328,9 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, rte_cpu_to_le_32(IXGBE_RXDADV_STAT_DD))) return 0; + if (rxq->rx_udp_csum_zero_err) + udp_p_flag = IXGBE_RXDADV_PKTTYPE_UDP; + /* Cache is empty -> need to scan the buffer rings, but first move * the next 'n' mbufs into the cache */ @@ -349,7 +402,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, /* set ol_flags with vlan packet type */ desc_to_olflags_v(sterr_tmp1, sterr_tmp2, staterr, vlan_flags, - &rx_pkts[pos]); + udp_p_flag, &rx_pkts[pos]); /* D.2 pkt 3,4 set in_port/nb_seg and remove crc */ tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb4), crc_adjust); @@ -625,11 +678,5 @@ ixgbe_txq_vec_setup(struct ixgbe_tx_queue *txq) int __rte_cold ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev) { - struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; - - /* no csum error report support */ - if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) - return -1; - return ixgbe_rx_vec_dev_conf_condition_check_default(dev); }