diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-10 18:21:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-10 18:21:38 -0400 |
commit | 7319a1a49781d6b845e541d13fd2e5d1303ec18b (patch) | |
tree | 3c53380e7f88e1efaccab548a2e2f91527b5652b | |
parent | a0e2c822bf0a1095dc250b5875e39ac0662a5df6 (diff) | |
parent | 09e05c3f78e9e82bda5958eb95bbf719f7a0ed6b (diff) |
Merge branch 'mlx4'
Or Gerlitz says:
====================
mlx4 SRIOV fixes
This series contains few SRIOV related fixes from Matan, please apply to net.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/qp.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 38 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 1 | ||||
-rw-r--r-- | include/linux/mlx4/qp.h | 12 |
6 files changed, 71 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index af8256353c7d..162b82c1dde4 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -1680,7 +1680,7 @@ static void mlx4_ib_update_qps(struct mlx4_ib_dev *ibdev, | |||
1680 | goto unlock; | 1680 | goto unlock; |
1681 | 1681 | ||
1682 | update_params.smac_index = new_smac_index; | 1682 | update_params.smac_index = new_smac_index; |
1683 | if (mlx4_update_qp(ibdev->dev, &qp->mqp, MLX4_UPDATE_QP_SMAC, | 1683 | if (mlx4_update_qp(ibdev->dev, qp->mqp.qpn, MLX4_UPDATE_QP_SMAC, |
1684 | &update_params)) { | 1684 | &update_params)) { |
1685 | release_mac = new_smac; | 1685 | release_mac = new_smac; |
1686 | goto unlock; | 1686 | goto unlock; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 65a4a0f88ea0..02a2e90d581a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -2389,6 +2389,22 @@ struct mlx4_slaves_pport mlx4_phys_to_slaves_pport_actv( | |||
2389 | } | 2389 | } |
2390 | EXPORT_SYMBOL_GPL(mlx4_phys_to_slaves_pport_actv); | 2390 | EXPORT_SYMBOL_GPL(mlx4_phys_to_slaves_pport_actv); |
2391 | 2391 | ||
2392 | static int mlx4_slaves_closest_port(struct mlx4_dev *dev, int slave, int port) | ||
2393 | { | ||
2394 | struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave); | ||
2395 | int min_port = find_first_bit(actv_ports.ports, dev->caps.num_ports) | ||
2396 | + 1; | ||
2397 | int max_port = min_port + | ||
2398 | bitmap_weight(actv_ports.ports, dev->caps.num_ports); | ||
2399 | |||
2400 | if (port < min_port) | ||
2401 | port = min_port; | ||
2402 | else if (port >= max_port) | ||
2403 | port = max_port - 1; | ||
2404 | |||
2405 | return port; | ||
2406 | } | ||
2407 | |||
2392 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | 2408 | int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) |
2393 | { | 2409 | { |
2394 | struct mlx4_priv *priv = mlx4_priv(dev); | 2410 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -2402,6 +2418,7 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | |||
2402 | if (slave < 0) | 2418 | if (slave < 0) |
2403 | return -EINVAL; | 2419 | return -EINVAL; |
2404 | 2420 | ||
2421 | port = mlx4_slaves_closest_port(dev, slave, port); | ||
2405 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | 2422 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; |
2406 | s_info->mac = mac; | 2423 | s_info->mac = mac; |
2407 | mlx4_info(dev, "default mac on vf %d port %d to %llX will take afect only after vf restart\n", | 2424 | mlx4_info(dev, "default mac on vf %d port %d to %llX will take afect only after vf restart\n", |
@@ -2428,6 +2445,7 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos) | |||
2428 | if (slave < 0) | 2445 | if (slave < 0) |
2429 | return -EINVAL; | 2446 | return -EINVAL; |
2430 | 2447 | ||
2448 | port = mlx4_slaves_closest_port(dev, slave, port); | ||
2431 | vf_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; | 2449 | vf_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; |
2432 | 2450 | ||
2433 | if ((0 == vlan) && (0 == qos)) | 2451 | if ((0 == vlan) && (0 == qos)) |
@@ -2455,6 +2473,7 @@ bool mlx4_get_slave_default_vlan(struct mlx4_dev *dev, int port, int slave, | |||
2455 | struct mlx4_priv *priv; | 2473 | struct mlx4_priv *priv; |
2456 | 2474 | ||
2457 | priv = mlx4_priv(dev); | 2475 | priv = mlx4_priv(dev); |
2476 | port = mlx4_slaves_closest_port(dev, slave, port); | ||
2458 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; | 2477 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; |
2459 | 2478 | ||
2460 | if (MLX4_VGT != vp_oper->state.default_vlan) { | 2479 | if (MLX4_VGT != vp_oper->state.default_vlan) { |
@@ -2482,6 +2501,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting) | |||
2482 | if (slave < 0) | 2501 | if (slave < 0) |
2483 | return -EINVAL; | 2502 | return -EINVAL; |
2484 | 2503 | ||
2504 | port = mlx4_slaves_closest_port(dev, slave, port); | ||
2485 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | 2505 | s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; |
2486 | s_info->spoofchk = setting; | 2506 | s_info->spoofchk = setting; |
2487 | 2507 | ||
@@ -2535,6 +2555,7 @@ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_stat | |||
2535 | if (slave < 0) | 2555 | if (slave < 0) |
2536 | return -EINVAL; | 2556 | return -EINVAL; |
2537 | 2557 | ||
2558 | port = mlx4_slaves_closest_port(dev, slave, port); | ||
2538 | switch (link_state) { | 2559 | switch (link_state) { |
2539 | case IFLA_VF_LINK_STATE_AUTO: | 2560 | case IFLA_VF_LINK_STATE_AUTO: |
2540 | /* get current link state */ | 2561 | /* get current link state */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 0dc31d85fc3b..2301365c79c7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
@@ -390,13 +390,14 @@ err_icm: | |||
390 | EXPORT_SYMBOL_GPL(mlx4_qp_alloc); | 390 | EXPORT_SYMBOL_GPL(mlx4_qp_alloc); |
391 | 391 | ||
392 | #define MLX4_UPDATE_QP_SUPPORTED_ATTRS MLX4_UPDATE_QP_SMAC | 392 | #define MLX4_UPDATE_QP_SUPPORTED_ATTRS MLX4_UPDATE_QP_SMAC |
393 | int mlx4_update_qp(struct mlx4_dev *dev, struct mlx4_qp *qp, | 393 | int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, |
394 | enum mlx4_update_qp_attr attr, | 394 | enum mlx4_update_qp_attr attr, |
395 | struct mlx4_update_qp_params *params) | 395 | struct mlx4_update_qp_params *params) |
396 | { | 396 | { |
397 | struct mlx4_cmd_mailbox *mailbox; | 397 | struct mlx4_cmd_mailbox *mailbox; |
398 | struct mlx4_update_qp_context *cmd; | 398 | struct mlx4_update_qp_context *cmd; |
399 | u64 pri_addr_path_mask = 0; | 399 | u64 pri_addr_path_mask = 0; |
400 | u64 qp_mask = 0; | ||
400 | int err = 0; | 401 | int err = 0; |
401 | 402 | ||
402 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 403 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
@@ -413,9 +414,16 @@ int mlx4_update_qp(struct mlx4_dev *dev, struct mlx4_qp *qp, | |||
413 | cmd->qp_context.pri_path.grh_mylmc = params->smac_index; | 414 | cmd->qp_context.pri_path.grh_mylmc = params->smac_index; |
414 | } | 415 | } |
415 | 416 | ||
417 | if (attr & MLX4_UPDATE_QP_VSD) { | ||
418 | qp_mask |= 1ULL << MLX4_UPD_QP_MASK_VSD; | ||
419 | if (params->flags & MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE) | ||
420 | cmd->qp_context.param3 |= cpu_to_be32(MLX4_STRIP_VLAN); | ||
421 | } | ||
422 | |||
416 | cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask); | 423 | cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask); |
424 | cmd->qp_mask = cpu_to_be64(qp_mask); | ||
417 | 425 | ||
418 | err = mlx4_cmd(dev, mailbox->dma, qp->qpn & 0xffffff, 0, | 426 | err = mlx4_cmd(dev, mailbox->dma, qpn & 0xffffff, 0, |
419 | MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A, | 427 | MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A, |
420 | MLX4_CMD_NATIVE); | 428 | MLX4_CMD_NATIVE); |
421 | 429 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1089367fed22..5d2498dcf536 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -702,11 +702,13 @@ static int update_vport_qp_param(struct mlx4_dev *dev, | |||
702 | struct mlx4_qp_context *qpc = inbox->buf + 8; | 702 | struct mlx4_qp_context *qpc = inbox->buf + 8; |
703 | struct mlx4_vport_oper_state *vp_oper; | 703 | struct mlx4_vport_oper_state *vp_oper; |
704 | struct mlx4_priv *priv; | 704 | struct mlx4_priv *priv; |
705 | u32 qp_type; | ||
705 | int port; | 706 | int port; |
706 | 707 | ||
707 | port = (qpc->pri_path.sched_queue & 0x40) ? 2 : 1; | 708 | port = (qpc->pri_path.sched_queue & 0x40) ? 2 : 1; |
708 | priv = mlx4_priv(dev); | 709 | priv = mlx4_priv(dev); |
709 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; | 710 | vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; |
711 | qp_type = (be32_to_cpu(qpc->flags) >> 16) & 0xff; | ||
710 | 712 | ||
711 | if (MLX4_VGT != vp_oper->state.default_vlan) { | 713 | if (MLX4_VGT != vp_oper->state.default_vlan) { |
712 | /* the reserved QPs (special, proxy, tunnel) | 714 | /* the reserved QPs (special, proxy, tunnel) |
@@ -715,8 +717,20 @@ static int update_vport_qp_param(struct mlx4_dev *dev, | |||
715 | if (mlx4_is_qp_reserved(dev, qpn)) | 717 | if (mlx4_is_qp_reserved(dev, qpn)) |
716 | return 0; | 718 | return 0; |
717 | 719 | ||
718 | /* force strip vlan by clear vsd */ | 720 | /* force strip vlan by clear vsd, MLX QP refers to Raw Ethernet */ |
719 | qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN); | 721 | if (qp_type == MLX4_QP_ST_UD || |
722 | (qp_type == MLX4_QP_ST_MLX && mlx4_is_eth(dev, port))) { | ||
723 | if (dev->caps.bmme_flags & MLX4_BMME_FLAG_VSD_INIT2RTR) { | ||
724 | *(__be32 *)inbox->buf = | ||
725 | cpu_to_be32(be32_to_cpu(*(__be32 *)inbox->buf) | | ||
726 | MLX4_QP_OPTPAR_VLAN_STRIPPING); | ||
727 | qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN); | ||
728 | } else { | ||
729 | struct mlx4_update_qp_params params = {.flags = 0}; | ||
730 | |||
731 | mlx4_update_qp(dev, qpn, MLX4_UPDATE_QP_VSD, ¶ms); | ||
732 | } | ||
733 | } | ||
720 | 734 | ||
721 | if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE && | 735 | if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE && |
722 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) { | 736 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) { |
@@ -3998,13 +4012,17 @@ int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave, | |||
3998 | } | 4012 | } |
3999 | 4013 | ||
4000 | port = (rqp->sched_queue >> 6 & 1) + 1; | 4014 | port = (rqp->sched_queue >> 6 & 1) + 1; |
4001 | smac_index = cmd->qp_context.pri_path.grh_mylmc; | 4015 | |
4002 | err = mac_find_smac_ix_in_slave(dev, slave, port, | 4016 | if (pri_addr_path_mask & (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX)) { |
4003 | smac_index, &mac); | 4017 | smac_index = cmd->qp_context.pri_path.grh_mylmc; |
4004 | if (err) { | 4018 | err = mac_find_smac_ix_in_slave(dev, slave, port, |
4005 | mlx4_err(dev, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n", | 4019 | smac_index, &mac); |
4006 | qpn, smac_index); | 4020 | |
4007 | goto err_mac; | 4021 | if (err) { |
4022 | mlx4_err(dev, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n", | ||
4023 | qpn, smac_index); | ||
4024 | goto err_mac; | ||
4025 | } | ||
4008 | } | 4026 | } |
4009 | 4027 | ||
4010 | err = mlx4_cmd(dev, inbox->dma, | 4028 | err = mlx4_cmd(dev, inbox->dma, |
@@ -4818,7 +4836,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) | |||
4818 | MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; | 4836 | MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; |
4819 | 4837 | ||
4820 | upd_context = mailbox->buf; | 4838 | upd_context = mailbox->buf; |
4821 | upd_context->qp_mask = cpu_to_be64(MLX4_UPD_QP_MASK_VSD); | 4839 | upd_context->qp_mask = cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_VSD); |
4822 | 4840 | ||
4823 | spin_lock_irq(mlx4_tlock(dev)); | 4841 | spin_lock_irq(mlx4_tlock(dev)); |
4824 | list_for_each_entry_safe(qp, tmp, qp_list, com.list) { | 4842 | list_for_each_entry_safe(qp, tmp, qp_list, com.list) { |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 511c6e0d21a9..a5b7d7cfcedf 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -209,6 +209,7 @@ enum { | |||
209 | MLX4_BMME_FLAG_TYPE_2_WIN = 1 << 9, | 209 | MLX4_BMME_FLAG_TYPE_2_WIN = 1 << 9, |
210 | MLX4_BMME_FLAG_RESERVED_LKEY = 1 << 10, | 210 | MLX4_BMME_FLAG_RESERVED_LKEY = 1 << 10, |
211 | MLX4_BMME_FLAG_FAST_REG_WR = 1 << 11, | 211 | MLX4_BMME_FLAG_FAST_REG_WR = 1 << 11, |
212 | MLX4_BMME_FLAG_VSD_INIT2RTR = 1 << 28, | ||
212 | }; | 213 | }; |
213 | 214 | ||
214 | enum mlx4_event { | 215 | enum mlx4_event { |
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index 7040dc98ff8b..5f4e36cf0091 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h | |||
@@ -56,7 +56,8 @@ enum mlx4_qp_optpar { | |||
56 | MLX4_QP_OPTPAR_RNR_RETRY = 1 << 13, | 56 | MLX4_QP_OPTPAR_RNR_RETRY = 1 << 13, |
57 | MLX4_QP_OPTPAR_ACK_TIMEOUT = 1 << 14, | 57 | MLX4_QP_OPTPAR_ACK_TIMEOUT = 1 << 14, |
58 | MLX4_QP_OPTPAR_SCHED_QUEUE = 1 << 16, | 58 | MLX4_QP_OPTPAR_SCHED_QUEUE = 1 << 16, |
59 | MLX4_QP_OPTPAR_COUNTER_INDEX = 1 << 20 | 59 | MLX4_QP_OPTPAR_COUNTER_INDEX = 1 << 20, |
60 | MLX4_QP_OPTPAR_VLAN_STRIPPING = 1 << 21, | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | enum mlx4_qp_state { | 63 | enum mlx4_qp_state { |
@@ -423,13 +424,20 @@ struct mlx4_wqe_inline_seg { | |||
423 | 424 | ||
424 | enum mlx4_update_qp_attr { | 425 | enum mlx4_update_qp_attr { |
425 | MLX4_UPDATE_QP_SMAC = 1 << 0, | 426 | MLX4_UPDATE_QP_SMAC = 1 << 0, |
427 | MLX4_UPDATE_QP_VSD = 1 << 2, | ||
428 | MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 2) - 1 | ||
429 | }; | ||
430 | |||
431 | enum mlx4_update_qp_params_flags { | ||
432 | MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE = 1 << 0, | ||
426 | }; | 433 | }; |
427 | 434 | ||
428 | struct mlx4_update_qp_params { | 435 | struct mlx4_update_qp_params { |
429 | u8 smac_index; | 436 | u8 smac_index; |
437 | u32 flags; | ||
430 | }; | 438 | }; |
431 | 439 | ||
432 | int mlx4_update_qp(struct mlx4_dev *dev, struct mlx4_qp *qp, | 440 | int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, |
433 | enum mlx4_update_qp_attr attr, | 441 | enum mlx4_update_qp_attr attr, |
434 | struct mlx4_update_qp_params *params); | 442 | struct mlx4_update_qp_params *params); |
435 | int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | 443 | int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, |