Skip to content

Commit ddd8a6c

Browse files
Eugenia Emantayevdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Amir Vadai <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d998735 commit ddd8a6c

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

drivers/net/ethernet/mellanox/mlx4/fw.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,9 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
10131013
#define QUERY_FW_COMM_BASE_OFFSET 0x40
10141014
#define QUERY_FW_COMM_BAR_OFFSET 0x48
10151015

1016+
#define QUERY_FW_CLOCK_OFFSET 0x50
1017+
#define QUERY_FW_CLOCK_BAR 0x58
1018+
10161019
mailbox = mlx4_alloc_cmd_mailbox(dev);
10171020
if (IS_ERR(mailbox))
10181021
return PTR_ERR(mailbox);
@@ -1087,6 +1090,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
10871090
fw->comm_bar, fw->comm_base);
10881091
mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2);
10891092

1093+
MLX4_GET(fw->clock_offset, outbox, QUERY_FW_CLOCK_OFFSET);
1094+
MLX4_GET(fw->clock_bar, outbox, QUERY_FW_CLOCK_BAR);
1095+
fw->clock_bar = (fw->clock_bar >> 6) * 2;
1096+
mlx4_dbg(dev, "Internal clock bar:%d offset:0x%llx\n",
1097+
fw->clock_bar, fw->clock_offset);
1098+
10901099
/*
10911100
* Round up number of system pages needed in case
10921101
* MLX4_ICM_PAGE_SIZE < PAGE_SIZE.
@@ -1374,6 +1383,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
13741383
u8 byte_field;
13751384

13761385
#define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04
1386+
#define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c
13771387

13781388
mailbox = mlx4_alloc_cmd_mailbox(dev);
13791389
if (IS_ERR(mailbox))
@@ -1388,6 +1398,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
13881398
goto out;
13891399

13901400
MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET);
1401+
MLX4_GET(param->hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET);
13911402

13921403
/* QPC/EEC/CQC/EQC/RDMARC attributes */
13931404

drivers/net/ethernet/mellanox/mlx4/fw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct mlx4_init_hca_param {
162162
u64 global_caps;
163163
u16 log_mc_entry_sz;
164164
u16 log_mc_hash_sz;
165+
u16 hca_core_clock; /* Internal Clock Frequency (in MHz) */
165166
u8 log_num_qps;
166167
u8 log_num_srqs;
167168
u8 log_num_cqs;

drivers/net/ethernet/mellanox/mlx4/main.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
513513

514514
mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
515515

516+
dev->caps.hca_core_clock = hca_param.hca_core_clock;
517+
516518
memset(&dev_cap, 0, sizeof(dev_cap));
517519
dev->caps.max_qp_dest_rdma = 1 << hca_param.log_rd_per_qp;
518520
err = mlx4_dev_cap(dev, &dev_cap);
@@ -1226,8 +1228,31 @@ static void unmap_bf_area(struct mlx4_dev *dev)
12261228
io_mapping_free(mlx4_priv(dev)->bf_mapping);
12271229
}
12281230

1231+
static int map_internal_clock(struct mlx4_dev *dev)
1232+
{
1233+
struct mlx4_priv *priv = mlx4_priv(dev);
1234+
1235+
priv->clock_mapping =
1236+
ioremap(pci_resource_start(dev->pdev, priv->fw.clock_bar) +
1237+
priv->fw.clock_offset, MLX4_CLOCK_SIZE);
1238+
1239+
if (!priv->clock_mapping)
1240+
return -ENOMEM;
1241+
1242+
return 0;
1243+
}
1244+
1245+
static void unmap_internal_clock(struct mlx4_dev *dev)
1246+
{
1247+
struct mlx4_priv *priv = mlx4_priv(dev);
1248+
1249+
if (priv->clock_mapping)
1250+
iounmap(priv->clock_mapping);
1251+
}
1252+
12291253
static void mlx4_close_hca(struct mlx4_dev *dev)
12301254
{
1255+
unmap_internal_clock(dev);
12311256
unmap_bf_area(dev);
12321257
if (mlx4_is_slave(dev))
12331258
mlx4_slave_exit(dev);
@@ -1445,6 +1470,37 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
14451470
mlx4_err(dev, "INIT_HCA command failed, aborting.\n");
14461471
goto err_free_icm;
14471472
}
1473+
/*
1474+
* If TS is supported by FW
1475+
* read HCA frequency by QUERY_HCA command
1476+
*/
1477+
if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) {
1478+
memset(&init_hca, 0, sizeof(init_hca));
1479+
err = mlx4_QUERY_HCA(dev, &init_hca);
1480+
if (err) {
1481+
mlx4_err(dev, "QUERY_HCA command failed, disable timestamp.\n");
1482+
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
1483+
} else {
1484+
dev->caps.hca_core_clock =
1485+
init_hca.hca_core_clock;
1486+
}
1487+
1488+
/* In case we got HCA frequency 0 - disable timestamping
1489+
* to avoid dividing by zero
1490+
*/
1491+
if (!dev->caps.hca_core_clock) {
1492+
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
1493+
mlx4_err(dev,
1494+
"HCA frequency is 0. Timestamping is not supported.");
1495+
} else if (map_internal_clock(dev)) {
1496+
/*
1497+
* Map internal clock,
1498+
* in case of failure disable timestamping
1499+
*/
1500+
dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
1501+
mlx4_err(dev, "Failed to map internal clock. Timestamping is not supported.\n");
1502+
}
1503+
}
14481504
} else {
14491505
err = mlx4_init_slave(dev);
14501506
if (err) {
@@ -1478,6 +1534,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
14781534
return 0;
14791535

14801536
unmap_bf:
1537+
unmap_internal_clock(dev);
14811538
unmap_bf_area(dev);
14821539

14831540
err_close:

drivers/net/ethernet/mellanox/mlx4/mlx4.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ enum {
8787
MLX4_HCR_SIZE = 0x0001c,
8888
MLX4_CLR_INT_SIZE = 0x00008,
8989
MLX4_SLAVE_COMM_BASE = 0x0,
90-
MLX4_COMM_PAGESIZE = 0x1000
90+
MLX4_COMM_PAGESIZE = 0x1000,
91+
MLX4_CLOCK_SIZE = 0x00008
9192
};
9293

9394
enum {
@@ -403,13 +404,15 @@ struct mlx4_fw {
403404
u64 clr_int_base;
404405
u64 catas_offset;
405406
u64 comm_base;
407+
u64 clock_offset;
406408
struct mlx4_icm *fw_icm;
407409
struct mlx4_icm *aux_icm;
408410
u32 catas_size;
409411
u16 fw_pages;
410412
u8 clr_int_bar;
411413
u8 catas_bar;
412414
u8 comm_bar;
415+
u8 clock_bar;
413416
};
414417

415418
struct mlx4_comm {
@@ -826,6 +829,7 @@ struct mlx4_priv {
826829
struct list_head bf_list;
827830
struct mutex bf_mutex;
828831
struct io_mapping *bf_mapping;
832+
void __iomem *clock_mapping;
829833
int reserved_mtts;
830834
int fs_hash_mode;
831835
u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS];

include/linux/mlx4/device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ struct mlx4_caps {
445445
u8 eqe_factor;
446446
u32 userspace_caps; /* userspace must be aware of these */
447447
u32 function_caps; /* VFs must be aware of these */
448+
u16 hca_core_clock;
448449
};
449450

450451
struct mlx4_buf_list {

0 commit comments

Comments
 (0)