#include <inttypes.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_pci.h>
#include <rte_io.h>
#include <rte_malloc.h>
#include <rte_mbuf.h>
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
+ .ptp_info_update = otx2_eth_dev_ptp_info_update,
+ .link_status_get = otx2_eth_dev_link_status_get,
};
static int
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;
+ if (dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_CH_LEN_90B) {
+ req->mode = OTX2_PRIV_FLAGS_CUSTOM;
+ req->pkind = NPC_RX_CHLEN90B_PKIND;
+ } else if (dev->npc_flow.switch_header_type ==
+ OTX2_PRIV_FLAGS_CH_LEN_24B) {
+ req->mode = OTX2_PRIV_FLAGS_CUSTOM;
+ req->pkind = NPC_RX_CHLEN24B_PKIND;
+ } else if (dev->npc_flow.switch_header_type ==
+ OTX2_PRIV_FLAGS_EXDSA) {
+ req->mode = OTX2_PRIV_FLAGS_CUSTOM;
+ req->pkind = NPC_RX_EXDSA_PKIND;
+ } else if (dev->npc_flow.switch_header_type ==
+ OTX2_PRIV_FLAGS_VLAN_EXDSA) {
+ req->mode = OTX2_PRIV_FLAGS_CUSTOM;
+ req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
+ }
+
if (enable == 0)
req->mode = OTX2_PRIV_FLAGS_DEFAULT;
req->dir = PKIND_RX;
return rc;
req = otx2_mbox_alloc_msg_npc_set_pkind(mbox);
req->mode = dev->npc_flow.switch_header_type;
+ if (dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_CH_LEN_90B ||
+ dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_CH_LEN_24B)
+ req->mode = OTX2_PRIV_FLAGS_DEFAULT;
+
if (enable == 0)
req->mode = OTX2_PRIV_FLAGS_DEFAULT;
req->dir = PKIND_TX;
}
static void
-otx2_nix_rx_queue_release(void *rx_queue)
+otx2_nix_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
{
- struct otx2_eth_rxq *rxq = rx_queue;
+ struct otx2_eth_rxq *rxq = dev->data->rx_queues[qid];
if (!rxq)
return;
otx2_nix_dbg("Releasing rxq %u", rxq->rq);
nix_cq_rq_uninit(rxq->eth_dev, rxq);
- rte_free(rx_queue);
+ rte_free(rxq);
+ dev->data->rx_queues[qid] = NULL;
}
static int
/* Free memory prior to re-allocation if needed */
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]);
+ otx2_nix_rx_queue_release(eth_dev, rq);
rte_eth_dma_zone_free(eth_dev, "cq", rq);
- eth_dev->data->rx_queues[rq] = NULL;
}
offloads = rx_conf->offloads | eth_dev->data->dev_conf.rxmode.offloads;
rxq->lookup_mem = otx2_nix_fastpath_lookup_mem_get();
rxq->tstamp = &dev->tstamp;
+ eth_dev->data->rx_queues[rq] = rxq;
+
/* Alloc completion queue */
rc = nix_cq_rq_init(eth_dev, dev, rq, rxq, mp);
if (rc) {
otx2_nix_dbg("rq=%d pool=%s qsize=%d nb_desc=%d->%d",
rq, mp->name, qsize, nb_desc, rxq->qlen);
- eth_dev->data->rx_queues[rq] = rxq;
eth_dev->data->rx_queue_state[rq] = RTE_ETH_QUEUE_STATE_STOPPED;
/* Calculating delta and freq mult between PTP HI clock and tsc.
return 0;
free_rxq:
- otx2_nix_rx_queue_release(rxq);
+ otx2_nix_rx_queue_release(eth_dev, rq);
fail:
return rc;
}
mbp_priv = rte_mempool_get_priv(rxq->pool);
buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
- if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len > buffsz) {
+ if (eth_dev->data->mtu + (uint32_t)NIX_L2_OVERHEAD > buffsz) {
dev->rx_offloads |= DEV_RX_OFFLOAD_SCATTER;
dev->tx_offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
txq->sqb_pool = rte_mempool_create_empty(name, NIX_MAX_SQB, blk_sz,
0, 0, dev->node,
- MEMPOOL_F_NO_SPREAD);
+ RTE_MEMPOOL_F_NO_SPREAD);
txq->nb_sqb_bufs = nb_sqb_bufs;
txq->sqes_per_sqb_log2 = (uint16_t)rte_log2_u32(sqes_per_sqb);
txq->nb_sqb_bufs_adj = nb_sqb_bufs -
goto fail;
}
- tmp = rte_mempool_calc_obj_size(blk_sz, MEMPOOL_F_NO_SPREAD, &sz);
+ tmp = rte_mempool_calc_obj_size(blk_sz, RTE_MEMPOOL_F_NO_SPREAD, &sz);
if (dev->sqb_size != sz.elt_size) {
otx2_err("sqe pool block size is not expected %d != %d",
dev->sqb_size, tmp);
}
static void
-otx2_nix_tx_queue_release(void *_txq)
+otx2_nix_tx_queue_release(struct rte_eth_dev *eth_dev, uint16_t qid)
{
- struct otx2_eth_txq *txq = _txq;
- struct rte_eth_dev *eth_dev;
+ struct otx2_eth_txq *txq = eth_dev->data->tx_queues[qid];
if (!txq)
return;
- eth_dev = txq->dev->eth_dev;
-
otx2_nix_dbg("Releasing txq %u", txq->sq);
/* Flush and disable tm */
}
otx2_nix_sq_flush_post(txq);
rte_free(txq);
+ eth_dev->data->tx_queues[qid] = NULL;
}
/* Free memory prior to re-allocation if needed. */
if (eth_dev->data->tx_queues[sq] != NULL) {
otx2_nix_dbg("Freeing memory prior to re-allocation %d", sq);
- otx2_nix_tx_queue_release(eth_dev->data->tx_queues[sq]);
- eth_dev->data->tx_queues[sq] = NULL;
+ otx2_nix_tx_queue_release(eth_dev, sq);
}
/* Find the expected offloads for this queue */
txq->sqb_pool = NULL;
txq->offloads = offloads;
dev->tx_offloads |= offloads;
+ eth_dev->data->tx_queues[sq] = txq;
/*
* Allocate memory for flow control updates from HW.
txq->qconf.nb_desc = nb_desc;
memcpy(&txq->qconf.conf.tx, tx_conf, sizeof(struct rte_eth_txconf));
+ txq->lso_tun_fmt = dev->lso_tun_fmt;
otx2_nix_form_default_desc(txq);
otx2_nix_dbg("sq=%d fc=%p offload=0x%" PRIx64 " sqb=0x%" PRIx64 ""
" lmt_addr=%p nb_sqb_bufs=%d sqes_per_sqb_log2=%d", sq,
fc->addr, offloads, txq->sqb_pool->pool_id, txq->lmt_addr,
txq->nb_sqb_bufs, txq->sqes_per_sqb_log2);
- eth_dev->data->tx_queues[sq] = txq;
eth_dev->data->tx_queue_state[sq] = RTE_ETH_QUEUE_STATE_STOPPED;
return 0;
free_txq:
- otx2_nix_tx_queue_release(txq);
+ otx2_nix_tx_queue_release(eth_dev, sq);
fail:
return rc;
}
}
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;
+ otx2_nix_tx_queue_release(eth_dev, i);
}
rxq = (struct otx2_eth_rxq **)eth_dev->data->rx_queues;
}
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;
+ otx2_nix_rx_queue_release(eth_dev, i);
}
dev->tx_qconf = tx_qconf;
return 0;
fail:
- if (tx_qconf)
- free(tx_qconf);
- if (rx_qconf)
- free(rx_qconf);
+ free(tx_qconf);
+ free(rx_qconf);
return -ENOMEM;
}
struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
struct otx2_eth_qconf *tx_qconf = dev->tx_qconf;
struct otx2_eth_qconf *rx_qconf = dev->rx_qconf;
- struct otx2_eth_txq **txq;
- struct otx2_eth_rxq **rxq;
int rc, i, nb_rxq, nb_txq;
nb_rxq = RTE_MIN(dev->configured_nb_rx_qs, eth_dev->data->nb_rx_queues);
&tx_qconf[i].conf.tx);
if (rc) {
otx2_err("Failed to setup tx queue rc=%d", rc);
- txq = (struct otx2_eth_txq **)eth_dev->data->tx_queues;
for (i -= 1; i >= 0; i--)
- otx2_nix_tx_queue_release(txq[i]);
+ otx2_nix_tx_queue_release(eth_dev, i);
goto fail;
}
}
rx_qconf[i].mempool);
if (rc) {
otx2_err("Failed to setup rx queue rc=%d", rc);
- rxq = (struct otx2_eth_rxq **)eth_dev->data->rx_queues;
for (i -= 1; i >= 0; i--)
- otx2_nix_rx_queue_release(rxq[i]);
+ otx2_nix_rx_queue_release(eth_dev, i);
goto release_tx_queues;
}
}
return 0;
release_tx_queues:
- txq = (struct otx2_eth_txq **)eth_dev->data->tx_queues;
for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
- otx2_nix_tx_queue_release(txq[i]);
+ otx2_nix_tx_queue_release(eth_dev, i);
fail:
if (tx_qconf)
free(tx_qconf);
struct otx2_mbox *mbox = dev->mbox;
struct nix_lso_format_cfg_rsp *rsp;
struct nix_lso_format_cfg *req;
- uint8_t base;
+ uint8_t *fmt;
int rc;
/* Skip if TSO was not requested */
if (rc)
return rc;
- base = rsp->lso_format_idx;
- if (base != NIX_LSO_FORMAT_IDX_TSOV4)
+ if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV4)
return -EFAULT;
- dev->lso_base_idx = base;
- otx2_nix_dbg("tcpv4 lso fmt=%u", base);
+ otx2_nix_dbg("tcpv4 lso fmt=%u", rsp->lso_format_idx);
/*
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 1)
+ if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV6)
return -EFAULT;
- otx2_nix_dbg("tcpv6 lso fmt=%u\n", base + 1);
+ otx2_nix_dbg("tcpv6 lso fmt=%u\n", rsp->lso_format_idx);
/*
* IPv4/UDP/TUN HDR/IPv4/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 2)
- return -EFAULT;
- otx2_nix_dbg("udp tun v4v4 fmt=%u\n", base + 2);
+ dev->lso_udp_tun_idx[NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
+ otx2_nix_dbg("udp tun v4v4 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv4/UDP/TUN HDR/IPv6/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 3)
- return -EFAULT;
- otx2_nix_dbg("udp tun v4v6 fmt=%u\n", base + 3);
+ dev->lso_udp_tun_idx[NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
+ otx2_nix_dbg("udp tun v4v6 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv6/UDP/TUN HDR/IPv4/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 4)
- return -EFAULT;
- otx2_nix_dbg("udp tun v6v4 fmt=%u\n", base + 4);
+ dev->lso_udp_tun_idx[NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
+ otx2_nix_dbg("udp tun v6v4 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv6/UDP/TUN HDR/IPv6/TCP LSO
rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 5)
- return -EFAULT;
- otx2_nix_dbg("udp tun v6v6 fmt=%u\n", base + 5);
+
+ dev->lso_udp_tun_idx[NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
+ otx2_nix_dbg("udp tun v6v6 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv4/TUN HDR/IPv4/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 6)
- return -EFAULT;
- otx2_nix_dbg("tun v4v4 fmt=%u\n", base + 6);
+ dev->lso_tun_idx[NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
+ otx2_nix_dbg("tun v4v4 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv4/TUN HDR/IPv6/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 7)
- return -EFAULT;
- otx2_nix_dbg("tun v4v6 fmt=%u\n", base + 7);
+ dev->lso_tun_idx[NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
+ otx2_nix_dbg("tun v4v6 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv6/TUN HDR/IPv4/TCP LSO
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 8)
- return -EFAULT;
- otx2_nix_dbg("tun v6v4 fmt=%u\n", base + 8);
+ dev->lso_tun_idx[NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
+ otx2_nix_dbg("tun v6v4 fmt=%u\n", rsp->lso_format_idx);
/*
* IPv6/TUN HDR/IPv6/TCP LSO
rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
if (rc)
return rc;
- if (rsp->lso_format_idx != base + 9)
- return -EFAULT;
- otx2_nix_dbg("tun v6v6 fmt=%u\n", base + 9);
+
+ dev->lso_tun_idx[NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
+ otx2_nix_dbg("tun v6v6 fmt=%u\n", rsp->lso_format_idx);
+
+ /* Save all tun formats into u64 for fast path.
+ * Lower 32bit has non-udp tunnel formats.
+ * Upper 32bit has udp tunnel formats.
+ */
+ fmt = dev->lso_tun_idx;
+ dev->lso_tun_fmt = ((uint64_t)fmt[NIX_LSO_TUN_V4V4] |
+ (uint64_t)fmt[NIX_LSO_TUN_V4V6] << 8 |
+ (uint64_t)fmt[NIX_LSO_TUN_V6V4] << 16 |
+ (uint64_t)fmt[NIX_LSO_TUN_V6V6] << 24);
+
+ fmt = dev->lso_udp_tun_idx;
+ dev->lso_tun_fmt |= ((uint64_t)fmt[NIX_LSO_TUN_V4V4] << 32 |
+ (uint64_t)fmt[NIX_LSO_TUN_V4V6] << 40 |
+ (uint64_t)fmt[NIX_LSO_TUN_V6V4] << 48 |
+ (uint64_t)fmt[NIX_LSO_TUN_V6V6] << 56);
+
return 0;
}
return rc;
}
-static void
+static int
otx2_nix_dev_stop(struct rte_eth_dev *eth_dev)
{
struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
struct rte_mbuf *rx_pkts[32];
struct otx2_eth_rxq *rxq;
+ struct rte_eth_link link;
int count, i, j, rc;
nix_lf_switch_header_type_enable(dev, false);
/* Stop tx queues */
for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
otx2_nix_tx_queue_stop(eth_dev, i);
+
+ /* Bring down link status internally */
+ memset(&link, 0, sizeof(link));
+ rte_eth_linkstatus_set(eth_dev, &link);
+
+ return 0;
}
static int
if (otx2_ethdev_is_ptp_en(dev) && otx2_dev_is_vf(dev))
otx2_nix_ptp_enable_vf(eth_dev);
+ if (dev->rx_offload_flags & NIX_RX_OFFLOAD_TSTAMP_F) {
+ rc = rte_mbuf_dyn_rx_timestamp_register(
+ &dev->tstamp.tstamp_dynfield_offset,
+ &dev->tstamp.rx_tstamp_dynflag);
+ if (rc != 0) {
+ otx2_err("Failed to register Rx timestamp field/flag");
+ return -rte_errno;
+ }
+ }
+
rc = npc_rx_enable(dev);
if (rc) {
otx2_err("Failed to enable NPC rx %d", rc);
}
static int otx2_nix_dev_reset(struct rte_eth_dev *eth_dev);
-static void otx2_nix_dev_close(struct rte_eth_dev *eth_dev);
+static int otx2_nix_dev_close(struct rte_eth_dev *eth_dev);
/* Initialize and register driver with DPDK Application */
static const struct eth_dev_ops otx2_eth_dev_ops = {
.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,
- .filter_ctrl = otx2_nix_dev_filter_ctrl,
+ .flow_ops_get = otx2_nix_dev_flow_ops_get,
.get_module_info = otx2_nix_get_module_info,
.get_module_eeprom = otx2_nix_get_module_eeprom,
.fw_version_get = otx2_nix_fw_version_get,
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;
pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
rte_eth_copy_pci_info(eth_dev, pci_dev);
- eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
/* Zero out everything after OTX2_DEV to allow proper dev_reset() */
memset(&dev->otx2_eth_dev_data_start, 0, sizeof(*dev) -
nix_cgx_stop_link_event(dev);
+ /* Unregister the dev ops, this is required to stop VFs from
+ * receiving link status updates on exit path.
+ */
+ dev->ops = NULL;
+
/* 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]);
- eth_dev->data->tx_queues[i] = NULL;
- }
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
+ otx2_nix_tx_queue_release(eth_dev, i);
eth_dev->data->nb_tx_queues = 0;
/* Free up RQ's and CQ's */
- for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
- otx2_nix_rx_queue_release(eth_dev->data->rx_queues[i]);
- eth_dev->data->rx_queues[i] = NULL;
- }
+ for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
+ otx2_nix_rx_queue_release(eth_dev, i);
eth_dev->data->nb_rx_queues = 0;
/* Free tm resources */
return 0;
}
-static void
+static int
otx2_nix_dev_close(struct rte_eth_dev *eth_dev)
{
otx2_eth_dev_uninit(eth_dev, true);
+ return 0;
}
static int
if (rc)
return rc;
- rte_eth_dev_pci_release(eth_dev);
+ rte_eth_dev_release_port(eth_dev);
}
/* Nothing to be done for secondary processes */
.remove = nix_remove,
};
-RTE_PMD_REGISTER_PCI(net_octeontx2, pci_nix);
-RTE_PMD_REGISTER_PCI_TABLE(net_octeontx2, pci_nix_map);
-RTE_PMD_REGISTER_KMOD_DEP(net_octeontx2, "vfio-pci");
+RTE_PMD_REGISTER_PCI(OCTEONTX2_PMD, pci_nix);
+RTE_PMD_REGISTER_PCI_TABLE(OCTEONTX2_PMD, pci_nix_map);
+RTE_PMD_REGISTER_KMOD_DEP(OCTEONTX2_PMD, "vfio-pci");