diff options
author | Matan Barak <matanb@mellanox.com> | 2014-05-15 08:29:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-16 15:12:45 -0400 |
commit | ce8d9e0d6746ff67c1870386b7121a4448f21130 (patch) | |
tree | 69663d0a46253cedb7ae0db367859ff7670719a9 | |
parent | 81c708068dfedece038e07d818ba68333d8d885d (diff) |
net/mlx4_core: Add UPDATE_QP SRIOV wrapper support
This patch adds UPDATE_QP SRIOV wrapper support.
The mechanism is a general one, but currently only source MAC
index changes are allowed for VFs.
Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/qp.c | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 54 | ||||
-rw-r--r-- | include/linux/mlx4/qp.h | 11 |
5 files changed, 108 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 78099eab7673..92d3249f63f1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1253,12 +1253,12 @@ static struct mlx4_cmd_info cmd_info[] = { | |||
1253 | }, | 1253 | }, |
1254 | { | 1254 | { |
1255 | .opcode = MLX4_CMD_UPDATE_QP, | 1255 | .opcode = MLX4_CMD_UPDATE_QP, |
1256 | .has_inbox = false, | 1256 | .has_inbox = true, |
1257 | .has_outbox = false, | 1257 | .has_outbox = false, |
1258 | .out_is_imm = false, | 1258 | .out_is_imm = false, |
1259 | .encode_slave_id = false, | 1259 | .encode_slave_id = false, |
1260 | .verify = NULL, | 1260 | .verify = NULL, |
1261 | .wrapper = mlx4_CMD_EPERM_wrapper | 1261 | .wrapper = mlx4_UPDATE_QP_wrapper |
1262 | }, | 1262 | }, |
1263 | { | 1263 | { |
1264 | .opcode = MLX4_CMD_GET_OP_REQ, | 1264 | .opcode = MLX4_CMD_GET_OP_REQ, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index f9c465101963..212cea440f90 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -1195,6 +1195,12 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
1195 | struct mlx4_cmd_mailbox *outbox, | 1195 | struct mlx4_cmd_mailbox *outbox, |
1196 | struct mlx4_cmd_info *cmd); | 1196 | struct mlx4_cmd_info *cmd); |
1197 | 1197 | ||
1198 | int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave, | ||
1199 | struct mlx4_vhcr *vhcr, | ||
1200 | struct mlx4_cmd_mailbox *inbox, | ||
1201 | struct mlx4_cmd_mailbox *outbox, | ||
1202 | struct mlx4_cmd_info *cmd); | ||
1203 | |||
1198 | int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, | 1204 | int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, |
1199 | struct mlx4_vhcr *vhcr, | 1205 | struct mlx4_vhcr *vhcr, |
1200 | struct mlx4_cmd_mailbox *inbox, | 1206 | struct mlx4_cmd_mailbox *inbox, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 61d64ebffd56..fbd32af89c7c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
@@ -389,6 +389,41 @@ err_icm: | |||
389 | 389 | ||
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 | ||
393 | int mlx4_update_qp(struct mlx4_dev *dev, struct mlx4_qp *qp, | ||
394 | enum mlx4_update_qp_attr attr, | ||
395 | struct mlx4_update_qp_params *params) | ||
396 | { | ||
397 | struct mlx4_cmd_mailbox *mailbox; | ||
398 | struct mlx4_update_qp_context *cmd; | ||
399 | u64 pri_addr_path_mask = 0; | ||
400 | int err = 0; | ||
401 | |||
402 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
403 | if (IS_ERR(mailbox)) | ||
404 | return PTR_ERR(mailbox); | ||
405 | |||
406 | cmd = (struct mlx4_update_qp_context *)mailbox->buf; | ||
407 | |||
408 | if (!attr || (attr & ~MLX4_UPDATE_QP_SUPPORTED_ATTRS)) | ||
409 | return -EINVAL; | ||
410 | |||
411 | if (attr & MLX4_UPDATE_QP_SMAC) { | ||
412 | pri_addr_path_mask |= 1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX; | ||
413 | cmd->qp_context.pri_path.grh_mylmc = params->smac_index; | ||
414 | } | ||
415 | |||
416 | cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask); | ||
417 | |||
418 | err = mlx4_cmd(dev, mailbox->dma, qp->qpn & 0xffffff, 0, | ||
419 | MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A, | ||
420 | MLX4_CMD_NATIVE); | ||
421 | |||
422 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
423 | return err; | ||
424 | } | ||
425 | EXPORT_SYMBOL_GPL(mlx4_update_qp); | ||
426 | |||
392 | void mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp) | 427 | void mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp) |
393 | { | 428 | { |
394 | struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; | 429 | struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1c3fdd4a1f7d..8f1254a79832 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -3895,6 +3895,60 @@ static int add_eth_header(struct mlx4_dev *dev, int slave, | |||
3895 | 3895 | ||
3896 | } | 3896 | } |
3897 | 3897 | ||
3898 | #define MLX4_UPD_QP_PATH_MASK_SUPPORTED (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX) | ||
3899 | int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave, | ||
3900 | struct mlx4_vhcr *vhcr, | ||
3901 | struct mlx4_cmd_mailbox *inbox, | ||
3902 | struct mlx4_cmd_mailbox *outbox, | ||
3903 | struct mlx4_cmd_info *cmd_info) | ||
3904 | { | ||
3905 | int err; | ||
3906 | u32 qpn = vhcr->in_modifier & 0xffffff; | ||
3907 | struct res_qp *rqp; | ||
3908 | u64 mac; | ||
3909 | unsigned port; | ||
3910 | u64 pri_addr_path_mask; | ||
3911 | struct mlx4_update_qp_context *cmd; | ||
3912 | int smac_index; | ||
3913 | |||
3914 | cmd = (struct mlx4_update_qp_context *)inbox->buf; | ||
3915 | |||
3916 | pri_addr_path_mask = be64_to_cpu(cmd->primary_addr_path_mask); | ||
3917 | if (cmd->qp_mask || cmd->secondary_addr_path_mask || | ||
3918 | (pri_addr_path_mask & ~MLX4_UPD_QP_PATH_MASK_SUPPORTED)) | ||
3919 | return -EPERM; | ||
3920 | |||
3921 | /* Just change the smac for the QP */ | ||
3922 | err = get_res(dev, slave, qpn, RES_QP, &rqp); | ||
3923 | if (err) { | ||
3924 | mlx4_err(dev, "Updating qpn 0x%x for slave %d rejected\n", qpn, slave); | ||
3925 | return err; | ||
3926 | } | ||
3927 | |||
3928 | port = (rqp->sched_queue >> 6 & 1) + 1; | ||
3929 | smac_index = cmd->qp_context.pri_path.grh_mylmc; | ||
3930 | err = mac_find_smac_ix_in_slave(dev, slave, port, | ||
3931 | smac_index, &mac); | ||
3932 | if (err) { | ||
3933 | mlx4_err(dev, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n", | ||
3934 | qpn, smac_index); | ||
3935 | goto err_mac; | ||
3936 | } | ||
3937 | |||
3938 | err = mlx4_cmd(dev, inbox->dma, | ||
3939 | vhcr->in_modifier, 0, | ||
3940 | MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A, | ||
3941 | MLX4_CMD_NATIVE); | ||
3942 | if (err) { | ||
3943 | mlx4_err(dev, "Failed to update qpn on qpn 0x%x, command failed\n", qpn); | ||
3944 | goto err_mac; | ||
3945 | } | ||
3946 | |||
3947 | err_mac: | ||
3948 | put_res(dev, slave, qpn, RES_QP); | ||
3949 | return err; | ||
3950 | } | ||
3951 | |||
3898 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 3952 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
3899 | struct mlx4_vhcr *vhcr, | 3953 | struct mlx4_vhcr *vhcr, |
3900 | struct mlx4_cmd_mailbox *inbox, | 3954 | struct mlx4_cmd_mailbox *inbox, |
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index b66e7610d4ee..7040dc98ff8b 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h | |||
@@ -421,6 +421,17 @@ struct mlx4_wqe_inline_seg { | |||
421 | __be32 byte_count; | 421 | __be32 byte_count; |
422 | }; | 422 | }; |
423 | 423 | ||
424 | enum mlx4_update_qp_attr { | ||
425 | MLX4_UPDATE_QP_SMAC = 1 << 0, | ||
426 | }; | ||
427 | |||
428 | struct mlx4_update_qp_params { | ||
429 | u8 smac_index; | ||
430 | }; | ||
431 | |||
432 | int mlx4_update_qp(struct mlx4_dev *dev, struct mlx4_qp *qp, | ||
433 | enum mlx4_update_qp_attr attr, | ||
434 | struct mlx4_update_qp_params *params); | ||
424 | int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | 435 | int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, |
425 | enum mlx4_qp_state cur_state, enum mlx4_qp_state new_state, | 436 | enum mlx4_qp_state cur_state, enum mlx4_qp_state new_state, |
426 | struct mlx4_qp_context *context, enum mlx4_qp_optpar optpar, | 437 | struct mlx4_qp_context *context, enum mlx4_qp_optpar optpar, |