net/dpaa2: support raw pattern in dpdmux
[dpdk.git] / drivers / net / hns3 / hns3_rxtx.c
index afb1e7d..222cf8a 100644 (file)
@@ -2,28 +2,15 @@
  * Copyright(c) 2018-2019 Hisilicon Limited.
  */
 
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
 #include <rte_bus_pci.h>
-#include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
-#include <rte_dev.h>
-#include <rte_eal.h>
-#include <rte_ether.h>
 #include <rte_vxlan.h>
-#include <rte_ethdev_driver.h>
+#include <ethdev_driver.h>
 #include <rte_io.h>
-#include <rte_ip.h>
-#include <rte_gre.h>
 #include <rte_net.h>
 #include <rte_malloc.h>
-#include <rte_pci.h>
-#if defined(RTE_ARCH_ARM64) && defined(CC_SVE_SUPPORT)
+#if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE)
 #include <rte_cpuflags.h>
 #endif
 
@@ -269,7 +256,7 @@ hns3_alloc_rx_queue_mbufs(struct hns3_hw *hw, struct hns3_rx_queue *rxq)
        for (i = 0; i < rxq->nb_rx_desc; i++) {
                mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
                if (unlikely(mbuf == NULL)) {
-                       hns3_err(hw, "Failed to allocate RXD[%d] for rx queue!",
+                       hns3_err(hw, "Failed to allocate RXD[%u] for rx queue!",
                                 i);
                        hns3_rx_queue_release_mbufs(rxq);
                        return -ENOMEM;
@@ -366,6 +353,19 @@ hns3_update_all_queues_pvid_proc_en(struct hns3_hw *hw)
        }
 }
 
+static void
+hns3_stop_unused_queue(void *tqp_base, enum hns3_ring_type queue_type)
+{
+       uint32_t reg_offset;
+       uint32_t reg;
+
+       reg_offset = queue_type == HNS3_RING_TYPE_TX ?
+                                  HNS3_RING_TX_EN_REG : HNS3_RING_RX_EN_REG;
+       reg = hns3_read_reg(tqp_base, reg_offset);
+       reg &= ~BIT(HNS3_RING_EN_B);
+       hns3_write_reg(tqp_base, reg_offset, reg);
+}
+
 void
 hns3_enable_all_queues(struct hns3_hw *hw, bool en)
 {
@@ -381,16 +381,22 @@ hns3_enable_all_queues(struct hns3_hw *hw, bool en)
                if (hns3_dev_indep_txrx_supported(hw)) {
                        rxq = i < nb_rx_q ? hw->data->rx_queues[i] : NULL;
                        txq = i < nb_tx_q ? hw->data->tx_queues[i] : NULL;
+
+                       tqp_base = (void *)((char *)hw->io_base +
+                                       hns3_get_tqp_reg_offset(i));
                        /*
-                        * After initialization, rxq and txq won't be NULL at
-                        * the same time.
+                        * If queue struct is not initialized, it means the
+                        * related HW ring has not been initialized yet.
+                        * So, these queues should be disabled before enable
+                        * the tqps to avoid a HW exception since the queues
+                        * are enabled by default.
                         */
-                       if (rxq != NULL)
-                               tqp_base = rxq->io_base;
-                       else if (txq != NULL)
-                               tqp_base = txq->io_base;
-                       else
-                               return;
+                       if (rxq == NULL)
+                               hns3_stop_unused_queue(tqp_base,
+                                                       HNS3_RING_TYPE_RX);
+                       if (txq == NULL)
+                               hns3_stop_unused_queue(tqp_base,
+                                                       HNS3_RING_TYPE_TX);
                } else {
                        rxq = i < nb_rx_q ? hw->data->rx_queues[i] :
                              hw->fkq_data.rx_queues[i - nb_rx_q];
@@ -515,6 +521,26 @@ start_rxqs_fail:
        return -EINVAL;
 }
 
+void
+hns3_restore_tqp_enable_state(struct hns3_hw *hw)
+{
+       struct hns3_rx_queue *rxq;
+       struct hns3_tx_queue *txq;
+       uint16_t i;
+
+       for (i = 0; i < hw->data->nb_rx_queues; i++) {
+               rxq = hw->data->rx_queues[i];
+               if (rxq != NULL)
+                       hns3_enable_rxq(rxq, rxq->enabled);
+       }
+
+       for (i = 0; i < hw->data->nb_tx_queues; i++) {
+               txq = hw->data->tx_queues[i];
+               if (txq != NULL)
+                       hns3_enable_txq(txq, txq->enabled);
+       }
+}
+
 void
 hns3_stop_all_txqs(struct rte_eth_dev *dev)
 {
@@ -808,6 +834,24 @@ queue_reset_fail:
        return ret;
 }
 
+uint32_t
+hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id)
+{
+       uint32_t reg_offset;
+
+       /* Need an extend offset to config queues > 64 */
+       if (tqp_intr_id < HNS3_MIN_EXT_TQP_INTR_ID)
+               reg_offset = HNS3_TQP_INTR_REG_BASE +
+                            tqp_intr_id * HNS3_TQP_INTR_LOW_ORDER_OFFSET;
+       else
+               reg_offset = HNS3_TQP_INTR_EXT_REG_BASE +
+                            tqp_intr_id / HNS3_MIN_EXT_TQP_INTR_ID *
+                            HNS3_TQP_INTR_HIGH_ORDER_OFFSET +
+                            tqp_intr_id % HNS3_MIN_EXT_TQP_INTR_ID *
+                            HNS3_TQP_INTR_LOW_ORDER_OFFSET;
+
+       return reg_offset;
+}
 
 void
 hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id,
@@ -821,7 +865,7 @@ hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id,
        if (gl_idx >= RTE_DIM(offset) || gl_value > HNS3_TQP_INTR_GL_MAX)
                return;
 
-       addr = offset[gl_idx] + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = offset[gl_idx] + hns3_get_tqp_intr_reg_offset(queue_id);
        if (hw->intr.gl_unit == HNS3_INTR_COALESCE_GL_UINT_1US)
                value = gl_value | HNS3_TQP_INTR_GL_UNIT_1US;
        else
@@ -838,7 +882,7 @@ hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id, uint16_t rl_value)
        if (rl_value > HNS3_TQP_INTR_RL_MAX)
                return;
 
