X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fice_rxtx.c;h=220537741d6c4ec9bdeaed1af2f5a0dad4a53bce;hb=1bb4a528c41f4af4847bd3d58cc2b2b9f1ec9a27;hp=ee576c362a39bdaacef60cd4fcaaf1c0b64c4c6f;hpb=c3d9ed69ffc32c3dc9239a5c2c64e5ee05032bf5;p=dpdk.git diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c index ee576c362a..220537741d 100644 --- a/drivers/net/ice/ice_rxtx.c +++ b/drivers/net/ice/ice_rxtx.c @@ -2,12 +2,13 @@ * Copyright(c) 2018 Intel Corporation */ -#include +#include #include #include #include "rte_pmd_ice.h" #include "ice_rxtx.h" +#include "ice_rxtx_vec_common.h" #define ICE_TX_CKSUM_OFFLOAD_MASK ( \ PKT_TX_IP_CKSUM | \ @@ -26,6 +27,40 @@ uint64_t rte_net_ice_dynflag_proto_xtr_ipv6_flow_mask; uint64_t rte_net_ice_dynflag_proto_xtr_tcp_mask; uint64_t rte_net_ice_dynflag_proto_xtr_ip_offset_mask; +static int +ice_monitor_callback(const uint64_t value, + const uint64_t arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused) +{ + const uint64_t m = rte_cpu_to_le_16(1 << ICE_RX_FLEX_DESC_STATUS0_DD_S); + /* + * we expect the DD bit to be set to 1 if this descriptor was already + * written to. + */ + return (value & m) == m ? -1 : 0; +} + +int +ice_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond *pmc) +{ + volatile union ice_rx_flex_desc *rxdp; + struct ice_rx_queue *rxq = rx_queue; + uint16_t desc; + + desc = rxq->rx_tail; + rxdp = &rxq->rx_ring[desc]; + /* watch for changes in status bit */ + pmc->addr = &rxdp->wb.status_error0; + + /* comparison callback */ + pmc->fn = ice_monitor_callback; + + /* register is 16-bit */ + pmc->size = sizeof(uint16_t); + + return 0; +} + + static inline uint8_t ice_proto_xtr_type_to_rxdid(uint8_t xtr_type) { @@ -43,6 +78,28 @@ ice_proto_xtr_type_to_rxdid(uint8_t xtr_type) rxdid_map[xtr_type] : ICE_RXDID_COMMS_OVS; } +static inline void +ice_rxd_to_pkt_fields_by_comms_generic(__rte_unused struct ice_rx_queue *rxq, + struct rte_mbuf *mb, + volatile union ice_rx_flex_desc *rxdp) +{ + volatile struct ice_32b_rx_flex_desc_comms *desc = + (volatile struct ice_32b_rx_flex_desc_comms *)rxdp; + uint16_t stat_err = rte_le_to_cpu_16(desc->status_error0); + + if (likely(stat_err & (1 << ICE_RX_FLEX_DESC_STATUS0_RSS_VALID_S))) { + mb->ol_flags |= PKT_RX_RSS_HASH; + mb->hash.rss = rte_le_to_cpu_32(desc->rss_hash); + } + +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + if (desc->flow_id != 0xFFFFFFFF) { + mb->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID; + mb->hash.fdir.hi = rte_le_to_cpu_32(desc->flow_id); + } +#endif +} + static inline void ice_rxd_to_pkt_fields_by_comms_ovs(__rte_unused struct ice_rx_queue *rxq, struct rte_mbuf *mb, @@ -148,7 +205,7 @@ ice_rxd_to_pkt_fields_by_comms_aux_v2(struct ice_rx_queue *rxq, #endif } -static void +void ice_select_rxd_to_pkt_fields_handler(struct ice_rx_queue *rxq, uint32_t rxdid) { switch (rxdid) { @@ -182,6 +239,10 @@ ice_select_rxd_to_pkt_fields_handler(struct ice_rx_queue *rxq, uint32_t rxdid) rxq->rxd_to_pkt_fields = ice_rxd_to_pkt_fields_by_comms_aux_v2; break; + case ICE_RXDID_COMMS_GENERIC: + rxq->rxd_to_pkt_fields = ice_rxd_to_pkt_fields_by_comms_generic; + break; + case ICE_RXDID_COMMS_OVS: rxq->rxd_to_pkt_fields = ice_rxd_to_pkt_fields_by_comms_ovs; break; @@ -202,41 +263,55 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq) struct ice_vsi *vsi = rxq->vsi; struct ice_hw *hw = ICE_VSI_TO_HW(vsi); struct ice_pf *pf = ICE_VSI_TO_PF(vsi); - struct rte_eth_dev *dev = ICE_VSI_TO_ETH_DEV(rxq->vsi); + struct rte_eth_dev_data *dev_data = rxq->vsi->adapter->pf.dev_data; struct ice_rlan_ctx rx_ctx; enum ice_status err; - uint16_t buf_size, len; - struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + uint16_t buf_size; + struct rte_eth_rxmode *rxmode = &dev_data->dev_conf.rxmode; uint32_t rxdid = ICE_RXDID_COMMS_OVS; uint32_t regval; + struct ice_adapter *ad = rxq->vsi->adapter; + uint32_t frame_size = dev_data->mtu + ICE_ETH_OVERHEAD; /* Set buffer size as the head split is disabled. */ buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM); rxq->rx_hdr_len = 0; rxq->rx_buf_len = RTE_ALIGN(buf_size, (1 << ICE_RLAN_CTX_DBUF_S)); - len = ICE_SUPPORT_CHAIN_NUM * rxq->rx_buf_len; - rxq->max_pkt_len = RTE_MIN(len, - dev->data->dev_conf.rxmode.max_rx_pkt_len); + rxq->max_pkt_len = + RTE_MIN((uint32_t)ICE_SUPPORT_CHAIN_NUM * rxq->rx_buf_len, + frame_size); if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { - if (rxq->max_pkt_len <= RTE_ETHER_MAX_LEN || + if (rxq->max_pkt_len <= ICE_ETH_MAX_LEN || rxq->max_pkt_len > ICE_FRAME_SIZE_MAX) { PMD_DRV_LOG(ERR, "maximum packet length must " "be larger than %u and smaller than %u," "as jumbo frame is enabled", - (uint32_t)RTE_ETHER_MAX_LEN, + (uint32_t)ICE_ETH_MAX_LEN, (uint32_t)ICE_FRAME_SIZE_MAX); return -EINVAL; } } else { if (rxq->max_pkt_len < RTE_ETHER_MIN_LEN || - rxq->max_pkt_len > RTE_ETHER_MAX_LEN) { + rxq->max_pkt_len > ICE_ETH_MAX_LEN) { PMD_DRV_LOG(ERR, "maximum packet length must be " "larger than %u and smaller than %u, " "as jumbo frame is disabled", (uint32_t)RTE_ETHER_MIN_LEN, - (uint32_t)RTE_ETHER_MAX_LEN); + (uint32_t)ICE_ETH_MAX_LEN); + return -EINVAL; + } + } + + if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) { + /* Register mbuf field and flag for Rx timestamp */ + err = rte_mbuf_dyn_rx_timestamp_register( + &ice_timestamp_dynfield_offset, + &ice_timestamp_dynflag); + if (err) { + PMD_DRV_LOG(ERR, + "Cannot register mbuf field/flag for timestamp"); return -EINVAL; } } @@ -293,6 +368,9 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq) regval |= (0x03 << QRXFLXP_CNTXT_RXDID_PRIO_S) & QRXFLXP_CNTXT_RXDID_PRIO_M; + if (ad->ptp_ena || rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) + regval |= QRXFLXP_CNTXT_TS_M; + ICE_WRITE_REG(hw, QRXFLXP_CNTXT(rxq->reg_idx), regval); err = ice_clear_rxq_ctx(hw, rxq->reg_idx); @@ -308,12 +386,9 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq) return -EINVAL; } - buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mp) - - RTE_PKTMBUF_HEADROOM); - /* Check if scattered RX needs to be used. */ - if (rxq->max_pkt_len > buf_size) - dev->data->scattered_rx = 1; + if (frame_size > buf_size) + dev_data->scattered_rx = 1; rxq->qrx_tail = hw->hw_addr + QRX_TAIL(rxq->reg_idx); @@ -628,6 +703,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) tx_ctx.tso_ena = 1; /* tso enable */ tx_ctx.tso_qnum = txq->reg_idx; /* index for tso state structure */ tx_ctx.legacy_int = 1; /* Legacy or Advanced Host Interface */ + tx_ctx.tsyn_ena = 1; ice_set_ctx(hw, (uint8_t *)&tx_ctx, txq_elem->txqs[0].txq_ctx, ice_tlan_ctx_info); @@ -675,7 +751,7 @@ ice_fdir_program_hw_rx_queue(struct ice_rx_queue *rxq) rx_ctx.hbuf = rxq->rx_hdr_len >> ICE_RLAN_CTX_HBUF_S; rx_ctx.dtype = 0; /* No Header Split mode */ rx_ctx.dsize = 1; /* 32B descriptors */ - rx_ctx.rxmax = RTE_ETHER_MAX_LEN; + rx_ctx.rxmax = ICE_ETH_MAX_LEN; /* TPH: Transaction Layer Packet (TLP) processing hints */ rx_ctx.tphrdesc_ena = 1; rx_ctx.tphwdesc_ena = 1; @@ -1006,6 +1082,7 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, uint32_t ring_size; uint16_t len; int use_def_burst_func = 1; + uint64_t offloads; if (nb_desc % ICE_ALIGN_RING_DESC != 0 || nb_desc > ICE_MAX_RING_DESC || @@ -1015,6 +1092,8 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, return -EINVAL; } + offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads; + /* Free memory if needed */ if (dev->data->rx_queues[queue_idx]) { ice_rx_queue_release(dev->data->rx_queues[queue_idx]); @@ -1035,6 +1114,7 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, rxq->nb_rx_desc = nb_desc; rxq->rx_free_thresh = rx_conf->rx_free_thresh; rxq->queue_id = queue_idx; + rxq->offloads = offloads; rxq->reg_idx = vsi->base_queue + queue_idx; rxq->port_id = dev->data->port_id; @@ -1070,6 +1150,7 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, return -ENOMEM; } + rxq->mz = rz; /* Zero all the descriptors in the ring. */ memset(rz->addr, 0, ring_size); @@ -1125,6 +1206,7 @@ ice_rx_queue_release(void *rxq) q->rx_rel_mbufs(q); rte_free(q->sw_ring); + rte_memzone_free(q->mz); rte_free(q); } @@ -1271,6 +1353,7 @@ ice_tx_queue_setup(struct rte_eth_dev *dev, return -ENOMEM; } + txq->mz = tz; txq->nb_tx_desc = nb_desc; txq->tx_rs_thresh = tx_rs_thresh; txq->tx_free_thresh = tx_free_thresh; @@ -1309,6 +1392,18 @@ ice_tx_queue_setup(struct rte_eth_dev *dev, return 0; } +void +ice_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) +{ + ice_rx_queue_release(dev->data->rx_queues[qid]); +} + +void +ice_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) +{ + ice_tx_queue_release(dev->data->tx_queues[qid]); +} + void ice_tx_queue_release(void *txq) { @@ -1321,6 +1416,7 @@ ice_tx_queue_release(void *txq) q->tx_rel_mbufs(q); rte_free(q->sw_ring); + rte_memzone_free(q->mz); rte_free(q); } @@ -1362,14 +1458,14 @@ ice_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, } uint32_t -ice_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) +ice_rx_queue_count(void *rx_queue) { #define ICE_RXQ_SCAN_INTERVAL 4 volatile union ice_rx_flex_desc *rxdp; struct ice_rx_queue *rxq; uint16_t desc = 0; - rxq = dev->data->rx_queues[rx_queue_id]; + rxq = rx_queue; rxdp = &rxq->rx_ring[rxq->rx_tail]; while ((desc < rxq->nb_rx_desc) && rte_le_to_cpu_16(rxdp->wb.status_error0) & @@ -1423,7 +1519,12 @@ ice_rxd_error_to_pkt_flags(uint16_t stat_err0) flags |= PKT_RX_L4_CKSUM_GOOD; if (unlikely(stat_err0 & (1 << ICE_RX_FLEX_DESC_STATUS0_XSUM_EIPE_S))) - flags |= PKT_RX_EIP_CKSUM_BAD; + flags |= PKT_RX_OUTER_IP_CKSUM_BAD; + + if (unlikely(stat_err0 & (1 << ICE_RX_FLEX_DESC_STATUS0_XSUM_EUDPE_S))) + flags |= PKT_RX_OUTER_L4_CKSUM_BAD; + else + flags |= PKT_RX_OUTER_L4_CKSUM_GOOD; return flags; } @@ -1476,7 +1577,12 @@ ice_rx_scan_hw_ring(struct ice_rx_queue *rxq) int32_t i, j, nb_rx = 0; uint64_t pkt_flags = 0; uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl; - +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + struct ice_vsi *vsi = rxq->vsi; + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + uint64_t ts_ns; + struct ice_adapter *ad = rxq->vsi->adapter; +#endif rxdp = &rxq->rx_ring[rxq->rx_tail]; rxep = &rxq->sw_ring[rxq->rx_tail]; @@ -1518,7 +1624,26 @@ ice_rx_scan_hw_ring(struct ice_rx_queue *rxq) rte_le_to_cpu_16(rxdp[j].wb.ptype_flex_flags0)]; ice_rxd_to_vlan_tci(mb, &rxdp[j]); rxq->rxd_to_pkt_fields(rxq, mb, &rxdp[j]); +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) { + ts_ns = ice_tstamp_convert_32b_64b(hw, + rte_le_to_cpu_32(rxdp[j].wb.flex_ts.ts_high)); + if (ice_timestamp_dynflag > 0) { + *RTE_MBUF_DYNFIELD(mb, + ice_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = ts_ns; + mb->ol_flags |= ice_timestamp_dynflag; + } + } + if (ad->ptp_ena && ((mb->packet_type & + RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_ETHER_TIMESYNC)) { + rxq->time_high = + rte_le_to_cpu_32(rxdp[j].wb.flex_ts.ts_high); + mb->timesync = rxq->queue_id; + pkt_flags |= PKT_RX_IEEE1588_PTP; + } +#endif mb->ol_flags |= pkt_flags; } @@ -1613,7 +1738,6 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) { struct ice_rx_queue *rxq = (struct ice_rx_queue *)rx_queue; uint16_t nb_rx = 0; - struct rte_eth_dev *dev; if (!nb_pkts) return 0; @@ -1630,8 +1754,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) if (ice_rx_alloc_bufs(rxq) != 0) { uint16_t i, j; - dev = ICE_VSI_TO_ETH_DEV(rxq->vsi); - dev->data->rx_mbuf_alloc_failed += + rxq->vsi->adapter->pf.dev_data->rx_mbuf_alloc_failed += rxq->rx_free_thresh; PMD_RX_LOG(DEBUG, "Rx mbuf alloc failed for " "port_id=%u, queue_id=%u", @@ -1704,8 +1827,12 @@ ice_recv_scattered_pkts(void *rx_queue, uint64_t dma_addr; uint64_t pkt_flags; uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl; - struct rte_eth_dev *dev; - +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + struct ice_vsi *vsi = rxq->vsi; + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + uint64_t ts_ns; + struct ice_adapter *ad = rxq->vsi->adapter; +#endif while (nb_rx < nb_pkts) { rxdp = &rx_ring[rx_id]; rx_stat_err0 = rte_le_to_cpu_16(rxdp->wb.status_error0); @@ -1717,8 +1844,7 @@ ice_recv_scattered_pkts(void *rx_queue, /* allocate mbuf */ nmb = rte_mbuf_raw_alloc(rxq->mp); if (unlikely(!nmb)) { - dev = ICE_VSI_TO_ETH_DEV(rxq->vsi); - dev->data->rx_mbuf_alloc_failed++; + rxq->vsi->adapter->pf.dev_data->rx_mbuf_alloc_failed++; break; } rxd = *rxdp; /* copy descriptor in ring to temp variable*/ @@ -1816,6 +1942,26 @@ ice_recv_scattered_pkts(void *rx_queue, ice_rxd_to_vlan_tci(first_seg, &rxd); rxq->rxd_to_pkt_fields(rxq, first_seg, &rxd); pkt_flags = ice_rxd_error_to_pkt_flags(rx_stat_err0); +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) { + ts_ns = ice_tstamp_convert_32b_64b(hw, + rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high)); + if (ice_timestamp_dynflag > 0) { + *RTE_MBUF_DYNFIELD(first_seg, + ice_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = ts_ns; + first_seg->ol_flags |= ice_timestamp_dynflag; + } + } + + if (ad->ptp_ena && ((first_seg->packet_type & RTE_PTYPE_L2_MASK) + == RTE_PTYPE_L2_ETHER_TIMESYNC)) { + rxq->time_high = + rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high); + first_seg->timesync = rxq->queue_id; + pkt_flags |= PKT_RX_IEEE1588_PTP; + } +#endif first_seg->ol_flags |= pkt_flags; /* Prefetch data of first segment, if configured to do so. */ rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, @@ -1930,8 +2076,16 @@ ice_dev_supported_ptypes_get(struct rte_eth_dev *dev) #ifdef RTE_ARCH_X86 if (dev->rx_pkt_burst == ice_recv_pkts_vec || dev->rx_pkt_burst == ice_recv_scattered_pkts_vec || +#ifdef CC_AVX512_SUPPORT + dev->rx_pkt_burst == ice_recv_pkts_vec_avx512 || + dev->rx_pkt_burst == ice_recv_pkts_vec_avx512_offload || + dev->rx_pkt_burst == ice_recv_scattered_pkts_vec_avx512 || + dev->rx_pkt_burst == ice_recv_scattered_pkts_vec_avx512_offload || +#endif dev->rx_pkt_burst == ice_recv_pkts_vec_avx2 || - dev->rx_pkt_burst == ice_recv_scattered_pkts_vec_avx2) + dev->rx_pkt_burst == ice_recv_pkts_vec_avx2_offload || + dev->rx_pkt_burst == ice_recv_scattered_pkts_vec_avx2 || + dev->rx_pkt_burst == ice_recv_scattered_pkts_vec_avx2_offload) return ptypes; #endif @@ -2006,7 +2160,6 @@ ice_free_queues(struct rte_eth_dev *dev) continue; ice_rx_queue_release(dev->data->rx_queues[i]); dev->data->rx_queues[i] = NULL; - rte_eth_dma_zone_free(dev, "rx_ring", i); } dev->data->nb_rx_queues = 0; @@ -2015,7 +2168,6 @@ ice_free_queues(struct rte_eth_dev *dev) continue; ice_tx_queue_release(dev->data->tx_queues[i]); dev->data->tx_queues[i] = NULL; - rte_eth_dma_zone_free(dev, "tx_ring", i); } dev->data->nb_tx_queues = 0; } @@ -2036,7 +2188,7 @@ ice_fdir_setup_tx_resources(struct ice_pf *pf) return -EINVAL; } - dev = pf->adapter->eth_dev; + dev = &rte_eth_devices[pf->adapter->pf.dev_data->port_id]; /* Allocate the TX queue data structure. */ txq = rte_zmalloc_socket("ice fdir tx queue", @@ -2062,6 +2214,7 @@ ice_fdir_setup_tx_resources(struct ice_pf *pf) return -ENOMEM; } + txq->mz = tz; txq->nb_tx_desc = ICE_FDIR_NUM_TX_DESC; txq->queue_id = ICE_FDIR_QUEUE_ID; txq->reg_idx = pf->fdir.fdir_vsi->base_queue; @@ -2094,7 +2247,7 @@ ice_fdir_setup_rx_resources(struct ice_pf *pf) return -EINVAL; } - dev = pf->adapter->eth_dev; + dev = &rte_eth_devices[pf->adapter->pf.dev_data->port_id]; /* Allocate the RX queue data structure. */ rxq = rte_zmalloc_socket("ice fdir rx queue", @@ -2120,6 +2273,7 @@ ice_fdir_setup_rx_resources(struct ice_pf *pf) return -ENOMEM; } + rxq->mz = rz; rxq->nb_rx_desc = ICE_FDIR_NUM_RX_DESC; rxq->queue_id = ICE_FDIR_QUEUE_ID; rxq->reg_idx = pf->fdir.fdir_vsi->base_queue; @@ -2163,8 +2317,12 @@ ice_recv_pkts(void *rx_queue, uint64_t dma_addr; uint64_t pkt_flags; uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl; - struct rte_eth_dev *dev; - +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + struct ice_vsi *vsi = rxq->vsi; + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + uint64_t ts_ns; + struct ice_adapter *ad = rxq->vsi->adapter; +#endif while (nb_rx < nb_pkts) { rxdp = &rx_ring[rx_id]; rx_stat_err0 = rte_le_to_cpu_16(rxdp->wb.status_error0); @@ -2176,8 +2334,7 @@ ice_recv_pkts(void *rx_queue, /* allocate mbuf */ nmb = rte_mbuf_raw_alloc(rxq->mp); if (unlikely(!nmb)) { - dev = ICE_VSI_TO_ETH_DEV(rxq->vsi); - dev->data->rx_mbuf_alloc_failed++; + rxq->vsi->adapter->pf.dev_data->rx_mbuf_alloc_failed++; break; } rxd = *rxdp; /* copy descriptor in ring to temp variable*/ @@ -2216,6 +2373,26 @@ ice_recv_pkts(void *rx_queue, ice_rxd_to_vlan_tci(rxm, &rxd); rxq->rxd_to_pkt_fields(rxq, rxm, &rxd); pkt_flags = ice_rxd_error_to_pkt_flags(rx_stat_err0); +#ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC + if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) { + ts_ns = ice_tstamp_convert_32b_64b(hw, + rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high)); + if (ice_timestamp_dynflag > 0) { + *RTE_MBUF_DYNFIELD(rxm, + ice_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = ts_ns; + rxm->ol_flags |= ice_timestamp_dynflag; + } + } + + if (ad->ptp_ena && ((rxm->packet_type & RTE_PTYPE_L2_MASK) == + RTE_PTYPE_L2_ETHER_TIMESYNC)) { + rxq->time_high = + rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high); + rxm->timesync = rxq->queue_id; + pkt_flags |= PKT_RX_IEEE1588_PTP; + } +#endif rxm->ol_flags |= pkt_flags; /* copy old mbuf to rx_pkts */ rx_pkts[nb_rx++] = rxm; @@ -2289,8 +2466,11 @@ ice_parse_tunneling_params(uint64_t ol_flags, *cd_tunneling |= (tx_offload.l2_len >> 1) << ICE_TXD_CTX_QW0_NATLEN_S; - if ((ol_flags & PKT_TX_OUTER_UDP_CKSUM) && - (ol_flags & PKT_TX_OUTER_IP_CKSUM) && + /** + * Calculate the tunneling UDP checksum. + * Shall be set only if L4TUNT = 01b and EIPT is not zero + */ + if (!(*cd_tunneling & ICE_TX_CTX_EIPT_NONE) && (*cd_tunneling & ICE_TXD_CTX_UDP_TUNNELING)) *cd_tunneling |= ICE_TXD_CTX_QW0_L4T_CS_M; } @@ -2372,11 +2552,11 @@ ice_xmit_cleanup(struct ice_tx_queue *txq) desc_to_clean_to = sw_ring[desc_to_clean_to].last_id; if (!(txd[desc_to_clean_to].cmd_type_offset_bsz & rte_cpu_to_le_64(ICE_TX_DESC_DTYPE_DESC_DONE))) { - PMD_TX_FREE_LOG(DEBUG, "TX descriptor %4u is not done " - "(port=%d queue=%d) value=0x%"PRIx64"\n", - desc_to_clean_to, - txq->port_id, txq->queue_id, - txd[desc_to_clean_to].cmd_type_offset_bsz); + PMD_TX_LOG(DEBUG, "TX descriptor %4u is not done " + "(port=%d queue=%d) value=0x%"PRIx64"\n", + desc_to_clean_to, + txq->port_id, txq->queue_id, + txd[desc_to_clean_to].cmd_type_offset_bsz); /* Failed to clean any descriptors */ return -1; } @@ -2424,7 +2604,8 @@ ice_calc_context_desc(uint64_t flags) static uint64_t mask = PKT_TX_TCP_SEG | PKT_TX_QINQ | PKT_TX_OUTER_IP_CKSUM | - PKT_TX_TUNNEL_MASK; + PKT_TX_TUNNEL_MASK | + PKT_TX_IEEE1588_TMST; return (flags & mask) ? 1 : 0; } @@ -2592,6 +2773,10 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) if (ol_flags & PKT_TX_TCP_SEG) cd_type_cmd_tso_mss |= ice_set_tso_ctx(tx_pkt, tx_offload); + else if (ol_flags & PKT_TX_IEEE1588_TMST) + cd_type_cmd_tso_mss |= + ((uint64_t)ICE_TX_CTX_DESC_TSYN << + ICE_TXD_CTX_QW1_CMD_S); ctx_txd->tunneling_params = rte_cpu_to_le_32(cd_tunneling_params); @@ -2667,10 +2852,10 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* set RS bit on the last descriptor of one packet */ if (txq->nb_tx_used >= txq->tx_rs_thresh) { - PMD_TX_FREE_LOG(DEBUG, - "Setting RS bit on TXD id=" - "%4u (port=%d queue=%d)", - tx_last, txq->port_id, txq->queue_id); + PMD_TX_LOG(DEBUG, + "Setting RS bit on TXD id=" + "%4u (port=%d queue=%d)", + tx_last, txq->port_id, txq->queue_id); td_cmd |= ICE_TX_DESC_CMD_RS; @@ -2987,11 +3172,16 @@ ice_set_rx_function(struct rte_eth_dev *dev) #ifdef RTE_ARCH_X86 struct ice_rx_queue *rxq; int i; - bool use_avx2 = false; + int rx_check_ret = -1; if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - if (!ice_rx_vec_dev_check(dev) && ad->rx_bulk_alloc_allowed && - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { + ad->rx_use_avx512 = false; + ad->rx_use_avx2 = false; + rx_check_ret = ice_rx_vec_dev_check(dev); + if (ad->ptp_ena) + rx_check_ret = -1; + if (rx_check_ret >= 0 && ad->rx_bulk_alloc_allowed && + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { ad->rx_vec_allowed = true; for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; @@ -3001,10 +3191,20 @@ ice_set_rx_function(struct rte_eth_dev *dev) } } - if ((rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1 || - rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1) && - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256) - use_avx2 = true; + if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_512 && + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1 && + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512BW) == 1) +#ifdef CC_AVX512_SUPPORT + ad->rx_use_avx512 = true; +#else + PMD_DRV_LOG(NOTICE, + "AVX512 is not supported in build env"); +#endif + if (!ad->rx_use_avx512 && + (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1 || + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1) && + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256) + ad->rx_use_avx2 = true; } else { ad->rx_vec_allowed = false; @@ -3013,20 +3213,79 @@ ice_set_rx_function(struct rte_eth_dev *dev) if (ad->rx_vec_allowed) { if (dev->data->scattered_rx) { - PMD_DRV_LOG(DEBUG, - "Using %sVector Scattered Rx (port %d).", - use_avx2 ? "avx2 " : "", + if (ad->rx_use_avx512) { +#ifdef CC_AVX512_SUPPORT + if (rx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX512 OFFLOAD Vector Scattered Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_scattered_pkts_vec_avx512_offload; + } else { + PMD_DRV_LOG(NOTICE, + "Using AVX512 Vector Scattered Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_scattered_pkts_vec_avx512; + } +#endif + } else if (ad->rx_use_avx2) { + if (rx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX2 OFFLOAD Vector Scattered Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_scattered_pkts_vec_avx2_offload; + } else { + PMD_DRV_LOG(NOTICE, + "Using AVX2 Vector Scattered Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_scattered_pkts_vec_avx2; + } + } else { + PMD_DRV_LOG(DEBUG, + "Using Vector Scattered Rx (port %d).", dev->data->port_id); - dev->rx_pkt_burst = use_avx2 ? - ice_recv_scattered_pkts_vec_avx2 : - ice_recv_scattered_pkts_vec; + dev->rx_pkt_burst = ice_recv_scattered_pkts_vec; + } } else { - PMD_DRV_LOG(DEBUG, "Using %sVector Rx (port %d).", - use_avx2 ? "avx2 " : "", + if (ad->rx_use_avx512) { +#ifdef CC_AVX512_SUPPORT + if (rx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX512 OFFLOAD Vector Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_pkts_vec_avx512_offload; + } else { + PMD_DRV_LOG(NOTICE, + "Using AVX512 Vector Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_pkts_vec_avx512; + } +#endif + } else if (ad->rx_use_avx2) { + if (rx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX2 OFFLOAD Vector Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_pkts_vec_avx2_offload; + } else { + PMD_DRV_LOG(NOTICE, + "Using AVX2 Vector Rx (port %d).", + dev->data->port_id); + dev->rx_pkt_burst = + ice_recv_pkts_vec_avx2; + } + } else { + PMD_DRV_LOG(DEBUG, + "Using Vector Rx (port %d).", dev->data->port_id); - dev->rx_pkt_burst = use_avx2 ? - ice_recv_pkts_vec_avx2 : - ice_recv_pkts_vec; + dev->rx_pkt_burst = ice_recv_pkts_vec; + } } return; } @@ -3063,8 +3322,16 @@ static const struct { { ice_recv_pkts_bulk_alloc, "Scalar Bulk Alloc" }, { ice_recv_pkts, "Scalar" }, #ifdef RTE_ARCH_X86 +#ifdef CC_AVX512_SUPPORT + { ice_recv_scattered_pkts_vec_avx512, "Vector AVX512 Scattered" }, + { ice_recv_scattered_pkts_vec_avx512_offload, "Offload Vector AVX512 Scattered" }, + { ice_recv_pkts_vec_avx512, "Vector AVX512" }, + { ice_recv_pkts_vec_avx512_offload, "Offload Vector AVX512" }, +#endif { ice_recv_scattered_pkts_vec_avx2, "Vector AVX2 Scattered" }, + { ice_recv_scattered_pkts_vec_avx2_offload, "Offload Vector AVX2 Scattered" }, { ice_recv_pkts_vec_avx2, "Vector AVX2" }, + { ice_recv_pkts_vec_avx2_offload, "Offload Vector AVX2" }, { ice_recv_scattered_pkts_vec, "Vector SSE Scattered" }, { ice_recv_pkts_vec, "Vector SSE" }, #endif @@ -3143,7 +3410,7 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts, return i; } -#ifdef RTE_LIBRTE_ETHDEV_DEBUG +#ifdef RTE_ETHDEV_DEBUG_TX ret = rte_validate_tx_offload(m); if (ret != 0) { rte_errno = -ret; @@ -3167,38 +3434,84 @@ ice_set_tx_function(struct rte_eth_dev *dev) #ifdef RTE_ARCH_X86 struct ice_tx_queue *txq; int i; - bool use_avx2 = false; + int tx_check_ret = -1; if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - if (!ice_tx_vec_dev_check(dev) && - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { + ad->tx_use_avx2 = false; + ad->tx_use_avx512 = false; + tx_check_ret = ice_tx_vec_dev_check(dev); + if (tx_check_ret >= 0 && + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) { ad->tx_vec_allowed = true; - for (i = 0; i < dev->data->nb_tx_queues; i++) { - txq = dev->data->tx_queues[i]; - if (txq && ice_txq_vec_setup(txq)) { - ad->tx_vec_allowed = false; - break; + + if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_512 && + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1 && + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512BW) == 1) +#ifdef CC_AVX512_SUPPORT + ad->tx_use_avx512 = true; +#else + PMD_DRV_LOG(NOTICE, + "AVX512 is not supported in build env"); +#endif + if (!ad->tx_use_avx512 && + (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1 || + rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1) && + rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256) + ad->tx_use_avx2 = true; + + if (!ad->tx_use_avx2 && !ad->tx_use_avx512 && + tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) + ad->tx_vec_allowed = false; + + if (ad->tx_vec_allowed) { + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = dev->data->tx_queues[i]; + if (txq && ice_txq_vec_setup(txq)) { + ad->tx_vec_allowed = false; + break; + } } } - - if ((rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1 || - rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1) && - rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256) - use_avx2 = true; - } else { ad->tx_vec_allowed = false; } } if (ad->tx_vec_allowed) { - PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).", - use_avx2 ? "avx2 " : "", - dev->data->port_id); - dev->tx_pkt_burst = use_avx2 ? - ice_xmit_pkts_vec_avx2 : - ice_xmit_pkts_vec; dev->tx_pkt_prepare = NULL; + if (ad->tx_use_avx512) { +#ifdef CC_AVX512_SUPPORT + if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX512 OFFLOAD Vector Tx (port %d).", + dev->data->port_id); + dev->tx_pkt_burst = + ice_xmit_pkts_vec_avx512_offload; + dev->tx_pkt_prepare = ice_prep_pkts; + } else { + PMD_DRV_LOG(NOTICE, + "Using AVX512 Vector Tx (port %d).", + dev->data->port_id); + dev->tx_pkt_burst = ice_xmit_pkts_vec_avx512; + } +#endif + } else { + if (tx_check_ret == ICE_VECTOR_OFFLOAD_PATH) { + PMD_DRV_LOG(NOTICE, + "Using AVX2 OFFLOAD Vector Tx (port %d).", + dev->data->port_id); + dev->tx_pkt_burst = + ice_xmit_pkts_vec_avx2_offload; + dev->tx_pkt_prepare = ice_prep_pkts; + } else { + PMD_DRV_LOG(DEBUG, "Using %sVector Tx (port %d).", + ad->tx_use_avx2 ? "avx2 " : "", + dev->data->port_id); + dev->tx_pkt_burst = ad->tx_use_avx2 ? + ice_xmit_pkts_vec_avx2 : + ice_xmit_pkts_vec; + } + } return; } @@ -3222,6 +3535,10 @@ static const struct { { ice_xmit_pkts_simple, "Scalar Simple" }, { ice_xmit_pkts, "Scalar" }, #ifdef RTE_ARCH_X86 +#ifdef CC_AVX512_SUPPORT + { ice_xmit_pkts_vec_avx512, "Vector AVX512" }, + { ice_xmit_pkts_vec_avx512_offload, "Offload Vector AVX512" }, +#endif { ice_xmit_pkts_vec_avx2, "Vector AVX2" }, { ice_xmit_pkts_vec, "Vector SSE" }, #endif @@ -3784,6 +4101,50 @@ ice_get_default_pkt_type(uint16_t ptype) RTE_PTYPE_TUNNEL_GTPU | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_ICMP, + + /* IPv4 --> UDP ECPRI */ + [372] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [373] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [374] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [375] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [376] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [377] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [378] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [379] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [380] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [381] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + + /* IPV6 --> UDP ECPRI */ + [382] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [383] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [384] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [385] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [386] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [387] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [388] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [389] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [390] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, + [391] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_UDP, /* All others reserved */ };