mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
bnxt_en: Improve the delay logic for firmware response.
The current code has 2 problems: 1. The maximum wait time is not long enough. It is about 60% of the duration specified by the firmware. It is calling usleep_range(600, 800) for every 1 msec we are supposed to wait. 2. The granularity of the delay is too coarse. Many simple firmware commands finish in 25 usec or less. We fix these 2 issues by multiplying the original 1 msec loop counter by 40 and calling usleep_range(25, 40) for each iteration. There is also a second delay loop to wait for the last DMA word to complete. This delay loop should be a very short 5 usec wait. This change results in much faster bring-up/down time: Before the patch: time ip link set p4p1 up real 0m0.120s user 0m0.001s sys 0m0.009s After the patch: time ip link set p4p1 up real 0m0.030s user 0m0.000s sys 0m0.010s Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d0a42d6fc8
commit
a11fa2be6d
1 changed files with 10 additions and 9 deletions
|
@ -2780,7 +2780,7 @@ void bnxt_hwrm_cmd_hdr_init(struct bnxt *bp, void *request, u16 req_type,
|
||||||
static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
||||||
int timeout, bool silent)
|
int timeout, bool silent)
|
||||||
{
|
{
|
||||||
int i, intr_process, rc;
|
int i, intr_process, rc, tmo_count;
|
||||||
struct input *req = msg;
|
struct input *req = msg;
|
||||||
u32 *data = msg;
|
u32 *data = msg;
|
||||||
__le32 *resp_len, *valid;
|
__le32 *resp_len, *valid;
|
||||||
|
@ -2809,11 +2809,12 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
||||||
timeout = DFLT_HWRM_CMD_TIMEOUT;
|
timeout = DFLT_HWRM_CMD_TIMEOUT;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
tmo_count = timeout * 40;
|
||||||
if (intr_process) {
|
if (intr_process) {
|
||||||
/* Wait until hwrm response cmpl interrupt is processed */
|
/* Wait until hwrm response cmpl interrupt is processed */
|
||||||
while (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID &&
|
while (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID &&
|
||||||
i++ < timeout) {
|
i++ < tmo_count) {
|
||||||
usleep_range(600, 800);
|
usleep_range(25, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID) {
|
if (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID) {
|
||||||
|
@ -2824,15 +2825,15 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
||||||
} else {
|
} else {
|
||||||
/* Check if response len is updated */
|
/* Check if response len is updated */
|
||||||
resp_len = bp->hwrm_cmd_resp_addr + HWRM_RESP_LEN_OFFSET;
|
resp_len = bp->hwrm_cmd_resp_addr + HWRM_RESP_LEN_OFFSET;
|
||||||
for (i = 0; i < timeout; i++) {
|
for (i = 0; i < tmo_count; i++) {
|
||||||
len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
|
len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
|
||||||
HWRM_RESP_LEN_SFT;
|
HWRM_RESP_LEN_SFT;
|
||||||
if (len)
|
if (len)
|
||||||
break;
|
break;
|
||||||
usleep_range(600, 800);
|
usleep_range(25, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= timeout) {
|
if (i >= tmo_count) {
|
||||||
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n",
|
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n",
|
||||||
timeout, le16_to_cpu(req->req_type),
|
timeout, le16_to_cpu(req->req_type),
|
||||||
le16_to_cpu(req->seq_id), *resp_len);
|
le16_to_cpu(req->seq_id), *resp_len);
|
||||||
|
@ -2841,13 +2842,13 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
|
||||||
|
|
||||||
/* Last word of resp contains valid bit */
|
/* Last word of resp contains valid bit */
|
||||||
valid = bp->hwrm_cmd_resp_addr + len - 4;
|
valid = bp->hwrm_cmd_resp_addr + len - 4;
|
||||||
for (i = 0; i < timeout; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
if (le32_to_cpu(*valid) & HWRM_RESP_VALID_MASK)
|
if (le32_to_cpu(*valid) & HWRM_RESP_VALID_MASK)
|
||||||
break;
|
break;
|
||||||
usleep_range(600, 800);
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= timeout) {
|
if (i >= 5) {
|
||||||
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n",
|
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n",
|
||||||
timeout, le16_to_cpu(req->req_type),
|
timeout, le16_to_cpu(req->req_type),
|
||||||
le16_to_cpu(req->seq_id), len, *valid);
|
le16_to_cpu(req->seq_id), len, *valid);
|
||||||
|
|
Loading…
Add table
Reference in a new issue