@@ -317,6 +317,15 @@ ionic_cq_init(struct ionic_cq *cq, uint16_t num_descs)
return 0;
}
+void
+ionic_cq_reset(struct ionic_cq *cq)
+{
+ cq->tail_idx = 0;
+ cq->done_color = 1;
+
+ memset(cq->base, 0, sizeof(struct ionic_nop_comp) * cq->num_descs);
+}
+
void
ionic_cq_map(struct ionic_cq *cq, void *base, rte_iova_t base_pa)
{
@@ -379,3 +388,10 @@ ionic_q_sg_map(struct ionic_queue *q, void *base, rte_iova_t base_pa)
q->sg_base = base;
q->sg_base_pa = base_pa;
}
+
+void
+ionic_q_reset(struct ionic_queue *q)
+{
+ q->head_idx = 0;
+ q->tail_idx = 0;
+}
@@ -225,6 +225,7 @@ struct ionic_doorbell __iomem *ionic_db_map(struct ionic_lif *lif,
struct ionic_queue *q);
int ionic_cq_init(struct ionic_cq *cq, uint16_t num_descs);
+void ionic_cq_reset(struct ionic_cq *cq);
void ionic_cq_map(struct ionic_cq *cq, void *base, rte_iova_t base_pa);
typedef bool (*ionic_cq_cb)(struct ionic_cq *cq, uint16_t cq_desc_index,
void *cb_arg);
@@ -232,6 +233,7 @@ uint32_t ionic_cq_service(struct ionic_cq *cq, uint32_t work_to_do,
ionic_cq_cb cb, void *cb_arg);
int ionic_q_init(struct ionic_queue *q, uint32_t index, uint16_t num_descs);
+void ionic_q_reset(struct ionic_queue *q);
void ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);
void ionic_q_sg_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);
@@ -30,25 +30,7 @@ static const uint8_t ionic_qtype_vers[IONIC_QTYPE_MAX] = {
static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
-int
-ionic_qcq_enable(struct ionic_qcq *qcq)
-{
- struct ionic_queue *q = &qcq->q;
- struct ionic_lif *lif = qcq->lif;
- struct ionic_admin_ctx ctx = {
- .pending_work = true,
- .cmd.q_control = {
- .opcode = IONIC_CMD_Q_CONTROL,
- .type = q->type,
- .index = rte_cpu_to_le_32(q->index),
- .oper = IONIC_Q_ENABLE,
- },
- };
-
- return ionic_adminq_post_wait(lif, &ctx);
-}
-
-int
+static int
ionic_qcq_disable(struct ionic_qcq *qcq)
{
struct ionic_queue *q = &qcq->q;
@@ -133,7 +115,6 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
for (i = 0; i < lif->nrxqcqs; i++) {
struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats;
stats->ierrors +=
- rx_stats->no_cb_arg +
rx_stats->bad_cq_status +
rx_stats->no_room +
rx_stats->bad_len;
@@ -154,7 +135,6 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
stats->q_ipackets[i] = rx_stats->packets;
stats->q_ibytes[i] = rx_stats->bytes;
stats->q_errors[i] =
- rx_stats->no_cb_arg +
rx_stats->bad_cq_status +
rx_stats->no_room +
rx_stats->bad_len;
@@ -1146,12 +1126,16 @@ ionic_lif_rss_teardown(struct ionic_lif *lif)
void
ionic_lif_txq_deinit(struct ionic_tx_qcq *txq)
{
+ ionic_qcq_disable(&txq->qcq);
+
txq->flags &= ~IONIC_QCQ_F_INITED;
}
void
ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq)
{
+ ionic_qcq_disable(&rxq->qcq);
+
rxq->flags &= ~IONIC_QCQ_F_INITED;
}
@@ -1488,6 +1472,9 @@ ionic_lif_txq_init(struct ionic_tx_qcq *txq)
ctx.cmd.q_init.ring_size);
IONIC_PRINT(DEBUG, "txq_init.ver %u", ctx.cmd.q_init.ver);
+ ionic_q_reset(q);
+ ionic_cq_reset(cq);
+
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
@@ -1536,6 +1523,9 @@ ionic_lif_rxq_init(struct ionic_rx_qcq *rxq)
ctx.cmd.q_init.ring_size);
IONIC_PRINT(DEBUG, "rxq_init.ver %u", ctx.cmd.q_init.ver);
+ ionic_q_reset(q);
+ ionic_cq_reset(cq);
+
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
@@ -39,7 +39,6 @@ struct ionic_tx_stats {
struct ionic_rx_stats {
uint64_t packets;
uint64_t bytes;
- uint64_t no_cb_arg;
uint64_t bad_cq_status;
uint64_t no_room;
uint64_t bad_len;
@@ -207,9 +206,6 @@ int ionic_tx_qcq_alloc(struct ionic_lif *lif, uint32_t socket_id,
struct ionic_tx_qcq **qcq_out);
void ionic_qcq_free(struct ionic_qcq *qcq);
-int ionic_qcq_enable(struct ionic_qcq *qcq);
-int ionic_qcq_disable(struct ionic_qcq *qcq);
-
int ionic_lif_rxq_init(struct ionic_rx_qcq *rxq);
void ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq);
@@ -47,6 +47,34 @@
#include "ionic_lif.h"
#include "ionic_rxtx.h"
+static void
+ionic_empty_array(void **array, uint32_t cnt, uint16_t idx)
+{
+ uint32_t i;
+
+ for (i = idx; i < cnt; i++)
+ if (array[i])
+ rte_pktmbuf_free_seg(array[i]);
+
+ memset(array, 0, sizeof(void *) * cnt);
+}
+
+static void __rte_cold
+ionic_tx_empty(struct ionic_tx_qcq *txq)
+{
+ struct ionic_queue *q = &txq->qcq.q;
+
+ ionic_empty_array(q->info, q->num_descs, 0);
+}
+
+static void __rte_cold
+ionic_rx_empty(struct ionic_rx_qcq *rxq)
+{
+ struct ionic_queue *q = &rxq->qcq.q;
+
+ ionic_empty_array(q->info, q->num_descs, 0);
+}
+
/*********************************************************************
*
* TX functions
@@ -121,21 +149,16 @@ void __rte_cold
ionic_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
{
struct ionic_tx_qcq *txq = dev->data->tx_queues[qid];
- struct ionic_tx_stats *stats = &txq->stats;
IONIC_PRINT_CALL();
- IONIC_PRINT(DEBUG, "TX queue %u pkts %ju tso %ju",
- txq->qcq.q.index, stats->packets, stats->tso);
-
- ionic_lif_txq_deinit(txq);
-
ionic_qcq_free(&txq->qcq);
}
int __rte_cold
ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
{
+ struct ionic_tx_stats *stats;
struct ionic_tx_qcq *txq;
IONIC_PRINT(DEBUG, "Stopping TX queue %u", tx_queue_id);
@@ -150,9 +173,14 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
* before disabling Tx queue
*/
- ionic_qcq_disable(&txq->qcq);
+ ionic_lif_txq_deinit(txq);
- ionic_tx_flush(txq);
+ /* Free all buffers from descriptor ring */
+ ionic_tx_empty(txq);
+
+ stats = &txq->stats;
+ IONIC_PRINT(DEBUG, "TX queue %u pkts %ju tso %ju",
+ txq->qcq.q.index, stats->packets, stats->tso);
return 0;
}
@@ -236,13 +264,9 @@ ionic_dev_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
IONIC_PRINT(DEBUG, "Starting TX queue %u, %u descs",
tx_queue_id, txq->qcq.q.num_descs);
- if (!(txq->flags & IONIC_QCQ_F_INITED)) {
- err = ionic_lif_txq_init(txq);
- if (err)
- return err;
- } else {
- ionic_qcq_enable(&txq->qcq);
- }
+ err = ionic_lif_txq_init(txq);
+ if (err)
+ return err;
tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
@@ -648,42 +672,16 @@ ionic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
}
-static void __rte_cold
-ionic_rx_empty(struct ionic_rx_qcq *rxq)
-{
- struct ionic_queue *q = &rxq->qcq.q;
- struct rte_mbuf *mbuf;
- void **info;
-
- while (q->tail_idx != q->head_idx) {
- info = IONIC_INFO_PTR(q, q->tail_idx);
- mbuf = info[0];
- rte_mempool_put(rxq->mb_pool, mbuf);
-
- q->tail_idx = Q_NEXT_TO_SRVC(q, 1);
- }
-}
-
void __rte_cold
ionic_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
{
struct ionic_rx_qcq *rxq = dev->data->rx_queues[qid];
- struct ionic_rx_stats *stats;
if (!rxq)
return;
IONIC_PRINT_CALL();
- stats = &rxq->stats;
-
- IONIC_PRINT(DEBUG, "RX queue %u pkts %ju mtod %ju",
- rxq->qcq.q.index, stats->packets, stats->mtods);
-
- ionic_rx_empty(rxq);
-
- ionic_lif_rxq_deinit(rxq);
-
ionic_qcq_free(&rxq->qcq);
}
@@ -787,17 +785,6 @@ ionic_rx_clean(struct ionic_rx_qcq *rxq,
rxm = info[0];
- if (!rx_svc) {
- stats->no_cb_arg++;
- /* Flush */
- rte_pktmbuf_free(rxm);
- /*
- * Note: rte_mempool_put is faster with no segs
- * rte_mempool_put(rxq->mb_pool, rxm);
- */
- return;
- }
-
if (cq_desc->status) {
stats->bad_cq_status++;
ionic_rx_recycle(q, q_desc_index, rxm);
@@ -1028,13 +1015,9 @@ ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
IONIC_PRINT(DEBUG, "Starting RX queue %u, %u descs, size %u",
rx_queue_id, rxq->qcq.q.num_descs, rxq->frame_size);
- if (!(rxq->flags & IONIC_QCQ_F_INITED)) {
- err = ionic_lif_rxq_init(rxq);
- if (err)
- return err;
- } else {
- ionic_qcq_enable(&rxq->qcq);
- }
+ err = ionic_lif_rxq_init(rxq);
+ if (err)
+ return err;
/* Allocate buffers for descriptor rings */
if (ionic_rx_fill(rxq) != 0) {
@@ -1103,19 +1086,24 @@ ionic_rxq_service(struct ionic_rx_qcq *rxq, uint32_t work_to_do,
int __rte_cold
ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
{
+ uint8_t *rx_queue_state = eth_dev->data->rx_queue_state;
+ struct ionic_rx_stats *stats;
struct ionic_rx_qcq *rxq;
IONIC_PRINT(DEBUG, "Stopping RX queue %u", rx_queue_id);
rxq = eth_dev->data->rx_queues[rx_queue_id];
- eth_dev->data->rx_queue_state[rx_queue_id] =
- RTE_ETH_QUEUE_STATE_STOPPED;
+ rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ ionic_lif_rxq_deinit(rxq);
- ionic_qcq_disable(&rxq->qcq);
+ /* Free all buffers from descriptor ring */
+ ionic_rx_empty(rxq);
- /* Flush */
- ionic_rxq_service(rxq, -1, NULL);
+ stats = &rxq->stats;
+ IONIC_PRINT(DEBUG, "RX queue %u pkts %ju mtod %ju",
+ rxq->qcq.q.index, stats->packets, stats->mtods);
return 0;
}