if (dev->npc_flow.switch_header_type == 0)
return 0;
+ if (dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_LEN_90B &&
+ !otx2_dev_is_sdp(dev)) {
+ otx2_err("chlen90b is not supported on non-SDP device");
+ return -EINVAL;
+ }
+
/* Notify AF about higig2 config */
req = otx2_mbox_alloc_msg_npc_set_pkind(mbox);
req->mode = dev->npc_flow.switch_header_type;
NIX_CQ_ALIGN, dev->node);
if (rz == NULL) {
otx2_err("Failed to allocate mem for cq hw ring");
- rc = -ENOMEM;
- goto fail;
+ return -ENOMEM;
}
memset(rz->addr, 0, rz->len);
rxq->desc = (uintptr_t)rz->addr;
rc = otx2_mbox_process(mbox);
if (rc) {
otx2_err("Failed to init cq context");
- goto fail;
+ return rc;
}
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
aq->rq.first_skip = first_skip;
aq->rq.later_skip = (sizeof(struct rte_mbuf) / 8);
aq->rq.flow_tagw = 32; /* 32-bits */
- aq->rq.lpb_sizem1 = rte_pktmbuf_data_room_size(mp);
- aq->rq.lpb_sizem1 += rte_pktmbuf_priv_size(mp);
- aq->rq.lpb_sizem1 += sizeof(struct rte_mbuf);
- aq->rq.lpb_sizem1 /= 8;
+ aq->rq.lpb_sizem1 = mp->elt_size / 8;
aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
aq->rq.ena = 1;
aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
rc = otx2_mbox_process(mbox);
if (rc) {
otx2_err("Failed to init rq context");
- goto fail;
+ return rc;
+ }
+
+ if (dev->lock_rx_ctx) {
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ aq->qidx = qid;
+ aq->ctype = NIX_AQ_CTYPE_CQ;
+ aq->op = NIX_AQ_INSTOP_LOCK;
+
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ if (!aq) {
+ /* The shared memory buffer can be full.
+ * Flush it and retry
+ */
+ otx2_mbox_msg_send(mbox, 0);
+ rc = otx2_mbox_wait_for_rsp(mbox, 0);
+ if (rc < 0) {
+ otx2_err("Failed to LOCK cq context");
+ return rc;
+ }
+
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ if (!aq) {
+ otx2_err("Failed to LOCK rq context");
+ return -ENOMEM;
+ }
+ }
+ aq->qidx = qid;
+ aq->ctype = NIX_AQ_CTYPE_RQ;
+ aq->op = NIX_AQ_INSTOP_LOCK;
+ rc = otx2_mbox_process(mbox);
+ if (rc < 0) {
+ otx2_err("Failed to LOCK rq context");
+ return rc;
+ }
}
return 0;
-fail:
- return rc;
}
static int
return rc;
}
+ if (dev->lock_rx_ctx) {
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ aq->qidx = rxq->rq;
+ aq->ctype = NIX_AQ_CTYPE_CQ;
+ aq->op = NIX_AQ_INSTOP_UNLOCK;
+
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ if (!aq) {
+ /* The shared memory buffer can be full.
+ * Flush it and retry
+ */
+ otx2_mbox_msg_send(mbox, 0);
+ rc = otx2_mbox_wait_for_rsp(mbox, 0);
+ if (rc < 0) {
+ otx2_err("Failed to UNLOCK cq context");
+ return rc;
+ }
+
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ if (!aq) {
+ otx2_err("Failed to UNLOCK rq context");
+ return -ENOMEM;
+ }
+ }
+ aq->qidx = rxq->rq;
+ aq->ctype = NIX_AQ_CTYPE_RQ;
+ aq->op = NIX_AQ_INSTOP_UNLOCK;
+ rc = otx2_mbox_process(mbox);
+ if (rc < 0) {
+ otx2_err("Failed to UNLOCK rq context");
+ return rc;
+ }
+ }
+
return 0;
}
if (eth_dev->data->rx_queues[rq] != NULL) {
otx2_nix_dbg("Freeing memory prior to re-allocation %d", rq);
otx2_nix_rx_queue_release(eth_dev->data->rx_queues[rq]);
+ rte_eth_dma_zone_free(eth_dev, "cq", rq);
eth_dev->data->rx_queues[rq] = NULL;
}
return flags;
}
+static int
+nix_sqb_lock(struct rte_mempool *mp)
+{
+ struct otx2_npa_lf *npa_lf = otx2_intra_dev_get_cfg()->npa_lf;
+ struct npa_aq_enq_req *req;
+ int rc;
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ req->aura_id = npa_lf_aura_handle_to_aura(mp->pool_id);
+ req->ctype = NPA_AQ_CTYPE_AURA;
+ req->op = NPA_AQ_INSTOP_LOCK;
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ if (!req) {
+ /* The shared memory buffer can be full.
+ * Flush it and retry
+ */
+ otx2_mbox_msg_send(npa_lf->mbox, 0);
+ rc = otx2_mbox_wait_for_rsp(npa_lf->mbox, 0);
+ if (rc < 0) {
+ otx2_err("Failed to LOCK AURA context");
+ return rc;
+ }
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ if (!req) {
+ otx2_err("Failed to LOCK POOL context");
+ return -ENOMEM;
+ }
+ }
+
+ req->aura_id = npa_lf_aura_handle_to_aura(mp->pool_id);
+ req->ctype = NPA_AQ_CTYPE_POOL;
+ req->op = NPA_AQ_INSTOP_LOCK;
+
+ rc = otx2_mbox_process(npa_lf->mbox);
+ if (rc < 0) {
+ otx2_err("Unable to lock POOL in NDC");
+ return rc;
+ }
+
+ return 0;
+}
+
+static int
+nix_sqb_unlock(struct rte_mempool *mp)
+{
+ struct otx2_npa_lf *npa_lf = otx2_intra_dev_get_cfg()->npa_lf;
+ struct npa_aq_enq_req *req;
+ int rc;
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ req->aura_id = npa_lf_aura_handle_to_aura(mp->pool_id);
+ req->ctype = NPA_AQ_CTYPE_AURA;
+ req->op = NPA_AQ_INSTOP_UNLOCK;
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ if (!req) {
+ /* The shared memory buffer can be full.
+ * Flush it and retry
+ */
+ otx2_mbox_msg_send(npa_lf->mbox, 0);
+ rc = otx2_mbox_wait_for_rsp(npa_lf->mbox, 0);
+ if (rc < 0) {
+ otx2_err("Failed to UNLOCK AURA context");
+ return rc;
+ }
+
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ if (!req) {
+ otx2_err("Failed to UNLOCK POOL context");
+ return -ENOMEM;
+ }
+ }
+ req = otx2_mbox_alloc_msg_npa_aq_enq(npa_lf->mbox);
+ req->aura_id = npa_lf_aura_handle_to_aura(mp->pool_id);
+ req->ctype = NPA_AQ_CTYPE_POOL;
+ req->op = NPA_AQ_INSTOP_UNLOCK;
+
+ rc = otx2_mbox_process(npa_lf->mbox);
+ if (rc < 0) {
+ otx2_err("Unable to UNLOCK AURA in NDC");
+ return rc;
+ }
+
+ return 0;
+}
+
static int
nix_sq_init(struct otx2_eth_txq *txq)
{
/* Many to one reduction */
sq->sq.qint_idx = txq->sq % dev->qints;
- return otx2_mbox_process(mbox);
+ rc = otx2_mbox_process(mbox);
+ if (rc < 0)
+ return rc;
+
+ if (dev->lock_tx_ctx) {
+ sq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ sq->qidx = txq->sq;
+ sq->ctype = NIX_AQ_CTYPE_SQ;
+ sq->op = NIX_AQ_INSTOP_LOCK;
+
+ rc = otx2_mbox_process(mbox);
+ }
+
+ return rc;
}
static int
if (rc)
return rc;
+ if (dev->lock_tx_ctx) {
+ /* Unlock sq */
+ aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
+ aq->qidx = txq->sq;
+ aq->ctype = NIX_AQ_CTYPE_SQ;
+ aq->op = NIX_AQ_INSTOP_UNLOCK;
+
+ rc = otx2_mbox_process(mbox);
+ if (rc < 0)
+ return rc;
+
+ nix_sqb_unlock(txq->sqb_pool);
+ }
+
/* Read SQ and free sqb's */
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
aq->qidx = txq->sq;
}
nix_sqb_aura_limit_cfg(txq->sqb_pool, txq->nb_sqb_bufs);
+ if (dev->lock_tx_ctx)
+ nix_sqb_lock(txq->sqb_pool);
return 0;
fail:
txq = (struct otx2_eth_txq **)eth_dev->data->tx_queues;
for (i = 0; i < nb_txq; i++) {
if (txq[i] == NULL) {
- otx2_err("txq[%d] is already released", i);
- goto fail;
+ tx_qconf[i].valid = false;
+ otx2_info("txq[%d] is already released", i);
+ continue;
}
memcpy(&tx_qconf[i], &txq[i]->qconf, sizeof(*tx_qconf));
+ tx_qconf[i].valid = true;
otx2_nix_tx_queue_release(txq[i]);
eth_dev->data->tx_queues[i] = NULL;
}
rxq = (struct otx2_eth_rxq **)eth_dev->data->rx_queues;
for (i = 0; i < nb_rxq; i++) {
if (rxq[i] == NULL) {
- otx2_err("rxq[%d] is already released", i);
- goto fail;
+ rx_qconf[i].valid = false;
+ otx2_info("rxq[%d] is already released", i);
+ continue;
}
memcpy(&rx_qconf[i], &rxq[i]->qconf, sizeof(*rx_qconf));
+ rx_qconf[i].valid = true;
otx2_nix_rx_queue_release(rxq[i]);
eth_dev->data->rx_queues[i] = NULL;
}
* queues are already setup in port_configure().
*/
for (i = 0; i < nb_txq; i++) {
+ if (!tx_qconf[i].valid)
+ continue;
rc = otx2_nix_tx_queue_setup(eth_dev, i, tx_qconf[i].nb_desc,
tx_qconf[i].socket_id,
&tx_qconf[i].conf.tx);
free(tx_qconf); tx_qconf = NULL;
for (i = 0; i < nb_rxq; i++) {
+ if (!rx_qconf[i].valid)
+ continue;
rc = otx2_nix_rx_queue_setup(eth_dev, i, rx_qconf[i].nb_desc,
rx_qconf[i].socket_id,
&rx_qconf[i].conf.rx,
.txq_info_get = otx2_nix_txq_info_get,
.rx_burst_mode_get = otx2_rx_burst_mode_get,
.tx_burst_mode_get = otx2_tx_burst_mode_get,
- .rx_queue_count = otx2_nix_rx_queue_count,
- .rx_descriptor_done = otx2_nix_rx_descriptor_done,
- .rx_descriptor_status = otx2_nix_rx_descriptor_status,
- .tx_descriptor_status = otx2_nix_tx_descriptor_status,
.tx_done_cleanup = otx2_nix_tx_done_cleanup,
.set_queue_rate_limit = otx2_nix_tm_set_queue_rate_limit,
.pool_ops_supported = otx2_nix_pool_ops_supported,
return false;
}
+static inline uint64_t
+nix_get_blkaddr(struct otx2_eth_dev *dev)
+{
+ uint64_t reg;
+
+ /* Reading the discovery register to know which NIX is the LF
+ * attached to.
+ */
+ reg = otx2_read64(dev->bar2 +
+ RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_NIX0));
+
+ return reg & 0x1FFULL ? RVU_BLOCK_ADDR_NIX0 : RVU_BLOCK_ADDR_NIX1;
+}
+
static int
otx2_eth_dev_init(struct rte_eth_dev *eth_dev)
{
int rc, max_entries;
eth_dev->dev_ops = &otx2_eth_dev_ops;
+ eth_dev->rx_descriptor_done = otx2_nix_rx_descriptor_done;
+ eth_dev->rx_queue_count = otx2_nix_rx_queue_count;
+ eth_dev->rx_descriptor_status = otx2_nix_rx_descriptor_status;
+ eth_dev->tx_descriptor_status = otx2_nix_tx_descriptor_status;
/* For secondary processes, the primary has done all the work */
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
dev->configured = 0;
dev->drv_inited = true;
dev->ptype_disable = 0;
- dev->base = dev->bar2 + (RVU_BLOCK_ADDR_NIX0 << 20);
dev->lmt_addr = dev->bar2 + (RVU_BLOCK_ADDR_LMT << 20);
/* Attach NIX LF */
if (rc)
goto otx2_npa_uninit;
+ dev->base = dev->bar2 + (nix_get_blkaddr(dev) << 20);
+
/* Get NIX MSIX offset */
rc = nix_lf_get_msix_offset(dev);
if (rc)