Commit 8cf1d12a authored by Kashyap Desai's avatar Kashyap Desai Committed by Leon Romanovsky

RDMA/bnxt_re: Enhance the existing functions that wait for FW responses

Use jiffies based timewait instead of counting iteration for
commands that block for FW response.

Also add a poll routine for control path commands. This is for
polling completion if the waiting commands timeout. This avoids cases
where the driver misses completion interrupts.
Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Link: https://lore.kernel.org/r/1686308514-11996-6-git-send-email-selvin.xavier@broadcom.comSigned-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 258ee043
......@@ -53,37 +53,74 @@
static void bnxt_qplib_service_creq(struct tasklet_struct *t);
/* Hardware communication channel */
/**
* __wait_for_resp - Don't hold the cpu context and wait for response
* @rcfw - rcfw channel instance of rdev
* @cookie - cookie to track the command
*
* Wait for command completion in sleepable context.
*
* Returns:
* 0 if command is completed by firmware.
* Non zero error code for rest of the case.
*/
static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
{
struct bnxt_qplib_cmdq_ctx *cmdq;
u16 cbit;
int rc;
int ret;
cmdq = &rcfw->cmdq;
cbit = cookie % rcfw->cmdq_depth;
rc = wait_event_timeout(cmdq->waitq,
!test_bit(cbit, cmdq->cmdq_bitmap),
msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS));
return rc ? 0 : -ETIMEDOUT;
do {
/* Non zero means command completed */
ret = wait_event_timeout(cmdq->waitq,
!test_bit(cbit, cmdq->cmdq_bitmap),
msecs_to_jiffies(10000));
if (!test_bit(cbit, cmdq->cmdq_bitmap))
return 0;
bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
if (!test_bit(cbit, cmdq->cmdq_bitmap))
return 0;
} while (true);
};
/**
* __block_for_resp - hold the cpu context and wait for response
* @rcfw - rcfw channel instance of rdev
* @cookie - cookie to track the command
*
* This function will hold the cpu (non-sleepable context) and
* wait for command completion. Maximum holding interval is 8 second.
*
* Returns:
* -ETIMEOUT if command is not completed in specific time interval.
* 0 if command is completed by firmware.
*/
static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
{
u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
struct bnxt_qplib_cmdq_ctx *cmdq;
struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
unsigned long issue_time = 0;
u16 cbit;
cmdq = &rcfw->cmdq;
cbit = cookie % rcfw->cmdq_depth;
if (!test_bit(cbit, cmdq->cmdq_bitmap))
goto done;
issue_time = jiffies;
do {
udelay(1);
bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
} while (test_bit(cbit, cmdq->cmdq_bitmap) && --count);
done:
return count ? 0 : -ETIMEDOUT;
if (!test_bit(cbit, cmdq->cmdq_bitmap))
return 0;
} while (time_before(jiffies, issue_time + (8 * HZ)));
return -ETIMEDOUT;
};
static int __send_message(struct bnxt_qplib_rcfw *rcfw,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment