+static void
+sfc_eth_dev_clear_ops(struct rte_eth_dev *dev)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ dev->dev_ops = NULL;
+ dev->rx_pkt_burst = NULL;
+ dev->tx_pkt_burst = NULL;
+
+ rte_free(sa->dp_tx_name);
+ sa->dp_tx_name = NULL;
+ sa->dp_tx = NULL;
+
+ rte_free(sa->dp_rx_name);
+ sa->dp_rx_name = NULL;
+ sa->dp_rx = NULL;
+}
+
+static const struct eth_dev_ops sfc_eth_dev_secondary_ops = {
+ .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)
+{
+ /*
+ * Device private data has really many process-local pointers.
+ * Below code should be extremely careful to use data located
+ * in shared memory only.
+ */
+ struct sfc_adapter *sa = dev->data->dev_private;
+ const struct sfc_dp_rx *dp_rx;
+ const struct sfc_dp_tx *dp_tx;
+ int rc;
+
+ 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);
+ 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);
+ 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);
+ 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",
+ sa->dp_tx_name);
+ rc = EINVAL;
+ goto fail_dp_tx_multi_process;
+ }
+
+ dev->rx_pkt_burst = dp_rx->pkt_burst;
+ dev->tx_pkt_burst = dp_tx->pkt_burst;
+ dev->dev_ops = &sfc_eth_dev_secondary_ops;
+
+ return 0;
+
+fail_dp_tx_multi_process:
+fail_dp_tx:
+fail_dp_rx_multi_process:
+fail_dp_rx:
+ return rc;
+}
+
+static void
+sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
+{
+ dev->dev_ops = NULL;
+ dev->tx_pkt_burst = NULL;
+ dev->rx_pkt_burst = NULL;
+}
+