numam-dpdk/drivers/net/hns3/hns3_rxtx_vec.c
Min Hu (Connor) fa485faca2 net/hns3: update HiSilicon copyright syntax
According to the suggestion of our legal department,
to standardize the copyright license of our code to
avoid potential copyright risks, we make a unified
modification to the "Hisilicon", which was nonstandard,
in the main modules we maintain.

We change it to "HiSilicon", which is consistent with
the terms used on the following official website:
https://www.hisilicon.com/en/terms-of-use.

Fixes: 565829db8b ("net/hns3: add build and doc infrastructure")
Fixes: 952ebacce4 ("net/hns3: support SVE Rx")
Fixes: e31f123db0 ("net/hns3: support NEON Tx")
Fixes: c09c7847d8 ("net/hns3: support traffic management")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
2021-04-06 18:28:13 +02:00

216 lines
5.5 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2020 HiSilicon Limited.
*/
#include <rte_io.h>
#include <ethdev_driver.h>
#include "hns3_ethdev.h"
#include "hns3_rxtx.h"
#include "hns3_rxtx_vec.h"
#if defined RTE_ARCH_ARM64
#include "hns3_rxtx_vec_neon.h"
#endif
int
hns3_tx_check_vec_support(struct rte_eth_dev *dev)
{
struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (hns3_dev_ptp_supported(hw))
return -ENOTSUP;
/* Only support DEV_TX_OFFLOAD_MBUF_FAST_FREE */
if (txmode->offloads != DEV_TX_OFFLOAD_MBUF_FAST_FREE)
return -ENOTSUP;
return 0;
}
uint16_t
hns3_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
struct hns3_tx_queue *txq = (struct hns3_tx_queue *)tx_queue;
uint16_t nb_tx = 0;
while (nb_pkts) {
uint16_t ret, new_burst;
new_burst = RTE_MIN(nb_pkts, txq->tx_rs_thresh);
ret = hns3_xmit_fixed_burst_vec(tx_queue, &tx_pkts[nb_tx],
new_burst);
nb_tx += ret;
nb_pkts -= ret;
if (ret < new_burst)
break;
}
return nb_tx;
}
static inline void
hns3_rxq_rearm_mbuf(struct hns3_rx_queue *rxq)
{
#define REARM_LOOP_STEP_NUM 4
struct hns3_entry *rxep = &rxq->sw_ring[rxq->rx_rearm_start];
struct hns3_desc *rxdp = rxq->rx_ring + rxq->rx_rearm_start;
uint64_t dma_addr;
int i;
if (unlikely(rte_mempool_get_bulk(rxq->mb_pool, (void *)rxep,
HNS3_DEFAULT_RXQ_REARM_THRESH) < 0)) {
rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed++;
return;
}
for (i = 0; i < HNS3_DEFAULT_RXQ_REARM_THRESH; i += REARM_LOOP_STEP_NUM,
rxep += REARM_LOOP_STEP_NUM, rxdp += REARM_LOOP_STEP_NUM) {
if (likely(i <
HNS3_DEFAULT_RXQ_REARM_THRESH - REARM_LOOP_STEP_NUM)) {
rte_prefetch_non_temporal(rxep[4].mbuf);
rte_prefetch_non_temporal(rxep[5].mbuf);
rte_prefetch_non_temporal(rxep[6].mbuf);
rte_prefetch_non_temporal(rxep[7].mbuf);
}
dma_addr = rte_mbuf_data_iova_default(rxep[0].mbuf);
rxdp[0].addr = rte_cpu_to_le_64(dma_addr);
rxdp[0].rx.bd_base_info = 0;
dma_addr = rte_mbuf_data_iova_default(rxep[1].mbuf);
rxdp[1].addr = rte_cpu_to_le_64(dma_addr);
rxdp[1].rx.bd_base_info = 0;
dma_addr = rte_mbuf_data_iova_default(rxep[2].mbuf);
rxdp[2].addr = rte_cpu_to_le_64(dma_addr);
rxdp[2].rx.bd_base_info = 0;
dma_addr = rte_mbuf_data_iova_default(rxep[3].mbuf);
rxdp[3].addr = rte_cpu_to_le_64(dma_addr);
rxdp[3].rx.bd_base_info = 0;
}
rxq->rx_rearm_start += HNS3_DEFAULT_RXQ_REARM_THRESH;
if (rxq->rx_rearm_start >= rxq->nb_rx_desc)
rxq->rx_rearm_start = 0;
rxq->rx_rearm_nb -= HNS3_DEFAULT_RXQ_REARM_THRESH;
hns3_write_reg_opt(rxq->io_head_reg, HNS3_DEFAULT_RXQ_REARM_THRESH);
}
uint16_t
hns3_recv_pkts_vec(void *__restrict rx_queue,
struct rte_mbuf **__restrict rx_pkts,
uint16_t nb_pkts)
{
struct hns3_rx_queue *rxq = rx_queue;
struct hns3_desc *rxdp = &rxq->rx_ring[rxq->next_to_use];
uint64_t bd_err_mask; /* bit mask indicate whick pkts is error */
uint16_t nb_rx;
nb_pkts = RTE_MIN(nb_pkts, HNS3_DEFAULT_RX_BURST);
nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, HNS3_DEFAULT_DESCS_PER_LOOP);
rte_prefetch_non_temporal(rxdp);
if (rxq->rx_rearm_nb > HNS3_DEFAULT_RXQ_REARM_THRESH)
hns3_rxq_rearm_mbuf(rxq);
if (unlikely(!(rxdp->rx.bd_base_info &
rte_cpu_to_le_32(1u << HNS3_RXD_VLD_B))))
return 0;
rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 0].mbuf);
rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 1].mbuf);
rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 2].mbuf);
rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 3].mbuf);
bd_err_mask = 0;
nb_rx = hns3_recv_burst_vec(rxq, rx_pkts, nb_pkts, &bd_err_mask);
if (unlikely(bd_err_mask))
nb_rx = hns3_rx_reassemble_pkts(rx_pkts, nb_rx, bd_err_mask);
return nb_rx;
}
static void
hns3_rxq_vec_setup_rearm_data(struct hns3_rx_queue *rxq)
{
uintptr_t p;
struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
mb_def.nb_segs = 1;
mb_def.data_off = RTE_PKTMBUF_HEADROOM;
mb_def.port = rxq->port_id;
rte_mbuf_refcnt_set(&mb_def, 1);
/* prevent compiler reordering: rearm_data covers previous fields */
rte_compiler_barrier();
p = (uintptr_t)&mb_def.rearm_data;
rxq->mbuf_initializer = *(uint64_t *)p;
}
void
hns3_rxq_vec_setup(struct hns3_rx_queue *rxq)
{
struct hns3_entry *sw_ring = &rxq->sw_ring[rxq->nb_rx_desc];
unsigned int i;
memset(&rxq->rx_ring[rxq->nb_rx_desc], 0,
sizeof(struct hns3_desc) * HNS3_DEFAULT_RX_BURST);
memset(&rxq->fake_mbuf, 0, sizeof(rxq->fake_mbuf));
for (i = 0; i < HNS3_DEFAULT_RX_BURST; i++)
sw_ring[i].mbuf = &rxq->fake_mbuf;
hns3_rxq_vec_setup_rearm_data(rxq);
memset(rxq->offset_table, 0, sizeof(rxq->offset_table));
}
static int
hns3_rxq_vec_check(struct hns3_rx_queue *rxq, void *arg)
{
uint32_t min_vec_bds = HNS3_DEFAULT_RXQ_REARM_THRESH +
HNS3_DEFAULT_RX_BURST;
if (rxq->nb_rx_desc < min_vec_bds)
return -ENOTSUP;
if (rxq->nb_rx_desc % HNS3_DEFAULT_RXQ_REARM_THRESH)
return -ENOTSUP;
RTE_SET_USED(arg);
return 0;
}
int
hns3_rx_check_vec_support(struct rte_eth_dev *dev)
{
struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
uint64_t offloads_mask = DEV_RX_OFFLOAD_TCP_LRO |
DEV_RX_OFFLOAD_VLAN;
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (hns3_dev_ptp_supported(hw))
return -ENOTSUP;
if (dev->data->scattered_rx)
return -ENOTSUP;
if (fconf->mode != RTE_FDIR_MODE_NONE)
return -ENOTSUP;
if (rxmode->offloads & offloads_mask)
return -ENOTSUP;
if (hns3_rxq_iterate(dev, hns3_rxq_vec_check, NULL) != 0)
return -ENOTSUP;
return 0;
}