From: Michael Chan <michael.chan@broadcom.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, andrew+netdev@lunn.ch,
pavan.chebbi@broadcom.com, andrew.gospodarek@broadcom.com
Subject: [PATCH net-next v2 10/15] bnxt_en: Add MPC transmit and completion functions
Date: Tue, 12 May 2026 14:21:00 -0700 [thread overview]
Message-ID: <20260512212105.3488258-11-michael.chan@broadcom.com> (raw)
In-Reply-To: <20260512212105.3488258-1-michael.chan@broadcom.com>
Add transmit, ring selection, and completion functions for midpath rings.
These will be used to send control data to the crypto engines.
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
v2:
Fix unused variable warnings
v1:
https://lore.kernel.org/netdev/20260504235836.3019499-11-michael.chan@broadcom.com/
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +
drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.c | 138 ++++++++++++++++++
drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.h | 65 +++++++++
4 files changed, 208 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 4f5de41d4e86..a772b86842c1 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -3109,6 +3109,9 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
rx_pkts++;
else if (rc == -EBUSY) /* partial completion */
break;
+ } else if (cmp_type == CMP_TYPE_MPC_CMP) {
+ if (bnxt_mpc_cmp(bp, cpr, &raw_cons))
+ break;
} else if (unlikely(cmp_type == CMPL_BASE_TYPE_HWRM_DONE ||
cmp_type == CMPL_BASE_TYPE_HWRM_FWD_REQ ||
cmp_type == CMPL_BASE_TYPE_HWRM_ASYNC_EVENT)) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index b832780b783d..f30e7c90471b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -47,6 +47,7 @@ struct tx_bd {
__le32 tx_bd_len_flags_type;
#define TX_BD_TYPE (0x3f << 0)
#define TX_BD_TYPE_SHORT_TX_BD (0x00 << 0)
+ #define TX_BD_TYPE_MPC_TX_BD (0x08 << 0)
#define TX_BD_TYPE_LONG_TX_BD (0x10 << 0)
#define TX_BD_FLAGS_PACKET_END (1 << 6)
#define TX_BD_FLAGS_NO_CMPL (1 << 7)
@@ -160,6 +161,7 @@ struct tx_cmp {
#define CMP_TYPE_RX_TPA_AGG_CMP 22
#define CMP_TYPE_RX_L2_V3_CMP 23
#define CMP_TYPE_RX_L2_TPA_START_V3_CMP 25
+ #define CMP_TYPE_MPC_CMP 30
#define CMP_TYPE_STATUS_CMP 32
#define CMP_TYPE_REMOTE_DRIVER_REQ 34
#define CMP_TYPE_REMOTE_DRIVER_RESP 36
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.c
index a121bdcf9686..67ba43b7f168 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.c
@@ -404,3 +404,141 @@ void bnxt_hwrm_mpc_ring_free(struct bnxt *bp, bool close_path)
}
}
}
+
+struct bnxt_tx_ring_info *bnxt_select_mpc_ring(struct bnxt *bp, int ring_type)
+{
+ struct bnxt_mpc_info *mpc = bp->mpc_info;
+ int n;
+
+ if (!mpc || ring_type >= BNXT_MPC_TYPE_MAX ||
+ !mpc->mpc_ring_count[ring_type])
+ return NULL;
+
+ n = smp_processor_id() % mpc->mpc_ring_count[ring_type];
+ return &mpc->mpc_rings[ring_type][n];
+}
+
+int bnxt_start_xmit_mpc(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ void *data, unsigned int len, unsigned long handle)
+{
+ u32 bds, total_bds, bd_space, free_size;
+ struct bnxt_sw_mpc_tx_bd *tx_buf;
+ struct tx_bd *txbd;
+ u16 prod;
+
+ if (READ_ONCE(txr->dev_state) == BNXT_DEV_STATE_CLOSING)
+ return -ENODEV;
+
+ bds = DIV_ROUND_UP(len, sizeof(*txbd));
+ total_bds = bds + 1;
+ free_size = bnxt_tx_avail(bp, txr);
+ if (free_size < total_bds)
+ return -EBUSY;
+
+ prod = txr->tx_prod;
+ txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
+ tx_buf = &txr->tx_mpc_buf_ring[RING_TX(bp, prod)];
+ tx_buf->handle = handle;
+ tx_buf->inline_bds = total_bds;
+
+ txbd->tx_bd_len_flags_type =
+ cpu_to_le32((len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_MPC_TX_BD |
+ TX_BD_CNT(total_bds));
+ txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, total_bds);
+
+ prod = NEXT_TX(prod);
+ txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
+ bd_space = TX_DESC_CNT - TX_IDX(prod);
+ if (bd_space < bds) {
+ unsigned int len0 = bd_space * sizeof(*txbd);
+
+ memcpy(txbd, data, len0);
+ prod += bd_space;
+ txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
+ bds -= bd_space;
+ len -= len0;
+ data += len0;
+ }
+ memcpy(txbd, data, len);
+ prod += bds;
+ txr->tx_prod = prod;
+
+ /* Sync BD data before updating doorbell */
+ wmb();
+ bnxt_db_write(bp, &txr->tx_db, prod);
+
+ return 0;
+}
+
+static bool bnxt_mpc_unsolicit(struct mpc_cmp *mpcmp)
+{
+ u32 client = MPC_CMP_CLIENT_TYPE(mpcmp);
+
+ if (client != MPC_CMP_CLIENT_TCE && client != MPC_CMP_CLIENT_RCE)
+ return false;
+ return MPC_CMP_UNSOLICIT_SUBTYPE(mpcmp);
+}
+
+int bnxt_mpc_cmp(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, u32 *raw_cons)
+{
+ struct bnxt_cmpl_entry cmpl_entry_arr[2];
+ struct bnxt_napi *bnapi = cpr->bnapi;
+ u16 cons = RING_CMP(*raw_cons);
+ struct mpc_cmp *mpcmp, *mpcmp1;
+ u32 tmp_raw_cons = *raw_cons;
+ u32 client, cmpl_num;
+ u8 type;
+
+ mpcmp = (struct mpc_cmp *)
+ &cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)];
+ type = MPC_CMP_CMP_TYPE(mpcmp);
+ cmpl_entry_arr[0].cmpl = mpcmp;
+ cmpl_entry_arr[0].len = sizeof(*mpcmp);
+ cmpl_num = 1;
+ if (type == MPC_CMP_TYPE_MID_PATH_LONG) {
+ tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+ cons = RING_CMP(tmp_raw_cons);
+ mpcmp1 = (struct mpc_cmp *)
+ &cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)];
+
+ if (!MPC_CMP_VALID(bp, mpcmp1, tmp_raw_cons))
+ return -EBUSY;
+ /* The valid test of the entry must be done first before
+ * reading any further.
+ */
+ dma_rmb();
+ if (mpcmp1 == mpcmp + 1) {
+ cmpl_entry_arr[cmpl_num - 1].len += sizeof(*mpcmp1);
+ } else {
+ cmpl_entry_arr[cmpl_num].cmpl = mpcmp1;
+ cmpl_entry_arr[cmpl_num].len = sizeof(*mpcmp1);
+ cmpl_num++;
+ }
+ }
+ client = MPC_CMP_CLIENT_TYPE(mpcmp) >> MPC_CMP_CLIENT_SFT;
+ if (client >= BNXT_MPC_TYPE_MAX)
+ goto cmp_done;
+
+ if (!bnxt_mpc_unsolicit(mpcmp)) {
+ struct bnxt_sw_mpc_tx_bd *mpc_buf;
+ struct bnxt_tx_ring_info *txr;
+ u16 tx_cons;
+ u32 opaque;
+
+ opaque = mpcmp->mpc_cmp_opaque;
+ txr = bnapi->tx_mpc_ring[client];
+ tx_cons = txr->tx_cons;
+ if (TX_OPAQUE_RING(opaque) != txr->tx_napi_idx)
+ netdev_warn(bp->dev, "Wrong opaque %x, expected ring %x, idx %x\n",
+ opaque, txr->tx_napi_idx, txr->tx_cons);
+ mpc_buf = &txr->tx_mpc_buf_ring[RING_TX(bp, tx_cons)];
+ mpc_buf->handle = 0;
+ tx_cons += mpc_buf->inline_bds;
+ txr->tx_cons = tx_cons;
+ txr->tx_hw_cons = RING_TX(bp, tx_cons);
+ }
+
+cmp_done:
+ *raw_cons = tmp_raw_cons;
+ return 0;
+}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.h
index cdc03a074963..9958d1749ffb 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_mpc.h
@@ -30,11 +30,53 @@ struct bnxt_mpc_info {
};
struct bnxt_sw_mpc_tx_bd {
+ u8 inline_bds;
unsigned long handle;
};
#define SW_MPC_TXBD_RING_SIZE (sizeof(struct bnxt_sw_mpc_tx_bd) * TX_DESC_CNT)
+struct bnxt_cmpl_entry {
+ void *cmpl;
+ u32 len;
+};
+
+struct mpc_cmp {
+ __le32 mpc_cmp_client_subtype_type;
+ #define MPC_CMP_TYPE (0x3f << 0)
+ #define MPC_CMP_TYPE_MID_PATH_SHORT 0x1e
+ #define MPC_CMP_TYPE_MID_PATH_LONG 0x1f
+ #define MPC_CMP_SUBTYPE 0xf00
+ #define MPC_CMP_SUBTYPE_SFT 8
+ #define MPC_CMP_SUBTYPE_SOLICITED (0x0 << 8)
+ #define MPC_CMP_SUBTYPE_ERR (0x1 << 8)
+ #define MPC_CMP_SUBTYPE_RESYNC (0x2 << 8)
+ #define MPC_CMP_CLIENT (0xf << 12)
+ #define MPC_CMP_CLIENT_SFT 12
+ #define MPC_CMP_CLIENT_TCE (0x0 << 12)
+ #define MPC_CMP_CLIENT_RCE (0x1 << 12)
+ #define MPC_CMP_CLIENT_TE_CFA (0x2 << 12)
+ #define MPC_CMP_CLIENT_RE_CFA (0x3 << 12)
+ u32 mpc_cmp_opaque;
+ __le32 mpc_cmp_v;
+ #define MPC_CMP_V (1 << 0)
+ __le32 mpc_cmp_filler;
+};
+
+#define MPC_CMP_CMP_TYPE(mpcmp) \
+ (le32_to_cpu((mpcmp)->mpc_cmp_client_subtype_type) & MPC_CMP_TYPE)
+
+#define MPC_CMP_CLIENT_TYPE(mpcmp) \
+ (le32_to_cpu((mpcmp)->mpc_cmp_client_subtype_type) & MPC_CMP_CLIENT)
+
+#define MPC_CMP_UNSOLICIT_SUBTYPE(mpcmp) \
+ ((le32_to_cpu((mpcmp)->mpc_cmp_client_subtype_type) & \
+ MPC_CMP_SUBTYPE) == MPC_CMP_SUBTYPE_ERR)
+
+#define MPC_CMP_VALID(bp, mpcmp, raw_cons) \
+ (!!((mpcmp)->mpc_cmp_v & cpu_to_le32(MPC_CMP_V)) == \
+ !((raw_cons) & (bp)->cp_bit))
+
#define BNXT_MPC_CRYPTO_CAP \
(FUNC_QCAPS_RESP_MPC_CHNLS_CAP_TCE | FUNC_QCAPS_RESP_MPC_CHNLS_CAP_RCE)
@@ -61,6 +103,10 @@ void bnxt_free_mpc_rings(struct bnxt *bp);
void bnxt_init_mpc_rings(struct bnxt *bp);
int bnxt_hwrm_mpc_ring_alloc(struct bnxt *bp);
void bnxt_hwrm_mpc_ring_free(struct bnxt *bp, bool close_path);
+struct bnxt_tx_ring_info *bnxt_select_mpc_ring(struct bnxt *bp, int ring_type);
+int bnxt_start_xmit_mpc(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ void *data, unsigned int len, unsigned long handle);
+int bnxt_mpc_cmp(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, u32 *raw_cons);
#else
static inline void bnxt_alloc_mpc_info(struct bnxt *bp, u8 mpc_chnls_cap)
{
@@ -132,5 +178,24 @@ static inline int bnxt_hwrm_mpc_ring_alloc(struct bnxt *bp)
static inline void bnxt_hwrm_mpc_ring_free(struct bnxt *bp, bool close_path)
{
}
+
+static inline struct bnxt_tx_ring_info *bnxt_select_mpc_ring(struct bnxt *bp,
+ int ring_type)
+{
+ return NULL;
+}
+
+static inline int bnxt_start_xmit_mpc(struct bnxt *bp,
+ struct bnxt_tx_ring_info *txr, void *data,
+ unsigned int len, unsigned long handle)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int bnxt_mpc_cmp(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ u32 *raw_cons)
+{
+ return 0;
+}
#endif /* CONFIG_BNXT_TLS */
#endif /* BNXT_MPC_H */
--
2.51.0
next prev parent reply other threads:[~2026-05-12 21:21 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 21:20 [PATCH net-next v2 00/15] bnxt_en: Add kTLS TX offload support Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 01/15] bnxt_en: Add Midpath channel information Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 02/15] bnxt_en: Account for the MPC TX and CP rings Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 03/15] bnxt_en: Set default MPC ring count Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:20 ` [PATCH net-next v2 04/15] bnxt_en: Rename xdp_tx_lock to tx_lock Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 05/15] bnxt_en: Allocate and free MPC software structures Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 06/15] bnxt_en: Allocate and free MPC channels from firmware Michael Chan
2026-05-12 21:20 ` [PATCH net-next v2 07/15] bnxt_en: Allocate crypto structure and backing store Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:20 ` [PATCH net-next v2 08/15] bnxt_en: Reserve crypto RX and TX key contexts on a PF Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:20 ` [PATCH net-next v2 09/15] bnxt_en: Add infrastructure for crypto key context IDs Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:21 ` Michael Chan [this message]
2026-05-16 1:10 ` [PATCH net-next v2 10/15] bnxt_en: Add MPC transmit and completion functions Jakub Kicinski
2026-05-12 21:21 ` [PATCH net-next v2 11/15] bnxt_en: Add crypto MPC transmit/completion infrastructure Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:21 ` [PATCH net-next v2 12/15] bnxt_en: Support kTLS TX offload by implementing .tls_dev_add/del() Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:21 ` [PATCH net-next v2 13/15] bnxt_en: Implement kTLS TX normal path Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
2026-05-12 21:21 ` [PATCH net-next v2 14/15] bnxt_en: Add support for inline transmit BDs Michael Chan
2026-05-12 21:21 ` [PATCH net-next v2 15/15] bnxt_en: Add kTLS retransmission support Michael Chan
2026-05-16 1:10 ` Jakub Kicinski
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=20260512212105.3488258-11-michael.chan@broadcom.com \
--to=michael.chan@broadcom.com \
--cc=andrew+netdev@lunn.ch \
--cc=andrew.gospodarek@broadcom.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pavan.chebbi@broadcom.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.