-       addr = HNS3_TQP_INTR_RL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_RL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        value = HNS3_RL_USEC_TO_REG(rl_value);
        if (value > 0)
                value |= HNS3_TQP_INTR_RL_ENABLE_MASK;
@@ -859,10 +903,10 @@ hns3_set_queue_intr_ql(struct hns3_hw *hw, uint16_t queue_id, uint16_t ql_value)
        if (hw->intr.int_ql_max == HNS3_INTR_QL_NONE)
                return;
 
-       addr = HNS3_TQP_INTR_TX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_TX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        hns3_write_dev(hw, addr, ql_value);
 
-       addr = HNS3_TQP_INTR_RX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_RX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        hns3_write_dev(hw, addr, ql_value);
 }
 
@@ -871,7 +915,7 @@ hns3_queue_intr_enable(struct hns3_hw *hw, uint16_t queue_id, bool en)
 {
        uint32_t addr, value;
 
-       addr = HNS3_TQP_INTR_CTRL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_CTRL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        value = en ? 1 : 0;
 
        hns3_write_dev(hw, addr, value);
@@ -1205,7 +1249,7 @@ hns3_alloc_rxq_and_dma_zone(struct rte_eth_dev *dev,
        rxq = rte_zmalloc_socket(q_info->type, sizeof(struct hns3_rx_queue),
                                 RTE_CACHE_LINE_SIZE, q_info->socket_id);
        if (rxq == NULL) {
-               hns3_err(hw, "Failed to allocate memory for No.%d rx ring!",
+               hns3_err(hw, "Failed to allocate memory for No.%u rx ring!",
                         q_info->idx);
                return NULL;
        }
@@ -1224,7 +1268,7 @@ hns3_alloc_rxq_and_dma_zone(struct rte_eth_dev *dev,
                                         rx_desc, HNS3_RING_BASE_ALIGN,
                                         q_info->socket_id);
        if (rx_mz == NULL) {
-               hns3_err(hw, "Failed to reserve DMA memory for No.%d rx ring!",
+               hns3_err(hw, "Failed to reserve DMA memory for No.%u rx ring!",
                         q_info->idx);
                hns3_rx_queue_release(rxq);
                return NULL;
@@ -1233,7 +1277,7 @@ hns3_alloc_rxq_and_dma_zone(struct rte_eth_dev *dev,
        rxq->rx_ring = (struct hns3_desc *)rx_mz->addr;
        rxq->rx_ring_phys_addr = rx_mz->iova;
 
-       hns3_dbg(hw, "No.%d rx descriptors iova 0x%" PRIx64, q_info->idx,
+       hns3_dbg(hw, "No.%u rx descriptors iova 0x%" PRIx64, q_info->idx,
                 rxq->rx_ring_phys_addr);
 
        return rxq;
@@ -1261,7 +1305,7 @@ hns3_fake_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
        q_info.ring_name = "rx_fake_ring";
        rxq = hns3_alloc_rxq_and_dma_zone(dev, &q_info);
        if (rxq == NULL) {
-               hns3_err(hw, "Failed to setup No.%d fake rx ring.", idx);
+               hns3_err(hw, "Failed to setup No.%u fake rx ring.", idx);
                return -ENOMEM;
        }
 
@@ -1298,7 +1342,7 @@ hns3_alloc_txq_and_dma_zone(struct rte_eth_dev *dev,
        txq = rte_zmalloc_socket(q_info->type, sizeof(struct hns3_tx_queue),
                                 RTE_CACHE_LINE_SIZE, q_info->socket_id);
        if (txq == NULL) {
-               hns3_err(hw, "Failed to allocate memory for No.%d tx ring!",
+               hns3_err(hw, "Failed to allocate memory for No.%u tx ring!",
                         q_info->idx);
                return NULL;
        }
@@ -1311,7 +1355,7 @@ hns3_alloc_txq_and_dma_zone(struct rte_eth_dev *dev,
                                         tx_desc, HNS3_RING_BASE_ALIGN,
                                         q_info->socket_id);
        if (tx_mz == NULL) {
-               hns3_err(hw, "Failed to reserve DMA memory for No.%d tx ring!",
+               hns3_err(hw, "Failed to reserve DMA memory for No.%u tx ring!",
                         q_info->idx);
                hns3_tx_queue_release(txq);
                return NULL;
@@ -1320,7 +1364,7 @@ hns3_alloc_txq_and_dma_zone(struct rte_eth_dev *dev,
        txq->tx_ring = (struct hns3_desc *)tx_mz->addr;
        txq->tx_ring_phys_addr = tx_mz->iova;
 
-       hns3_dbg(hw, "No.%d tx descriptors iova 0x%" PRIx64, q_info->idx,
+       hns3_dbg(hw, "No.%u tx descriptors iova 0x%" PRIx64, q_info->idx,
                 txq->tx_ring_phys_addr);
 
        /* Clear tx bd */
@@ -1355,7 +1399,7 @@ hns3_fake_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
        q_info.ring_name = "tx_fake_ring";
        txq = hns3_alloc_txq_and_dma_zone(dev, &q_info);
        if (txq == NULL) {
-               hns3_err(hw, "Failed to setup No.%d fake tx ring.", idx);
+               hns3_err(hw, "Failed to setup No.%u fake tx ring.", idx);
                return -ENOMEM;
        }
 
@@ -1577,7 +1621,6 @@ hns3_rx_buf_len_calc(struct rte_mempool *mp, uint16_t *rx_buf_len)
 
        vld_buf_size = (uint16_t)(rte_pktmbuf_data_room_size(mp) -
                        RTE_PKTMBUF_HEADROOM);
-
        if (vld_buf_size < HNS3_MIN_BD_BUF_SIZE)
                return -EINVAL;
 
@@ -1767,12 +1810,9 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
        rxq->io_head_reg = (volatile void *)((char *)rxq->io_base +
                           HNS3_RING_RX_HEAD_REG);
        rxq->rx_buf_len = rx_buf_size;
-       rxq->l2_errors = 0;
-       rxq->pkt_len_errors = 0;
-       rxq->l3_csum_errors = 0;
-       rxq->l4_csum_errors = 0;
-       rxq->ol3_csum_errors = 0;
-       rxq->ol4_csum_errors = 0;
+       memset(&rxq->basic_stats, 0, sizeof(struct hns3_rx_basic_stats));
+       memset(&rxq->err_stats, 0, sizeof(struct hns3_rx_bd_errors_stats));
+       memset(&rxq->dfx_stats, 0, sizeof(struct hns3_rx_dfx_stats));
 
        /* CRC len set here is used for amending packet length */
        if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC)
@@ -2442,7 +2482,7 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
 static bool
 hns3_check_sve_support(void)
 {
-#if defined(RTE_ARCH_ARM64) && defined(CC_SVE_SUPPORT)
+#if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE)
        if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SVE))
                return true;
 #endif
@@ -2488,8 +2528,8 @@ hns3_tx_queue_conf_check(struct hns3_hw *hw, const struct rte_eth_txconf *conf,
        if (rs_thresh + free_thresh > nb_desc || nb_desc % rs_thresh ||
            rs_thresh >= nb_desc - HNS3_TX_RS_FREE_THRESH_GAP ||
            free_thresh >= nb_desc - HNS3_TX_RS_FREE_THRESH_GAP) {
-               hns3_err(hw, "tx_rs_thresh (%d) tx_free_thresh (%d) nb_desc "
-                        "(%d) of tx descriptors for port=%d queue=%d check "
+               hns3_err(hw, "tx_rs_thresh (%u) tx_free_thresh (%u) nb_desc "
+                        "(%u) of tx descriptors for port=%u queue=%u check "
                         "fail!",
                         rs_thresh, free_thresh, nb_desc, hw->data->port_id,
                         idx);
@@ -2597,12 +2637,9 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
                                             HNS3_RING_TX_TAIL_REG);
        txq->min_tx_pkt_len = hw->min_tx_pkt_len;
        txq->tso_mode = hw->tso_mode;
-       txq->over_length_pkt_cnt = 0;
-       txq->exceed_limit_bd_pkt_cnt = 0;
-       txq->exceed_limit_bd_reassem_fail = 0;
-       txq->unsupported_tunnel_pkt_cnt = 0;
-       txq->queue_full_cnt = 0;
-       txq->pkt_padding_fail_cnt = 0;
+       memset(&txq->basic_stats, 0, sizeof(struct hns3_tx_basic_stats));
+       memset(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats));
+
        rte_spinlock_lock(&hw->lock);
        dev->data->tx_queues[idx] = txq;
        rte_spinlock_unlock(&hw->lock);
@@ -3325,7 +3362,7 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
        if (m->ol_flags & HNS3_TX_CKSUM_OFFLOAD_MASK) {
                /* Fill in tunneling parameters if necessary */
                if (hns3_parse_tunneling_params(txq, m, tx_desc_id)) {
-                       txq->unsupported_tunnel_pkt_cnt++;
+                       txq->dfx_stats.unsupported_tunnel_pkt_cnt++;
                                return -EINVAL;
                }
 
@@ -3355,17 +3392,17 @@ hns3_check_non_tso_pkt(uint16_t nb_buf, struct rte_mbuf **m_seg,
         * driver support, the packet will be ignored.
         */
        if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN)) {
-               txq->over_length_pkt_cnt++;
+               txq->dfx_stats.over_length_pkt_cnt++;
                return -EINVAL;
        }
 
        max_non_tso_bd_num = txq->max_non_tso_bd_num;
        if (unlikely(nb_buf > max_non_tso_bd_num)) {
-               txq->exceed_limit_bd_pkt_cnt++;
+               txq->dfx_stats.exceed_limit_bd_pkt_cnt++;
                ret = hns3_reassemble_tx_pkts(tx_pkt, &new_pkt,
                                              max_non_tso_bd_num);
                if (ret) {
-                       txq->exceed_limit_bd_reassem_fail++;
+                       txq->dfx_stats.exceed_limit_bd_reassem_fail++;
                        return ret;
                }
                *m_seg = new_pkt;
@@ -3503,7 +3540,7 @@ hns3_xmit_pkts_simple(void *tx_queue,
        nb_pkts = RTE_MIN(txq->tx_bd_ready, nb_pkts);
        if (unlikely(nb_pkts == 0)) {
                if (txq->tx_bd_ready == 0)
-                       txq->queue_full_cnt++;
+                       txq->dfx_stats.queue_full_cnt++;
                return 0;
        }
 
@@ -3555,7 +3592,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                nb_buf = tx_pkt->nb_segs;
 
                if (nb_buf > txq->tx_bd_ready) {
-                       txq->queue_full_cnt++;
+                       txq->dfx_stats.queue_full_cnt++;
                        if (nb_tx == 0)
                                return 0;
 
@@ -3576,7 +3613,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                                         rte_pktmbuf_pkt_len(tx_pkt);
                        appended = rte_pktmbuf_append(tx_pkt, add_len);
                        if (appended == NULL) {
-                               txq->pkt_padding_fail_cnt++;
+                               txq->dfx_stats.pkt_padding_fail_cnt++;
                                break;
                        }
 
@@ -3719,7 +3756,7 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev)
        eth_tx_prep_t prep = NULL;
 
        if (hns->hw.adapter_state == HNS3_NIC_STARTED &&
-           rte_atomic16_read(&hns->hw.reset.resetting) == 0) {
+           __atomic_load_n(&hns->hw.reset.resetting, __ATOMIC_RELAXED) == 0) {
                eth_dev->rx_pkt_burst = hns3_get_rx_function(eth_dev);
                eth_dev->tx_pkt_burst = hns3_get_tx_function(eth_dev, &prep);
                eth_dev->tx_pkt_prepare = prep;