RDMA/irdma: Provide scratch buffers to firmware for internal use

For GEN3 and higher, FW requires scratch buffers for bookkeeping
during cleanup, specifically during QP and MR destroy ops.

Signed-off-by: Jay Bhat <jay.bhat@intel.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
Jay Bhat 2026-03-16 13:39:48 -05:00 committed by Leon Romanovsky
parent 5aeb6e0399
commit 9d6ba4ced7
5 changed files with 61 additions and 3 deletions

View File

@ -3570,6 +3570,41 @@ static int irdma_sc_parse_fpm_query_buf(struct irdma_sc_dev *dev, __le64 *buf,
hmc_fpm_misc->loc_mem_pages = (u32)FIELD_GET(IRDMA_QUERY_FPM_LOC_MEM_PAGES, temp);
if (!hmc_fpm_misc->loc_mem_pages)
return -EINVAL;
get_64bit_val(buf, 184, &temp);
if (temp) {
hmc_fpm_misc->fw_scratch_buf0.size = temp;
hmc_fpm_misc->fw_scratch_buf0.va =
dma_alloc_coherent(dev->hw->device,
hmc_fpm_misc->fw_scratch_buf0.size,
&hmc_fpm_misc->fw_scratch_buf0.pa,
GFP_KERNEL);
if (!hmc_fpm_misc->fw_scratch_buf0.va) {
hmc_fpm_misc->fw_scratch_buf0.size = 0;
return -ENOMEM;
}
}
get_64bit_val(buf, 192, &temp);
if (temp) {
hmc_fpm_misc->fw_scratch_buf1.size = temp;
hmc_fpm_misc->fw_scratch_buf1.va =
dma_alloc_coherent(dev->hw->device,
hmc_fpm_misc->fw_scratch_buf1.size,
&hmc_fpm_misc->fw_scratch_buf1.pa,
GFP_KERNEL);
if (!hmc_fpm_misc->fw_scratch_buf1.va) {
hmc_fpm_misc->fw_scratch_buf1.size = 0;
dma_free_coherent(dev->hw->device,
hmc_fpm_misc->fw_scratch_buf0.size,
hmc_fpm_misc->fw_scratch_buf0.va,
hmc_fpm_misc->fw_scratch_buf0.pa);
hmc_fpm_misc->fw_scratch_buf0.va = NULL;
hmc_fpm_misc->fw_scratch_buf0.size = 0;
return -ENOMEM;
}
}
}
return 0;
@ -4187,6 +4222,8 @@ static int irdma_sc_commit_fpm_val(struct irdma_sc_cqp *cqp, u64 scratch,
hdr = FIELD_PREP(IRDMA_CQPSQ_BUFSIZE, IRDMA_COMMIT_FPM_BUF_SIZE) |
FIELD_PREP(IRDMA_CQPSQ_OPCODE, IRDMA_CQP_OP_COMMIT_FPM_VAL) |
FIELD_PREP(IRDMA_CQPSQ_CFPM_FW_SCRATCH_BUF_PRESENT,
cqp->dev->hmc_fpm_misc.fw_scratch_buf0.va != NULL) |
FIELD_PREP(IRDMA_CQPSQ_WQEVALID, cqp->polarity);
dma_wmb(); /* make sure WQE is written before valid bit is set */
@ -5034,7 +5071,9 @@ static void irdma_set_loc_mem(__le64 *buf)
for (offset = 0; offset < IRDMA_COMMIT_FPM_BUF_SIZE;
offset += sizeof(__le64)) {
if (offset == IRDMA_PBLE_COMMIT_OFFSET)
if (offset == IRDMA_PBLE_COMMIT_OFFSET ||
offset == IRDMA_SCRATCH_BUF0_COMMIT_OFFSET ||
offset == IRDMA_SCRATCH_BUF1_COMMIT_OFFSET)
continue;
get_64bit_val(buf, offset, &temp);
if (temp)
@ -5090,6 +5129,8 @@ static int irdma_sc_cfg_iw_fpm(struct irdma_sc_dev *dev, u8 hmc_fn_id)
(u64)obj_info[IRDMA_HMC_IW_OOISC].cnt);
set_64bit_val(buf, 168,
(u64)obj_info[IRDMA_HMC_IW_OOISCFFL].cnt);
set_64bit_val(buf, 192, dev->hmc_fpm_misc.fw_scratch_buf0.pa);
set_64bit_val(buf, 200, dev->hmc_fpm_misc.fw_scratch_buf1.pa);
if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3 &&
dev->hmc_fpm_misc.loc_mem_pages)
irdma_set_loc_mem(buf);

