From: <wanry@3snic.com>
To: <dev@dpdk.org>
Cc: <ferruh.yigit@amd.com>, Renyong Wan <wanry@3snic.com>,
Steven Song <steven.song@3snic.com>
Subject: [PATCH v5 09/32] net/sssnic/base: add control queue
Date: Mon, 4 Sep 2023 12:56:35 +0800 [thread overview]
Message-ID: <20230904045658.238185-10-wanry@3snic.com> (raw)
In-Reply-To: <20230904045658.238185-1-wanry@3snic.com>
From: Renyong Wan <wanry@3snic.com>
Control queue is used for communication between driver and datapath code
of firmware.
Signed-off-by: Steven Song <steven.song@3snic.com>
Signed-off-by: Renyong Wan <wanry@3snic.com>
---
v2:
* Fixed variable 'cmd_len' is uninitialized when used.
---
drivers/net/sssnic/base/meson.build | 2 +
drivers/net/sssnic/base/sssnic_api.c | 102 +++++
drivers/net/sssnic/base/sssnic_api.h | 23 ++
drivers/net/sssnic/base/sssnic_cmd.h | 114 ++++++
drivers/net/sssnic/base/sssnic_ctrlq.c | 521 +++++++++++++++++++++++++
drivers/net/sssnic/base/sssnic_ctrlq.h | 58 +++
drivers/net/sssnic/base/sssnic_hw.c | 149 +++++++
drivers/net/sssnic/base/sssnic_hw.h | 8 +
8 files changed, 977 insertions(+)
create mode 100644 drivers/net/sssnic/base/sssnic_api.c
create mode 100644 drivers/net/sssnic/base/sssnic_api.h
create mode 100644 drivers/net/sssnic/base/sssnic_cmd.h
create mode 100644 drivers/net/sssnic/base/sssnic_ctrlq.c
create mode 100644 drivers/net/sssnic/base/sssnic_ctrlq.h
diff --git a/drivers/net/sssnic/base/meson.build b/drivers/net/sssnic/base/meson.build
index 7c23a82ff3..e93ca7b24b 100644
--- a/drivers/net/sssnic/base/meson.build
+++ b/drivers/net/sssnic/base/meson.build
@@ -7,6 +7,8 @@ sources = [
'sssnic_msg.c',
'sssnic_mbox.c',
'sssnic_workq.c',
+ 'sssnic_ctrlq.c',
+ 'sssnic_api.c',
]
c_args = cflags
diff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c
new file mode 100644
index 0000000000..51a59f0f25
--- /dev/null
+++ b/drivers/net/sssnic/base/sssnic_api.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.
+ */
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+
+#include "../sssnic_log.h"
+#include "sssnic_hw.h"
+#include "sssnic_cmd.h"
+#include "sssnic_mbox.h"
+#include "sssnic_api.h"
+
+int
+sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,
+ struct sssnic_msix_attr *attr)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_msix_ctrl_cmd cmd;
+ uint32_t cmd_len;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.opcode = SSSNIC_CMD_OPCODE_GET;
+ cmd.idx = msix_idx;
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_MSIX_CTRL_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (cmd_len == 0 || cmd.common.status != 0) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to MSIX_CTRL_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+ attr->lli_credit = cmd.lli_credit;
+ attr->lli_timer = cmd.lli_timer;
+ attr->pending_limit = cmd.pending_count;
+ attr->coalescing_timer = cmd.coalescing_timer;
+ attr->resend_timer = cmd.resend_timer;
+
+ return 0;
+}
+
+int
+sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,
+ struct sssnic_msix_attr *attr)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_msix_ctrl_cmd cmd;
+ struct sssnic_msix_attr tmp;
+ uint32_t cmd_len;
+
+ ret = sssnic_msix_attr_get(hw, msix_idx, &tmp);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to get interrupt configuration");
+ return ret;
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.opcode = SSSNIC_CMD_OPCODE_SET;
+ cmd.idx = msix_idx;
+ cmd.lli_credit = tmp.lli_credit;
+ cmd.lli_timer = tmp.lli_timer;
+ cmd.pending_count = tmp.pending_limit;
+ cmd.coalescing_timer = tmp.coalescing_timer;
+ cmd.resend_timer = tmp.resend_timer;
+ if (attr->lli_set != 0) {
+ cmd.lli_credit = attr->lli_credit;
+ cmd.lli_timer = attr->lli_timer;
+ }
+ if (attr->coalescing_set != 0) {
+ cmd.pending_count = attr->pending_limit;
+ cmd.coalescing_timer = attr->coalescing_timer;
+ cmd.resend_timer = attr->resend_timer;
+ }
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_MSIX_CTRL_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (cmd_len == 0 || cmd.common.status != 0) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to MSIX_CTRL_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h
new file mode 100644
index 0000000000..3d54eb826a
--- /dev/null
+++ b/drivers/net/sssnic/base/sssnic_api.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.
+ */
+
+#ifndef _SSSNIC_API_H_
+#define _SSSNIC_API_H_
+
+struct sssnic_msix_attr {
+ uint32_t lli_set;
+ uint32_t coalescing_set;
+ uint8_t lli_credit;
+ uint8_t lli_timer;
+ uint8_t pending_limit;
+ uint8_t coalescing_timer;
+ uint8_t resend_timer;
+};
+
+int sssnic_msix_attr_get(struct sssnic_hw *hw, uint16_t msix_idx,
+ struct sssnic_msix_attr *attr);
+int sssnic_msix_attr_set(struct sssnic_hw *hw, uint16_t msix_idx,
+ struct sssnic_msix_attr *attr);
+
+#endif /* _SSSNIC_API_H_ */
diff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h
new file mode 100644
index 0000000000..ee9f536ac2
--- /dev/null
+++ b/drivers/net/sssnic/base/sssnic_cmd.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.
+ */
+
+#ifndef _SSSNIC_CMD_H_
+#define _SSSNIC_CMD_H_
+
+#define SSSNIC_CMD_OPCODE_SET 1
+#define SSSNIC_CMD_OPCODE_GET 0
+
+enum sssnic_mgmt_cmd_id {
+ SSSNIC_RESET_FUNC_CMD = 0,
+ SSSNIC_SET_CTRLQ_CTX_CMD = 20,
+ SSSNIC_SET_ROOT_CTX_CMD = 21,
+ SSSNIC_PAGESIZE_CFG_CMD = 22,
+ SSSNIC_MSIX_CTRL_CMD = 23,
+ SSSNIC_SET_DMA_ATTR_CMD = 25,
+ SSSNIC_GET_FW_VERSION_CMD = 60,
+};
+
+struct sssnic_cmd_common {
+ uint8_t status;
+ uint8_t version;
+ uint8_t resvd[6];
+};
+
+struct sssnic_set_ctrlq_ctx_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ /* CtrlQ ID, here always is 0 */
+ uint8_t qid;
+ uint8_t resvd[5];
+ union {
+ uint64_t data[2];
+ struct {
+ /* Page frame number*/
+ uint64_t pfn : 52;
+ uint64_t resvd0 : 4;
+ /* Completion event queue ID*/
+ uint64_t eq_id : 5;
+ /* Interrupt enable indication */
+ uint64_t informed : 1;
+ /* Completion event queue enable indication */
+ uint64_t eq_en : 1;
+ /* Entries wrapped indication */
+ uint64_t wrapped : 1;
+ uint64_t block_pfn : 52;
+ uint64_t start_ci : 12;
+ };
+ };
+};
+
+struct sssnic_dma_attr_set_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ uint8_t idx;
+ uint8_t st;
+ uint8_t at;
+ uint8_t ph;
+ uint8_t no_snooping;
+ uint8_t tph;
+ uint32_t resvd0;
+};
+
+struct sssnic_func_reset_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ uint16_t resvd[3];
+ /* Mask of reource to be reset */
+ uint64_t res_mask;
+};
+
+struct sssnic_root_ctx_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ /* set ctrlq depth enable */
+ uint8_t set_ctrlq_depth;
+ /* real depth is 2^ctrlq_depth */
+ uint8_t ctrlq_depth;
+ uint16_t rx_buf;
+ uint8_t lro_enable;
+ uint8_t resvd0;
+ uint16_t txq_depth;
+ uint16_t rxq_depth;
+ uint64_t resvd1;
+};
+
+struct sssnic_pagesize_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ /* SSSNIC_CMD_OPCODE_xx */
+ uint8_t opcode;
+ /* real size is (2^pagesz)*4KB */
+ uint8_t pagesz;
+ uint32_t resvd0;
+};
+
+struct sssnic_msix_ctrl_cmd {
+ struct sssnic_cmd_common common;
+ uint16_t func_id;
+ /* SSSNIC_CMD_OPCODE_xx */
+ uint8_t opcode;
+ uint8_t resvd0;
+ /* MSIX index */
+ uint16_t idx;
+ uint8_t pending_count;
+ uint8_t coalescing_timer;
+ uint8_t resend_timer;
+ uint8_t lli_timer;
+ uint8_t lli_credit;
+ uint8_t resvd1[5];
+};
+
+#endif /* _SSSNIC_CMD_H_ */
diff --git a/drivers/net/sssnic/base/sssnic_ctrlq.c b/drivers/net/sssnic/base/sssnic_ctrlq.c
new file mode 100644
index 0000000000..d0b507125c
--- /dev/null
+++ b/drivers/net/sssnic/base/sssnic_ctrlq.c
@@ -0,0 +1,521 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.
+ */
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+
+#include "../sssnic_log.h"
+#include "sssnic_hw.h"
+#include "sssnic_reg.h"
+#include "sssnic_cmd.h"
+#include "sssnic_mbox.h"
+#include "sssnic_ctrlq.h"
+
+#define SSSNIC_CTRLQ_DOORBELL_OFFSET 0
+#define SSSNIC_CTRLQ_BUF_SIZE 4096
+#define SSSNIC_CTRLQ_ENTRY_SIZE 64
+#define SSSNIC_CTRLQ_DEPTH 64
+
+#define SSSNIC_CTRLQ_RESP_TIMEOUT 5000 /* Default response timeout */
+
+enum sssnic_ctrlq_response_fmt {
+ /* return result and write it back into corresponding field of ctrlq entry */
+ SSSNIC_CTRLQ_RESPONSE_RESULT,
+ /* return data write it into DMA memory that usually is pktmbuf*/
+ SSSNIC_CTRLQ_RESPONSE_DATA,
+};
+
+struct sssnic_ctrlq_entry_desc_section {
+ union {
+ uint32_t dword;
+ struct {
+ /* buffer section length, always 2*/
+ uint32_t buf_sec_len : 8;
+ uint32_t resvd0 : 7;
+ /* response fmt, 0:result 1:data */
+ uint32_t resp_fmt : 1;
+ uint32_t resvd1 : 6;
+ /* buffer data format,always 0 */
+ uint32_t buf_fmt : 1;
+ /* always 1 */
+ uint32_t need_resp : 1;
+ uint32_t resvd2 : 3;
+ /* response section length, always 3 */
+ uint32_t resp_sec_len : 2;
+ /* control section length, always 1 */
+ uint32_t ctrl_sec_len : 2;
+ /* wrapped bit */
+ uint32_t wrapped : 1;
+ };
+ };
+};
+
+struct sssnic_ctrlq_entry_status_section {
+ union {
+ uint32_t dword;
+ struct {
+ /* status value, usually it saves error code */
+ uint32_t value : 31;
+ uint32_t resvd0 : 1;
+ };
+ };
+};
+
+struct sssnic_ctrlq_entry_ctrl_section {
+ union {
+ uint32_t dword;
+ struct {
+ /* producer index*/
+ uint32_t pi : 16;
+ /* command ID */
+ uint32_t cmd : 8;
+ /* hardware module */
+ uint32_t module : 5;
+ uint32_t resvd0 : 2;
+ /* Indication of command done */
+ uint32_t done : 1;
+ };
+ };
+};
+
+struct sssnic_ctrlq_entry_response_section {
+ union {
+ struct {
+ uint32_t hi_addr;
+ uint32_t lo_addr;
+ uint32_t len;
+ uint32_t resvd0;
+ } data;
+ struct {
+ uint64_t value;
+ uint64_t resvd0;
+ } result;
+ };
+};
+
+struct sssnic_ctrlq_entry_buf_section {
+ struct {
+ uint32_t hi_addr;
+ uint32_t lo_addr;
+ uint32_t len;
+ uint32_t resvd0;
+ } sge;
+ uint64_t resvd0[2];
+};
+
+/* Hardware format of control queue entry */
+struct sssnic_ctrlq_entry {
+ union {
+ uint32_t dword[16];
+ struct {
+ struct sssnic_ctrlq_entry_desc_section desc;
+ uint32_t resvd0;
+ struct sssnic_ctrlq_entry_status_section status;
+ struct sssnic_ctrlq_entry_ctrl_section ctrl;
+ struct sssnic_ctrlq_entry_response_section response;
+ struct sssnic_ctrlq_entry_buf_section buf;
+ };
+ };
+};
+
+/* Hardware format of control queue doorbell */
+struct sssnic_ctrlq_doorbell {
+ union {
+ uint64_t u64;
+ struct {
+ uint64_t resvd0 : 23;
+ /* ctrlq type is always 1*/
+ uint64_t qtype : 1;
+ /* cltrq id is always 0*/
+ uint64_t qid : 3;
+ uint64_t resvd1 : 5;
+ /* most significant byte of pi*/
+ uint64_t pi_msb : 8;
+ uint64_t resvd2 : 24;
+ };
+ };
+};
+static int
+sssnic_ctrlq_wait_response(struct sssnic_ctrlq *ctrlq, int *err_code,
+ uint32_t timeout_ms)
+{
+ struct sssnic_ctrlq_entry *entry;
+ struct sssnic_workq *workq;
+ uint64_t end;
+ int done = 0;
+
+ workq = ctrlq->workq;
+ entry = (struct sssnic_ctrlq_entry *)sssnic_workq_peek(workq);
+ if (entry == NULL) {
+ PMD_DRV_LOG(ERR, "Not found executing ctrlq command");
+ return -EINVAL;
+ }
+ if (timeout_ms == 0)
+ timeout_ms = SSSNIC_CTRLQ_RESP_TIMEOUT;
+ end = rte_get_timer_cycles() + rte_get_timer_hz() * timeout_ms / 1000;
+ do {
+ done = entry->ctrl.done;
+ if (done)
+ break;
+ rte_delay_us(1);
+ } while (((long)(rte_get_timer_cycles() - end)) < 0);
+
+ if (!done) {
+ PMD_DRV_LOG(ERR, "Waiting ctrlq response timeout, ci=%u",
+ workq->ci);
+ return -ETIMEDOUT;
+ }
+ if (err_code)
+ *err_code = entry->status.value;
+ sssnic_workq_consume(workq, 1, NULL);
+ return 0;
+}
+
+static void
+sssnic_ctrlq_doorbell_ring(struct sssnic_ctrlq *ctrlq, uint16_t next_pi)
+{
+ struct sssnic_ctrlq_doorbell db;
+
+ db.u64 = 0;
+ db.qtype = 1;
+ db.qid = 0;
+ db.pi_msb = (next_pi >> 8) & 0xff;
+ rte_wmb();
+ rte_write64(db.u64, ctrlq->doorbell + ((next_pi & 0xff) << 3));
+}
+
+static void
+sssnic_ctrlq_entry_init(struct sssnic_ctrlq_entry *entry, struct rte_mbuf *mbuf,
+ struct sssnic_ctrlq_cmd *cmd, uint16_t pi, uint16_t wrapped)
+{
+ struct sssnic_ctrlq_entry tmp_entry;
+ void *buf_addr;
+ rte_iova_t buf_iova;
+
+ /* Fill the temporary ctrlq entry */
+ memset(&tmp_entry, 0, sizeof(tmp_entry));
+ tmp_entry.desc.buf_fmt = 0;
+ tmp_entry.desc.buf_sec_len = 2;
+ tmp_entry.desc.need_resp = 1;
+ tmp_entry.desc.resp_sec_len = 3;
+ tmp_entry.desc.ctrl_sec_len = 1;
+ tmp_entry.desc.wrapped = wrapped;
+
+ tmp_entry.status.value = 0;
+
+ tmp_entry.ctrl.cmd = cmd->cmd;
+ tmp_entry.ctrl.pi = pi;
+ tmp_entry.ctrl.module = cmd->module;
+ tmp_entry.ctrl.done = 0;
+
+ buf_iova = rte_mbuf_data_iova(mbuf);
+ if (cmd->mbuf == NULL && cmd->data != NULL) {
+ /* cmd data is not allocated in mbuf*/
+ buf_addr = rte_pktmbuf_mtod(mbuf, void *);
+ rte_memcpy(buf_addr, cmd->data, cmd->data_len);
+ }
+ tmp_entry.buf.sge.hi_addr = (uint32_t)((buf_iova >> 16) >> 16);
+ tmp_entry.buf.sge.lo_addr = (uint32_t)buf_iova;
+ tmp_entry.buf.sge.len = cmd->data_len;
+
+ if (cmd->response_len == 0) {
+ tmp_entry.desc.resp_fmt = SSSNIC_CTRLQ_RESPONSE_RESULT;
+ tmp_entry.response.result.value = 0;
+ } else {
+ tmp_entry.desc.resp_fmt = SSSNIC_CTRLQ_RESPONSE_DATA;
+ /* response sge shares cmd mbuf */
+ tmp_entry.response.data.hi_addr =
+ (uint32_t)((buf_iova >> 16) >> 16);
+ tmp_entry.response.data.lo_addr = (uint32_t)buf_iova;
+ tmp_entry.response.data.len = SSSNIC_CTRLQ_MBUF_SIZE;
+ }
+
+ /* write temporary entry to real ctrlq entry
+ * the first 64bits must be copied last
+ */
+ rte_memcpy(((uint8_t *)entry) + sizeof(uint64_t),
+ ((uint8_t *)&tmp_entry) + sizeof(uint64_t),
+ SSSNIC_CTRLQ_ENTRY_SIZE - sizeof(sizeof(uint64_t)));
+ rte_wmb();
+ *((uint64_t *)entry) = *((uint64_t *)&tmp_entry);
+}
+
+static int
+sssnic_ctrlq_cmd_exec_internal(struct sssnic_ctrlq *ctrlq,
+ struct sssnic_ctrlq_cmd *cmd, uint32_t timeout_ms)
+{
+ struct rte_mbuf *mbuf;
+ struct sssnic_ctrlq_entry *entry;
+ struct sssnic_workq *workq;
+ uint16_t pi; /* current pi */
+ uint16_t next_pi;
+ uint16_t wrapped;
+ int ret;
+ int err_code;
+
+ /* Allocate cmd mbuf */
+ if (cmd->mbuf == NULL) {
+ mbuf = rte_pktmbuf_alloc(ctrlq->mbuf_pool);
+ if (mbuf == NULL) {
+ PMD_DRV_LOG(ERR, "Could not alloc mbuf for ctrlq cmd");
+ return -ENOMEM;
+ }
+ } else {
+ mbuf = cmd->mbuf;
+ }
+
+ /* allocate ctrlq entry */
+ workq = ctrlq->workq;
+ wrapped = ctrlq->wrapped;
+ entry = (struct sssnic_ctrlq_entry *)sssnic_workq_produce(workq, 1,
+ &pi);
+ if (entry == NULL) {
+ PMD_DRV_LOG(ERR, "No enough control queue entry");
+ ret = -EBUSY;
+ goto out;
+ }
+ /* workq->pi will be the next pi, the next pi could not exceed workq
+ * depth else must recalculate next pi, and reverse wrapped bit.
+ */
+ if (workq->pi >= workq->num_entries) {
+ ctrlq->wrapped = !ctrlq->wrapped;
+ workq->pi -= workq->num_entries;
+ }
+ next_pi = workq->pi;
+
+ /* fill ctrlq entry */
+ sssnic_ctrlq_entry_init(entry, mbuf, cmd, pi, wrapped);
+
+ /* Ring doorbell */
+ sssnic_ctrlq_doorbell_ring(ctrlq, next_pi);
+
+ /* Wait response */
+ ret = sssnic_ctrlq_wait_response(ctrlq, &err_code, timeout_ms);
+ if (ret != 0)
+ goto out;
+
+ if (err_code) {
+ PMD_DRV_LOG(ERR,
+ "Found error while control queue command executing, error code:%x.",
+ err_code);
+ ret = err_code;
+ goto out;
+ }
+
+ if (cmd->response_len == 0) {
+ cmd->result = entry->response.result.value;
+ } else if ((cmd->mbuf != NULL && cmd->response_data != cmd->data) ||
+ cmd->mbuf == NULL) {
+ /* cmd data may be as same as response data if mbuf is not null */
+ rte_memcpy(cmd->response_data, rte_pktmbuf_mtod(mbuf, void *),
+ cmd->response_len);
+ }
+out:
+ if (cmd->mbuf == NULL)
+ rte_pktmbuf_free(mbuf);
+ return ret;
+}
+
+int
+sssnic_ctrlq_cmd_exec(struct sssnic_hw *hw, struct sssnic_ctrlq_cmd *cmd,
+ uint32_t timeout_ms)
+{
+ int ret;
+ struct sssnic_ctrlq *ctrlq;
+
+ if (hw == NULL || hw->ctrlq == NULL || cmd == NULL ||
+ (cmd->response_len != 0 && cmd->response_data == NULL)) {
+ PMD_DRV_LOG(ERR, "Bad parameter to execute ctrlq command");
+ return -EINVAL;
+ }
+
+ SSSNIC_DEBUG("module=%u, cmd=%u, data=%p, data_len=%u, response_len=%u",
+ cmd->module, cmd->cmd, cmd->data, cmd->data_len,
+ cmd->response_len);
+
+ ctrlq = hw->ctrlq;
+ rte_spinlock_lock(&ctrlq->lock);
+ ret = sssnic_ctrlq_cmd_exec_internal(ctrlq, cmd, timeout_ms);
+ rte_spinlock_unlock(&ctrlq->lock);
+
+ return ret;
+}
+
+static int
+sssnic_ctrlq_depth_set(struct sssnic_hw *hw, uint32_t depth)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_root_ctx_cmd cmd;
+ uint32_t cmd_len;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.set_ctrlq_depth = 1;
+ cmd.ctrlq_depth = (uint8_t)rte_log2_u32(depth);
+ cmd_len = sizeof(cmd);
+
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_ROOT_CTX_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (!cmd_len || cmd.common.status) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to SET_ROOT_CTX_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int
+sssnic_ctrlq_ctx_setup(struct sssnic_ctrlq *ctrlq)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_set_ctrlq_ctx_cmd cmd;
+ uint32_t cmd_len;
+ struct sssnic_hw *hw = ctrlq->hw;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.qid = 0;
+ cmd.pfn = ctrlq->workq->buf_phyaddr / RTE_PGSIZE_4K;
+ cmd.wrapped = !!ctrlq->wrapped;
+ cmd.start_ci = 0;
+ cmd.block_pfn = cmd.pfn;
+
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,
+ SSSNIC_SET_CTRLQ_CTX_CMD, SSSNIC_MPU_FUNC_IDX,
+ SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send SSSNIC_SET_CTRLQ_CTX_CMD");
+ return ret;
+ }
+ return 0;
+}
+
+struct sssnic_ctrlq_cmd *
+sssnic_ctrlq_cmd_alloc(struct sssnic_hw *hw)
+{
+ struct sssnic_ctrlq_cmd *cmd;
+
+ cmd = rte_zmalloc(NULL, sizeof(struct sssnic_ctrlq_cmd), 0);
+ if (cmd == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to allocate sssnic_ctrlq_cmd");
+ return NULL;
+ }
+
+ cmd->mbuf = rte_pktmbuf_alloc(hw->ctrlq->mbuf_pool);
+ if (cmd->mbuf == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to allocate sssnic_ctrlq_cmd mbuf");
+ rte_free(cmd);
+ return NULL;
+ }
+
+ cmd->data = rte_pktmbuf_mtod(cmd->mbuf, void *);
+ cmd->response_data = cmd->data;
+
+ return cmd;
+}
+
+void
+sssnic_ctrlq_cmd_destroy(__rte_unused struct sssnic_hw *hw,
+ struct sssnic_ctrlq_cmd *cmd)
+{
+ if (cmd != NULL) {
+ if (cmd->mbuf != NULL)
+ rte_pktmbuf_free(cmd->mbuf);
+
+ rte_free(cmd);
+ }
+}
+
+int
+sssnic_ctrlq_init(struct sssnic_hw *hw)
+{
+ int ret;
+ struct sssnic_ctrlq *ctrlq;
+ char m_name[RTE_MEMPOOL_NAMESIZE];
+
+ PMD_INIT_FUNC_TRACE();
+
+ ctrlq = rte_zmalloc(NULL, sizeof(struct sssnic_ctrlq), 0);
+ if (ctrlq == NULL) {
+ PMD_DRV_LOG(ERR, "Could not alloc memory for ctrlq");
+ return -ENOMEM;
+ }
+
+ ctrlq->hw = hw;
+ rte_spinlock_init(&ctrlq->lock);
+ ctrlq->doorbell = hw->db_base_addr + SSSNIC_CTRLQ_DOORBELL_OFFSET;
+
+ snprintf(m_name, sizeof(m_name), "sssnic%u_ctrlq_wq",
+ SSSNIC_ETH_PORT_ID(hw));
+ ctrlq->workq = sssnic_workq_new(m_name, rte_socket_id(),
+ SSSNIC_CTRLQ_ENTRY_SIZE, SSSNIC_CTRLQ_DEPTH);
+ if (ctrlq->workq == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to alloc work queue for ctrlq");
+ ret = -ENOMEM;
+ goto new_workq_fail;
+ }
+ ctrlq->wrapped = 1;
+
+ snprintf(m_name, sizeof(m_name), "sssnic%u_ctrlq_mbuf",
+ SSSNIC_ETH_PORT_ID(hw));
+ ctrlq->mbuf_pool = rte_pktmbuf_pool_create(m_name, SSSNIC_CTRLQ_DEPTH,
+ 0, 0, SSSNIC_CTRLQ_MBUF_SIZE, rte_socket_id());
+ if (ctrlq->mbuf_pool == NULL) {
+ PMD_DRV_LOG(ERR, "Failed to alloc mbuf for %s", m_name);
+ ret = -ENOMEM;
+ goto alloc_mbuf_fail;
+ }
+
+ ret = sssnic_ctrlq_ctx_setup(ctrlq);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to setup control queue context");
+ goto setup_ctrlq_ctx_fail;
+ }
+
+ ret = sssnic_ctrlq_depth_set(hw, SSSNIC_CTRLQ_DEPTH);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to initialize control queue depth");
+ goto setup_ctrlq_ctx_fail;
+ }
+
+ hw->ctrlq = ctrlq;
+
+ return 0;
+
+setup_ctrlq_ctx_fail:
+ rte_mempool_free(ctrlq->mbuf_pool);
+alloc_mbuf_fail:
+ sssnic_workq_destroy(ctrlq->workq);
+new_workq_fail:
+ rte_free(ctrlq);
+ return ret;
+}
+
+void
+sssnic_ctrlq_shutdown(struct sssnic_hw *hw)
+{
+ struct sssnic_ctrlq *ctrlq;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (hw == NULL || hw->ctrlq == NULL)
+ return;
+ ctrlq = hw->ctrlq;
+ rte_mempool_free(ctrlq->mbuf_pool);
+ sssnic_workq_destroy(ctrlq->workq);
+ rte_free(ctrlq);
+}
diff --git a/drivers/net/sssnic/base/sssnic_ctrlq.h b/drivers/net/sssnic/base/sssnic_ctrlq.h
new file mode 100644
index 0000000000..61b182e9f4
--- /dev/null
+++ b/drivers/net/sssnic/base/sssnic_ctrlq.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2022 Shenzhen 3SNIC Information Technology Co., Ltd.
+ */
+
+#ifndef _SSSNIC_CTRLQ_H_
+#define _SSSNIC_CTRLQ_H_
+
+#include "sssnic_workq.h"
+
+#define SSSNIC_CTRLQ_MBUF_SIZE 2048
+#define SSSNIC_CTRLQ_MAX_CMD_DATA_LEN \
+ (SSSNIC_CTRLQ_MBUF_SIZE - RTE_PKTMBUF_HEADROOM)
+
+struct sssnic_ctrlq_cmd {
+ uint32_t module;
+ /* Command ID */
+ uint32_t cmd;
+ /* Command data */
+ void *data;
+ /* mbuf is just used for dynamic allocation of ctrlq cmd,
+ * cmd data will point to mbuf data to reduce data copying
+ * as well as response_data.
+ */
+ struct rte_mbuf *mbuf;
+ union {
+ /* response data buffer */
+ void *response_data;
+ /* result of command executing */
+ uint64_t result;
+ };
+ /* command data length */
+ uint32_t data_len;
+ /* length of response data buffer, return result of command
+ * if response_len=0, else return response_data
+ */
+ uint32_t response_len;
+};
+
+struct sssnic_ctrlq {
+ struct sssnic_hw *hw;
+ struct sssnic_workq *workq;
+ struct rte_mempool *mbuf_pool;
+ uint8_t *doorbell;
+ uint32_t wrapped;
+ uint32_t resvd0;
+ rte_spinlock_t lock;
+};
+
+struct sssnic_ctrlq_cmd *sssnic_ctrlq_cmd_alloc(struct sssnic_hw *hw);
+void sssnic_ctrlq_cmd_destroy(__rte_unused struct sssnic_hw *hw,
+ struct sssnic_ctrlq_cmd *cmd);
+
+int sssnic_ctrlq_cmd_exec(struct sssnic_hw *hw, struct sssnic_ctrlq_cmd *cmd,
+ uint32_t timeout_ms);
+int sssnic_ctrlq_init(struct sssnic_hw *hw);
+void sssnic_ctrlq_shutdown(struct sssnic_hw *hw);
+
+#endif /* _SSSNIC_CTRLQ_H_ */
diff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c
index ff527b2c7f..4ca75208af 100644
--- a/drivers/net/sssnic/base/sssnic_hw.c
+++ b/drivers/net/sssnic/base/sssnic_hw.c
@@ -9,9 +9,12 @@
#include "../sssnic_log.h"
#include "sssnic_hw.h"
#include "sssnic_reg.h"
+#include "sssnic_cmd.h"
+#include "sssnic_api.h"
#include "sssnic_eventq.h"
#include "sssnic_msg.h"
#include "sssnic_mbox.h"
+#include "sssnic_ctrlq.h"
static int
wait_for_sssnic_hw_ready(struct sssnic_hw *hw)
@@ -140,6 +143,116 @@ sssnic_pf_status_set(struct sssnic_hw *hw, enum sssnic_pf_status status)
sssnic_cfg_reg_write(hw, SSSNIC_ATTR6_REG, reg.u32);
}
+static int
+sssnic_dma_attr_init(struct sssnic_hw *hw)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_dma_attr_set_cmd cmd;
+ uint32_t cmd_len;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_SET_DMA_ATTR_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (cmd_len == 0 || cmd.common.status != 0) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to SET_DMA_ATTR_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+sssnic_func_reset(struct sssnic_hw *hw)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_func_reset_cmd cmd;
+ uint32_t cmd_len;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.res_mask = RTE_BIT64(0) | RTE_BIT64(1) | RTE_BIT64(2) |
+ RTE_BIT64(10) | RTE_BIT64(12) | RTE_BIT64(13);
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_RESET_FUNC_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (cmd_len == 0 || cmd.common.status != 0) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to RESET_FUNC_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+sssnic_pagesize_set(struct sssnic_hw *hw, uint32_t pagesize)
+{
+ int ret;
+ struct sssnic_msg msg;
+ struct sssnic_pagesize_cmd cmd;
+ uint32_t cmd_len;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.func_id = SSSNIC_FUNC_IDX(hw);
+ cmd.pagesz = (uint8_t)rte_log2_u32(pagesize >> 12);
+ cmd.opcode = SSSNIC_CMD_OPCODE_SET;
+ cmd_len = sizeof(cmd);
+ sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len, SSSNIC_PAGESIZE_CFG_CMD,
+ SSSNIC_MPU_FUNC_IDX, SSSNIC_COMM_MODULE, SSSNIC_MSG_TYPE_REQ);
+ ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+ return ret;
+ }
+ if (cmd_len == 0 || cmd.common.status != 0) {
+ PMD_DRV_LOG(ERR,
+ "Bad response to PAGESIZE_CFG_CMD, len=%u, status=%u",
+ cmd_len, cmd.common.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* Only initialize msix 0 attributes */
+static int
+sssnic_msix_attr_init(struct sssnic_hw *hw)
+{
+ int ret;
+ struct sssnic_msix_attr attr;
+
+ attr.lli_set = 0;
+ attr.coalescing_set = 1;
+ attr.pending_limit = 0;
+ attr.coalescing_timer = 0xff;
+ attr.resend_timer = 0x7;
+
+ ret = sssnic_msix_attr_set(hw, 0, &attr);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to set msix0 attributes.");
+ return ret;
+ }
+
+ return 0;
+}
+
static int
sssnic_base_init(struct sssnic_hw *hw)
{
@@ -217,8 +330,42 @@ sssnic_hw_init(struct sssnic_hw *hw)
goto mbox_init_fail;
}
+ ret = sssnic_func_reset(hw);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to reset function resources");
+ goto mbox_init_fail;
+ }
+
+ ret = sssnic_dma_attr_init(hw);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to initialize DMA attributes");
+ goto mbox_init_fail;
+ }
+
+ ret = sssnic_msix_attr_init(hw);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to initialize msix attributes");
+ goto mbox_init_fail;
+ }
+
+ ret = sssnic_pagesize_set(hw, 0x100000);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to set page size to 0x100000");
+ goto mbox_init_fail;
+ }
+
+ ret = sssnic_ctrlq_init(hw);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to initialize control queue");
+ goto ctrlq_init_fail;
+ }
+
+ sssnic_pf_status_set(hw, SSSNIC_PF_STATUS_ACTIVE);
+
return -EINVAL;
+ctrlq_init_fail:
+ sssnic_mbox_shutdown(hw);
mbox_init_fail:
sssnic_eventq_all_shutdown(hw);
eventq_init_fail:
@@ -231,6 +378,8 @@ sssnic_hw_shutdown(struct sssnic_hw *hw)
{
PMD_INIT_FUNC_TRACE();
+ sssnic_pf_status_set(hw, SSSNIC_PF_STATUS_INIT);
+ sssnic_ctrlq_shutdown(hw);
sssnic_mbox_shutdown(hw);
sssnic_eventq_all_shutdown(hw);
sssnic_msg_inbox_shutdown(hw);
diff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h
index 41e65f5880..c1b9539015 100644
--- a/drivers/net/sssnic/base/sssnic_hw.h
+++ b/drivers/net/sssnic/base/sssnic_hw.h
@@ -54,6 +54,7 @@ struct sssnic_hw {
struct sssnic_eventq *eventqs;
struct sssnic_msg_inbox *msg_inbox;
struct sssnic_mbox *mbox;
+ struct sssnic_ctrlq *ctrlq;
uint8_t num_eventqs;
uint16_t eth_port_id;
};
@@ -64,6 +65,13 @@ struct sssnic_hw {
#define SSSNIC_FUNC_TYPE(hw) ((hw)->attr.func_type)
#define SSSNIC_AF_FUNC_IDX(hw) ((hw)->attr.af_idx)
+enum sssnic_module {
+ SSSNIC_COMM_MODULE = 0,
+ SSSNIC_LAN_MODULE = 1,
+ SSSNIC_CFG_MODULE = 7,
+ SSSNIC_NETIF_MODULE = 14,
+};
+
int sssnic_hw_init(struct sssnic_hw *hw);
void sssnic_hw_shutdown(struct sssnic_hw *hw);
void sssnic_msix_state_set(struct sssnic_hw *hw, uint16_t msix_id, int state);
--
2.27.0
next prev parent reply other threads:[~2023-09-04 4:58 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-04 4:56 [PATCH v5 00/32] Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters wanry
2023-09-04 4:56 ` [PATCH v5 01/32] net/sssnic: add build and doc infrastructure wanry
2023-09-26 13:06 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 02/32] net/sssnic: add log type and log macros wanry
2023-09-04 4:56 ` [PATCH v5 03/32] net/sssnic: support probe and remove wanry
2023-09-18 16:08 ` Stephen Hemminger
2023-09-19 2:00 ` Renyong Wan
2023-09-04 4:56 ` [PATCH v5 04/32] net/sssnic: initialize hardware base wanry
2023-09-18 2:28 ` Stephen Hemminger
2023-09-18 4:47 ` Renyong Wan
2023-09-04 4:56 ` [PATCH v5 05/32] net/sssnic: add event queue wanry
2023-09-04 4:56 ` [PATCH v5 06/32] net/sssnic/base: add message definition and utility wanry
2023-09-18 2:31 ` Stephen Hemminger
2023-09-18 5:08 ` Renyong Wan
2023-09-04 4:56 ` [PATCH v5 07/32] net/sssnic/base: add mailbox support wanry
2023-09-18 2:32 ` Stephen Hemminger
2023-09-18 5:10 ` Renyong Wan
2023-09-26 13:13 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 08/32] net/sssnic/base: add work queue wanry
2023-09-18 2:33 ` Stephen Hemminger
2023-09-18 5:11 ` Renyong Wan
2023-09-04 4:56 ` wanry [this message]
2023-09-18 2:36 ` [PATCH v5 09/32] net/sssnic/base: add control queue Stephen Hemminger
2023-09-18 5:22 ` Renyong Wan
2023-09-04 4:56 ` [PATCH v5 10/32] net/sssnic: add dev configure and infos get wanry
2023-09-04 4:56 ` [PATCH v5 11/32] net/sssnic: add dev MAC ops wanry
2023-09-26 13:07 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 12/32] net/sssnic: support dev link status wanry
2023-09-04 4:56 ` [PATCH v5 13/32] net/sssnic: support link status event wanry
2023-09-26 13:08 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 14/32] net/sssnic: support Rx queue setup and release wanry
2023-09-04 4:56 ` [PATCH v5 15/32] net/sssnic: support Tx " wanry
2023-09-04 4:56 ` [PATCH v5 16/32] net/sssnic: support Rx queue start and stop wanry
2023-09-04 4:56 ` [PATCH v5 17/32] net/sssnic: support Tx " wanry
2023-09-04 4:56 ` [PATCH v5 18/32] net/sssnic: add Rx interrupt support wanry
2023-09-04 4:56 ` [PATCH v5 19/32] net/sssnic: support dev start and stop wanry
2023-09-26 13:09 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 20/32] net/sssnic: support dev close and reset wanry
2023-09-26 13:09 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 21/32] net/sssnic: add allmulticast and promiscuous ops wanry
2023-09-04 4:56 ` [PATCH v5 22/32] net/sssnic: add basic and extended stats ops wanry
2023-09-04 4:56 ` [PATCH v5 23/32] net/sssnic: support Rx packet burst wanry
2023-09-04 4:56 ` [PATCH v5 24/32] net/sssnic: support Tx " wanry
2023-09-26 13:10 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 25/32] net/sssnic: add RSS support wanry
2023-09-04 4:56 ` [PATCH v5 26/32] net/sssnic: support dev MTU set wanry
2023-09-04 4:56 ` [PATCH v5 27/32] net/sssnic: support dev queue info get wanry
2023-09-04 4:56 ` [PATCH v5 28/32] net/sssnic: support dev firmware version get wanry
2023-09-04 4:56 ` [PATCH v5 29/32] net/sssnic: add dev flow control ops wanry
2023-09-26 13:12 ` Ferruh Yigit
2023-09-04 4:56 ` [PATCH v5 30/32] net/sssnic: support VLAN offload and filter wanry
2023-09-04 4:56 ` [PATCH v5 31/32] net/sssnic: add generic flow ops wanry
2023-09-04 4:56 ` [PATCH v5 32/32] net/sssnic: add VF dev support wanry
2023-09-26 13:11 ` Ferruh Yigit
2023-09-18 2:37 ` [PATCH v5 00/32] Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters Stephen Hemminger
2023-09-18 3:23 ` Renyong Wan
2023-09-19 3:19 ` Stephen Hemminger
2023-09-19 5:18 ` Renyong Wan
2023-09-19 3:21 ` Stephen Hemminger
2023-09-19 5:18 ` Renyong Wan
2023-09-19 3:23 ` Stephen Hemminger
2023-09-19 5:19 ` Renyong Wan
2023-09-19 15:24 ` Stephen Hemminger
2023-09-26 13:13 ` Ferruh Yigit
2024-03-29 11:32 ` Ferruh Yigit
2024-07-31 17:32 ` Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230904045658.238185-10-wanry@3snic.com \
--to=wanry@3snic.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=steven.song@3snic.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).