#include <rte_pci.h>
#include <rte_bus_pci.h>
#include <rte_errno.h>
+#include <rte_string_fns.h>
#include "efx.h"
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;
- const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
struct sfc_rss *rss = &sa->rss;
uint64_t txq_offloads_def = 0;
dev_info->default_txconf.offloads |= txq_offloads_def;
- dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
- if ((~sa->dp_tx->features & SFC_DP_TX_FEAT_VLAN_INSERT) ||
- !encp->enc_hw_tx_insert_vlan_enabled)
- dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL;
-
- if (~sa->dp_tx->features & SFC_DP_TX_FEAT_MULTI_SEG)
- dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
-
- if (~sa->dp_tx->features & SFC_DP_TX_FEAT_MULTI_POOL)
- dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOMULTMEMP;
-
- if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT)
- dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT;
-
if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) {
uint64_t rte_hf = 0;
unsigned int i;
*/
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);
- sa->eth_dev->data->rx_queues[sw_index] = NULL;
-
sfc_rx_qfini(sa, sw_index);
sfc_adapter_unlock(sa);
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_lock(sa);
- SFC_ASSERT(sw_index < sa->eth_dev->data->nb_tx_queues);
- sa->eth_dev->data->tx_queues[sw_index] = NULL;
-
sfc_tx_qfini(sa, sw_index);
sfc_adapter_unlock(sa);
}
+/*
+ * Some statistics are computed as A - B where A and B each increase
+ * monotonically with some hardware counter(s) and the counters are read
+ * asynchronously.
+ *
+ * If packet X is counted in A, but not counted in B yet, computed value is
+ * greater than real.
+ *
+ * If packet X is not counted in A at the moment of reading the counter,
+ * but counted in B at the moment of reading the counter, computed value
+ * is less than real.
+ *
+ * However, counter which grows backward is worse evil than slightly wrong
+ * value. So, let's try to guarantee that it never happens except may be
+ * the case when the MAC stats are zeroed as a result of a NIC reset.
+ */
+static void
+sfc_update_diff_stat(uint64_t *stat, uint64_t newval)
+{
+ if ((int64_t)(newval - *stat) > 0 || newval == 0)
+ *stat = newval;
+}
+
static int
sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
- stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_OVERFLOW];
- stats->ierrors = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
+ stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
} else {
- stats->ipackets = mac_stats[EFX_MAC_RX_PKTS];
stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
stats->ibytes = mac_stats[EFX_MAC_RX_OCTETS];
stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
mac_stats[EFX_MAC_RX_ALIGN_ERRORS] +
mac_stats[EFX_MAC_RX_JABBER_PKTS];
/* no oerrors counters supported on EF10 */
+
+ /* Exclude missed, errors and pauses from Rx packets */
+ sfc_update_diff_stat(&port->ipackets,
+ mac_stats[EFX_MAC_RX_PKTS] -
+ mac_stats[EFX_MAC_RX_PAUSE_PKTS] -
+ stats->imissed - stats->ierrors);
+ stats->ipackets = port->ipackets;
}
unlock:
for (i = 0; i < EFX_MAC_NSTATS; ++i) {
if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
if (xstats_names != NULL && nstats < xstats_count)
- strncpy(xstats_names[nstats].name,
+ strlcpy(xstats_names[nstats].name,
efx_mac_stat_name(sa->nic, i),
sizeof(xstats_names[0].name));
nstats++;
if ((ids == NULL) || (ids[nb_written] == nb_supported)) {
char *name = xstats_names[nb_written++].name;
- strncpy(name, efx_mac_stat_name(sa->nic, i),
+ strlcpy(name, efx_mac_stat_name(sa->nic, i),
sizeof(xstats_names[0].name));
- name[sizeof(xstats_names[0].name) - 1] = '\0';
}
++nb_supported;
}
/*
- * The driver does not use it, but other PMDs update jumbo_frame
+ * The driver does not use it, but other PMDs update jumbo frame
* flag and max_rx_pkt_len when MTU is set.
*/
if (mtu > ETHER_MAX_LEN) {
struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
-
rxmode->offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
- rxmode->jumbo_frame = 1;
}
dev->data->dev_conf.rxmode.max_rx_pkt_len = sa->port.pdu;
if (rc != 0)
sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
- SFC_ASSERT(rc > 0);
+ SFC_ASSERT(rc >= 0);
return -rc;
}
{
struct sfc_adapter *sa = dev->data->dev_private;
struct sfc_rxq_info *rxq_info;
- struct sfc_rxq *rxq;
sfc_adapter_lock(sa);
SFC_ASSERT(rx_queue_id < sa->rxq_count);
rxq_info = &sa->rxq_info[rx_queue_id];
- rxq = rxq_info->rxq;
- SFC_ASSERT(rxq != NULL);
- qinfo->mp = rxq->refill_mb_pool;
- qinfo->conf.rx_free_thresh = rxq->refill_threshold;
+ qinfo->mp = rxq_info->refill_mb_pool;
+ qinfo->conf.rx_free_thresh = rxq_info->refill_threshold;
qinfo->conf.rx_drop_en = 1;
qinfo->conf.rx_deferred_start = rxq_info->deferred_start;
- qinfo->conf.offloads = DEV_RX_OFFLOAD_IPV4_CKSUM |
- DEV_RX_OFFLOAD_UDP_CKSUM |
- DEV_RX_OFFLOAD_TCP_CKSUM;
+ qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
if (rxq_info->type_flags & EFX_RXQ_FLAG_SCATTER) {
qinfo->conf.offloads |= DEV_RX_OFFLOAD_SCATTER;
qinfo->scattered_rx = 1;
SFC_ASSERT(tx_queue_id < sa->txq_count);
txq_info = &sa->txq_info[tx_queue_id];
- SFC_ASSERT(txq_info->txq != NULL);
memset(qinfo, 0, sizeof(*qinfo));
- qinfo->conf.txq_flags = txq_info->txq->flags;
- qinfo->conf.offloads = txq_info->txq->offloads;
- qinfo->conf.tx_free_thresh = txq_info->txq->free_thresh;
+ qinfo->conf.offloads = txq_info->offloads;
+ qinfo->conf.tx_free_thresh = txq_info->free_thresh;
qinfo->conf.tx_deferred_start = txq_info->deferred_start;
qinfo->nb_desc = txq_info->entries;
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_info *rxq_info;
- sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+ SFC_ASSERT(rx_queue_id < sa->rxq_count);
+ rxq_info = &sa->rxq_info[rx_queue_id];
+
+ if ((rxq_info->state & SFC_RXQ_STARTED) == 0)
+ return 0;
- return sfc_rx_qdesc_npending(sa, rx_queue_id);
+ 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;
+ const struct sfc_dp_rx *dp_rx;
+
+ dp_rx = sfc_dp_rx_by_dp_rxq(dp_rxq);
- return sfc_rx_qdesc_done(dp_rxq, offset);
+ 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].state != SFC_RXQ_INITIALIZED)
+ goto fail_not_setup;
+
rc = sfc_rx_qstart(sa, rx_queue_id);
if (rc != 0)
goto fail_rx_qstart;
return 0;
fail_rx_qstart:
+fail_not_setup:
fail_not_started:
sfc_adapter_unlock(sa);
SFC_ASSERT(rc > 0);
if (sa->state != SFC_ADAPTER_STARTED)
goto fail_not_started;
+ if (sa->txq_info[tx_queue_id].state != SFC_TXQ_INITIALIZED)
+ goto fail_not_setup;
+
rc = sfc_tx_qstart(sa, tx_queue_id);
if (rc != 0)
goto fail_tx_qstart;
fail_tx_qstart:
+fail_not_setup:
fail_not_started:
sfc_adapter_unlock(sa);
SFC_ASSERT(rc > 0);
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)
{
struct sfc_adapter *sa = dev->data->dev_private;
struct sfc_rss *rss = &sa->rss;
- struct sfc_port *port = &sa->port;
- if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated)
+ if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE)
return -ENOTSUP;
- if (rss->channels == 0)
- return -EINVAL;
-
sfc_adapter_lock(sa);
/*
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_eth_dev_set_ops(struct rte_eth_dev *dev)
{
struct sfc_adapter *sa = dev->data->dev_private;
+ const struct sfc_dp_rx *dp_rx;
+ const struct sfc_dp_tx *dp_tx;
const efx_nic_cfg_t *encp;
unsigned int avail_caps = 0;
const char *rx_name = NULL;
goto fail_kvarg_rx_datapath;
if (rx_name != NULL) {
- sa->dp_rx = sfc_dp_find_rx_by_name(&sfc_dp_head, rx_name);
- if (sa->dp_rx == NULL) {
+ dp_rx = sfc_dp_find_rx_by_name(&sfc_dp_head, rx_name);
+ if (dp_rx == NULL) {
sfc_err(sa, "Rx datapath %s not found", rx_name);
rc = ENOENT;
goto fail_dp_rx;
}
- if (!sfc_dp_match_hw_fw_caps(&sa->dp_rx->dp, avail_caps)) {
+ if (!sfc_dp_match_hw_fw_caps(&dp_rx->dp, avail_caps)) {
sfc_err(sa,
"Insufficient Hw/FW capabilities to use Rx datapath %s",
rx_name);
goto fail_dp_rx_caps;
}
} else {
- sa->dp_rx = sfc_dp_find_rx_by_caps(&sfc_dp_head, avail_caps);
- if (sa->dp_rx == NULL) {
+ dp_rx = sfc_dp_find_rx_by_caps(&sfc_dp_head, avail_caps);
+ if (dp_rx == NULL) {
sfc_err(sa, "Rx datapath by caps %#x not found",
avail_caps);
rc = ENOENT;
}
}
- sa->dp_rx_name = sfc_strdup(sa->dp_rx->dp.name);
+ sa->dp_rx_name = sfc_strdup(dp_rx->dp.name);
if (sa->dp_rx_name == NULL) {
rc = ENOMEM;
goto fail_dp_rx_name;
sfc_notice(sa, "use %s Rx datapath", sa->dp_rx_name);
- dev->rx_pkt_burst = sa->dp_rx->pkt_burst;
-
rc = sfc_kvargs_process(sa, SFC_KVARG_TX_DATAPATH,
sfc_kvarg_string_handler, &tx_name);
if (rc != 0)
goto fail_kvarg_tx_datapath;
if (tx_name != NULL) {
- sa->dp_tx = sfc_dp_find_tx_by_name(&sfc_dp_head, tx_name);
- if (sa->dp_tx == NULL) {
+ dp_tx = sfc_dp_find_tx_by_name(&sfc_dp_head, tx_name);
+ if (dp_tx == NULL) {
sfc_err(sa, "Tx datapath %s not found", tx_name);
rc = ENOENT;
goto fail_dp_tx;
}
- if (!sfc_dp_match_hw_fw_caps(&sa->dp_tx->dp, avail_caps)) {
+ if (!sfc_dp_match_hw_fw_caps(&dp_tx->dp, avail_caps)) {
sfc_err(sa,
"Insufficient Hw/FW capabilities to use Tx datapath %s",
tx_name);
goto fail_dp_tx_caps;
}
} else {
- sa->dp_tx = sfc_dp_find_tx_by_caps(&sfc_dp_head, avail_caps);
- if (sa->dp_tx == NULL) {
+ dp_tx = sfc_dp_find_tx_by_caps(&sfc_dp_head, avail_caps);
+ if (dp_tx == NULL) {
sfc_err(sa, "Tx datapath by caps %#x not found",
avail_caps);
rc = ENOENT;
}
}
- sa->dp_tx_name = sfc_strdup(sa->dp_tx->dp.name);
+ sa->dp_tx_name = sfc_strdup(dp_tx->dp.name);
if (sa->dp_tx_name == NULL) {
rc = ENOMEM;
goto fail_dp_tx_name;
sfc_notice(sa, "use %s Tx datapath", sa->dp_tx_name);
- dev->tx_pkt_burst = sa->dp_tx->pkt_burst;
+ 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;
dev->dev_ops = &sfc_eth_dev_ops;
fail_dp_tx_name:
fail_dp_tx_caps:
- sa->dp_tx = NULL;
-
fail_dp_tx:
fail_kvarg_tx_datapath:
rte_free(sa->dp_rx_name);
fail_dp_rx_name:
fail_dp_rx_caps:
- sa->dp_rx = NULL;
-
fail_dp_rx:
fail_kvarg_rx_datapath:
return rc;
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)
+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_err(sa, "cannot find %s Rx datapath", sa->dp_tx_name);
+ SFC_LOG(sa, RTE_LOG_ERR, logtype_main,
+ "cannot find %s Rx datapath", sa->dp_rx_name);
rc = ENOENT;
goto fail_dp_rx;
}
if (~dp_rx->features & SFC_DP_RX_FEAT_MULTI_PROCESS) {
- sfc_err(sa, "%s Rx datapath does not support multi-process",
- sa->dp_tx_name);
+ SFC_LOG(sa, RTE_LOG_ERR, logtype_main,
+ "%s Rx datapath does not support multi-process",
+ sa->dp_rx_name);
rc = EINVAL;
goto fail_dp_rx_multi_process;
}
dp_tx = sfc_dp_find_tx_by_name(&sfc_dp_head, sa->dp_tx_name);
if (dp_tx == NULL) {
- sfc_err(sa, "cannot find %s Tx datapath", sa->dp_tx_name);
+ SFC_LOG(sa, RTE_LOG_ERR, logtype_main,
+ "cannot find %s Tx datapath", sa->dp_tx_name);
rc = ENOENT;
goto fail_dp_tx;
}
if (~dp_tx->features & SFC_DP_TX_FEAT_MULTI_PROCESS) {
- sfc_err(sa, "%s Tx datapath does not support multi-process",
+ SFC_LOG(sa, RTE_LOG_ERR, logtype_main,
+ "%s Tx datapath does not support multi-process",
sa->dp_tx_name);
rc = EINVAL;
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;
const efx_nic_cfg_t *encp;
const struct ether_addr *from;
sfc_register_dp();
+ logtype_main = sfc_register_logtype(&pci_dev->addr,
+ 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);
+ 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;
+ sas->pci_addr = pci_dev->addr;
+ sas->port_id = dev->data->port_id;
+ sa->priv.logtype_main = logtype_main;
sa->eth_dev = dev;
/* Copy PCI device info to the dev->data */
rte_eth_copy_pci_info(dev, pci_dev);
- sa->logtype_main = sfc_register_logtype(sa, SFC_LOGTYPE_MAIN_STR,
- RTE_LOG_NOTICE);
-
rc = sfc_kvargs_parse(sa);
if (rc != 0)
goto fail_kvargs_parse;
fail_kvargs_parse:
sfc_log_init(sa, "failed %d", rc);
+ dev->process_private = NULL;
SFC_ASSERT(rc > 0);
return -rc;
}
sfc_detach(sa);
sfc_unprobe(sa);
- rte_free(dev->data->mac_addrs);
- dev->data->mac_addrs = NULL;
-
sfc_kvargs_cleanup(sa);
sfc_adapter_unlock(sa);
SFC_KVARG_RXD_WAIT_TIMEOUT_NS "=<long> "
SFC_KVARG_STATS_UPDATE_PERIOD_MS "=<long>");
-RTE_INIT(sfc_driver_register_logtype);
-static void
-sfc_driver_register_logtype(void)
+RTE_INIT(sfc_driver_register_logtype)
{
int ret;