View File

@ -133,6 +133,8 @@ enum irdma_protocol_used {
#define MAX_MR_PER_SD 0x8000
#define MAX_MR_SD_PER_FCN 0x80
#define IRDMA_PBLE_COMMIT_OFFSET 112
#define IRDMA_SCRATCH_BUF0_COMMIT_OFFSET 192
#define IRDMA_SCRATCH_BUF1_COMMIT_OFFSET 200
#define IRDMA_MAX_QUANTA_PER_WR 8
#define IRDMA_QP_SW_MAX_WQ_QUANTA 32768
@ -658,6 +660,8 @@ enum irdma_cqp_op_type {
#define IRDMA_COMMIT_FPM_QPCNT GENMASK_ULL(20, 0)
#define IRDMA_COMMIT_FPM_BASE_S 32
#define IRDMA_CQPSQ_CFPM_HMCFNID GENMASK_ULL(15, 0)
#define IRDMA_CQPSQ_CFPM_FW_SCRATCH_BUF_PRESENT_S 38
#define IRDMA_CQPSQ_CFPM_FW_SCRATCH_BUF_PRESENT BIT_ULL(38)
#define IRDMA_CQPSQ_FWQE_AECODE GENMASK_ULL(15, 0)
#define IRDMA_CQPSQ_FWQE_AESOURCE GENMASK_ULL(19, 16)

View File

@ -1693,6 +1693,8 @@ static int irdma_hmc_setup(struct irdma_pci_f *rf)
static void irdma_del_init_mem(struct irdma_pci_f *rf)
{
struct irdma_sc_dev *dev = &rf->sc_dev;
struct irdma_dma_mem *fw_scratch_buf0;
struct irdma_dma_mem *fw_scratch_buf1;
if (!rf->sc_dev.privileged)
irdma_vchnl_req_put_hmc_fcn(&rf->sc_dev);
@ -1713,6 +1715,15 @@ static void irdma_del_init_mem(struct irdma_pci_f *rf)
rf->iw_msixtbl = NULL;
kfree(rf->hmc_info_mem);
rf->hmc_info_mem = NULL;
fw_scratch_buf0 = &dev->hmc_fpm_misc.fw_scratch_buf0;
fw_scratch_buf1 = &dev->hmc_fpm_misc.fw_scratch_buf1;
if (fw_scratch_buf0->va)
dma_free_coherent(dev->hw->device, fw_scratch_buf0->size,
fw_scratch_buf0->va, fw_scratch_buf0->pa);
if (fw_scratch_buf1->va)
dma_free_coherent(dev->hw->device, fw_scratch_buf1->size,
fw_scratch_buf1->va, fw_scratch_buf1->pa);
}
/**

View File

@ -622,6 +622,8 @@ struct irdma_hmc_fpm_misc {
u32 timer_bucket;
u32 rrf_block_size;
u32 ooiscf_block_size;
struct irdma_dma_mem fw_scratch_buf0;
struct irdma_dma_mem fw_scratch_buf1;
};
#define IRDMA_VCHNL_MAX_MSG_SIZE 512

View File

@ -159,8 +159,8 @@ enum irdma_device_caps_const {
IRDMA_CEQE_SIZE = 1,
IRDMA_CQP_CTX_SIZE = 8,
IRDMA_SHADOW_AREA_SIZE = 8,
IRDMA_QUERY_FPM_BUF_SIZE = 192,
IRDMA_COMMIT_FPM_BUF_SIZE = 192,
IRDMA_QUERY_FPM_BUF_SIZE = 200,
IRDMA_COMMIT_FPM_BUF_SIZE = 208,
IRDMA_GATHER_STATS_BUF_SIZE = 1024,
IRDMA_MIN_IW_QP_ID = 0,
IRDMA_MAX_IW_QP_ID = 262143,