forked from Minki/linux
[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: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
97f52eb438
commit
2e8b981c5d
@ -1085,6 +1085,34 @@ out:
|
||||
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;
|
||||
|
@ -184,10 +184,11 @@ struct mthca_dev_lim {
|
||||
};
|
||||
|
||||
struct mthca_adapter {
|
||||
u32 vendor_id;
|
||||
u32 device_id;
|
||||
u32 revision_id;
|
||||
u8 inta_pin;
|
||||
u32 vendor_id;
|
||||
u32 device_id;
|
||||
u32 revision_id;
|
||||
char board_id[MTHCA_BOARD_ID_LEN];
|
||||
u8 inta_pin;
|
||||
};
|
||||
|
||||
struct mthca_init_hca_param {
|
||||
|
@ -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;
|
||||
|
@ -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 @@ err_disable:
|
||||
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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user