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

Commit 2e8b981c authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Roland Dreier
Browse files

[PATCH] IB/mthca: add HCA board ID to sysfs info



Add support for reporting HCA board ID returned from QUERY_ADAPTER
firmware command through sysfs.

Signed-off-by: default avatarMichael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 97f52eb4
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,34 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
	return err;
}

static void get_board_id(void *vsd, char *board_id)
{
	int i;

#define VSD_OFFSET_SIG1		0x00
#define VSD_OFFSET_SIG2		0xde
#define VSD_OFFSET_MLX_BOARD_ID	0xd0
#define VSD_OFFSET_TS_BOARD_ID	0x20

#define VSD_SIGNATURE_TOPSPIN	0x5ad

	memset(board_id, 0, MTHCA_BOARD_ID_LEN);

	if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN &&
	    be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) {
		strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MTHCA_BOARD_ID_LEN);
	} else {
		/*
		 * The board ID is a string but the firmware byte
		 * swaps each 4-byte word before passing it back to
		 * us.  Therefore we need to swab it before printing.
		 */
		for (i = 0; i < 4; ++i)
			((u32 *) board_id)[i] =
				swab32(*(u32 *) (vsd + VSD_OFFSET_MLX_BOARD_ID + i * 4));
	}
}

int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
			struct mthca_adapter *adapter, u8 *status)
{
@@ -1097,6 +1125,7 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
#define QUERY_ADAPTER_DEVICE_ID_OFFSET     0x04
#define QUERY_ADAPTER_REVISION_ID_OFFSET   0x08
#define QUERY_ADAPTER_INTA_PIN_OFFSET      0x10
#define QUERY_ADAPTER_VSD_OFFSET           0x20

	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
	if (IS_ERR(mailbox))
@@ -1114,6 +1143,9 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
	MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET);
	MTHCA_GET(adapter->inta_pin, outbox,    QUERY_ADAPTER_INTA_PIN_OFFSET);

	get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4,
		     adapter->board_id);

out:
	mthca_free_mailbox(dev, mailbox);
	return err;
+5 −4
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ struct mthca_adapter {
	u32  vendor_id;
	u32  device_id;
	u32  revision_id;
	char board_id[MTHCA_BOARD_ID_LEN];
	u8   inta_pin;
};

+5 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ enum {
	MTHCA_MAX_PORTS = 2
};

enum {
	MTHCA_BOARD_ID_LEN = 64
};

enum {
	MTHCA_EQ_CONTEXT_SIZE =  0x40,
	MTHCA_CQ_CONTEXT_SIZE =  0x40,
@@ -248,6 +252,7 @@ struct mthca_dev {
	unsigned long    device_cap_flags;

	u32              rev_id;
	char             board_id[MTHCA_BOARD_ID_LEN];

	/* firmware info */
	u64              fw_ver;
+58 −64
Original line number Diff line number Diff line
@@ -213,7 +213,6 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
	struct mthca_dev_lim        dev_lim;
	struct mthca_profile        profile;
	struct mthca_init_hca_param init_hca;
	struct mthca_adapter        adapter;

	err = mthca_SYS_EN(mdev, &status);
	if (err) {
@@ -271,26 +270,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
		goto err_disable;
	}

	err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
	if (err) {
		mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
		goto err_close;
	}
	if (status) {
		mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
			  "aborting.\n", status);
		err = -EINVAL;
		goto err_close;
	}

	mdev->eq_table.inta_pin = adapter.inta_pin;
	mdev->rev_id            = adapter.revision_id;

	return 0;

err_close:
	mthca_CLOSE_HCA(mdev, 0, &status);

err_disable:
	mthca_SYS_DIS(mdev, &status);

@@ -507,7 +488,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
	struct mthca_dev_lim        dev_lim;
	struct mthca_profile        profile;
	struct mthca_init_hca_param init_hca;
	struct mthca_adapter        adapter;
	u64 icm_size;
	u8 status;
	int err;
@@ -575,21 +555,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
		goto err_free_icm;
	}

	err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
	if (err) {
		mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
		goto err_free_icm;
	}
	if (status) {
		mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
			  "aborting.\n", status);
		err = -EINVAL;
		goto err_free_icm;
	}

	mdev->eq_table.inta_pin = adapter.inta_pin;
	mdev->rev_id            = adapter.revision_id;

	return 0;

err_free_icm:
@@ -615,12 +580,68 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
	return err;
}

static void mthca_close_hca(struct mthca_dev *mdev)
{
	u8 status;

	mthca_CLOSE_HCA(mdev, 0, &status);

	if (mthca_is_memfree(mdev)) {
		mthca_free_icm_table(mdev, mdev->cq_table.table);
		mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
		mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
		mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
		mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
		mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
		mthca_unmap_eq_icm(mdev);

		mthca_UNMAP_ICM_AUX(mdev, &status);
		mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);

		mthca_UNMAP_FA(mdev, &status);
		mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);

		if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
			mthca_DISABLE_LAM(mdev, &status);
	} else
		mthca_SYS_DIS(mdev, &status);
}

static int __devinit mthca_init_hca(struct mthca_dev *mdev)
{
	u8 status;
	int err;
	struct mthca_adapter adapter;

	if (mthca_is_memfree(mdev))
		return mthca_init_arbel(mdev);
		err = mthca_init_arbel(mdev);
	else
		return mthca_init_tavor(mdev);
		err = mthca_init_tavor(mdev);

	if (err)
		return err;

	err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
	if (err) {
		mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
		goto err_close;
	}
	if (status) {
		mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
			  "aborting.\n", status);
		err = -EINVAL;
		goto err_close;
	}

	mdev->eq_table.inta_pin = adapter.inta_pin;
	mdev->rev_id            = adapter.revision_id;
	memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id);

	return 0;

err_close:
	mthca_close_hca(mdev);
	return err;
}

static int __devinit mthca_setup_hca(struct mthca_dev *dev)
@@ -845,33 +866,6 @@ static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev)
	return 0;
}

static void mthca_close_hca(struct mthca_dev *mdev)
{
	u8 status;

	mthca_CLOSE_HCA(mdev, 0, &status);

	if (mthca_is_memfree(mdev)) {
		mthca_free_icm_table(mdev, mdev->cq_table.table);
		mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
		mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
		mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
		mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
		mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
		mthca_unmap_eq_icm(mdev);

		mthca_UNMAP_ICM_AUX(mdev, &status);
		mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);

		mthca_UNMAP_FA(mdev, &status);
		mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);

		if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
			mthca_DISABLE_LAM(mdev, &status);
	} else
		mthca_SYS_DIS(mdev, &status);
}

/* Types of supported HCA */
enum {
	TAVOR,			/* MT23108                        */
+9 −1
Original line number Diff line number Diff line
@@ -958,14 +958,22 @@ static ssize_t show_hca(struct class_device *cdev, char *buf)
	}
}

static ssize_t show_board(struct class_device *cdev, char *buf)
{
	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
	return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
}

static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);

static struct class_device_attribute *mthca_class_attributes[] = {
	&class_device_attr_hw_rev,
	&class_device_attr_fw_ver,
	&class_device_attr_hca_type
	&class_device_attr_hca_type,
	&class_device_attr_board_id
};

int mthca_register_device(struct mthca_dev *dev)