diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/fw.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 7e2995ecea6f..6bd33e2fc17c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -225,13 +225,25 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
225 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 | 225 | #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 |
226 | 226 | ||
227 | if (vhcr->op_modifier == 1) { | 227 | if (vhcr->op_modifier == 1) { |
228 | struct mlx4_active_ports actv_ports = | ||
229 | mlx4_get_active_ports(dev, slave); | ||
230 | int converted_port = mlx4_slave_convert_port( | ||
231 | dev, slave, vhcr->in_modifier); | ||
232 | |||
233 | if (converted_port < 0) | ||
234 | return -EINVAL; | ||
235 | |||
236 | vhcr->in_modifier = converted_port; | ||
228 | /* Set nic_info bit to mark new fields support */ | 237 | /* Set nic_info bit to mark new fields support */ |
229 | field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; | 238 | field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; |
230 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); | 239 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); |
231 | 240 | ||
232 | field = vhcr->in_modifier; /* phys-port = logical-port */ | 241 | /* phys-port = logical-port */ |
242 | field = vhcr->in_modifier - | ||
243 | find_first_bit(actv_ports.ports, dev->caps.num_ports); | ||
233 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 244 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
234 | 245 | ||
246 | field = vhcr->in_modifier; | ||
235 | /* size is now the QP number */ | 247 | /* size is now the QP number */ |
236 | size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1; | 248 | size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + field - 1; |
237 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); | 249 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); |
@@ -249,12 +261,16 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
249 | QUERY_FUNC_CAP_PHYS_PORT_ID); | 261 | QUERY_FUNC_CAP_PHYS_PORT_ID); |
250 | 262 | ||
251 | } else if (vhcr->op_modifier == 0) { | 263 | } else if (vhcr->op_modifier == 0) { |
264 | struct mlx4_active_ports actv_ports = | ||
265 | mlx4_get_active_ports(dev, slave); | ||
252 | /* enable rdma and ethernet interfaces, and new quota locations */ | 266 | /* enable rdma and ethernet interfaces, and new quota locations */ |
253 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA | | 267 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA | |
254 | QUERY_FUNC_CAP_FLAG_QUOTAS); | 268 | QUERY_FUNC_CAP_FLAG_QUOTAS); |
255 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); | 269 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); |
256 | 270 | ||
257 | field = dev->caps.num_ports; | 271 | field = min( |
272 | bitmap_weight(actv_ports.ports, dev->caps.num_ports), | ||
273 | dev->caps.num_ports); | ||
258 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 274 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
259 | 275 | ||
260 | size = dev->caps.function_caps; /* set PF behaviours */ | 276 | size = dev->caps.function_caps; /* set PF behaviours */ |
@@ -840,6 +856,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
840 | int err = 0; | 856 | int err = 0; |
841 | u8 field; | 857 | u8 field; |
842 | u32 bmme_flags; | 858 | u32 bmme_flags; |
859 | int real_port; | ||
860 | int slave_port; | ||
861 | int first_port; | ||
862 | struct mlx4_active_ports actv_ports; | ||
843 | 863 | ||
844 | err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, | 864 | err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, |
845 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); | 865 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); |
@@ -852,8 +872,26 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
852 | MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); | 872 | MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); |
853 | flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; | 873 | flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; |
854 | flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; | 874 | flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; |
875 | actv_ports = mlx4_get_active_ports(dev, slave); | ||
876 | first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports); | ||
877 | for (slave_port = 0, real_port = first_port; | ||
878 | real_port < first_port + | ||
879 | bitmap_weight(actv_ports.ports, dev->caps.num_ports); | ||
880 | ++real_port, ++slave_port) { | ||
881 | if (flags & (MLX4_DEV_CAP_FLAG_WOL_PORT1 << real_port)) | ||
882 | flags |= MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port; | ||
883 | else | ||
884 | flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); | ||
885 | } | ||
886 | for (; slave_port < dev->caps.num_ports; ++slave_port) | ||
887 | flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); | ||
855 | MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); | 888 | MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); |
856 | 889 | ||
890 | MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VL_PORT_OFFSET); | ||
891 | field &= ~0x0F; | ||
892 | field |= bitmap_weight(actv_ports.ports, dev->caps.num_ports) & 0x0F; | ||
893 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VL_PORT_OFFSET); | ||
894 | |||
857 | /* For guests, disable timestamp */ | 895 | /* For guests, disable timestamp */ |
858 | MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); | 896 | MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); |
859 | field &= 0x7f; | 897 | field &= 0x7f; |
@@ -903,12 +941,20 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
903 | u16 short_field; | 941 | u16 short_field; |
904 | int err; | 942 | int err; |
905 | int admin_link_state; | 943 | int admin_link_state; |
944 | int port = mlx4_slave_convert_port(dev, slave, | ||
945 | vhcr->in_modifier & 0xFF); | ||
906 | 946 | ||
907 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 | 947 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 |
908 | #define MLX4_PORT_LINK_UP_MASK 0x80 | 948 | #define MLX4_PORT_LINK_UP_MASK 0x80 |
909 | #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c | 949 | #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c |
910 | #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e | 950 | #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e |
911 | 951 | ||
952 | if (port < 0) | ||
953 | return -EINVAL; | ||
954 | |||
955 | vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) | | ||
956 | (port & 0xFF); | ||
957 | |||
912 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, | 958 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, |
913 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, | 959 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, |
914 | MLX4_CMD_NATIVE); | 960 | MLX4_CMD_NATIVE); |
@@ -935,7 +981,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
935 | MLX4_PUT(outbox->buf, port_type, | 981 | MLX4_PUT(outbox->buf, port_type, |
936 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 982 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
937 | 983 | ||
938 | short_field = 1; /* slave max gids */ | 984 | if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH) |
985 | short_field = mlx4_get_slave_num_gids(dev, slave, port); | ||
986 | else | ||
987 | short_field = 1; /* slave max gids */ | ||
939 | MLX4_PUT(outbox->buf, short_field, | 988 | MLX4_PUT(outbox->buf, short_field, |
940 | QUERY_PORT_CUR_MAX_GID_OFFSET); | 989 | QUERY_PORT_CUR_MAX_GID_OFFSET); |
941 | 990 | ||
@@ -1585,9 +1634,12 @@ int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
1585 | struct mlx4_cmd_info *cmd) | 1634 | struct mlx4_cmd_info *cmd) |
1586 | { | 1635 | { |
1587 | struct mlx4_priv *priv = mlx4_priv(dev); | 1636 | struct mlx4_priv *priv = mlx4_priv(dev); |
1588 | int port = vhcr->in_modifier; | 1637 | int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); |
1589 | int err; | 1638 | int err; |
1590 | 1639 | ||
1640 | if (port < 0) | ||
1641 | return -EINVAL; | ||
1642 | |||
1591 | if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)) | 1643 | if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)) |
1592 | return 0; | 1644 | return 0; |
1593 | 1645 | ||
@@ -1677,9 +1729,12 @@ int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
1677 | struct mlx4_cmd_info *cmd) | 1729 | struct mlx4_cmd_info *cmd) |
1678 | { | 1730 | { |
1679 | struct mlx4_priv *priv = mlx4_priv(dev); | 1731 | struct mlx4_priv *priv = mlx4_priv(dev); |
1680 | int port = vhcr->in_modifier; | 1732 | int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); |
1681 | int err; | 1733 | int err; |
1682 | 1734 | ||
1735 | if (port < 0) | ||
1736 | return -EINVAL; | ||
1737 | |||
1683 | if (!(priv->mfunc.master.slave_state[slave].init_port_mask & | 1738 | if (!(priv->mfunc.master.slave_state[slave].init_port_mask & |
1684 | (1 << port))) | 1739 | (1 << port))) |
1685 | return 0; | 1740 | return 0; |
@@ -1891,7 +1946,8 @@ void mlx4_opreq_action(struct work_struct *work) | |||
1891 | err = EINVAL; | 1946 | err = EINVAL; |
1892 | break; | 1947 | break; |
1893 | } | 1948 | } |
1894 | err = mlx4_cmd(dev, 0, ((u32) err | cpu_to_be32(token) << 16), | 1949 | err = mlx4_cmd(dev, 0, ((u32) err | |
1950 | (__force u32)cpu_to_be32(token) << 16), | ||
1895 | 1, MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, | 1951 | 1, MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, |
1896 | MLX4_CMD_NATIVE); | 1952 | MLX4_CMD_NATIVE); |
1897 | if (err) { | 1953 | if (err) { |