static void
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
+ const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
struct sfc_adapter *sa = dev->data->dev_private;
struct sfc_rss *rss = &sa->rss;
uint64_t txq_offloads_def = 0;
*/
dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
- if (sa->dp_rx->get_dev_info != NULL)
- sa->dp_rx->get_dev_info(dev_info);
- if (sa->dp_tx->get_dev_info != NULL)
- sa->dp_tx->get_dev_info(dev_info);
+ if (sap->dp_rx->get_dev_info != NULL)
+ sap->dp_rx->get_dev_info(dev_info);
+ if (sap->dp_tx->get_dev_info != NULL)
+ sap->dp_tx->get_dev_info(dev_info);
dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
static const uint32_t *
sfc_dev_supported_ptypes_get(struct rte_eth_dev *dev)
{
+ const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
struct sfc_adapter *sa = dev->data->dev_private;
const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
uint32_t tunnel_encaps = encp->enc_tunnel_encapsulations_supported;
- return sa->dp_rx->supported_ptypes_get(tunnel_encaps);
+ return sap->dp_rx->supported_ptypes_get(tunnel_encaps);
}
static int
if (rc != 0)
goto fail_rx_qinit;
- dev->data->rx_queues[rx_queue_id] = sa->rxq_info[rx_queue_id].rxq->dp;
+ dev->data->rx_queues[rx_queue_id] = sa->rxq_info[rx_queue_id].dp;
sfc_adapter_unlock(sa);
sa = rxq->evq->sa;
sfc_adapter_lock(sa);
- sw_index = sfc_rxq_sw_index(rxq);
+ sw_index = dp_rxq->dpq.queue_id;
sfc_log_init(sa, "RxQ=%u", sw_index);
if (rc != 0)
goto fail_tx_qinit;
- dev->data->tx_queues[tx_queue_id] = sa->txq_info[tx_queue_id].txq->dp;
+ dev->data->tx_queues[tx_queue_id] = sa->txq_info[tx_queue_id].dp;
sfc_adapter_unlock(sa);
return 0;
return;
txq = sfc_txq_by_dp_txq(dp_txq);
- sw_index = sfc_txq_sw_index(txq);
+ sw_index = dp_txq->dpq.queue_id;
SFC_ASSERT(txq->evq != NULL);
sa = txq->evq->sa;
sfc_adapter_unlock(sa);
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static uint32_t
sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
{
+ const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
struct sfc_adapter *sa = dev->data->dev_private;
- struct sfc_rxq *rxq;
+ struct sfc_rxq_info *rxq_info;
SFC_ASSERT(rx_queue_id < sa->rxq_count);
- rxq = sa->rxq_info[rx_queue_id].rxq;
+ rxq_info = &sa->rxq_info[rx_queue_id];
- if (rxq == NULL || (rxq->state & SFC_RXQ_STARTED) == 0)
+ if ((rxq_info->state & SFC_RXQ_STARTED) == 0)
return 0;
- return sa->dp_rx->qdesc_npending(rxq->dp);
+ return sap->dp_rx->qdesc_npending(rxq_info->dp);
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static int
sfc_rx_descriptor_done(void *queue, uint16_t offset)
{
struct sfc_dp_rxq *dp_rxq = queue;
- struct sfc_rxq *rxq = sfc_rxq_by_dp_rxq(dp_rxq);
+ const struct sfc_dp_rx *dp_rx;
+
+ dp_rx = sfc_dp_rx_by_dp_rxq(dp_rxq);
- return offset < rxq->evq->sa->dp_rx->qdesc_npending(dp_rxq);
+ return offset < dp_rx->qdesc_npending(dp_rxq);
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static int
sfc_rx_descriptor_status(void *queue, uint16_t offset)
{
struct sfc_dp_rxq *dp_rxq = queue;
- struct sfc_rxq *rxq = sfc_rxq_by_dp_rxq(dp_rxq);
+ const struct sfc_dp_rx *dp_rx;
+
+ dp_rx = sfc_dp_rx_by_dp_rxq(dp_rxq);
- return rxq->evq->sa->dp_rx->qdesc_status(dp_rxq, offset);
+ return dp_rx->qdesc_status(dp_rxq, offset);
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static int
sfc_tx_descriptor_status(void *queue, uint16_t offset)
{
struct sfc_dp_txq *dp_txq = queue;
- struct sfc_txq *txq = sfc_txq_by_dp_txq(dp_txq);
+ const struct sfc_dp_tx *dp_tx;
+
+ dp_tx = sfc_dp_tx_by_dp_txq(dp_txq);
- return txq->evq->sa->dp_tx->qdesc_status(dp_txq, offset);
+ return dp_tx->qdesc_status(dp_txq, offset);
}
static int
if (sa->state != SFC_ADAPTER_STARTED)
goto fail_not_started;
- if (sa->rxq_info[rx_queue_id].rxq == NULL)
+ if (sa->rxq_info[rx_queue_id].state != SFC_RXQ_INITIALIZED)
goto fail_not_setup;
rc = sfc_rx_qstart(sa, rx_queue_id);
if (sa->state != SFC_ADAPTER_STARTED)
goto fail_not_started;
- if (sa->txq_info[tx_queue_id].txq == NULL)
+ if (sa->txq_info[tx_queue_id].state != SFC_TXQ_INITIALIZED)
goto fail_not_setup;
rc = sfc_tx_qstart(sa, tx_queue_id);
return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_DEL_PORT);
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static int
sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf)
return -rc;
}
+/*
+ * The function is used by the secondary process as well. It must not
+ * use any process-local pointers from the adapter data.
+ */
static int
sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
struct rte_eth_rss_reta_entry64 *reta_conf,
static int
sfc_pool_ops_supported(struct rte_eth_dev *dev, const char *pool)
{
- struct sfc_adapter *sa = dev->data->dev_private;
+ const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
/*
* If Rx datapath does not provide callback to check mempool,
* all pools are supported.
*/
- if (sa->dp_rx->pool_ops_supported == NULL)
+ if (sap->dp_rx->pool_ops_supported == NULL)
return 1;
- return sa->dp_rx->pool_ops_supported(pool);
+ return sap->dp_rx->pool_ops_supported(pool);
}
static const struct eth_dev_ops sfc_eth_dev_ops = {
sfc_notice(sa, "use %s Tx datapath", sa->dp_tx_name);
- sa->dp_rx = dp_rx;
- sa->dp_tx = dp_tx;
+ sa->priv.dp_rx = dp_rx;
+ sa->priv.dp_tx = dp_tx;
dev->rx_pkt_burst = dp_rx->pkt_burst;
dev->tx_pkt_burst = dp_tx->pkt_burst;
rte_free(sa->dp_tx_name);
sa->dp_tx_name = NULL;
- sa->dp_tx = NULL;
+ sa->priv.dp_tx = NULL;
rte_free(sa->dp_rx_name);
sa->dp_rx_name = NULL;
- sa->dp_rx = NULL;
+ sa->priv.dp_rx = NULL;
}
static const struct eth_dev_ops sfc_eth_dev_secondary_ops = {
+ .rx_queue_count = sfc_rx_queue_count,
+ .rx_descriptor_done = sfc_rx_descriptor_done,
+ .rx_descriptor_status = sfc_rx_descriptor_status,
+ .tx_descriptor_status = sfc_tx_descriptor_status,
+ .reta_query = sfc_dev_rss_reta_query,
+ .rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
.rxq_info_get = sfc_rx_queue_info_get,
.txq_info_get = sfc_tx_queue_info_get,
};
static int
-sfc_eth_dev_secondary_set_ops(struct rte_eth_dev *dev, uint32_t logtype_main)
+sfc_eth_dev_secondary_init(struct rte_eth_dev *dev, uint32_t logtype_main)
{
/*
* Device private data has really many process-local pointers.
* in shared memory only.
*/
struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_adapter_priv *sap;
const struct sfc_dp_rx *dp_rx;
const struct sfc_dp_tx *dp_tx;
int rc;
+ /*
+ * Allocate process private data from heap, since it should not
+ * be located in shared memory allocated using rte_malloc() API.
+ */
+ sap = calloc(1, sizeof(*sap));
+ if (sap == NULL) {
+ rc = ENOMEM;
+ goto fail_alloc_priv;
+ }
+
+ sap->logtype_main = logtype_main;
+
dp_rx = sfc_dp_find_rx_by_name(&sfc_dp_head, sa->dp_rx_name);
if (dp_rx == NULL) {
SFC_LOG(sa, RTE_LOG_ERR, logtype_main,
goto fail_dp_tx_multi_process;
}
+ sap->dp_rx = dp_rx;
+ sap->dp_tx = dp_tx;
+
+ dev->process_private = sap;
dev->rx_pkt_burst = dp_rx->pkt_burst;
dev->tx_pkt_burst = dp_tx->pkt_burst;
dev->dev_ops = &sfc_eth_dev_secondary_ops;
fail_dp_tx:
fail_dp_rx_multi_process:
fail_dp_rx:
+ free(sap);
+
+fail_alloc_priv:
return rc;
}
static void
sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
{
+ free(dev->process_private);
+ dev->process_private = NULL;
dev->dev_ops = NULL;
dev->tx_pkt_burst = NULL;
dev->rx_pkt_burst = NULL;
sfc_eth_dev_init(struct rte_eth_dev *dev)
{
struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_adapter_shared *sas;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
uint32_t logtype_main;
int rc;
SFC_LOGTYPE_MAIN_STR,
RTE_LOG_NOTICE);
+ sa->priv.shared = &sa->_shared;
+ sas = sa->priv.shared;
+
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
- return -sfc_eth_dev_secondary_set_ops(dev, logtype_main);
+ return -sfc_eth_dev_secondary_init(dev, logtype_main);
+
+ /*
+ * sfc_adapter is a mixture of shared and process private data.
+ * During transition period use it in both kinds. When the
+ * driver becomes ready to separate it, sfc_adapter will become
+ * primary process private only.
+ */
+ dev->process_private = sa;
/* Required for logging */
- sa->pci_addr = pci_dev->addr;
- sa->port_id = dev->data->port_id;
- sa->logtype_main = logtype_main;
+ sas->pci_addr = pci_dev->addr;
+ sas->port_id = dev->data->port_id;
+ sa->priv.logtype_main = logtype_main;
sa->eth_dev = dev;
fail_kvargs_parse:
sfc_log_init(sa, "failed %d", rc);
+ dev->process_private = NULL;
SFC_ASSERT(rc > 0);
return -rc;
}