Commit 02e8be5a authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnxt_en: Fix ethtool -d byte order for 32-bit values



For version 1 register dump that includes the PCIe stats, the existing
code incorrectly assumes that all PCIe stats are 64-bit values.  Fix it
by using an array containing the starting and ending index of the 32-bit
values.  The loop in bnxt_get_regs() will use the array to do proper
endian swap for the 32-bit values.

Fixes: b5d600b0 ("bnxt_en: Add support for 'ethtool -d'")
Reviewed-by: default avatarShruti Parab <shruti.parab@broadcom.com>
Reviewed-by: default avatarKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: default avatarAndy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6b87bd94
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -2062,6 +2062,17 @@ static int bnxt_get_regs_len(struct net_device *dev)
	return reg_len;
}

#define BNXT_PCIE_32B_ENTRY(start, end)			\
	 { offsetof(struct pcie_ctx_hw_stats, start),	\
	   offsetof(struct pcie_ctx_hw_stats, end) }

static const struct {
	u16 start;
	u16 end;
} bnxt_pcie_32b_entries[] = {
	BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]),
};

static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			  void *_p)
{
@@ -2094,12 +2105,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
	req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
	rc = hwrm_req_send(bp, req);
	if (!rc) {
		__le64 *src = (__le64 *)hw_pcie_stats;
		u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
		int i;
		u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN);
		u8 *src = (u8 *)hw_pcie_stats;
		int i, j;

		for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) {
			if (i >= bnxt_pcie_32b_entries[j].start &&
			    i <= bnxt_pcie_32b_entries[j].end) {
				u32 *dst32 = (u32 *)(dst + i);

				*dst32 = le32_to_cpu(*(__le32 *)(src + i));
				i += 4;
				if (i > bnxt_pcie_32b_entries[j].end &&
				    j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1)
					j++;
			} else {
				u64 *dst64 = (u64 *)(dst + i);

		for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
			dst[i] = le64_to_cpu(src[i]);
				*dst64 = le64_to_cpu(*(__le64 *)(src + i));
				i += 8;
			}
		}
	}
	hwrm_req_drop(bp, req);
}