#include "hns3_rxtx.h"
#include "hns3_mp.h"
-static bool hns3_inited;
+/* local data for primary or secondary process. */
+static struct hns3_process_local_data process_data;
/*
* Initialize IPC message.
struct hns3_mp_param *res = (struct hns3_mp_param *)mp_res.param;
const struct hns3_mp_param *param =
(const struct hns3_mp_param *)mp_msg->param;
- eth_tx_prep_t prep = NULL;
struct rte_eth_dev *dev;
int ret;
case HNS3_MP_REQ_START_TX:
PMD_INIT_LOG(INFO, "port %u starting Tx datapath",
dev->data->port_id);
- dev->tx_pkt_burst = hns3_get_tx_function(dev, &prep);
- dev->tx_pkt_prepare = prep;
+ hns3_start_tx_datapath(dev);
break;
case HNS3_MP_REQ_STOP_TX:
PMD_INIT_LOG(INFO, "port %u stopping Tx datapath",
dev->data->port_id);
- dev->tx_pkt_burst = hns3_dummy_rxtx_burst;
- dev->tx_pkt_prepare = NULL;
+ hns3_stop_tx_datapath(dev);
break;
default:
rte_errno = EINVAL;
int ret;
int i;
- if (rte_eal_process_type() == RTE_PROC_SECONDARY || !hw->secondary_cnt)
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY ||
+ __atomic_load_n(&hw->secondary_cnt, __ATOMIC_RELAXED) == 0)
return;
+
if (!mp_req_type_is_valid(type)) {
hns3_err(hw, "port %u unknown request (req_type %d)",
dev->data->port_id, type);
/*
* Initialize by primary process.
*/
-int hns3_mp_init_primary(void)
+static int
+hns3_mp_init_primary(void)
{
int ret;
- if (!hns3_inited) {
- /* primary is allowed to not support IPC */
- ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle);
- if (ret && rte_errno != ENOTSUP)
- return ret;
+ if (process_data.init_done)
+ return 0;
- hns3_inited = true;
- }
+ /* primary is allowed to not support IPC */
+ ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle);
+ if (ret && rte_errno != ENOTSUP)
+ return ret;
+
+ process_data.init_done = true;
return 0;
}
/*
- * Un-initialize by primary process.
+ * Initialize by secondary process.
*/
-void hns3_mp_uninit_primary(void)
+static int
+hns3_mp_init_secondary(void)
{
- if (hns3_inited)
- rte_mp_action_unregister(HNS3_MP_NAME);
+ int ret;
+
+ if (process_data.init_done)
+ return 0;
+
+ ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle);
+ if (ret && rte_errno != ENOTSUP)
+ return ret;
+
+ process_data.init_done = true;
+
+ return 0;
}
-/*
- * Initialize by secondary process.
- */
-int hns3_mp_init_secondary(void)
+int
+hns3_mp_init(struct rte_eth_dev *dev)
{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int ret;
- if (!hns3_inited) {
- ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle);
- if (ret)
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ ret = hns3_mp_init_secondary();
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to init for secondary process, ret = %d",
+ ret);
return ret;
-
- hns3_inited = true;
+ }
+ __atomic_fetch_add(&hw->secondary_cnt, 1, __ATOMIC_RELAXED);
+ } else {
+ ret = hns3_mp_init_primary();
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to init for primary process, ret = %d",
+ ret);
+ return ret;
+ }
}
+ process_data.eth_dev_cnt++;
+
return 0;
}
+
+void hns3_mp_uninit(struct rte_eth_dev *dev)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED);
+
+ process_data.eth_dev_cnt--;
+ if (process_data.eth_dev_cnt == 0) {
+ rte_mp_action_unregister(HNS3_MP_NAME);
+ process_data.init_done = false;
+ }
+}