X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fdpaa2%2Fdpaa2_rxtx.c;h=2d4b9ef145e1678030dfaa908e011d49c0ad0a55;hb=fb720b7d8b2704cffa9ff872f242ea3aa216a916;hp=dc0da96174fdadb5583716bdbc9177088e463815;hpb=3ef648aa4854f53b5ad3f148dc021852157a0246;p=dpdk.git diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c index dc0da96174..2d4b9ef145 100644 --- a/drivers/net/dpaa2/dpaa2_rxtx.c +++ b/drivers/net/dpaa2/dpaa2_rxtx.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. - * Copyright 2016 NXP + * Copyright 2016-2018 NXP * */ @@ -25,18 +25,25 @@ #include "dpaa2_ethdev.h" #include "base/dpaa2_hw_dpni_annot.h" +static inline uint32_t __attribute__((hot)) +dpaa2_dev_rx_parse_slow(struct rte_mbuf *mbuf, + struct dpaa2_annot_hdr *annotation); + #define DPAA2_MBUF_TO_CONTIG_FD(_mbuf, _fd, _bpid) do { \ DPAA2_SET_FD_ADDR(_fd, DPAA2_MBUF_VADDR_TO_IOVA(_mbuf)); \ DPAA2_SET_FD_LEN(_fd, _mbuf->data_len); \ DPAA2_SET_ONLY_FD_BPID(_fd, _bpid); \ DPAA2_SET_FD_OFFSET(_fd, _mbuf->data_off); \ - DPAA2_SET_FD_ASAL(_fd, DPAA2_ASAL_VAL); \ + DPAA2_SET_FD_FRC(_fd, 0); \ + DPAA2_RESET_FD_CTRL(_fd); \ + DPAA2_RESET_FD_FLC(_fd); \ } while (0) static inline void __attribute__((hot)) -dpaa2_dev_rx_parse_frc(struct rte_mbuf *m, uint16_t frc) +dpaa2_dev_rx_parse_new(struct rte_mbuf *m, const struct qbman_fd *fd) { - DPAA2_PMD_DP_DEBUG("frc = 0x%x\t", frc); + struct dpaa2_annot_hdr *annotation; + uint16_t frc = DPAA2_GET_FD_FRC_PARSE_SUM(fd); m->packet_type = RTE_PTYPE_UNKNOWN; switch (frc) { @@ -91,29 +98,58 @@ dpaa2_dev_rx_parse_frc(struct rte_mbuf *m, uint16_t frc) m->packet_type = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP; break; - case DPAA2_PKT_TYPE_VLAN_1: - case DPAA2_PKT_TYPE_VLAN_2: - m->ol_flags |= PKT_RX_VLAN; - break; - /* More switch cases can be added */ - /* TODO: Add handling for checksum error check from FRC */ default: - m->packet_type = RTE_PTYPE_UNKNOWN; + m->packet_type = dpaa2_dev_rx_parse_slow(m, + (void *)((size_t)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)) + + DPAA2_FD_PTA_SIZE)); } + m->hash.rss = fd->simple.flc_hi; + m->ol_flags |= PKT_RX_RSS_HASH; + + if (dpaa2_enable_ts == PMD_DPAA2_ENABLE_TS) { + annotation = (struct dpaa2_annot_hdr *) + ((size_t)DPAA2_IOVA_TO_VADDR( + DPAA2_GET_FD_ADDR(fd)) + DPAA2_FD_PTA_SIZE); + m->timestamp = annotation->word2; + m->ol_flags |= PKT_RX_TIMESTAMP; + DPAA2_PMD_DP_DEBUG("pkt timestamp:0x%" PRIx64 "", m->timestamp); + } + + DPAA2_PMD_DP_DEBUG("HW frc = 0x%x\t packet type =0x%x " + "ol_flags =0x%" PRIx64 "", + frc, m->packet_type, m->ol_flags); } static inline uint32_t __attribute__((hot)) -dpaa2_dev_rx_parse_slow(struct dpaa2_annot_hdr *annotation) +dpaa2_dev_rx_parse_slow(struct rte_mbuf *mbuf, + struct dpaa2_annot_hdr *annotation) { uint32_t pkt_type = RTE_PTYPE_UNKNOWN; + uint16_t *vlan_tci; + + DPAA2_PMD_DP_DEBUG("(slow parse)annotation(3)=0x%" PRIx64 "\t" + "(4)=0x%" PRIx64 "\t", + annotation->word3, annotation->word4); + + if (BIT_ISSET_AT_POS(annotation->word3, L2_VLAN_1_PRESENT)) { + vlan_tci = rte_pktmbuf_mtod_offset(mbuf, uint16_t *, + (VLAN_TCI_OFFSET_1(annotation->word5) >> 16)); + mbuf->vlan_tci = rte_be_to_cpu_16(*vlan_tci); + mbuf->ol_flags |= PKT_RX_VLAN; + pkt_type |= RTE_PTYPE_L2_ETHER_VLAN; + } else if (BIT_ISSET_AT_POS(annotation->word3, L2_VLAN_N_PRESENT)) { + vlan_tci = rte_pktmbuf_mtod_offset(mbuf, uint16_t *, + (VLAN_TCI_OFFSET_1(annotation->word5) >> 16)); + mbuf->vlan_tci = rte_be_to_cpu_16(*vlan_tci); + mbuf->ol_flags |= PKT_RX_VLAN | PKT_RX_QINQ; + pkt_type |= RTE_PTYPE_L2_ETHER_QINQ; + } - DPAA2_PMD_DP_DEBUG("(slow parse) Annotation = 0x%" PRIx64 "\t", - annotation->word4); if (BIT_ISSET_AT_POS(annotation->word3, L2_ARP_PRESENT)) { - pkt_type = RTE_PTYPE_L2_ETHER_ARP; + pkt_type |= RTE_PTYPE_L2_ETHER_ARP; goto parse_done; } else if (BIT_ISSET_AT_POS(annotation->word3, L2_ETH_MAC_PRESENT)) { - pkt_type = RTE_PTYPE_L2_ETHER; + pkt_type |= RTE_PTYPE_L2_ETHER; } else { goto parse_done; } @@ -135,6 +171,11 @@ dpaa2_dev_rx_parse_slow(struct dpaa2_annot_hdr *annotation) goto parse_done; } + if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L3CE)) + mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD; + else if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L4CE)) + mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD; + if (BIT_ISSET_AT_POS(annotation->word4, L3_IP_1_FIRST_FRAGMENT | L3_IP_1_MORE_FRAGMENT | L3_IP_N_FIRST_FRAGMENT | @@ -173,16 +214,19 @@ dpaa2_dev_rx_parse(struct rte_mbuf *mbuf, void *hw_annot_addr) DPAA2_PMD_DP_DEBUG("(fast parse) Annotation = 0x%" PRIx64 "\t", annotation->word4); - /* Check offloads first */ - if (BIT_ISSET_AT_POS(annotation->word3, - L2_VLAN_1_PRESENT | L2_VLAN_N_PRESENT)) - mbuf->ol_flags |= PKT_RX_VLAN; - if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L3CE)) mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD; else if (BIT_ISSET_AT_POS(annotation->word8, DPAA2_ETH_FAS_L4CE)) mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD; + mbuf->ol_flags |= PKT_RX_TIMESTAMP; + mbuf->timestamp = annotation->word2; + DPAA2_PMD_DP_DEBUG("pkt timestamp: 0x%" PRIx64 "", mbuf->timestamp); + + /* Check detailed parsing requirement */ + if (annotation->word3 & 0x7FFFFC3FFFF) + return dpaa2_dev_rx_parse_slow(mbuf, annotation); + /* Return some common types from parse processing */ switch (annotation->word4) { case DPAA2_L3_IPv4: @@ -205,7 +249,7 @@ dpaa2_dev_rx_parse(struct rte_mbuf *mbuf, void *hw_annot_addr) break; } - return dpaa2_dev_rx_parse_slow(annotation); + return dpaa2_dev_rx_parse_slow(mbuf, annotation); } static inline struct rte_mbuf *__attribute__((hot)) @@ -236,8 +280,7 @@ eth_sg_fd_to_mbuf(const struct qbman_fd *fd) first_seg->nb_segs = 1; first_seg->next = NULL; if (dpaa2_svr_family == SVR_LX2160A) - dpaa2_dev_rx_parse_frc(first_seg, - DPAA2_GET_FD_FRC_PARSE_SUM(fd)); + dpaa2_dev_rx_parse_new(first_seg, fd); else first_seg->packet_type = dpaa2_dev_rx_parse(first_seg, (void *)((size_t)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)) @@ -293,7 +336,7 @@ eth_fd_to_mbuf(const struct qbman_fd *fd) */ if (dpaa2_svr_family == SVR_LX2160A) - dpaa2_dev_rx_parse_frc(mbuf, DPAA2_GET_FD_FRC_PARSE_SUM(fd)); + dpaa2_dev_rx_parse_new(mbuf, fd); else mbuf->packet_type = dpaa2_dev_rx_parse(mbuf, (void *)((size_t)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)) @@ -447,6 +490,12 @@ eth_copy_mbuf_to_fd(struct rte_mbuf *mbuf, return 0; } +/* This function assumes that caller will be keep the same value for nb_pkts + * across calls per queue, if that is not the case, better use non-prefetch + * version of rx call. + * It will return the packets as requested in previous call without honoring + * the current nb_pkts or bufs space. + */ uint16_t dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) { @@ -454,13 +503,13 @@ dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)queue; struct qbman_result *dq_storage, *dq_storage1 = NULL; uint32_t fqid = dpaa2_q->fqid; - int ret, num_rx = 0; + int ret, num_rx = 0, pull_size; uint8_t pending, status; struct qbman_swp *swp; const struct qbman_fd *fd, *next_fd; struct qbman_pull_desc pulldesc; struct queue_storage_info_t *q_storage = dpaa2_q->q_storage; - struct rte_eth_dev *dev = dpaa2_q->dev; + struct rte_eth_dev_data *eth_data = dpaa2_q->eth_data; if (unlikely(!DPAA2_PER_LCORE_ETHRX_DPIO)) { ret = dpaa2_affine_qbman_ethrx_swp(); @@ -469,13 +518,17 @@ dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) return 0; } } - swp = DPAA2_PER_LCORE_ETHRX_PORTAL; + if (unlikely(!rte_dpaa2_bpid_info && + rte_eal_process_type() == RTE_PROC_SECONDARY)) + rte_dpaa2_bpid_info = dpaa2_q->bp_array; + + swp = DPAA2_PER_LCORE_ETHRX_PORTAL; + pull_size = (nb_pkts > dpaa2_dqrr_size) ? dpaa2_dqrr_size : nb_pkts; if (unlikely(!q_storage->active_dqs)) { q_storage->toggle = 0; dq_storage = q_storage->dq_storage[q_storage->toggle]; - q_storage->last_num_pkts = (nb_pkts > DPAA2_DQRR_RING_SIZE) ? - DPAA2_DQRR_RING_SIZE : nb_pkts; + q_storage->last_num_pkts = pull_size; qbman_pull_desc_clear(&pulldesc); qbman_pull_desc_set_numframes(&pulldesc, q_storage->last_num_pkts); @@ -514,7 +567,7 @@ dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) q_storage->toggle ^= 1; dq_storage1 = q_storage->dq_storage[q_storage->toggle]; qbman_pull_desc_clear(&pulldesc); - qbman_pull_desc_set_numframes(&pulldesc, DPAA2_DQRR_RING_SIZE); + qbman_pull_desc_set_numframes(&pulldesc, pull_size); qbman_pull_desc_set_fq(&pulldesc, fqid); qbman_pull_desc_set_storage(&pulldesc, dq_storage1, (uint64_t)(DPAA2_VADDR_TO_IOVA(dq_storage1)), 1); @@ -549,18 +602,21 @@ dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } fd = qbman_result_DQ_fd(dq_storage); - next_fd = qbman_result_DQ_fd(dq_storage + 1); - /* Prefetch Annotation address for the parse results */ - rte_prefetch0((void *)(size_t)(DPAA2_GET_FD_ADDR(next_fd) - + DPAA2_FD_PTA_SIZE + 16)); + if (dpaa2_svr_family != SVR_LX2160A) { + next_fd = qbman_result_DQ_fd(dq_storage + 1); + /* Prefetch Annotation address for the parse results */ + rte_prefetch0((void *)(size_t)(DPAA2_GET_FD_ADDR( + next_fd) + DPAA2_FD_PTA_SIZE + 16)); + } if (unlikely(DPAA2_FD_GET_FORMAT(fd) == qbman_fd_sg)) bufs[num_rx] = eth_sg_fd_to_mbuf(fd); else bufs[num_rx] = eth_fd_to_mbuf(fd); - bufs[num_rx]->port = dev->data->port_id; + bufs[num_rx]->port = eth_data->port_id; - if (dev->data->dev_conf.rxmode.hw_vlan_strip) + if (eth_data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_STRIP) rte_vlan_strip(bufs[num_rx]); dq_storage++; @@ -661,8 +717,8 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct qbman_swp *swp; uint16_t num_tx = 0; uint16_t bpid; - struct rte_eth_dev *dev = dpaa2_q->dev; - struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct rte_eth_dev_data *eth_data = dpaa2_q->eth_data; + struct dpaa2_dev_priv *priv = eth_data->dev_private; uint32_t flags[MAX_TX_RING_SLOTS] = {0}; if (unlikely(!DPAA2_PER_LCORE_DPIO)) { @@ -674,12 +730,12 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } swp = DPAA2_PER_LCORE_PORTAL; - DPAA2_PMD_DP_DEBUG("===> dev =%p, fqid =%d\n", dev, dpaa2_q->fqid); + DPAA2_PMD_DP_DEBUG("===> eth_data =%p, fqid =%d\n", + eth_data, dpaa2_q->fqid); /*Prepare enqueue descriptor*/ qbman_eq_desc_clear(&eqdesc); qbman_eq_desc_set_no_orp(&eqdesc, DPAA2_EQ_RESP_ERR_FQ); - qbman_eq_desc_set_response(&eqdesc, 0, 0); qbman_eq_desc_set_qd(&eqdesc, priv->qdid, dpaa2_q->flow_id, dpaa2_q->tc_index); /*Clear the unused FD fields before sending*/ @@ -693,7 +749,8 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) goto skip_tx; } - frames_to_send = (nb_pkts >> 3) ? MAX_TX_RING_SLOTS : nb_pkts; + frames_to_send = (nb_pkts > dpaa2_eqcr_size) ? + dpaa2_eqcr_size : nb_pkts; for (loop = 0; loop < frames_to_send; loop++) { if ((*bufs)->seqn) { @@ -706,9 +763,6 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) (*bufs)->seqn = DPAA2_INVALID_MBUF_SEQN; } - fd_arr[loop].simple.frc = 0; - DPAA2_RESET_FD_CTRL((&fd_arr[loop])); - DPAA2_SET_FD_FLC((&fd_arr[loop]), (size_t)NULL); if (likely(RTE_MBUF_DIRECT(*bufs))) { mp = (*bufs)->pool; /* Check the basic scenario and set @@ -720,7 +774,7 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) rte_mbuf_refcnt_read((*bufs)) == 1)) { if (unlikely(((*bufs)->ol_flags & PKT_TX_VLAN_PKT) || - (dev->data->dev_conf.txmode.offloads + (eth_data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_VLAN_INSERT))) { ret = rte_vlan_insert(bufs); if (ret) @@ -742,7 +796,7 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } if (unlikely(((*bufs)->ol_flags & PKT_TX_VLAN_PKT) || - (dev->data->dev_conf.txmode.offloads + (eth_data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_VLAN_INSERT))) { int ret = rte_vlan_insert(bufs); if (ret)