[PATCH net-next v5 07/15] bnxt_en: Allocate crypto structure and backing store
From: Michael Chan <michael.chan@broadcom.com>
Date: 2026-07-10 04:24:58
Subsystem:
broadcom bnxt_en 50 gigabit ethernet driver, networking drivers, the rest · Maintainers:
Michael Chan, Pavan Chebbi, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
If the chip and firmware support crypto (TLS) offload, allocate a bp->crypto_info software structure and backing store to support the RX and TX contexts. Each offloaded TLS connection requires a backing store context for each direction. bp->crypto_info will stay persistent even if kTLS is no longer supported after a FW reset. This makes it easier to avoid NULL dereference of bp->crypto_info during FW reset and kTLS offload race conditions. Reviewed-by: Andy Gospodarek <redacted> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> --- v4: Clear BNXT_FW_CAP_KTLS in bnxt_free_cryto_info() v3: https://lore.kernel.org/netdev/20260614072407.2761092-8-michael.chan@broadcom.com/ (local) bp->crypto_info and bp->ktls_info now stay persistent for the driver's lifetime. max keys are refreshed after re-init. v2: https://lore.kernel.org/netdev/20260512212105.3488258-8-michael.chan@broadcom. --- drivers/net/ethernet/broadcom/bnxt/Makefile | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 21 +++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 + .../net/ethernet/broadcom/bnxt/bnxt_crypto.c | 83 +++++++++++++++++++ .../net/ethernet/broadcom/bnxt/bnxt_crypto.h | 47 +++++++++++ include/linux/bnxt/hsi.h | 37 +++++++++ 6 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.c create mode 100644 drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.h
diff --git a/drivers/net/ethernet/broadcom/bnxt/Makefile b/drivers/net/ethernet/broadcom/bnxt/Makefile
index 0506574c007a..3acdb81fa958 100644
--- a/drivers/net/ethernet/broadcom/bnxt/Makefile
+++ b/drivers/net/ethernet/broadcom/bnxt/Makefile@@ -5,4 +5,4 @@ bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp. bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o bnxt_en-$(CONFIG_BNXT_HWMON) += bnxt_hwmon.o -bnxt_en-$(CONFIG_BNXT_TLS) += bnxt_mpc.o +bnxt_en-$(CONFIG_BNXT_TLS) += bnxt_mpc.o bnxt_crypto.o
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index e68b970bf21b..b663824cb559 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c@@ -77,6 +77,7 @@ #include "bnxt_gso.h" #include <net/tso.h> #include "bnxt_mpc.h" +#include "bnxt_crypto.h" #define BNXT_TX_TIMEOUT (5 * HZ) #define BNXT_DEF_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_HW | \
@@ -9376,6 +9377,7 @@ static int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt *bp, static int bnxt_backing_store_cfg_v2(struct bnxt *bp) { + struct bnxt_crypto_info *crypto = bp->crypto_info; struct bnxt_mpc_info *mpc = bp->mpc_info; struct bnxt_ctx_mem_info *ctx = bp->ctx; struct bnxt_ctx_mem_type *ctxm;
@@ -9383,6 +9385,19 @@ static int bnxt_backing_store_cfg_v2(struct bnxt *bp) int rc = 0; u16 type; + if (BNXT_SUPPORTS_KTLS(bp)) { + ctxm = &ctx->ctx_arr[BNXT_CTX_TCK]; + rc = bnxt_setup_ctxm_pg_tbls(bp, ctxm, + BNXT_TCK(crypto).max_ctx, 1); + if (rc) + return rc; + ctxm = &ctx->ctx_arr[BNXT_CTX_RCK]; + rc = bnxt_setup_ctxm_pg_tbls(bp, ctxm, + BNXT_RCK(crypto).max_ctx, 1); + if (rc) + return rc; + last_type = BNXT_CTX_RCK; + } if (mpc && mpc->mpc_chnls_cap) { ctxm = &ctx->ctx_arr[BNXT_CTX_MTQM]; rc = bnxt_setup_ctxm_pg_tbls(bp, ctxm, ctxm->max_entries, 1);
@@ -9925,6 +9940,10 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->fw_cap |= BNXT_FW_CAP_BACKING_STORE_V2; if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_TX_COAL_CMPL_CAP) bp->flags |= BNXT_FLAG_TX_COAL_CMPL; + if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_KTLS_SUPPORTED) + bnxt_alloc_crypto_info(bp, resp); + else + bp->fw_cap &= ~BNXT_FW_CAP_KTLS; flags_ext2 = le32_to_cpu(resp->flags_ext2); if (flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_RX_ALL_PKTS_TIMESTAMPS_SUPPORTED)
@@ -16613,6 +16632,7 @@ static void bnxt_remove_one(struct pci_dev *pdev) bp->ptp_cfg = NULL; kfree(bp->fw_health); bp->fw_health = NULL; + bnxt_free_crypto_info(bp); bnxt_free_mpc_info(bp); bnxt_cleanup_pci(bp); bnxt_free_ctx_mem(bp, true);
@@ -17296,6 +17316,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) bnxt_ethtool_free(bp); kfree(bp->fw_health); bp->fw_health = NULL; + bnxt_free_crypto_info(bp); bnxt_free_mpc_info(bp); bnxt_cleanup_pci(bp); bnxt_free_ctx_mem(bp, true);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 416ae86111fa..621f275b49fd 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h@@ -2461,6 +2461,7 @@ struct bnxt { u8 tph_mode; struct bnxt_mpc_info *mpc_info; + struct bnxt_crypto_info *crypto_info; unsigned int current_interval; #define BNXT_TIMER_INTERVAL HZ
@@ -2548,6 +2549,7 @@ struct bnxt { #define BNXT_FW_CAP_NPAR_1_2 BIT_ULL(42) #define BNXT_FW_CAP_MIRROR_ON_ROCE BIT_ULL(43) #define BNXT_FW_CAP_PTP_PTM BIT_ULL(44) + #define BNXT_FW_CAP_KTLS BIT_ULL(45) u32 fw_dbg_cap;
@@ -2573,6 +2575,8 @@ struct bnxt { ((bp)->fw_cap & BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS) #define BNXT_MIRROR_ON_ROCE_CAP(bp) \ ((bp)->fw_cap & BNXT_FW_CAP_MIRROR_ON_ROCE) +#define BNXT_SUPPORTS_KTLS(bp) \ + ((bp)->fw_cap & BNXT_FW_CAP_KTLS) u32 hwrm_spec_code; u16 hwrm_cmd_seq;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.c
new file mode 100644
index 000000000000..5bc31ee8d7fd
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.c@@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2026 Broadcom Inc. */ + +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/bnxt/hsi.h> + +#include "bnxt.h" +#include "bnxt_crypto.h" + +static u32 bnxt_get_max_crypto_key_ctx(struct bnxt *bp, int key_type) +{ + u32 fw_maj = BNXT_FW_MAJ(bp); + + if (key_type == BNXT_TX_CRYPTO_KEY_TYPE) + return (fw_maj < 233) ? BNXT_MAX_TX_CRYPTO_KEYS_PRE_233FW : + BNXT_MAX_TX_CRYPTO_KEYS; + + return (fw_maj < 233) ? BNXT_MAX_RX_CRYPTO_KEYS_PRE_233FW : + BNXT_MAX_RX_CRYPTO_KEYS; +} + +/** + * bnxt_alloc_crypto_info - Allocate and initialize crypto offload context + * @bp: pointer to bnxt device + * @resp: pointer to firmware capability response + * + * Allocates the main crypto info structure + * + * This function is called during device initialization when firmware + * reports crypto offload capability. If allocation fails, crypto offload + * will not be available but the device will still function. + * + * Context: Process context + */ +void bnxt_alloc_crypto_info(struct bnxt *bp, + struct hwrm_func_qcaps_output *resp) +{ + u16 max_keys = le16_to_cpu(resp->max_key_ctxs_alloc); + struct bnxt_crypto_info *crypto = bp->crypto_info; + struct bnxt_kctx *kctx; + int i; + + if (BNXT_VF(bp)) + return; + if (!crypto) { + crypto = kzalloc_obj(*crypto); + if (!crypto) { + netdev_warn(bp->dev, + "Unable to allocate crypto info\n"); + return; + } + for (i = 0; i < BNXT_MAX_CRYPTO_KEY_TYPE; i++) { + kctx = &crypto->kctx[i]; + kctx->type = i; + } + bp->crypto_info = crypto; + } + for (i = 0; i < BNXT_MAX_CRYPTO_KEY_TYPE; i++) { + kctx = &crypto->kctx[i]; + kctx->max_ctx = bnxt_get_max_crypto_key_ctx(bp, i); + } + crypto->max_key_ctxs_alloc = max_keys; + bp->fw_cap |= BNXT_FW_CAP_KTLS; +} + +/** + * bnxt_free_crypto_info - Free crypto offload resources + * @bp: pointer to bnxt device + * + * Frees all resources associated with crypto offload. Call this function + * only when it is idle with nothing in-flight. + * + * Context: Process context during device shutdown/removal + */ +void bnxt_free_crypto_info(struct bnxt *bp) +{ + kfree(bp->crypto_info); + bp->crypto_info = NULL; + bp->fw_cap &= ~BNXT_FW_CAP_KTLS; +}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.h
new file mode 100644
index 000000000000..629388fe1e6d
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_crypto.h@@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2026 Broadcom Inc. */ + +#ifndef BNXT_CRYPTO_H +#define BNXT_CRYPTO_H + +#define BNXT_MAX_TX_CRYPTO_KEYS 204800 +#define BNXT_MAX_RX_CRYPTO_KEYS 204800 + +#define BNXT_MAX_TX_CRYPTO_KEYS_PRE_233FW 65535 +#define BNXT_MAX_RX_CRYPTO_KEYS_PRE_233FW 65535 + +enum bnxt_crypto_type { + BNXT_TX_CRYPTO_KEY_TYPE = FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_TX, + BNXT_RX_CRYPTO_KEY_TYPE = FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_RX, + BNXT_MAX_CRYPTO_KEY_TYPE, +}; + +struct bnxt_kctx { + u8 type; + u32 max_ctx; +}; + +struct bnxt_crypto_info { + u16 max_key_ctxs_alloc; + + struct bnxt_kctx kctx[BNXT_MAX_CRYPTO_KEY_TYPE]; +}; + +#define BNXT_TCK(crypto) ((crypto)->kctx[BNXT_TX_CRYPTO_KEY_TYPE]) +#define BNXT_RCK(crypto) ((crypto)->kctx[BNXT_RX_CRYPTO_KEY_TYPE]) + +#ifdef CONFIG_BNXT_TLS +void bnxt_alloc_crypto_info(struct bnxt *bp, + struct hwrm_func_qcaps_output *resp); +void bnxt_free_crypto_info(struct bnxt *bp); +#else +static inline void bnxt_alloc_crypto_info(struct bnxt *bp, + struct hwrm_func_qcaps_output *resp) +{ +} + +static inline void bnxt_free_crypto_info(struct bnxt *bp) +{ +} +#endif /* CONFIG_BNXT_TLS */ +#endif /* BNXT_CRYPTO_H */
diff --git a/include/linux/bnxt/hsi.h b/include/linux/bnxt/hsi.h
index 74a6bf278d88..03444b81beb0 100644
--- a/include/linux/bnxt/hsi.h
+++ b/include/linux/bnxt/hsi.h@@ -3837,6 +3837,43 @@ struct hwrm_func_ptp_ext_qcfg_output { u8 valid; }; +/* hwrm_func_key_ctx_alloc_input (size:384b/48B) */ +struct hwrm_func_key_ctx_alloc_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 fid; + __le16 num_key_ctxs; + __le32 dma_bufr_size_bytes; + u8 key_ctx_type; + #define FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_TX 0x0UL + #define FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_RX 0x1UL + #define FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_QUIC_TX 0x2UL + #define FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_QUIC_RX 0x3UL + #define FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_LAST FUNC_KEY_CTX_ALLOC_REQ_KEY_CTX_TYPE_QUIC_RX + u8 unused_0[7]; + __le64 host_dma_addr; + __le32 partition_start_xid; + u8 unused_1[4]; +}; + +/* hwrm_func_key_ctx_alloc_output (size:192b/24B) */ +struct hwrm_func_key_ctx_alloc_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 num_key_ctxs_allocated; + u8 flags; + #define FUNC_KEY_CTX_ALLOC_RESP_FLAGS_KEY_CTXS_CONTIGUOUS 0x1UL + u8 unused_0; + __le32 partition_start_xid; + u8 unused_1[7]; + u8 valid; +}; + /* hwrm_func_backing_store_cfg_v2_input (size:512b/64B) */ struct hwrm_func_backing_store_cfg_v2_input { __le16 req_type;
--
2.51.0