aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c57
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h6
-rw-r--r--include/linux/mlx4/device.h1
5 files changed, 75 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index f1e70979b4c1..6776c257bd34 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -1013,6 +1013,9 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
1013#define QUERY_FW_COMM_BASE_OFFSET 0x40 1013#define QUERY_FW_COMM_BASE_OFFSET 0x40
1014#define QUERY_FW_COMM_BAR_OFFSET 0x48 1014#define QUERY_FW_COMM_BAR_OFFSET 0x48
1015 1015
1016#define QUERY_FW_CLOCK_OFFSET 0x50
1017#define QUERY_FW_CLOCK_BAR 0x58
1018
1016 mailbox = mlx4_alloc_cmd_mailbox(dev); 1019 mailbox = mlx4_alloc_cmd_mailbox(dev);
1017 if (IS_ERR(mailbox)) 1020 if (IS_ERR(mailbox))
1018 return PTR_ERR(mailbox); 1021 return PTR_ERR(mailbox);
@@ -1087,6 +1090,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
1087 fw->comm_bar, fw->comm_base); 1090 fw->comm_bar, fw->comm_base);
1088 mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2); 1091 mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2);
1089 1092
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
1090 /* 1099 /*
1091 * Round up number of system pages needed in case 1100 * Round up number of system pages needed in case
1092 * MLX4_ICM_PAGE_SIZE < PAGE_SIZE. 1101 * MLX4_ICM_PAGE_SIZE < PAGE_SIZE.
@@ -1374,6 +1383,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
1374 u8 byte_field; 1383 u8 byte_field;
1375 1384
1376#define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 1385#define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04
1386#define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c
1377 1387
1378 mailbox = mlx4_alloc_cmd_mailbox(dev); 1388 mailbox = mlx4_alloc_cmd_mailbox(dev);
1379 if (IS_ERR(mailbox)) 1389 if (IS_ERR(mailbox))
@@ -1388,6 +1398,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
1388 goto out; 1398 goto out;
1389 1399
1390 MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET); 1400 MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET);
1401 MLX4_GET(param->hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET);
1391 1402
1392 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 1403 /* QPC/EEC/CQC/EQC/RDMARC attributes */
1393 1404
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 151c2bb380a6..fdf41665a059 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -162,6 +162,7 @@ struct mlx4_init_hca_param {
162 u64 global_caps; 162 u64 global_caps;
163 u16 log_mc_entry_sz; 163 u16 log_mc_entry_sz;
164 u16 log_mc_hash_sz; 164 u16 log_mc_hash_sz;
165 u16 hca_core_clock; /* Internal Clock Frequency (in MHz) */
165 u8 log_num_qps; 166 u8 log_num_qps;
166 u8 log_num_srqs; 167 u8 log_num_srqs;
167 u8 log_num_cqs; 168 u8 log_num_cqs;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 16abde20e1fc..e81840faa6c6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -513,6 +513,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
513 513
514 mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz; 514 mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
515 515
516 dev->caps.hca_core_clock = hca_param.hca_core_clock;
517
516 memset(&dev_cap, 0, sizeof(dev_cap)); 518 memset(&dev_cap, 0, sizeof(dev_cap));
517 dev->caps.max_qp_dest_rdma = 1 << hca_param.log_rd_per_qp; 519 dev->caps.max_qp_dest_rdma = 1 << hca_param.log_rd_per_qp;
518 err = mlx4_dev_cap(dev, &dev_cap); 520 err = mlx4_dev_cap(dev, &dev_cap);
@@ -1226,8 +1228,31 @@ static void unmap_bf_area(struct mlx4_dev *dev)
1226 io_mapping_free(mlx4_priv(dev)->bf_mapping); 1228 io_mapping_free(mlx4_priv(dev)->bf_mapping);
1227} 1229}
1228 1230
1231static 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
1245static 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
1229static void mlx4_close_hca(struct mlx4_dev *dev) 1253static void mlx4_close_hca(struct mlx4_dev *dev)
1230{ 1254{
1255 unmap_internal_clock(dev);
1231 unmap_bf_area(dev); 1256 unmap_bf_area(dev);
1232 if (mlx4_is_slave(dev)) 1257 if (mlx4_is_slave(dev))
1233 mlx4_slave_exit(dev); 1258 mlx4_slave_exit(dev);
@@ -1445,6 +1470,37 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
1445 mlx4_err(dev, "INIT_HCA command failed, aborting.\n"); 1470 mlx4_err(dev, "INIT_HCA command failed, aborting.\n");
1446 goto err_free_icm; 1471 goto err_free_icm;
1447 } 1472 }
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 }
1448 } else { 1504 } else {
1449 err = mlx4_init_slave(dev); 1505 err = mlx4_init_slave(dev);
1450 if (err) { 1506 if (err) {
@@ -1478,6 +1534,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
1478 return 0; 1534 return 0;
1479 1535
1480unmap_bf: 1536unmap_bf:
1537 unmap_internal_clock(dev);
1481 unmap_bf_area(dev); 1538 unmap_bf_area(dev);
1482 1539
1483err_close: 1540err_close:
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 252f4ba7f32c..0567f01938ed 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -87,7 +87,8 @@ enum {
87 MLX4_HCR_SIZE = 0x0001c, 87 MLX4_HCR_SIZE = 0x0001c,
88 MLX4_CLR_INT_SIZE = 0x00008, 88 MLX4_CLR_INT_SIZE = 0x00008,
89 MLX4_SLAVE_COMM_BASE = 0x0, 89 MLX4_SLAVE_COMM_BASE = 0x0,
90 MLX4_COMM_PAGESIZE = 0x1000 90 MLX4_COMM_PAGESIZE = 0x1000,
91 MLX4_CLOCK_SIZE = 0x00008
91}; 92};
92 93
93enum { 94enum {
@@ -403,6 +404,7 @@ struct mlx4_fw {
403 u64 clr_int_base; 404 u64 clr_int_base;
404 u64 catas_offset; 405 u64 catas_offset;
405 u64 comm_base; 406 u64 comm_base;
407 u64 clock_offset;
406 struct mlx4_icm *fw_icm; 408 struct mlx4_icm *fw_icm;
407 struct mlx4_icm *aux_icm; 409 struct mlx4_icm *aux_icm;
408 u32 catas_size; 410 u32 catas_size;
@@ -410,6 +412,7 @@ struct mlx4_fw {
410 u8 clr_int_bar; 412 u8 clr_int_bar;
411 u8 catas_bar; 413 u8 catas_bar;
412 u8 comm_bar; 414 u8 comm_bar;
415 u8 clock_bar;
413}; 416};
414 417
415struct mlx4_comm { 418struct mlx4_comm {
@@ -826,6 +829,7 @@ struct mlx4_priv {
826 struct list_head bf_list; 829 struct list_head bf_list;
827 struct mutex bf_mutex; 830 struct mutex bf_mutex;
828 struct io_mapping *bf_mapping; 831 struct io_mapping *bf_mapping;
832 void __iomem *clock_mapping;
829 int reserved_mtts; 833 int reserved_mtts;
830 int fs_hash_mode; 834 int fs_hash_mode;
831 u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; 835 u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS];
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 86ae260c2e53..e088290d9792 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -445,6 +445,7 @@ struct mlx4_caps {
445 u8 eqe_factor; 445 u8 eqe_factor;
446 u32 userspace_caps; /* userspace must be aware of these */ 446 u32 userspace_caps; /* userspace must be aware of these */
447 u32 function_caps; /* VFs must be aware of these */ 447 u32 function_caps; /* VFs must be aware of these */
448 u16 hca_core_clock;
448}; 449};
449 450
450struct mlx4_buf_list { 451struct mlx4_buf_list {