diff options
| -rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 52 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 144 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/profile.c | 19 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 4 |
7 files changed, 190 insertions, 42 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 8b72cf392b34..0c3375524a64 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -1975,8 +1975,7 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1975 | dev->caps.num_ports > dev->caps.comp_pool) | 1975 | dev->caps.num_ports > dev->caps.comp_pool) |
| 1976 | return; | 1976 | return; |
| 1977 | 1977 | ||
| 1978 | eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ | 1978 | eq_per_port = dev->caps.comp_pool / dev->caps.num_ports; |
| 1979 | dev->caps.num_ports); | ||
| 1980 | 1979 | ||
| 1981 | /* Init eq table */ | 1980 | /* Init eq table */ |
| 1982 | added_eqs = 0; | 1981 | added_eqs = 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 49290a405903..d68b264cee4d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
| @@ -1123,8 +1123,12 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) | |||
| 1123 | goto err_out_free; | 1123 | goto err_out_free; |
| 1124 | } | 1124 | } |
| 1125 | 1125 | ||
| 1126 | err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs, | 1126 | err = mlx4_bitmap_init(&priv->eq_table.bitmap, |
| 1127 | dev->caps.num_eqs - 1, dev->caps.reserved_eqs, 0); | 1127 | roundup_pow_of_two(dev->caps.num_eqs), |
| 1128 | dev->caps.num_eqs - 1, | ||
| 1129 | dev->caps.reserved_eqs, | ||
| 1130 | roundup_pow_of_two(dev->caps.num_eqs) - | ||
| 1131 | dev->caps.num_eqs); | ||
| 1128 | if (err) | 1132 | if (err) |
| 1129 | goto err_out_free; | 1133 | goto err_out_free; |
| 1130 | 1134 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index b3bbeb97da14..d2f594fadfbf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
| @@ -142,7 +142,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) | |||
| 142 | [13] = "Large cache line (>64B) EQE stride support", | 142 | [13] = "Large cache line (>64B) EQE stride support", |
| 143 | [14] = "Ethernet protocol control support", | 143 | [14] = "Ethernet protocol control support", |
| 144 | [15] = "Ethernet Backplane autoneg support", | 144 | [15] = "Ethernet Backplane autoneg support", |
| 145 | [16] = "CONFIG DEV support" | 145 | [16] = "CONFIG DEV support", |
| 146 | [17] = "Asymmetric EQs support" | ||
| 146 | }; | 147 | }; |
| 147 | int i; | 148 | int i; |
| 148 | 149 | ||
| @@ -200,7 +201,6 @@ int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave) | |||
| 200 | outbox = mailbox->buf; | 201 | outbox = mailbox->buf; |
| 201 | 202 | ||
| 202 | in_modifier = slave; | 203 | in_modifier = slave; |
| 203 | mlx4_dbg(dev, "%s for VF %d\n", __func__, in_modifier); | ||
| 204 | 204 | ||
| 205 | err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, | 205 | err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, |
| 206 | MLX4_CMD_QUERY_FUNC, | 206 | MLX4_CMD_QUERY_FUNC, |
| @@ -243,6 +243,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 243 | u8 field, port; | 243 | u8 field, port; |
| 244 | u32 size, proxy_qp, qkey; | 244 | u32 size, proxy_qp, qkey; |
| 245 | int err = 0; | 245 | int err = 0; |
| 246 | struct mlx4_func func; | ||
| 246 | 247 | ||
| 247 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 | 248 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 |
| 248 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 | 249 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 |
| @@ -287,6 +288,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 287 | #define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 | 288 | #define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 |
| 288 | 289 | ||
| 289 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 | 290 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 |
| 291 | #define QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS (1 << 31) | ||
| 290 | 292 | ||
| 291 | if (vhcr->op_modifier == 1) { | 293 | if (vhcr->op_modifier == 1) { |
| 292 | struct mlx4_active_ports actv_ports = | 294 | struct mlx4_active_ports actv_ports = |
| @@ -365,11 +367,24 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
| 365 | size = dev->caps.num_cqs; | 367 | size = dev->caps.num_cqs; |
| 366 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); | 368 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); |
| 367 | 369 | ||
| 368 | size = dev->caps.num_eqs; | 370 | if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) || |
| 369 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); | 371 | mlx4_QUERY_FUNC(dev, &func, slave)) { |
| 370 | 372 | size = vhcr->in_modifier & | |
| 371 | size = dev->caps.reserved_eqs; | 373 | QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? |
| 372 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); | 374 | dev->caps.num_eqs : |
| 375 | rounddown_pow_of_two(dev->caps.num_eqs); | ||
| 376 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); | ||
| 377 | size = dev->caps.reserved_eqs; | ||
| 378 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); | ||
| 379 | } else { | ||
| 380 | size = vhcr->in_modifier & | ||
| 381 | QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? | ||
| 382 | func.max_eq : | ||
| 383 | rounddown_pow_of_two(func.max_eq); | ||
| 384 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); | ||
| 385 | size = func.rsvd_eqs; | ||
| 386 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); | ||
| 387 | } | ||
| 373 | 388 | ||
| 374 | size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; | 389 | size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; |
| 375 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); | 390 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); |
| @@ -399,14 +414,17 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, | |||
| 399 | u8 field, op_modifier; | 414 | u8 field, op_modifier; |
| 400 | u32 size, qkey; | 415 | u32 size, qkey; |
| 401 | int err = 0, quotas = 0; | 416 | int err = 0, quotas = 0; |
| 417 | u32 in_modifier; | ||
| 402 | 418 | ||
| 403 | op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ | 419 | op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ |
| 420 | in_modifier = op_modifier ? gen_or_port : | ||
| 421 | QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS; | ||
| 404 | 422 | ||
| 405 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 423 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
| 406 | if (IS_ERR(mailbox)) | 424 | if (IS_ERR(mailbox)) |
| 407 | return PTR_ERR(mailbox); | 425 | return PTR_ERR(mailbox); |
| 408 | 426 | ||
| 409 | err = mlx4_cmd_box(dev, 0, mailbox->dma, gen_or_port, op_modifier, | 427 | err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, op_modifier, |
| 410 | MLX4_CMD_QUERY_FUNC_CAP, | 428 | MLX4_CMD_QUERY_FUNC_CAP, |
| 411 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); | 429 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); |
| 412 | if (err) | 430 | if (err) |
| @@ -578,6 +596,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 578 | #define QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET 0x21 | 596 | #define QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET 0x21 |
| 579 | #define QUERY_DEV_CAP_RSVD_MRW_OFFSET 0x22 | 597 | #define QUERY_DEV_CAP_RSVD_MRW_OFFSET 0x22 |
| 580 | #define QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET 0x23 | 598 | #define QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET 0x23 |
| 599 | #define QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET 0x26 | ||
| 581 | #define QUERY_DEV_CAP_MAX_AV_OFFSET 0x27 | 600 | #define QUERY_DEV_CAP_MAX_AV_OFFSET 0x27 |
| 582 | #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 | 601 | #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 |
| 583 | #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b | 602 | #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b |
| @@ -678,6 +697,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 678 | dev_cap->reserved_mrws = 1 << (field & 0xf); | 697 | dev_cap->reserved_mrws = 1 << (field & 0xf); |
| 679 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET); | 698 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET); |
| 680 | dev_cap->max_mtt_seg = 1 << (field & 0x3f); | 699 | dev_cap->max_mtt_seg = 1 << (field & 0x3f); |
| 700 | MLX4_GET(size, outbox, QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET); | ||
| 701 | dev_cap->num_sys_eqs = size & 0xfff; | ||
| 681 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET); | 702 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET); |
| 682 | dev_cap->max_requester_per_qp = 1 << (field & 0x3f); | 703 | dev_cap->max_requester_per_qp = 1 << (field & 0x3f); |
| 683 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RES_QP_OFFSET); | 704 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RES_QP_OFFSET); |
| @@ -905,8 +926,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 905 | * we can't use any EQs whose doorbell falls on that page, | 926 | * we can't use any EQs whose doorbell falls on that page, |
| 906 | * even if the EQ itself isn't reserved. | 927 | * even if the EQ itself isn't reserved. |
| 907 | */ | 928 | */ |
| 908 | dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, | 929 | if (dev_cap->num_sys_eqs == 0) |
| 909 | dev_cap->reserved_eqs); | 930 | dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, |
| 931 | dev_cap->reserved_eqs); | ||
| 932 | else | ||
| 933 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS; | ||
| 910 | 934 | ||
| 911 | mlx4_dbg(dev, "Max ICM size %lld MB\n", | 935 | mlx4_dbg(dev, "Max ICM size %lld MB\n", |
| 912 | (unsigned long long) dev_cap->max_icm_sz >> 20); | 936 | (unsigned long long) dev_cap->max_icm_sz >> 20); |
| @@ -916,8 +940,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 916 | dev_cap->max_srqs, dev_cap->reserved_srqs, dev_cap->srq_entry_sz); | 940 | dev_cap->max_srqs, dev_cap->reserved_srqs, dev_cap->srq_entry_sz); |
| 917 | mlx4_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", | 941 | mlx4_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", |
| 918 | dev_cap->max_cqs, dev_cap->reserved_cqs, dev_cap->cqc_entry_sz); | 942 | dev_cap->max_cqs, dev_cap->reserved_cqs, dev_cap->cqc_entry_sz); |
| 919 | mlx4_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", | 943 | mlx4_dbg(dev, "Num sys EQs: %d, max EQs: %d, reserved EQs: %d, entry size: %d\n", |
| 920 | dev_cap->max_eqs, dev_cap->reserved_eqs, dev_cap->eqc_entry_sz); | 944 | dev_cap->num_sys_eqs, dev_cap->max_eqs, dev_cap->reserved_eqs, |
| 945 | dev_cap->eqc_entry_sz); | ||
| 921 | mlx4_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", | 946 | mlx4_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", |
| 922 | dev_cap->reserved_mrws, dev_cap->reserved_mtts); | 947 | dev_cap->reserved_mrws, dev_cap->reserved_mtts); |
| 923 | mlx4_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", | 948 | mlx4_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", |
| @@ -1463,6 +1488,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
| 1463 | #define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) | 1488 | #define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) |
| 1464 | #define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) | 1489 | #define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) |
| 1465 | #define INIT_HCA_LOG_EQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x67) | 1490 | #define INIT_HCA_LOG_EQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x67) |
| 1491 | #define INIT_HCA_NUM_SYS_EQS_OFFSET (INIT_HCA_QPC_OFFSET + 0x6a) | ||
| 1466 | #define INIT_HCA_RDMARC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x70) | 1492 | #define INIT_HCA_RDMARC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x70) |
| 1467 | #define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) | 1493 | #define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) |
| 1468 | #define INIT_HCA_MCAST_OFFSET 0x0c0 | 1494 | #define INIT_HCA_MCAST_OFFSET 0x0c0 |
| @@ -1566,6 +1592,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
| 1566 | MLX4_PUT(inbox, param->auxc_base, INIT_HCA_AUXC_BASE_OFFSET); | 1592 | MLX4_PUT(inbox, param->auxc_base, INIT_HCA_AUXC_BASE_OFFSET); |
| 1567 | MLX4_PUT(inbox, param->eqc_base, INIT_HCA_EQC_BASE_OFFSET); | 1593 | MLX4_PUT(inbox, param->eqc_base, INIT_HCA_EQC_BASE_OFFSET); |
| 1568 | MLX4_PUT(inbox, param->log_num_eqs, INIT_HCA_LOG_EQ_OFFSET); | 1594 | MLX4_PUT(inbox, param->log_num_eqs, INIT_HCA_LOG_EQ_OFFSET); |
| 1595 | MLX4_PUT(inbox, param->num_sys_eqs, INIT_HCA_NUM_SYS_EQS_OFFSET); | ||
| 1569 | MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); | 1596 | MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); |
| 1570 | MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); | 1597 | MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); |
| 1571 | 1598 | ||
| @@ -1676,6 +1703,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
| 1676 | MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); | 1703 | MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); |
| 1677 | MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); | 1704 | MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); |
| 1678 | MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); | 1705 | MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); |
| 1706 | MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); | ||
| 1679 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); | 1707 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); |
| 1680 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); | 1708 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); |
| 1681 | 1709 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 48c11b5e73e7..475215ee370f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
| @@ -56,6 +56,7 @@ struct mlx4_dev_cap { | |||
| 56 | int max_mpts; | 56 | int max_mpts; |
| 57 | int reserved_eqs; | 57 | int reserved_eqs; |
| 58 | int max_eqs; | 58 | int max_eqs; |
| 59 | int num_sys_eqs; | ||
| 59 | int reserved_mtts; | 60 | int reserved_mtts; |
| 60 | int max_mrw_sz; | 61 | int max_mrw_sz; |
| 61 | int reserved_mrws; | 62 | int reserved_mrws; |
| @@ -180,6 +181,7 @@ struct mlx4_init_hca_param { | |||
| 180 | u8 log_num_srqs; | 181 | u8 log_num_srqs; |
| 181 | u8 log_num_cqs; | 182 | u8 log_num_cqs; |
| 182 | u8 log_num_eqs; | 183 | u8 log_num_eqs; |
| 184 | u16 num_sys_eqs; | ||
| 183 | u8 log_rd_per_qp; | 185 | u8 log_rd_per_qp; |
| 184 | u8 log_mc_table_sz; | 186 | u8 log_mc_table_sz; |
| 185 | u8 log_mpt_sz; | 187 | u8 log_mpt_sz; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 43047b2a2aac..ebb279060a25 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -197,6 +197,29 @@ static void mlx4_set_port_mask(struct mlx4_dev *dev) | |||
| 197 | dev->caps.port_mask[i] = dev->caps.port_type[i]; | 197 | dev->caps.port_mask[i] = dev->caps.port_type[i]; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | enum { | ||
| 201 | MLX4_QUERY_FUNC_NUM_SYS_EQS = 1 << 0, | ||
| 202 | }; | ||
| 203 | |||
| 204 | static int mlx4_query_func(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | ||
| 205 | { | ||
| 206 | int err = 0; | ||
| 207 | struct mlx4_func func; | ||
| 208 | |||
| 209 | if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { | ||
| 210 | err = mlx4_QUERY_FUNC(dev, &func, 0); | ||
| 211 | if (err) { | ||
| 212 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); | ||
| 213 | return err; | ||
| 214 | } | ||
| 215 | dev_cap->max_eqs = func.max_eq; | ||
| 216 | dev_cap->reserved_eqs = func.rsvd_eqs; | ||
| 217 | dev_cap->reserved_uars = func.rsvd_uars; | ||
| 218 | err |= MLX4_QUERY_FUNC_NUM_SYS_EQS; | ||
| 219 | } | ||
| 220 | return err; | ||
| 221 | } | ||
| 222 | |||
| 200 | static void mlx4_enable_cqe_eqe_stride(struct mlx4_dev *dev) | 223 | static void mlx4_enable_cqe_eqe_stride(struct mlx4_dev *dev) |
| 201 | { | 224 | { |
| 202 | struct mlx4_caps *dev_cap = &dev->caps; | 225 | struct mlx4_caps *dev_cap = &dev->caps; |
| @@ -261,7 +284,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 261 | } | 284 | } |
| 262 | 285 | ||
| 263 | dev->caps.num_ports = dev_cap->num_ports; | 286 | dev->caps.num_ports = dev_cap->num_ports; |
| 264 | dev->phys_caps.num_phys_eqs = MLX4_MAX_EQ_NUM; | 287 | dev->caps.num_sys_eqs = dev_cap->num_sys_eqs; |
| 288 | dev->phys_caps.num_phys_eqs = dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS ? | ||
| 289 | dev->caps.num_sys_eqs : | ||
| 290 | MLX4_MAX_EQ_NUM; | ||
| 265 | for (i = 1; i <= dev->caps.num_ports; ++i) { | 291 | for (i = 1; i <= dev->caps.num_ports; ++i) { |
| 266 | dev->caps.vl_cap[i] = dev_cap->max_vl[i]; | 292 | dev->caps.vl_cap[i] = dev_cap->max_vl[i]; |
| 267 | dev->caps.ib_mtu_cap[i] = dev_cap->ib_mtu[i]; | 293 | dev->caps.ib_mtu_cap[i] = dev_cap->ib_mtu[i]; |
| @@ -1130,8 +1156,7 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base, | |||
| 1130 | if (err) | 1156 | if (err) |
| 1131 | goto err_srq; | 1157 | goto err_srq; |
| 1132 | 1158 | ||
| 1133 | num_eqs = (mlx4_is_master(dev)) ? dev->phys_caps.num_phys_eqs : | 1159 | num_eqs = dev->phys_caps.num_phys_eqs; |
| 1134 | dev->caps.num_eqs; | ||
| 1135 | err = mlx4_init_icm_table(dev, &priv->eq_table.cmpt_table, | 1160 | err = mlx4_init_icm_table(dev, &priv->eq_table.cmpt_table, |
| 1136 | cmpt_base + | 1161 | cmpt_base + |
| 1137 | ((u64) (MLX4_CMPT_TYPE_EQ * | 1162 | ((u64) (MLX4_CMPT_TYPE_EQ * |
| @@ -1193,8 +1218,7 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, | |||
| 1193 | } | 1218 | } |
| 1194 | 1219 | ||
| 1195 | 1220 | ||
| 1196 | num_eqs = (mlx4_is_master(dev)) ? dev->phys_caps.num_phys_eqs : | 1221 | num_eqs = dev->phys_caps.num_phys_eqs; |
| 1197 | dev->caps.num_eqs; | ||
| 1198 | err = mlx4_init_icm_table(dev, &priv->eq_table.table, | 1222 | err = mlx4_init_icm_table(dev, &priv->eq_table.table, |
| 1199 | init_hca->eqc_base, dev_cap->eqc_entry_sz, | 1223 | init_hca->eqc_base, dev_cap->eqc_entry_sz, |
| 1200 | num_eqs, num_eqs, 0, 0); | 1224 | num_eqs, num_eqs, 0, 0); |
| @@ -1719,6 +1743,19 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
| 1719 | mlx4_err(dev, "INIT_HCA command failed, aborting\n"); | 1743 | mlx4_err(dev, "INIT_HCA command failed, aborting\n"); |
| 1720 | goto err_free_icm; | 1744 | goto err_free_icm; |
| 1721 | } | 1745 | } |
| 1746 | |||
| 1747 | if (dev_cap.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { | ||
| 1748 | err = mlx4_query_func(dev, &dev_cap); | ||
| 1749 | if (err < 0) { | ||
| 1750 | mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); | ||
| 1751 | goto err_stop_fw; | ||
| 1752 | } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { | ||
| 1753 | dev->caps.num_eqs = dev_cap.max_eqs; | ||
| 1754 | dev->caps.reserved_eqs = dev_cap.reserved_eqs; | ||
| 1755 | dev->caps.reserved_uars = dev_cap.reserved_uars; | ||
| 1756 | } | ||
| 1757 | } | ||
| 1758 | |||
| 1722 | /* | 1759 | /* |
| 1723 | * If TS is supported by FW | 1760 | * If TS is supported by FW |
| 1724 | * read HCA frequency by QUERY_HCA command | 1761 | * read HCA frequency by QUERY_HCA command |
| @@ -2085,12 +2122,11 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) | |||
| 2085 | { | 2122 | { |
| 2086 | struct mlx4_priv *priv = mlx4_priv(dev); | 2123 | struct mlx4_priv *priv = mlx4_priv(dev); |
| 2087 | struct msix_entry *entries; | 2124 | struct msix_entry *entries; |
| 2088 | int nreq = min_t(int, dev->caps.num_ports * | ||
| 2089 | min_t(int, num_online_cpus() + 1, | ||
| 2090 | MAX_MSIX_P_PORT) + MSIX_LEGACY_SZ, MAX_MSIX); | ||
| 2091 | int i; | 2125 | int i; |
| 2092 | 2126 | ||
| 2093 | if (msi_x) { | 2127 | if (msi_x) { |
| 2128 | int nreq = dev->caps.num_ports * num_online_cpus() + MSIX_LEGACY_SZ; | ||
| 2129 | |||
| 2094 | nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, | 2130 | nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, |
| 2095 | nreq); | 2131 | nreq); |
| 2096 | 2132 | ||
| @@ -2345,6 +2381,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, | |||
| 2345 | int err; | 2381 | int err; |
| 2346 | int port; | 2382 | int port; |
| 2347 | int i; | 2383 | int i; |
| 2384 | struct mlx4_dev_cap *dev_cap = NULL; | ||
| 2348 | int existing_vfs = 0; | 2385 | int existing_vfs = 0; |
| 2349 | 2386 | ||
| 2350 | dev = &priv->dev; | 2387 | dev = &priv->dev; |
| @@ -2381,15 +2418,6 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, | |||
| 2381 | } | 2418 | } |
| 2382 | } | 2419 | } |
| 2383 | 2420 | ||
| 2384 | if (total_vfs) { | ||
| 2385 | existing_vfs = pci_num_vf(pdev); | ||
| 2386 | dev->flags = MLX4_FLAG_MASTER; | ||
| 2387 | dev->flags = mlx4_enable_sriov(dev, pdev, total_vfs, | ||
| 2388 | existing_vfs); | ||
| 2389 | if (!SRIOV_VALID_STATE(dev->flags)) | ||
| 2390 | goto err_sriov; | ||
| 2391 | } | ||
| 2392 | |||
| 2393 | atomic_set(&priv->opreq_count, 0); | 2421 | atomic_set(&priv->opreq_count, 0); |
| 2394 | INIT_WORK(&priv->opreq_task, mlx4_opreq_action); | 2422 | INIT_WORK(&priv->opreq_task, mlx4_opreq_action); |
| 2395 | 2423 | ||
| @@ -2403,6 +2431,12 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, | |||
| 2403 | mlx4_err(dev, "Failed to reset HCA, aborting\n"); | 2431 | mlx4_err(dev, "Failed to reset HCA, aborting\n"); |
| 2404 | goto err_sriov; | 2432 | goto err_sriov; |
| 2405 | } | 2433 | } |
| 2434 | |||
| 2435 | if (total_vfs) { | ||
| 2436 | existing_vfs = pci_num_vf(pdev); | ||
| 2437 | dev->flags = MLX4_FLAG_MASTER; | ||
| 2438 | dev->num_vfs = total_vfs; | ||
| 2439 | } | ||
| 2406 | } | 2440 | } |
| 2407 | 2441 | ||
| 2408 | slave_start: | 2442 | slave_start: |
| @@ -2416,9 +2450,10 @@ slave_start: | |||
| 2416 | * before posting commands. Also, init num_slaves before calling | 2450 | * before posting commands. Also, init num_slaves before calling |
| 2417 | * mlx4_init_hca */ | 2451 | * mlx4_init_hca */ |
| 2418 | if (mlx4_is_mfunc(dev)) { | 2452 | if (mlx4_is_mfunc(dev)) { |
| 2419 | if (mlx4_is_master(dev)) | 2453 | if (mlx4_is_master(dev)) { |
| 2420 | dev->num_slaves = MLX4_MAX_NUM_SLAVES; | 2454 | dev->num_slaves = MLX4_MAX_NUM_SLAVES; |
| 2421 | else { | 2455 | |
| 2456 | } else { | ||
| 2422 | dev->num_slaves = 0; | 2457 | dev->num_slaves = 0; |
| 2423 | err = mlx4_multi_func_init(dev); | 2458 | err = mlx4_multi_func_init(dev); |
| 2424 | if (err) { | 2459 | if (err) { |
| @@ -2434,6 +2469,52 @@ slave_start: | |||
| 2434 | goto err_mfunc; | 2469 | goto err_mfunc; |
| 2435 | } | 2470 | } |
| 2436 | 2471 | ||
| 2472 | if (mlx4_is_master(dev)) { | ||
| 2473 | if (!dev_cap) { | ||
| 2474 | dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); | ||
| 2475 | |||
| 2476 | if (!dev_cap) { | ||
| 2477 | err = -ENOMEM; | ||
| 2478 | goto err_fw; | ||
| 2479 | } | ||
| 2480 | |||
| 2481 | err = mlx4_QUERY_DEV_CAP(dev, dev_cap); | ||
| 2482 | if (err) { | ||
| 2483 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); | ||
| 2484 | goto err_fw; | ||
| 2485 | } | ||
| 2486 | |||
| 2487 | if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) { | ||
| 2488 | u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs, | ||
| 2489 | existing_vfs); | ||
| 2490 | |||
| 2491 | mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); | ||
| 2492 | dev->flags = dev_flags; | ||
| 2493 | if (!SRIOV_VALID_STATE(dev->flags)) { | ||
| 2494 | mlx4_err(dev, "Invalid SRIOV state\n"); | ||
| 2495 | goto err_sriov; | ||
| 2496 | } | ||
| 2497 | err = mlx4_reset(dev); | ||
| 2498 | if (err) { | ||
| 2499 | mlx4_err(dev, "Failed to reset HCA, aborting.\n"); | ||
| 2500 | goto err_sriov; | ||
| 2501 | } | ||
| 2502 | goto slave_start; | ||
| 2503 | } | ||
| 2504 | } else { | ||
| 2505 | /* Legacy mode FW requires SRIOV to be enabled before | ||
| 2506 | * doing QUERY_DEV_CAP, since max_eq's value is different if | ||
| 2507 | * SRIOV is enabled. | ||
| 2508 | */ | ||
| 2509 | memset(dev_cap, 0, sizeof(*dev_cap)); | ||
| 2510 | err = mlx4_QUERY_DEV_CAP(dev, dev_cap); | ||
| 2511 | if (err) { | ||
| 2512 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); | ||
| 2513 | goto err_fw; | ||
| 2514 | } | ||
| 2515 | } | ||
| 2516 | } | ||
| 2517 | |||
| 2437 | err = mlx4_init_hca(dev); | 2518 | err = mlx4_init_hca(dev); |
| 2438 | if (err) { | 2519 | if (err) { |
| 2439 | if (err == -EACCES) { | 2520 | if (err == -EACCES) { |
| @@ -2457,6 +2538,30 @@ slave_start: | |||
| 2457 | goto err_fw; | 2538 | goto err_fw; |
| 2458 | } | 2539 | } |
| 2459 | 2540 | ||
| 2541 | if (mlx4_is_master(dev) && (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) { | ||
| 2542 | u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs, existing_vfs); | ||
| 2543 | |||
| 2544 | if ((dev->flags ^ dev_flags) & (MLX4_FLAG_MASTER | MLX4_FLAG_SLAVE)) { | ||
| 2545 | mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_VHCR); | ||
| 2546 | dev->flags = dev_flags; | ||
| 2547 | err = mlx4_cmd_init(dev); | ||
| 2548 | if (err) { | ||
| 2549 | /* Only VHCR is cleaned up, so could still | ||
| 2550 | * send FW commands | ||
| 2551 | */ | ||
| 2552 | mlx4_err(dev, "Failed to init VHCR command interface, aborting\n"); | ||
| 2553 | goto err_close; | ||
| 2554 | } | ||
| 2555 | } else { | ||
| 2556 | dev->flags = dev_flags; | ||
| 2557 | } | ||
| 2558 | |||
| 2559 | if (!SRIOV_VALID_STATE(dev->flags)) { | ||
| 2560 | mlx4_err(dev, "Invalid SRIOV state\n"); | ||
| 2561 | goto err_close; | ||
| 2562 | } | ||
| 2563 | } | ||
| 2564 | |||
| 2460 | /* check if the device is functioning at its maximum possible speed. | 2565 | /* check if the device is functioning at its maximum possible speed. |
| 2461 | * No return code for this call, just warn the user in case of PCI | 2566 | * No return code for this call, just warn the user in case of PCI |
| 2462 | * express device capabilities are under-satisfied by the bus. | 2567 | * express device capabilities are under-satisfied by the bus. |
| @@ -2631,6 +2736,7 @@ err_sriov: | |||
| 2631 | if (!mlx4_is_slave(dev)) | 2736 | if (!mlx4_is_slave(dev)) |
| 2632 | mlx4_free_ownership(dev); | 2737 | mlx4_free_ownership(dev); |
| 2633 | 2738 | ||
| 2739 | kfree(dev_cap); | ||
| 2634 | return err; | 2740 | return err; |
| 2635 | } | 2741 | } |
| 2636 | 2742 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 14089d9e1667..2bf437aafc53 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c | |||
| @@ -126,8 +126,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
| 126 | profile[MLX4_RES_AUXC].num = request->num_qp; | 126 | profile[MLX4_RES_AUXC].num = request->num_qp; |
| 127 | profile[MLX4_RES_SRQ].num = request->num_srq; | 127 | profile[MLX4_RES_SRQ].num = request->num_srq; |
| 128 | profile[MLX4_RES_CQ].num = request->num_cq; | 128 | profile[MLX4_RES_CQ].num = request->num_cq; |
| 129 | profile[MLX4_RES_EQ].num = mlx4_is_mfunc(dev) ? | 129 | profile[MLX4_RES_EQ].num = mlx4_is_mfunc(dev) ? dev->phys_caps.num_phys_eqs : |
| 130 | dev->phys_caps.num_phys_eqs : | ||
| 131 | min_t(unsigned, dev_cap->max_eqs, MAX_MSIX); | 130 | min_t(unsigned, dev_cap->max_eqs, MAX_MSIX); |
| 132 | profile[MLX4_RES_DMPT].num = request->num_mpt; | 131 | profile[MLX4_RES_DMPT].num = request->num_mpt; |
| 133 | profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; | 132 | profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; |
| @@ -216,10 +215,18 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
| 216 | init_hca->log_num_cqs = profile[i].log_num; | 215 | init_hca->log_num_cqs = profile[i].log_num; |
| 217 | break; | 216 | break; |
| 218 | case MLX4_RES_EQ: | 217 | case MLX4_RES_EQ: |
| 219 | dev->caps.num_eqs = roundup_pow_of_two(min_t(unsigned, dev_cap->max_eqs, | 218 | if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { |
| 220 | MAX_MSIX)); | 219 | init_hca->log_num_eqs = 0x1f; |
| 221 | init_hca->eqc_base = profile[i].start; | 220 | init_hca->eqc_base = profile[i].start; |
| 222 | init_hca->log_num_eqs = ilog2(dev->caps.num_eqs); | 221 | init_hca->num_sys_eqs = dev_cap->num_sys_eqs; |
| 222 | } else { | ||
| 223 | dev->caps.num_eqs = roundup_pow_of_two( | ||
| 224 | min_t(unsigned, | ||
| 225 | dev_cap->max_eqs, | ||
| 226 | MAX_MSIX)); | ||
| 227 | init_hca->eqc_base = profile[i].start; | ||
| 228 | init_hca->log_num_eqs = ilog2(dev->caps.num_eqs); | ||
| 229 | } | ||
| 223 | break; | 230 | break; |
| 224 | case MLX4_RES_DMPT: | 231 | case MLX4_RES_DMPT: |
| 225 | dev->caps.num_mpts = profile[i].num; | 232 | dev->caps.num_mpts = profile[i].num; |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 3d9bff00f24a..1c560eb870ad 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -189,7 +189,8 @@ enum { | |||
| 189 | MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, | 189 | MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, |
| 190 | MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, | 190 | MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, |
| 191 | MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, | 191 | MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, |
| 192 | MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16 | 192 | MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, |
| 193 | MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17 | ||
| 193 | }; | 194 | }; |
| 194 | 195 | ||
| 195 | enum { | 196 | enum { |
| @@ -443,6 +444,7 @@ struct mlx4_caps { | |||
| 443 | int num_cqs; | 444 | int num_cqs; |
| 444 | int max_cqes; | 445 | int max_cqes; |
| 445 | int reserved_cqs; | 446 | int reserved_cqs; |
| 447 | int num_sys_eqs; | ||
| 446 | int num_eqs; | 448 | int num_eqs; |
| 447 | int reserved_eqs; | 449 | int reserved_eqs; |
| 448 | int num_comp_vectors; | 450 | int num_comp_vectors; |
