From patchwork Fri Aug 11 16:34:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harman Kalra X-Patchwork-Id: 130176 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 207BA43036; Fri, 11 Aug 2023 18:35:36 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 293BF43272; Fri, 11 Aug 2023 18:35:14 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 5741B43263 for ; Fri, 11 Aug 2023 18:35:12 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37BBmUgn001610 for ; Fri, 11 Aug 2023 09:35:11 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=t7DTeBJCxxvXtrbrs+d4wXFn6oNkKJL1grifnzCPxb8=; b=B2MvHyVkmnpY51CLwEStaa5vvrM4+rDmvToaPDEoaopvLZcrTpRbFutFWs0jyD2hPfzY 879QHBtnuiMxbNaOAiSFSd6dehGcbNW9YigyGKPbR3R/dreAlqEvIOqW0R2IqAjd6eyc CnvUqdQNvstAz51an5fuXqcBArE+l+WpTh9OwDiEeBk7k7zzrRI2ck5CnxxCCsljbLmz SIO4MjhtRPnd5JQ+qG5fBWbJ3g8W3bYT5n/M+4lEe2EXt9kYx31DX9lWVbpMgJPaghVS 7SeH+ROEeClM6uqVgtxBPZyiFEkzkbQ29prUFuUvw6Lu/mJ3tRFX5FBUBMV5l4jGTmOf 3A== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3sd8ypb91u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Fri, 11 Aug 2023 09:35:10 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Fri, 11 Aug 2023 09:35:07 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Fri, 11 Aug 2023 09:35:07 -0700 Received: from localhost.localdomain (unknown [10.29.52.211]) by maili.marvell.com (Postfix) with ESMTP id 729BD3F705D; Fri, 11 Aug 2023 09:35:05 -0700 (PDT) From: Harman Kalra To: , Nithin Dabilpuram , "Kiran Kumar K" , Sunil Kumar Kori , Satha Rao CC: , Harman Kalra Subject: [PATCH 5/9] net/cnxk: add representor control plane Date: Fri, 11 Aug 2023 22:04:15 +0530 Message-ID: <20230811163419.165790-6-hkalra@marvell.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230811163419.165790-1-hkalra@marvell.com> References: <20230811163419.165790-1-hkalra@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: sSE1Y2BCVuQb7HV5u9zb_mr76dW7GwTo X-Proofpoint-GUID: sSE1Y2BCVuQb7HV5u9zb_mr76dW7GwTo X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-08-11_08,2023-08-10_01,2023-05-22_02 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Implementing the control path for representor ports, where represented ports can be configured using TLV messaging. Signed-off-by: Harman Kalra --- drivers/net/cnxk/cnxk_ethdev.c | 8 + drivers/net/cnxk/cnxk_ethdev.h | 3 + drivers/net/cnxk/cnxk_rep.c | 13 +- drivers/net/cnxk/cnxk_rep.h | 1 + drivers/net/cnxk/cnxk_rep_msg.c | 559 ++++++++++++++++++++++++++++++++ drivers/net/cnxk/cnxk_rep_msg.h | 78 +++++ drivers/net/cnxk/meson.build | 1 + 7 files changed, 662 insertions(+), 1 deletion(-) create mode 100644 drivers/net/cnxk/cnxk_rep_msg.c create mode 100644 drivers/net/cnxk/cnxk_rep_msg.h diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c index 902e6df72d..a63c020c0e 100644 --- a/drivers/net/cnxk/cnxk_ethdev.c +++ b/drivers/net/cnxk/cnxk_ethdev.c @@ -1645,6 +1645,14 @@ cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev) memset(&link, 0, sizeof(link)); rte_eth_linkstatus_set(eth_dev, &link); + /* Exiting the rep msg ctrl thread */ + if (dev->num_reps) { + if (dev->start_rep_thread) { + dev->start_rep_thread = false; + pthread_join(dev->rep_ctrl_msg_thread, NULL); + } + } + return 0; } diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h index 3896db38e1..0a1a4e377d 100644 --- a/drivers/net/cnxk/cnxk_ethdev.h +++ b/drivers/net/cnxk/cnxk_ethdev.h @@ -425,6 +425,9 @@ struct cnxk_eth_dev { uint16_t switch_domain_id; uint16_t num_reps; uint16_t rep_xport_vdev; + rte_spinlock_t rep_lock; + bool start_rep_thread; + pthread_t rep_ctrl_msg_thread; struct cnxk_rep_info *rep_info; }; diff --git a/drivers/net/cnxk/cnxk_rep.c b/drivers/net/cnxk/cnxk_rep.c index 4dd564058c..e6f5790adc 100644 --- a/drivers/net/cnxk/cnxk_rep.c +++ b/drivers/net/cnxk/cnxk_rep.c @@ -2,6 +2,7 @@ * Copyright(C) 2023 Marvell. */ #include +#include /* CNXK platform representor dev ops */ struct eth_dev_ops cnxk_rep_dev_ops = { @@ -203,7 +204,7 @@ cnxk_process_representor_status(void *roc_nix, uint16_t pf_func, uint8_t op) case 0: /* update pffunc of vf being represented */ match = 0; func_val = pf_func; - is_vf_active = true; + is_vf_active = false; break; case 1: /* check if any representor is representing pffunc */ match = pf_func; @@ -314,6 +315,9 @@ cnxk_rep_dev_probe(struct rte_pci_device *pci_dev, struct rte_eth_dev *pf_ethdev pf_dev->num_reps++; } + /* Spinlock for synchronization between the control messages */ + plt_spinlock_init(&pf_dev->rep_lock); + /* Register up msg callbacks for processing representor information */ if (roc_nix_process_rep_state_cb_register(&pf_dev->nix, cnxk_process_representor_status)) { plt_err("Failed to register callback for representor status"); @@ -321,6 +325,13 @@ cnxk_rep_dev_probe(struct rte_pci_device *pci_dev, struct rte_eth_dev *pf_ethdev goto err; } + /* Launch a thread to handle control messages */ + rc = cnxk_rep_control_thread_launch(pf_dev); + if (rc) { + plt_err("Failed to launch message ctrl thread"); + goto err; + } + return 0; err: return rc; diff --git a/drivers/net/cnxk/cnxk_rep.h b/drivers/net/cnxk/cnxk_rep.h index e3fc717a58..8825fa1cf2 100644 --- a/drivers/net/cnxk/cnxk_rep.h +++ b/drivers/net/cnxk/cnxk_rep.h @@ -8,6 +8,7 @@ #define CNXK_REP_XPORT_VDEV_DEVARGS "role=server" #define CNXK_REP_XPORT_VDEV_NAME "net_memif" +#define CNXK_REP_VDEV_CTRL_QUEUE 0 #define CNXK_MAX_REP_PORTS 128 /* Common ethdev ops */ diff --git a/drivers/net/cnxk/cnxk_rep_msg.c b/drivers/net/cnxk/cnxk_rep_msg.c new file mode 100644 index 0000000000..ca3b6b014e --- /dev/null +++ b/drivers/net/cnxk/cnxk_rep_msg.c @@ -0,0 +1,559 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include +#include + +#define CTRL_MSG_RCV_TIMEOUT_MS 2000 +#define CTRL_MSG_READY_WAIT_US 2000 +#define CTRL_MSG_THRD_NAME_LEN 35 +#define CTRL_MSG_BUFFER_SZ 1500 +#define CTRL_MSG_SIGNATURE 0xcdacdeadbeefcadc + +static int +send_message(void *buffer, size_t len, struct rte_mempool *mb_pool, uint16_t portid) +{ + struct rte_mbuf *m = NULL; + uint8_t nb_pkt; + int rc = 0; + char *data; + + m = rte_pktmbuf_alloc(mb_pool); + if (m == NULL) { + plt_err("Cannot allocate mbuf"); + rc = -rte_errno; + goto fail; + } + + if (rte_pktmbuf_pkt_len(m) != 0) { + plt_err("Bad length"); + rc = -EINVAL; + goto fail; + } + + /* append data */ + data = rte_pktmbuf_append(m, len); + if (data == NULL) { + plt_err("Cannot append data\n"); + rc = -EINVAL; + goto fail; + } + if (rte_pktmbuf_pkt_len(m) != len) { + plt_err("Bad pkt length\n"); + rc = -EINVAL; + goto fail; + } + + if (rte_pktmbuf_data_len(m) != len) { + plt_err("Bad data length\n"); + rc = -EINVAL; + goto fail; + } + + rte_memcpy(data, buffer, len); + + /* Send the control message */ + nb_pkt = rte_eth_tx_burst(portid, CNXK_REP_VDEV_CTRL_QUEUE, (struct rte_mbuf **)&m, 1); + if (nb_pkt == 0) { + plt_err("Failed to send message"); + rc = -EINVAL; + goto fail; + } + + return 0; +fail: + return rc; +} + +void +cnxk_rep_msg_populate_msg_end(void *buffer, uint32_t *length) +{ + cnxk_rep_msg_populate_command(buffer, length, CNXK_REP_MSG_END, 0); +} + +void +cnxk_rep_msg_populate_type(void *buffer, uint32_t *length, cnxk_type_t type, uint32_t sz) +{ + uint32_t len = *length; + cnxk_type_data_t data; + + /* Prepare type data */ + data.type = type; + data.length = sz; + + /* Populate the type data */ + rte_memcpy(RTE_PTR_ADD(buffer, len), &data, sizeof(cnxk_type_data_t)); + len += sizeof(cnxk_type_data_t); + + *length = len; +} + +void +cnxk_rep_msg_populate_header(void *buffer, uint32_t *length) +{ + cnxk_header_t hdr; + int len; + + cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_HEADER, sizeof(cnxk_header_t)); + + len = *length; + /* Prepare header data */ + hdr.signature = CTRL_MSG_SIGNATURE; + + /* Populate header data */ + rte_memcpy(RTE_PTR_ADD(buffer, len), &hdr, sizeof(cnxk_header_t)); + len += sizeof(cnxk_header_t); + + *length = len; +} + +void +cnxk_rep_msg_populate_command(void *buffer, uint32_t *length, cnxk_rep_msg_t type, uint32_t size) +{ + cnxk_rep_msg_data_t msg_data; + uint32_t len; + uint16_t sz = sizeof(cnxk_rep_msg_data_t); + + cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_MSG, sz); + + len = *length; + /* Prepare command data */ + msg_data.type = type; + msg_data.length = size; + + /* Populate the command */ + rte_memcpy(RTE_PTR_ADD(buffer, len), &msg_data, sz); + len += sz; + + *length = len; +} + +void +cnxk_rep_msg_populate_command_meta(void *buffer, uint32_t *length, void *msg_meta, uint32_t sz, + cnxk_rep_msg_t msg) +{ + uint32_t len; + + cnxk_rep_msg_populate_command(buffer, length, msg, sz); + + len = *length; + /* Populate command data */ + rte_memcpy(RTE_PTR_ADD(buffer, len), msg_meta, sz); + len += sz; + + *length = len; +} + +static int +parse_validate_header(void *msg_buf, uint32_t *buf_trav_len) +{ + cnxk_type_data_t *tdata = NULL; + cnxk_header_t *hdr = NULL; + void *data = NULL; + uint16_t len = 0; + + /* Read first bytes of type data */ + data = msg_buf; + tdata = (cnxk_type_data_t *)data; + if (tdata->type != CNXK_TYPE_HEADER) { + plt_err("Invalid type %d, type header expected", tdata->type); + goto fail; + } + + /* Get the header value */ + data = RTE_PTR_ADD(msg_buf, sizeof(cnxk_type_data_t)); + len += sizeof(cnxk_type_data_t); + + /* Validate the header */ + hdr = (cnxk_header_t *)data; + if (hdr->signature != CTRL_MSG_SIGNATURE) { + plt_err("Invalid signature detected: 0x%lx", hdr->signature); + goto fail; + } + + /* Update length read till point */ + len += tdata->length; + + *buf_trav_len = len; + return 0; +fail: + return errno; +} + +static cnxk_rep_msg_data_t * +message_data_extract(void *msg_buf, uint32_t *buf_trav_len) +{ + cnxk_type_data_t *tdata = NULL; + cnxk_rep_msg_data_t *msg = NULL; + uint16_t len = *buf_trav_len; + void *data; + + tdata = (cnxk_type_data_t *)RTE_PTR_ADD(msg_buf, len); + if (tdata->type != CNXK_TYPE_MSG) { + plt_err("Invalid type %d, type MSG expected", tdata->type); + goto fail; + } + + /* Get the message type */ + len += sizeof(cnxk_type_data_t); + data = RTE_PTR_ADD(msg_buf, len); + msg = (cnxk_rep_msg_data_t *)data; + + /* Advance to actual message data */ + len += tdata->length; + *buf_trav_len = len; + + return msg; +fail: + return NULL; +} + +static void +process_ack_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data) +{ + cnxk_rep_msg_ack_data_t *adata = (cnxk_rep_msg_ack_data_t *)data; + uint16_t len = *buf_trav_len; + void *buf; + + /* Get the message type data viz ack data */ + buf = RTE_PTR_ADD(msg_buf, len); + adata->u.data = rte_zmalloc("Ack data", msg_len, 0); + adata->size = msg_len; + if (adata->size == sizeof(uint64_t)) + rte_memcpy(&adata->u.data, buf, msg_len); + else + rte_memcpy(adata->u.data, buf, msg_len); + plt_rep_dbg("Address %p val 0x%lx sval %ld msg_len %d", adata->u.data, adata->u.val, + adata->u.sval, msg_len); + + /* Advance length to nex message */ + len += msg_len; + *buf_trav_len = len; +} + +static int +notify_rep_dev_ready(void *data, bool state) +{ + struct cnxk_eth_dev *pf_dev = (struct cnxk_eth_dev *)data; + struct cnxk_rep_dev *rep_dev = NULL; + struct rte_eth_dev *rep_eth_dev; + int i; + + for (i = 0; i < pf_dev->num_reps; i++) { + rep_eth_dev = pf_dev->rep_info[i].rep_eth_dev; + if (!rep_eth_dev) + continue; + + rep_dev = cnxk_rep_pmd_priv(rep_eth_dev); + rep_dev->is_vf_active = state; + } + + return 0; +} + +static void +process_ready_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data) +{ + cnxk_rep_msg_ready_data_t *rdata = NULL; + uint16_t len = *buf_trav_len; + void *buf; + + /* Get the message type data viz ready data */ + buf = RTE_PTR_ADD(msg_buf, len); + rdata = (cnxk_rep_msg_ready_data_t *)buf; + + plt_rep_dbg("Ready data received %d", rdata->val); + + /* Wait required to ensure other side ready for recieving the ack */ + usleep(CTRL_MSG_READY_WAIT_US); + /* Update all representor about ready message */ + if (rdata->val) + notify_rep_dev_ready(data, true); + + /* Advance length to nex message */ + len += msg_len; + *buf_trav_len = len; +} + +static void +process_exit_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data) +{ + cnxk_rep_msg_exit_data_t *edata = NULL; + uint16_t len = *buf_trav_len; + void *buf; + + /* Get the message type data viz exit data */ + buf = RTE_PTR_ADD(msg_buf, len); + edata = (cnxk_rep_msg_exit_data_t *)buf; + + plt_rep_dbg("Exit data received %d", edata->val); + + /* Update all representor about ready/exit message */ + if (edata->val) + notify_rep_dev_ready(data, false); + + /* Advance length to nex message */ + len += msg_len; + *buf_trav_len = len; +} + +static void +populate_ack_msg(void *buffer, uint32_t *length, cnxk_rep_msg_ack_data_t *adata) +{ + uint32_t sz = sizeof(cnxk_rep_msg_ack_data_t); + uint32_t len; + + cnxk_rep_msg_populate_command(buffer, length, CNXK_REP_MSG_ACK, sz); + + len = *length; + + rte_memcpy(RTE_PTR_ADD(buffer, len), adata, sz); + + len += sz; + + *length = len; +} + +static int +send_ack_message(cnxk_rep_msg_ack_data_t *adata, struct rte_mempool *mb_pool, uint16_t portid) +{ + uint32_t len = 0, size; + void *buffer; + int rc = 0; + + /* Allocate memory for preparing a message */ + size = CTRL_MSG_BUFFER_SZ; + buffer = rte_zmalloc("ACK msg", size, 0); + if (!buffer) { + plt_err("Failed to allocate mem"); + return -ENOMEM; + } + + /* Prepare the ACK message */ + cnxk_rep_msg_populate_header(buffer, &len); + populate_ack_msg(buffer, &len, adata); + cnxk_rep_msg_populate_msg_end(buffer, &len); + + /* Send it to the peer */ + rc = send_message(buffer, len, mb_pool, portid); + if (rc) + plt_err("Failed send ack"); + + return rc; +} + +static int +process_message(void *msg_buf, uint32_t *buf_trav_len, void *data, struct rte_mempool *mb_pool, + uint16_t portid) +{ + cnxk_rep_msg_data_t *msg = NULL; + cnxk_rep_msg_ack_data_t adata; + bool send_ack; + int rc = 0; + + /* Get the message data */ + msg = message_data_extract(msg_buf, buf_trav_len); + if (!msg) { + plt_err("Failed to get message data"); + rc = -EINVAL; + goto fail; + } + + /* Different message type processing */ + while (msg->type != CNXK_REP_MSG_END) { + send_ack = true; + switch (msg->type) { + case CNXK_REP_MSG_ACK: + process_ack_message(msg_buf, buf_trav_len, msg->length, data); + send_ack = false; + break; + case CNXK_REP_MSG_READY: + process_ready_message(msg_buf, buf_trav_len, msg->length, data); + adata.type = CNXK_REP_MSG_READY; + adata.u.val = 0; + adata.size = sizeof(uint64_t); + break; + case CNXK_REP_MSG_EXIT: + process_exit_message(msg_buf, buf_trav_len, msg->length, data); + adata.type = CNXK_REP_MSG_EXIT; + adata.u.val = 0; + adata.size = sizeof(uint64_t); + break; + default: + plt_err("Invalid message type: %d", msg->type); + rc = -EINVAL; + }; + + /* Send ACK */ + if (send_ack) + send_ack_message(&adata, mb_pool, portid); + + /* Advance to next message */ + msg = message_data_extract(msg_buf, buf_trav_len); + } + + return 0; +fail: + return rc; +} + +static int +process_control_packet(struct rte_mbuf *mbuf, void *data, uint16_t portid) +{ + uint32_t len = mbuf->data_len; + uint32_t buf_trav_len = 0; + void *msg_buf; + int rc; + + msg_buf = plt_zmalloc(len, 0); + if (!msg_buf) { + plt_err("Failed to allocate mem for msg_buf"); + rc = -ENOMEM; + goto fail; + } + + /* Extract the packet data which contains the message */ + rte_memcpy(msg_buf, rte_pktmbuf_mtod(mbuf, void *), len); + + /* Validate the validity of the received message */ + parse_validate_header(msg_buf, &buf_trav_len); + + /* Detect message and process */ + rc = process_message(msg_buf, &buf_trav_len, data, mbuf->pool, portid); + if (rc) { + plt_err("Failed to process message"); + goto fail; + } + + /* Ensuring entire message has been processed */ + if (len != buf_trav_len) { + plt_err("Out of %d bytes %d bytes of msg_buf processed", len, buf_trav_len); + rc = -EFAULT; + goto fail; + } + + rte_free(msg_buf); + + return 0; +fail: + return rc; +} + +static int +receive_control_msg_resp(uint16_t portid, void *data) +{ + uint32_t wait_us = CTRL_MSG_RCV_TIMEOUT_MS * 1000; + uint32_t timeout = 0, sleep = 1; + struct rte_mbuf *m = NULL; + uint8_t rx = 0; + int rc = -1; + + do { + rx = rte_eth_rx_burst(portid, CNXK_REP_VDEV_CTRL_QUEUE, &m, 1); + if (rx != 0) + break; + + /* Timeout after CTRL_MSG_RCV_TIMEOUT_MS */ + if (timeout >= wait_us) { + plt_err("Control message wait timedout"); + return -ETIMEDOUT; + } + + plt_delay_us(sleep); + timeout += sleep; + } while ((rx == 0) || (timeout < wait_us)); + + if (rx) { + rc = process_control_packet(m, data, portid); + /* Freeing the allocated buffer */ + rte_pktmbuf_free(m); + } + + return rc; +} + +int +cnxk_rep_msg_send_process(struct cnxk_rep_dev *rep_dev, void *buffer, uint32_t len, + cnxk_rep_msg_ack_data_t *adata) +{ + struct cnxk_eth_dev *pf_dev; + int rc = 0; + + pf_dev = cnxk_eth_pmd_priv(rep_dev->parent_dev); + if (!pf_dev) { + plt_err("Failed to get parent pf handle"); + rc = -1; + goto fail; + } + + plt_spinlock_lock(&pf_dev->rep_lock); + rc = send_message(buffer, len, rep_dev->ctrl_chan_pool, rep_dev->rep_xport_vdev); + if (rc) { + plt_err("Failed to send the message, err %d", rc); + goto free; + } + + rc = receive_control_msg_resp(rep_dev->rep_xport_vdev, adata); + if (rc) { + plt_err("Failed to receive the response, err %d", rc); + goto free; + } + plt_spinlock_unlock(&pf_dev->rep_lock); + + return 0; +free: + plt_spinlock_unlock(&pf_dev->rep_lock); +fail: + return rc; +} + +static void +poll_for_control_msg(void *data) +{ + struct cnxk_eth_dev *pf_dev = (struct cnxk_eth_dev *)data; + uint16_t portid = pf_dev->rep_xport_vdev; + struct rte_mbuf *m = NULL; + uint8_t rx = 0; + + do { + rx = rte_eth_rx_burst(portid, CNXK_REP_VDEV_CTRL_QUEUE, &m, 1); + if (rx != 0) + break; + } while (rx == 0 && pf_dev->start_rep_thread); + + if (rx) { + plt_spinlock_lock(&pf_dev->rep_lock); + process_control_packet(m, data, portid); + /* Freeing the allocated buffer */ + rte_pktmbuf_free(m); + plt_spinlock_unlock(&pf_dev->rep_lock); + } +} + +static void * +rep_ctrl_msg_thread_main(void *arg) +{ + struct cnxk_eth_dev *pf_dev = (struct cnxk_eth_dev *)arg; + + while (pf_dev->start_rep_thread) + poll_for_control_msg(pf_dev); + + return NULL; +} + +int +cnxk_rep_control_thread_launch(struct cnxk_eth_dev *pf_dev) +{ + char name[CTRL_MSG_THRD_NAME_LEN]; + int rc = 0; + + rte_strscpy(name, "rep_ctrl_msg_hndlr", CTRL_MSG_THRD_NAME_LEN); + pf_dev->start_rep_thread = true; + rc = plt_ctrl_thread_create(&pf_dev->rep_ctrl_msg_thread, name, NULL, + rep_ctrl_msg_thread_main, pf_dev); + if (rc != 0) + plt_err("Failed to create rep control message handling"); + + return rc; +} diff --git a/drivers/net/cnxk/cnxk_rep_msg.h b/drivers/net/cnxk/cnxk_rep_msg.h new file mode 100644 index 0000000000..a28c63f762 --- /dev/null +++ b/drivers/net/cnxk/cnxk_rep_msg.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#ifndef __CNXK_REP_MSG_H__ +#define __CNXK_REP_MSG_H__ + +#include + +#define CNXK_REP_MSG_MAX_BUFFER_SZ 1500 + +typedef enum CNXK_TYPE { + CNXK_TYPE_HEADER = 0, + CNXK_TYPE_MSG, +} cnxk_type_t; + +typedef enum CNXK_REP_MSG { + /* General sync messages */ + CNXK_REP_MSG_READY = 0, + CNXK_REP_MSG_ACK, + CNXK_REP_MSG_EXIT, + /* End of messaging sequence */ + CNXK_REP_MSG_END, +} cnxk_rep_msg_t; + +/* Types */ +typedef struct cnxk_type_data { + cnxk_type_t type; + uint32_t length; + uint64_t data[]; +} __rte_packed cnxk_type_data_t; + +/* Header */ +typedef struct cnxk_header { + uint64_t signature; + uint16_t nb_hops; +} __rte_packed cnxk_header_t; + +/* Message meta */ +typedef struct cnxk_rep_msg_data { + cnxk_rep_msg_t type; + uint32_t length; + uint64_t data[]; +} __rte_packed cnxk_rep_msg_data_t; + +/* Ack msg */ +typedef struct cnxk_rep_msg_ack_data { + cnxk_rep_msg_t type; + uint32_t size; + union { + void *data; + uint64_t val; + int64_t sval; + } u; +} __rte_packed cnxk_rep_msg_ack_data_t; + +/* Ready msg */ +typedef struct cnxk_rep_msg_ready_data { + uint8_t val; +} __rte_packed cnxk_rep_msg_ready_data_t; + +/* Exit msg */ +typedef struct cnxk_rep_msg_exit_data { + uint8_t val; +} __rte_packed cnxk_rep_msg_exit_data_t; + +void cnxk_rep_msg_populate_command(void *buffer, uint32_t *length, cnxk_rep_msg_t type, + uint32_t size); +void cnxk_rep_msg_populate_command_meta(void *buffer, uint32_t *length, void *msg_meta, uint32_t sz, + cnxk_rep_msg_t msg); +void cnxk_rep_msg_populate_msg_end(void *buffer, uint32_t *length); +void cnxk_rep_msg_populate_type(void *buffer, uint32_t *length, cnxk_type_t type, uint32_t sz); +void cnxk_rep_msg_populate_header(void *buffer, uint32_t *length); +int cnxk_rep_msg_send_process(struct cnxk_rep_dev *rep_dev, void *buffer, uint32_t len, + cnxk_rep_msg_ack_data_t *adata); +int cnxk_rep_control_thread_launch(struct cnxk_eth_dev *pf_dev); + +#endif /* __CNXK_REP_MSG_H__ */ diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build index 38dde54ce9..0e7334f5cd 100644 --- a/drivers/net/cnxk/meson.build +++ b/drivers/net/cnxk/meson.build @@ -33,6 +33,7 @@ sources = files( 'cnxk_ptp.c', 'cnxk_flow.c', 'cnxk_rep.c', + 'cnxk_rep_msg.c', 'cnxk_rep_ops.c', 'cnxk_stats.c', 'cnxk_tm.c',