mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 10:32:35 +00:00
net/mlx4_core: Read HCA frequency and map internal clock
Read HCA frequency, read PCI clock bar and offset, map internal clock to PCI bar. Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d998735f44
commit
ddd8a6c12d
@ -1013,6 +1013,9 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
|
||||
#define QUERY_FW_COMM_BASE_OFFSET 0x40
|
||||
#define QUERY_FW_COMM_BAR_OFFSET 0x48
|
||||
|
||||
#define QUERY_FW_CLOCK_OFFSET 0x50
|
||||
#define QUERY_FW_CLOCK_BAR 0x58
|
||||
|
||||
mailbox = mlx4_alloc_cmd_mailbox(dev);
|
||||
if (IS_ERR(mailbox))
|
||||
return PTR_ERR(mailbox);
|
||||
@ -1087,6 +1090,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
|
||||
fw->comm_bar, fw->comm_base);
|
||||
mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2);
|
||||
|
||||
MLX4_GET(fw->clock_offset, outbox, QUERY_FW_CLOCK_OFFSET);
|
||||
MLX4_GET(fw->clock_bar, outbox, QUERY_FW_CLOCK_BAR);
|
||||
fw->clock_bar = (fw->clock_bar >> 6) * 2;
|
||||
mlx4_dbg(dev, "Internal clock bar:%d offset:0x%llx\n",
|
||||
fw->clock_bar, fw->clock_offset);
|
||||
|
||||
/*
|
||||
* Round up number of system pages needed in case
|
||||
* MLX4_ICM_PAGE_SIZE < PAGE_SIZE.
|
||||
@ -1374,6 +1383,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||
u8 byte_field;
|
||||
|
||||
#define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04
|
||||
#define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c
|
||||
|
||||
mailbox = mlx4_alloc_cmd_mailbox(dev);
|
||||
if (IS_ERR(mailbox))
|
||||
@ -1388,6 +1398,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||
goto out;
|
||||
|
||||
MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET);
|
||||
MLX4_GET(param->hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET);
|
||||
|
||||
/* QPC/EEC/CQC/EQC/RDMARC attributes */
|
||||
|
||||
|
@ -162,6 +162,7 @@ struct mlx4_init_hca_param {
|
||||
u64 global_caps;
|
||||
u16 log_mc_entry_sz;
|
||||
u16 log_mc_hash_sz;
|
||||
u16 hca_core_clock; /* Internal Clock Frequency (in MHz) */
|
||||
u8 log_num_qps;
|
||||
u8 log_num_srqs;
|
||||
u8 log_num_cqs;
|
||||
|
@ -513,6 +513,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
|
||||
|
||||
mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
|
||||
|
||||
dev->caps.hca_core_clock = hca_param.hca_core_clock;
|
||||
|
||||
memset(&dev_cap, 0, sizeof(dev_cap));
|
||||
dev->caps.max_qp_dest_rdma = 1 << hca_param.log_rd_per_qp;
|
||||
err = mlx4_dev_cap(dev, &dev_cap);
|
||||
@ -1226,8 +1228,31 @@ static void unmap_bf_area(struct mlx4_dev *dev)
|
||||
io_mapping_free(mlx4_priv(dev)->bf_mapping);
|
||||
}
|
||||
|
||||
static int map_internal_clock(struct mlx4_dev *dev)
|
||||
{
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
|
||||
priv->clock_mapping =
|
||||
ioremap(pci_resource_start(dev->pdev, priv->fw.clock_bar) +
|
||||
priv->fw.clock_offset, MLX4_CLOCK_SIZE);
|
||||
|
||||
if (!priv->clock_mapping)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unmap_internal_clock(struct mlx4_dev *dev)
|
||||
{
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
|
||||
if (priv->clock_mapping)
|
||||
iounmap(priv->clock_mapping);
|
||||
}
|
||||
|
||||
static void mlx4_close_hca(struct mlx4_dev *dev)
|
||||
{
|
||||
unmap_internal_clock(dev);
|
||||
unmap_bf_area(dev);
|
||||
if (mlx4_is_slave(dev))
|
||||
mlx4_slave_exit(dev);
|
||||
@ -1445,6 +1470,37 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
||||
mlx4_err(dev, "INIT_HCA command failed, aborting.\n");
|
||||
goto err_free_icm;
|
||||
}
|
||||
/*
|
||||
* If TS is supported by FW
|
||||
* read HCA frequency by QUERY_HCA command
|
||||
*/
|
||||
if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) {
|
||||
memset(&init_hca, 0, sizeof(init_hca));
|
||||
err = mlx4_QUERY_HCA(dev, &init_hca);
|
||||
if (err) {
|
||||
mlx4_err(dev, "QUERY_HCA command failed, disable timestamp.\n");
|
||||
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
|
||||
} else {
|
||||
dev->caps.hca_core_clock =
|
||||
init_hca.hca_core_clock;
|
||||
}
|
||||
|
||||
/* In case we got HCA frequency 0 - disable timestamping
|
||||
* to avoid dividing by zero
|
||||
*/
|
||||
if (!dev->caps.hca_core_clock) {
|
||||
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
|
||||
mlx4_err(dev,
|
||||
"HCA frequency is 0. Timestamping is not supported.");
|
||||
} else if (map_internal_clock(dev)) {
|
||||
/*
|
||||
* Map internal clock,
|
||||
* in case of failure disable timestamping
|
||||
*/
|
||||
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
|
||||
mlx4_err(dev, "Failed to map internal clock. Timestamping is not supported.\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = mlx4_init_slave(dev);
|
||||
if (err) {
|
||||
@ -1478,6 +1534,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
||||
return 0;
|
||||
|
||||
unmap_bf:
|
||||
unmap_internal_clock(dev);
|
||||
unmap_bf_area(dev);
|
||||
|
||||
err_close:
|
||||
|
@ -87,7 +87,8 @@ enum {
|
||||
MLX4_HCR_SIZE = 0x0001c,
|
||||
MLX4_CLR_INT_SIZE = 0x00008,
|
||||
MLX4_SLAVE_COMM_BASE = 0x0,
|
||||
MLX4_COMM_PAGESIZE = 0x1000
|
||||
MLX4_COMM_PAGESIZE = 0x1000,
|
||||
MLX4_CLOCK_SIZE = 0x00008
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -403,6 +404,7 @@ struct mlx4_fw {
|
||||
u64 clr_int_base;
|
||||
u64 catas_offset;
|
||||
u64 comm_base;
|
||||
u64 clock_offset;
|
||||
struct mlx4_icm *fw_icm;
|
||||
struct mlx4_icm *aux_icm;
|
||||
u32 catas_size;
|
||||
@ -410,6 +412,7 @@ struct mlx4_fw {
|
||||
u8 clr_int_bar;
|
||||
u8 catas_bar;
|
||||
u8 comm_bar;
|
||||
u8 clock_bar;
|
||||
};
|
||||
|
||||
struct mlx4_comm {
|
||||
@ -826,6 +829,7 @@ struct mlx4_priv {
|
||||
struct list_head bf_list;
|
||||
struct mutex bf_mutex;
|
||||
struct io_mapping *bf_mapping;
|
||||
void __iomem *clock_mapping;
|
||||
int reserved_mtts;
|
||||
int fs_hash_mode;
|
||||
u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS];
|
||||
|
@ -445,6 +445,7 @@ struct mlx4_caps {
|
||||
u8 eqe_factor;
|
||||
u32 userspace_caps; /* userspace must be aware of these */
|
||||
u32 function_caps; /* VFs must be aware of these */
|
||||
u16 hca_core_clock;
|
||||
};
|
||||
|
||||
struct mlx4_buf_list {
|
||||
|
Loading…
Reference in New Issue
Block a user