#include "otx2_ethdev.h"
-static inline void
-otx2_eth_set_rx_function(struct rte_eth_dev *eth_dev)
-{
- RTE_SET_USED(eth_dev);
-}
-
-static inline void
-otx2_eth_set_tx_function(struct rte_eth_dev *eth_dev)
-{
- RTE_SET_USED(eth_dev);
-}
-
static inline uint64_t
nix_get_rx_offload_capa(struct otx2_eth_dev *dev)
{
static const struct otx2_dev_ops otx2_dev_ops = {
.link_status_update = otx2_eth_dev_link_status_update,
+ .ptp_info_update = otx2_eth_dev_ptp_info_update
};
static int
return otx2_mbox_process(mbox);
}
+int
+otx2_cgx_rxtx_start(struct otx2_eth_dev *dev)
+{
+ struct otx2_mbox *mbox = dev->mbox;
+
+ if (otx2_dev_is_vf(dev))
+ return 0;
+
+ otx2_mbox_alloc_msg_cgx_start_rxtx(mbox);
+
+ return otx2_mbox_process(mbox);
+}
+
+int
+otx2_cgx_rxtx_stop(struct otx2_eth_dev *dev)
+{
+ struct otx2_mbox *mbox = dev->mbox;
+
+ if (otx2_dev_is_vf(dev))
+ return 0;
+
+ otx2_mbox_alloc_msg_cgx_stop_rxtx(mbox);
+
+ return otx2_mbox_process(mbox);
+}
+
static inline void
nix_rx_queue_reset(struct otx2_eth_rxq *rxq)
{
aq->cq.cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
aq->cq.cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
+ /* TX pause frames enable flowctrl on RX side */
+ if (dev->fc_info.tx_pause) {
+ /* Single bpid is allocated for all rx channels for now */
+ aq->cq.bpid = dev->fc_info.bpid[0];
+ aq->cq.bp = NIX_CQ_BP_LEVEL;
+ aq->cq.bp_ena = 1;
+ }
+
/* Many to one reduction */
aq->cq.qint_idx = qid % dev->qints;
static inline int
nix_get_data_off(struct otx2_eth_dev *dev)
{
- RTE_SET_USED(dev);
-
- return 0;
+ return otx2_ethdev_is_ptp_en(dev) ? NIX_TIMESYNC_RX_OFFSET : 0;
}
uint64_t
rxq->pool = mp;
rxq->qlen = nix_qsize_to_val(qsize);
rxq->qsize = qsize;
+ rxq->lookup_mem = otx2_nix_fastpath_lookup_mem_get();
+ rxq->tstamp = &dev->tstamp;
/* Alloc completion queue */
rc = nix_cq_rq_init(eth_dev, dev, rq, rxq, mp);
struct otx2_eth_dev *dev = txq->dev;
struct otx2_mbox *mbox = dev->mbox;
struct nix_aq_enq_req *sq;
+ uint32_t rr_quantum;
+ uint16_t smq;
+ int rc;
if (txq->sqb_pool->pool_id == 0)
return -EINVAL;
+ rc = otx2_nix_tm_get_leaf_data(dev, txq->sq, &rr_quantum, &smq);
+ if (rc) {
+ otx2_err("Failed to get sq->smq(leaf node), rc=%d", rc);
+ return rc;
+ }
+
sq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
sq->qidx = txq->sq;
sq->ctype = NIX_AQ_CTYPE_SQ;
sq->op = NIX_AQ_INSTOP_INIT;
sq->sq.max_sqe_size = nix_sq_max_sqe_sz(txq);
+ sq->sq.smq = smq;
+ sq->sq.smq_rr_quantum = rr_quantum;
sq->sq.default_chan = dev->tx_chan_base;
sq->sq.sqe_stype = NIX_STYPE_STF;
sq->sq.ena = 1;
send_mem->dsz = 0x0;
send_mem->wmem = 0x1;
send_mem->alg = NIX_SENDMEMALG_SETTSTMP;
+ send_mem->addr = txq->dev->tstamp.tx_tstamp_iova;
}
sg = (union nix_send_sg_s *)&txq->cmd[4];
} else {
otx2_nix_tx_queue_release(void *_txq)
{
struct otx2_eth_txq *txq = _txq;
+ struct rte_eth_dev *eth_dev;
if (!txq)
return;
+ eth_dev = txq->dev->eth_dev;
+
otx2_nix_dbg("Releasing txq %u", txq->sq);
+ /* Flush and disable tm */
+ otx2_nix_tm_sw_xoff(txq, eth_dev->data->dev_started);
+
/* Free sqb's and disable sq */
nix_sq_uninit(txq);
/* Free the resources allocated from the previous configure */
if (dev->configured == 1) {
+ otx2_nix_rxchan_bpid_cfg(eth_dev, false);
+ otx2_nix_vlan_fini(eth_dev);
oxt2_nix_unregister_queue_irqs(eth_dev);
nix_set_nop_rxtx_function(eth_dev);
rc = nix_store_queue_cfg_and_then_release(eth_dev);
goto free_nix_lf;
}
+ rc = otx2_nix_vlan_offload_init(eth_dev);
+ if (rc) {
+ otx2_err("Failed to init vlan offload rc=%d", rc);
+ goto free_nix_lf;
+ }
+
/* Register queue IRQs */
rc = oxt2_nix_register_queue_irqs(eth_dev);
if (rc) {
goto free_nix_lf;
}
+ rc = otx2_nix_rxchan_bpid_cfg(eth_dev, true);
+ if (rc) {
+ otx2_err("Failed to configure nix rx chan bpid cfg rc=%d", rc);
+ goto free_nix_lf;
+ }
+
+ /* Enable PTP if it was requested by the app or if it is already
+ * enabled in PF owning this VF
+ */
+ memset(&dev->tstamp, 0, sizeof(struct otx2_timesync_info));
+ if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) ||
+ otx2_ethdev_is_ptp_en(dev))
+ otx2_nix_timesync_enable(eth_dev);
+ else
+ otx2_nix_timesync_disable(eth_dev);
+
/*
* Restore queue config when reconfigure followed by
* reconfigure and no queue configure invoked from application case.
otx2_nix_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)
{
struct rte_eth_dev_data *data = eth_dev->data;
+ struct otx2_eth_txq *txq;
+ int rc = -EINVAL;
+
+ txq = eth_dev->data->tx_queues[qidx];
if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED)
return 0;
+ rc = otx2_nix_sq_sqb_aura_fc(txq, true);
+ if (rc) {
+ otx2_err("Failed to enable sqb aura fc, txq=%u, rc=%d",
+ qidx, rc);
+ goto done;
+ }
+
data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
- return 0;
+
+done:
+ return rc;
}
int
otx2_nix_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
{
struct rte_eth_dev_data *data = eth_dev->data;
+ struct otx2_eth_txq *txq;
+ int rc;
+
+ txq = eth_dev->data->tx_queues[qidx];
if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED)
return 0;
+ txq->fc_cache_pkts = 0;
+
+ rc = otx2_nix_sq_sqb_aura_fc(txq, false);
+ if (rc) {
+ otx2_err("Failed to disable sqb aura fc, txq=%u, rc=%d",
+ qidx, rc);
+ goto done;
+ }
+
data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
- return 0;
+
+done:
+ return rc;
}
static int
.tx_queue_stop = otx2_nix_tx_queue_stop,
.rx_queue_start = otx2_nix_rx_queue_start,
.rx_queue_stop = otx2_nix_rx_queue_stop,
+ .dev_supported_ptypes_get = otx2_nix_supported_ptypes_get,
.stats_get = otx2_nix_dev_stats_get,
.stats_reset = otx2_nix_dev_stats_reset,
.get_reg = otx2_nix_dev_get_reg,
.xstats_reset = otx2_nix_xstats_reset,
.xstats_get_by_id = otx2_nix_xstats_get_by_id,
.xstats_get_names_by_id = otx2_nix_xstats_get_names_by_id,
+ .rxq_info_get = otx2_nix_rxq_info_get,
+ .txq_info_get = otx2_nix_txq_info_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_done_cleanup = otx2_nix_tx_done_cleanup,
+ .pool_ops_supported = otx2_nix_pool_ops_supported,
+ .filter_ctrl = otx2_nix_dev_filter_ctrl,
+ .get_module_info = otx2_nix_get_module_info,
+ .get_module_eeprom = otx2_nix_get_module_eeprom,
+ .fw_version_get = otx2_nix_fw_version_get,
+ .flow_ctrl_get = otx2_nix_flow_ctrl_get,
+ .flow_ctrl_set = otx2_nix_flow_ctrl_set,
+ .timesync_enable = otx2_nix_timesync_enable,
+ .timesync_disable = otx2_nix_timesync_disable,
+ .timesync_read_rx_timestamp = otx2_nix_timesync_read_rx_timestamp,
+ .timesync_read_tx_timestamp = otx2_nix_timesync_read_tx_timestamp,
+ .timesync_adjust_time = otx2_nix_timesync_adjust_time,
+ .timesync_read_time = otx2_nix_timesync_read_time,
+ .timesync_write_time = otx2_nix_timesync_write_time,
+ .vlan_offload_set = otx2_nix_vlan_offload_set,
+ .vlan_filter_set = otx2_nix_vlan_filter_set,
+ .vlan_strip_queue_set = otx2_nix_vlan_strip_queue_set,
+ .vlan_tpid_set = otx2_nix_vlan_tpid_set,
+ .vlan_pvid_set = otx2_nix_vlan_pvid_set,
};
static inline int
dev->hwcap |= OTX2_FIXUP_F_LIMIT_CQ_FULL;
}
+ /* Initialize rte-flow */
+ rc = otx2_flow_init(dev);
+ if (rc)
+ goto free_mac_addrs;
+
otx2_nix_dbg("Port=%d pf=%d vf=%d ver=%s msix_off=%d hwcap=0x%" PRIx64
" rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64,
eth_dev->data->port_id, dev->pf, dev->vf,
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
+ /* Disable nix bpid config */
+ otx2_nix_rxchan_bpid_cfg(eth_dev, false);
+
+ /* Disable vlan offloads */
+ otx2_nix_vlan_fini(eth_dev);
+
+ /* Disable other rte_flow entries */
+ otx2_flow_fini(dev);
+
+ /* Disable PTP if already enabled */
+ if (otx2_ethdev_is_ptp_en(dev))
+ otx2_nix_timesync_disable(eth_dev);
+
/* Free up SQs */
for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
otx2_nix_tx_queue_release(eth_dev->data->tx_queues[i]);