Commit 2a5a8800 authored by Edwin Peer's avatar Edwin Peer Committed by David S. Miller
Browse files

bnxt_en: fix firmware message length endianness



The explicit mask and shift is not the appropriate way to parse fields
out of a little endian struct. The length field is internally __le16
and the strategy employed only happens to work on little endian machines
because the offset used is actually incorrect (length is at offset 6).

Also remove the related and no longer used definitions from bnxt.h.

Fixes: 845adfe4 ("bnxt_en: Improve valid bit checking in firmware response message.")
Signed-off-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 95ec1f47
Loading
Loading
Loading
Loading
+4 −10
Original line number Diff line number Diff line
@@ -4176,14 +4176,12 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
	int i, intr_process, rc, tmo_count;
	struct input *req = msg;
	u32 *data = msg;
	__le32 *resp_len;
	u8 *valid;
	u16 cp_ring_id, len = 0;
	struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
	u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
	struct hwrm_short_input short_input = {0};
	u32 doorbell_offset = BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER;
	u8 *resp_addr = (u8 *)bp->hwrm_cmd_resp_addr;
	u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
	u16 dst = BNXT_HWRM_CHNL_CHIMP;

@@ -4201,7 +4199,6 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
		bar_offset = BNXT_GRCPF_REG_KONG_COMM;
		doorbell_offset = BNXT_GRCPF_REG_KONG_COMM_TRIGGER;
		resp = bp->hwrm_cmd_kong_resp_addr;
		resp_addr = (u8 *)bp->hwrm_cmd_kong_resp_addr;
	}

	memset(resp, 0, PAGE_SIZE);
@@ -4270,7 +4267,6 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
	tmo_count = HWRM_SHORT_TIMEOUT_COUNTER;
	timeout = timeout - HWRM_SHORT_MIN_TIMEOUT * HWRM_SHORT_TIMEOUT_COUNTER;
	tmo_count += DIV_ROUND_UP(timeout, HWRM_MIN_TIMEOUT);
	resp_len = (__le32 *)(resp_addr + HWRM_RESP_LEN_OFFSET);

	if (intr_process) {
		u16 seq_id = bp->hwrm_intr_seq_id;
@@ -4298,9 +4294,8 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
					   le16_to_cpu(req->req_type));
			return -EBUSY;
		}
		len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
		      HWRM_RESP_LEN_SFT;
		valid = resp_addr + len - 1;
		len = le16_to_cpu(resp->resp_len);
		valid = ((u8 *)resp) + len - 1;
	} else {
		int j;

@@ -4311,8 +4306,7 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
			 */
			if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
				return -EBUSY;
			len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
			      HWRM_RESP_LEN_SFT;
			len = le16_to_cpu(resp->resp_len);
			if (len)
				break;
			/* on first few passes, just barely sleep */
@@ -4334,7 +4328,7 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
		}

		/* Last byte of resp contains valid bit */
		valid = resp_addr + len - 1;
		valid = ((u8 *)resp) + len - 1;
		for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
			/* make sure we read from updated DMA memory */
			dma_rmb();
+0 −5
Original line number Diff line number Diff line
@@ -656,11 +656,6 @@ struct nqe_cn {
#define HWRM_CMD_TIMEOUT		(bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT		((HWRM_CMD_TIMEOUT) * 4)
#define HWRM_COREDUMP_TIMEOUT		((HWRM_CMD_TIMEOUT) * 12)
#define HWRM_RESP_ERR_CODE_MASK		0xffff
#define HWRM_RESP_LEN_OFFSET		4
#define HWRM_RESP_LEN_MASK		0xffff0000
#define HWRM_RESP_LEN_SFT		16
#define HWRM_RESP_VALID_MASK		0xff000000
#define BNXT_HWRM_REQ_MAX_SIZE		128
#define BNXT_HWRM_REQS_PER_PAGE		(BNXT_PAGE_SIZE /	\
					 BNXT_HWRM_REQ_MAX_SIZE)