Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edca5ea3 authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: read and print all six FW status registers



ME devices prior to PCH8 (Lynx Point) have two FW status registers,
on PCH8 and newer excluding txe there are six FW status registers.

Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e88281ed
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -117,14 +117,18 @@
#define MEI_DEV_ID_WPT_LP     0x9CBA  /* Wildcat Point LP */
#define MEI_DEV_ID_WPT_LP_2   0x9CBB  /* Wildcat Point LP 2 */

/* Host Firmware Status Registers in PCI Config Space */
#define PCI_CFG_HFS_1         0x40
#define PCI_CFG_HFS_2         0x48

/*
 * MEI HW Section
 */

/* Host Firmware Status Registers in PCI Config Space */
#define PCI_CFG_HFS_1         0x40
#define PCI_CFG_HFS_2         0x48
#define PCI_CFG_HFS_3         0x60
#define PCI_CFG_HFS_4         0x64
#define PCI_CFG_HFS_5         0x68
#define PCI_CFG_HFS_6         0x6C

/* MEI registers */
/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
#define H_CB_WW    0
+16 −3
Original line number Diff line number Diff line
@@ -835,6 +835,14 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev)
	.fw_status.status[0] = PCI_CFG_HFS_1,   \
	.fw_status.status[1] = PCI_CFG_HFS_2

#define MEI_CFG_PCH8_HFS                        \
	.fw_status.count = 6,                   \
	.fw_status.status[0] = PCI_CFG_HFS_1,   \
	.fw_status.status[1] = PCI_CFG_HFS_2,   \
	.fw_status.status[2] = PCI_CFG_HFS_3,   \
	.fw_status.status[3] = PCI_CFG_HFS_4,   \
	.fw_status.status[4] = PCI_CFG_HFS_5,   \
	.fw_status.status[5] = PCI_CFG_HFS_6

/* ICH Legacy devices */
const struct mei_cfg mei_me_legacy_cfg = {
@@ -858,9 +866,14 @@ const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {
	MEI_CFG_FW_NM,
};

/* PCH Lynx Point with quirk for SPS Firmware exclusion */
const struct mei_cfg mei_me_lpt_cfg = {
	MEI_CFG_PCH_HFS,
/* PCH8 Lynx Point and newer devices */
const struct mei_cfg mei_me_pch8_cfg = {
	MEI_CFG_PCH8_HFS,
};

/* PCH8 Lynx Point with quirk for SPS Firmware exclusion */
const struct mei_cfg mei_me_pch8_sps_cfg = {
	MEI_CFG_PCH8_HFS,
	MEI_CFG_FW_SPS,
};

+2 −1
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@ extern const struct mei_cfg mei_me_legacy_cfg;
extern const struct mei_cfg mei_me_ich_cfg;
extern const struct mei_cfg mei_me_pch_cfg;
extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg;
extern const struct mei_cfg mei_me_lpt_cfg;
extern const struct mei_cfg mei_me_pch8_cfg;
extern const struct mei_cfg mei_me_pch8_sps_cfg;

struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
				   const struct mei_cfg *cfg);
+3 −4
Original line number Diff line number Diff line
@@ -700,11 +700,10 @@ static int mei_txe_write(struct mei_device *dev,
	mei_txe_input_ready_interrupt_enable(dev);

	if (!mei_txe_is_input_ready(dev)) {
		struct mei_fw_status fw_status;
		char fw_sts_str[MEI_FW_STATUS_STR_SZ];

		mei_fw_status(dev, &fw_status);
		dev_err(dev->dev, "Input is not ready " FW_STS_FMT "\n",
			FW_STS_PRM(fw_status));
		mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
		dev_err(dev->dev, "Input is not ready %s\n", fw_sts_str);
		return -EAGAIN;
	}

+33 −5
Original line number Diff line number Diff line
@@ -54,6 +54,35 @@ const char *mei_pg_state_str(enum mei_pg_state state)
#undef MEI_PG_STATE
}

/**
 * mei_fw_status2str - convert fw status registers to printable string
 *
 * @fw_status:  firmware status
 * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
 * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
 *
 * Return: number of bytes written or -EINVAL if buffer is to small
 */
ssize_t mei_fw_status2str(struct mei_fw_status *fw_status,
			  char *buf, size_t len)
{
	ssize_t cnt = 0;
	int i;

	buf[0] = '\0';

	if (len < MEI_FW_STATUS_STR_SZ)
		return -EINVAL;

	for (i = 0; i < fw_status->count; i++)
		cnt += scnprintf(buf + cnt, len - cnt, "%08X ",
				fw_status->status[i]);

	/* drop last space */
	buf[cnt] = '\0';
	return cnt;
}
EXPORT_SYMBOL_GPL(mei_fw_status2str);

/**
 * mei_cancel_work - Cancel mei background jobs
@@ -86,12 +115,11 @@ int mei_reset(struct mei_device *dev)
	    state != MEI_DEV_DISABLED &&
	    state != MEI_DEV_POWER_DOWN &&
	    state != MEI_DEV_POWER_UP) {
		struct mei_fw_status fw_status;
		char fw_sts_str[MEI_FW_STATUS_STR_SZ];

		mei_fw_status(dev, &fw_status);
		dev_warn(dev->dev,
			"unexpected reset: dev_state = %s " FW_STS_FMT "\n",
			mei_dev_state_str(state), FW_STS_PRM(fw_status));
		mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
		dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n",
			 mei_dev_state_str(state), fw_sts_str);
	}

	/* we're already in reset, cancel the init timer
Loading