X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fsfc%2Fsfc_ef10_rx.c;h=5c0152d01f134928f6d9708ab93b900f1a2871c8;hb=f609ee3f2a32806689e0f1d9d841c97e0409bf55;hp=f31a7e0e0888c08a7cb2e06077171bf3fd4029e1;hpb=7e48cfe9ef36f9a11363a568332be5595119aea3;p=dpdk.git diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c index f31a7e0e08..5c0152d01f 100644 --- a/drivers/net/sfc/sfc_ef10_rx.c +++ b/drivers/net/sfc/sfc_ef10_rx.c @@ -26,15 +26,12 @@ #include "sfc_kvargs.h" #include "sfc_ef10.h" +#define SFC_EF10_RX_EV_ENCAP_SUPPORT 1 +#include "sfc_ef10_rx_ev.h" + #define sfc_ef10_rx_err(dpq, ...) \ SFC_DP_LOG(SFC_KVARG_DATAPATH_EF10, ERR, dpq, __VA_ARGS__) -/** - * Alignment requirement for value written to RX WPTR: - * the WPTR must be aligned to an 8 descriptor boundary. - */ -#define SFC_EF10_RX_WPTR_ALIGN 8 - /** * Maximum number of descriptors/buffers in the Rx ring. * It should guarantee that corresponding event queue never overfill. @@ -87,29 +84,6 @@ sfc_ef10_rxq_by_dp_rxq(struct sfc_dp_rxq *dp_rxq) return container_of(dp_rxq, struct sfc_ef10_rxq, dp); } -static void -sfc_ef10_rx_qpush(struct sfc_ef10_rxq *rxq) -{ - efx_dword_t dword; - - /* Hardware has alignment restriction for WPTR */ - RTE_BUILD_BUG_ON(SFC_RX_REFILL_BULK % SFC_EF10_RX_WPTR_ALIGN != 0); - SFC_ASSERT(RTE_ALIGN(rxq->added, SFC_EF10_RX_WPTR_ALIGN) == rxq->added); - - EFX_POPULATE_DWORD_1(dword, ERF_DZ_RX_DESC_WPTR, - rxq->added & rxq->ptr_mask); - - /* DMA sync to device is not required */ - - /* - * rte_write32() has rte_io_wmb() which guarantees that the STORE - * operations (i.e. Rx and event descriptor updates) that precede - * the rte_io_wmb() call are visible to NIC before the STORE - * operations that follow it (i.e. doorbell write). - */ - rte_write32(dword.ed_u32[0], rxq->doorbell); -} - static void sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq) { @@ -120,6 +94,8 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq) void *objs[SFC_RX_REFILL_BULK]; unsigned int added = rxq->added; + RTE_BUILD_BUG_ON(SFC_RX_REFILL_BULK % SFC_EF10_RX_WPTR_ALIGN != 0); + free_space = rxq->max_fill_level - (added - rxq->completed); if (free_space < rxq->refill_threshold) @@ -178,7 +154,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq) SFC_ASSERT(rxq->added != added); rxq->added = added; - sfc_ef10_rx_qpush(rxq); + sfc_ef10_rx_qpush(rxq->doorbell, added, ptr_mask); } static void @@ -225,147 +201,6 @@ sfc_ef10_rx_prepared(struct sfc_ef10_rxq *rxq, struct rte_mbuf **rx_pkts, return n_rx_pkts; } -static void -sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev, - struct rte_mbuf *m) -{ - uint32_t tun_ptype = 0; - /* Which event bit is mapped to PKT_RX_IP_CKSUM_* */ - int8_t ip_csum_err_bit; - /* Which event bit is mapped to PKT_RX_L4_CKSUM_* */ - int8_t l4_csum_err_bit; - uint32_t l2_ptype = 0; - uint32_t l3_ptype = 0; - uint32_t l4_ptype = 0; - uint64_t ol_flags = 0; - - if (unlikely(EFX_TEST_QWORD_BIT(rx_ev, ESF_DZ_RX_PARSE_INCOMPLETE_LBN))) - goto done; - - switch (EFX_QWORD_FIELD(rx_ev, ESF_EZ_RX_ENCAP_HDR)) { - default: - /* Unexpected encapsulation tag class */ - SFC_ASSERT(false); - /* FALLTHROUGH */ - case ESE_EZ_ENCAP_HDR_NONE: - break; - case ESE_EZ_ENCAP_HDR_VXLAN: - /* - * It is definitely UDP, but we have no information - * about IPv4 vs IPv6 and VLAN tagging. - */ - tun_ptype = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP; - break; - case ESE_EZ_ENCAP_HDR_GRE: - /* - * We have no information about IPv4 vs IPv6 and VLAN tagging. - */ - tun_ptype = RTE_PTYPE_TUNNEL_NVGRE; - break; - } - - if (tun_ptype == 0) { - ip_csum_err_bit = ESF_DZ_RX_IPCKSUM_ERR_LBN; - l4_csum_err_bit = ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN; - } else { - ip_csum_err_bit = ESF_EZ_RX_IP_INNER_CHKSUM_ERR_LBN; - l4_csum_err_bit = ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR_LBN; - if (unlikely(EFX_TEST_QWORD_BIT(rx_ev, - ESF_DZ_RX_IPCKSUM_ERR_LBN))) - ol_flags |= PKT_RX_EIP_CKSUM_BAD; - } - - switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_ETH_TAG_CLASS)) { - case ESE_DZ_ETH_TAG_CLASS_NONE: - l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER : - RTE_PTYPE_INNER_L2_ETHER; - break; - case ESE_DZ_ETH_TAG_CLASS_VLAN1: - l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_VLAN : - RTE_PTYPE_INNER_L2_ETHER_VLAN; - break; - case ESE_DZ_ETH_TAG_CLASS_VLAN2: - l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_QINQ : - RTE_PTYPE_INNER_L2_ETHER_QINQ; - break; - default: - /* Unexpected Eth tag class */ - SFC_ASSERT(false); - } - - switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_L3_CLASS)) { - case ESE_DZ_L3_CLASS_IP4_FRAG: - l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG : - RTE_PTYPE_INNER_L4_FRAG; - /* FALLTHROUGH */ - case ESE_DZ_L3_CLASS_IP4: - l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV4_EXT_UNKNOWN : - RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; - ol_flags |= PKT_RX_RSS_HASH | - ((EFX_TEST_QWORD_BIT(rx_ev, ip_csum_err_bit)) ? - PKT_RX_IP_CKSUM_BAD : PKT_RX_IP_CKSUM_GOOD); - break; - case ESE_DZ_L3_CLASS_IP6_FRAG: - l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG : - RTE_PTYPE_INNER_L4_FRAG; - /* FALLTHROUGH */ - case ESE_DZ_L3_CLASS_IP6: - l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV6_EXT_UNKNOWN : - RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; - ol_flags |= PKT_RX_RSS_HASH; - break; - case ESE_DZ_L3_CLASS_ARP: - /* Override Layer 2 packet type */ - /* There is no ARP classification for inner packets */ - if (tun_ptype == 0) - l2_ptype = RTE_PTYPE_L2_ETHER_ARP; - break; - default: - /* Unexpected Layer 3 class */ - SFC_ASSERT(false); - } - - /* - * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is only - * 2 bits wide on Medford2. Check it is safe to use the Medford2 field - * and values for all EF10 controllers. - */ - RTE_BUILD_BUG_ON(ESF_FZ_RX_L4_CLASS_LBN != ESF_DE_RX_L4_CLASS_LBN); - switch (EFX_QWORD_FIELD(rx_ev, ESF_FZ_RX_L4_CLASS)) { - case ESE_FZ_L4_CLASS_TCP: - RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_TCP != ESE_DE_L4_CLASS_TCP); - l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_TCP : - RTE_PTYPE_INNER_L4_TCP; - ol_flags |= - (EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ? - PKT_RX_L4_CKSUM_BAD : PKT_RX_L4_CKSUM_GOOD; - break; - case ESE_FZ_L4_CLASS_UDP: - RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_UDP != ESE_DE_L4_CLASS_UDP); - l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_UDP : - RTE_PTYPE_INNER_L4_UDP; - ol_flags |= - (EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ? - PKT_RX_L4_CKSUM_BAD : PKT_RX_L4_CKSUM_GOOD; - break; - case ESE_FZ_L4_CLASS_UNKNOWN: - RTE_BUILD_BUG_ON(ESE_FZ_L4_CLASS_UNKNOWN != - ESE_DE_L4_CLASS_UNKNOWN); - break; - default: - /* Unexpected Layer 4 class */ - SFC_ASSERT(false); - } - - /* Remove RSS hash offload flag if RSS is not enabled */ - if (~rxq->flags & SFC_EF10_RXQ_RSS_HASH) - ol_flags &= ~PKT_RX_RSS_HASH; - -done: - m->ol_flags = ol_flags; - m->packet_type = tun_ptype | l2_ptype | l3_ptype | l4_ptype; -} - static uint16_t sfc_ef10_rx_pseudo_hdr_get_len(const uint8_t *pseudo_hdr) { @@ -424,7 +259,10 @@ sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev, m->rearm_data[0] = rxq->rearm_data; /* Classify packet based on Rx event */ - sfc_ef10_rx_ev_to_offloads(rxq, rx_ev, m); + /* Mask RSS hash offload flag if RSS is not enabled */ + sfc_ef10_rx_ev_to_offloads(rx_ev, m, + (rxq->flags & SFC_EF10_RXQ_RSS_HASH) ? + ~0ull : ~PKT_RX_RSS_HASH); /* data_off already moved past pseudo header */ pseudo_hdr = (uint8_t *)m->buf_addr + RTE_PKTMBUF_HEADROOM; @@ -521,11 +359,11 @@ sfc_ef10_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) uint16_t n_rx_pkts; efx_qword_t rx_ev; + n_rx_pkts = sfc_ef10_rx_prepared(rxq, rx_pkts, nb_pkts); + if (unlikely(rxq->flags & (SFC_EF10_RXQ_NOT_RUNNING | SFC_EF10_RXQ_EXCEPTION))) - return 0; - - n_rx_pkts = sfc_ef10_rx_prepared(rxq, rx_pkts, nb_pkts); + goto done; evq_old_read_ptr = rxq->evq_read_ptr; while (n_rx_pkts != nb_pkts && sfc_ef10_rx_get_event(rxq, &rx_ev)) { @@ -545,10 +383,11 @@ sfc_ef10_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) /* It is not a problem if we refill in the case of exception */ sfc_ef10_rx_qrefill(rxq); +done: return n_rx_pkts; } -static const uint32_t * +const uint32_t * sfc_ef10_supported_ptypes_get(uint32_t tunnel_encaps) { static const uint32_t ef10_native_ptypes[] = { @@ -597,8 +436,8 @@ sfc_ef10_supported_ptypes_get(uint32_t tunnel_encaps) 1u << EFX_TUNNEL_PROTOCOL_NVGRE): return ef10_overlay_ptypes; default: - RTE_LOG(ERR, PMD, - "Unexpected set of supported tunnel encapsulations: %#x\n", + SFC_GENERIC_LOG(ERR, + "Unexpected set of supported tunnel encapsulations: %#x", tunnel_encaps); /* FALLTHROUGH */ case 0: @@ -642,6 +481,7 @@ sfc_ef10_rx_get_dev_info(struct rte_eth_dev_info *dev_info) static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings; static int sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc, + __rte_unused struct rte_mempool *mb_pool, unsigned int *rxq_entries, unsigned int *evq_entries, unsigned int *rxq_max_fill_level) @@ -726,7 +566,7 @@ sfc_ef10_rx_qcreate(uint16_t port_id, uint16_t queue_id, rxq->rxq_hw_ring = info->rxq_hw_ring; rxq->doorbell = (volatile uint8_t *)info->mem_bar + ER_DZ_RX_DESC_UPD_REG_OFST + - info->hw_index * ER_DZ_RX_DESC_UPD_REG_STEP; + (info->hw_index << info->vi_window_shift); *dp_rxqp = &rxq->dp; return 0; @@ -755,8 +595,9 @@ sfc_ef10_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr) { struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(dp_rxq); - rxq->prepared = 0; - rxq->completed = rxq->added = 0; + SFC_ASSERT(rxq->prepared == 0); + SFC_ASSERT(rxq->completed == 0); + SFC_ASSERT(rxq->added == 0); sfc_ef10_rx_qrefill(rxq); @@ -803,12 +644,16 @@ sfc_ef10_rx_qpurge(struct sfc_dp_rxq *dp_rxq) unsigned int i; struct sfc_ef10_rx_sw_desc *rxd; + rxq->prepared = 0; + for (i = rxq->completed; i != rxq->added; ++i) { rxd = &rxq->sw_ring[i & rxq->ptr_mask]; rte_mempool_put(rxq->refill_mb_pool, rxd->mbuf); rxd->mbuf = NULL; } + rxq->completed = rxq->added = 0; + rxq->flags &= ~SFC_EF10_RXQ_STARTED; } @@ -819,7 +664,8 @@ struct sfc_dp_rx sfc_ef10_rx = { .hw_fw_caps = SFC_DP_HW_FW_CAP_EF10, }, .features = SFC_DP_RX_FEAT_MULTI_PROCESS | - SFC_DP_RX_FEAT_TUNNELS, + SFC_DP_RX_FEAT_TUNNELS | + SFC_DP_RX_FEAT_CHECKSUM, .get_dev_info = sfc_ef10_rx_get_dev_info, .qsize_up_rings = sfc_ef10_rx_qsize_up_rings, .qcreate = sfc_ef10_rx_qcreate,