diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/fw.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 132 |
1 files changed, 102 insertions, 30 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 1d70657058a5..c69648487321 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -109,6 +109,7 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) | |||
109 | [41] = "Unicast VEP steering support", | 109 | [41] = "Unicast VEP steering support", |
110 | [42] = "Multicast VEP steering support", | 110 | [42] = "Multicast VEP steering support", |
111 | [48] = "Counters support", | 111 | [48] = "Counters support", |
112 | [59] = "Port management change event support", | ||
112 | }; | 113 | }; |
113 | int i; | 114 | int i; |
114 | 115 | ||
@@ -174,6 +175,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
174 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 | 175 | #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 |
175 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 | 176 | #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 |
176 | #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 | 177 | #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 |
178 | #define QUERY_FUNC_CAP_FMR_OFFSET 0x8 | ||
177 | #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 | 179 | #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 |
178 | #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 | 180 | #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 |
179 | #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 | 181 | #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 |
@@ -183,25 +185,44 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
183 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c | 185 | #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c |
184 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 | 186 | #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0X30 |
185 | 187 | ||
188 | #define QUERY_FUNC_CAP_FMR_FLAG 0x80 | ||
189 | #define QUERY_FUNC_CAP_FLAG_RDMA 0x40 | ||
190 | #define QUERY_FUNC_CAP_FLAG_ETH 0x80 | ||
191 | |||
192 | /* when opcode modifier = 1 */ | ||
186 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 | 193 | #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 |
194 | #define QUERY_FUNC_CAP_RDMA_PROPS_OFFSET 0x8 | ||
187 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc | 195 | #define QUERY_FUNC_CAP_ETH_PROPS_OFFSET 0xc |
188 | 196 | ||
197 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC 0x40 | ||
198 | #define QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN 0x80 | ||
199 | |||
200 | #define QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID 0x80 | ||
201 | |||
189 | if (vhcr->op_modifier == 1) { | 202 | if (vhcr->op_modifier == 1) { |
190 | field = vhcr->in_modifier; | 203 | field = vhcr->in_modifier; |
191 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 204 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
192 | 205 | ||
193 | field = 0; /* ensure fvl bit is not set */ | 206 | field = 0; |
207 | /* ensure force vlan and force mac bits are not set */ | ||
194 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 208 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
209 | /* ensure that phy_wqe_gid bit is not set */ | ||
210 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | ||
211 | |||
195 | } else if (vhcr->op_modifier == 0) { | 212 | } else if (vhcr->op_modifier == 0) { |
196 | field = 1 << 7; /* enable only ethernet interface */ | 213 | /* enable rdma and ethernet interfaces */ |
214 | field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); | ||
197 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); | 215 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); |
198 | 216 | ||
199 | field = dev->caps.num_ports; | 217 | field = dev->caps.num_ports; |
200 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 218 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
201 | 219 | ||
202 | size = 0; /* no PF behavious is set for now */ | 220 | size = 0; /* no PF behaviour is set for now */ |
203 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); | 221 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); |
204 | 222 | ||
223 | field = 0; /* protected FMR support not available as yet */ | ||
224 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); | ||
225 | |||
205 | size = dev->caps.num_qps; | 226 | size = dev->caps.num_qps; |
206 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); | 227 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); |
207 | 228 | ||
@@ -254,11 +275,12 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) | |||
254 | outbox = mailbox->buf; | 275 | outbox = mailbox->buf; |
255 | 276 | ||
256 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); | 277 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); |
257 | if (!(field & (1 << 7))) { | 278 | if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { |
258 | mlx4_err(dev, "The host doesn't support eth interface\n"); | 279 | mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); |
259 | err = -EPROTONOSUPPORT; | 280 | err = -EPROTONOSUPPORT; |
260 | goto out; | 281 | goto out; |
261 | } | 282 | } |
283 | func_cap->flags = field; | ||
262 | 284 | ||
263 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 285 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
264 | func_cap->num_ports = field; | 286 | func_cap->num_ports = field; |
@@ -297,17 +319,27 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, struct mlx4_func_cap *func_cap) | |||
297 | if (err) | 319 | if (err) |
298 | goto out; | 320 | goto out; |
299 | 321 | ||
300 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); | 322 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) { |
301 | if (field & (1 << 7)) { | 323 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_ETH_PROPS_OFFSET); |
302 | mlx4_err(dev, "VLAN is enforced on this port\n"); | 324 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_VLAN) { |
303 | err = -EPROTONOSUPPORT; | 325 | mlx4_err(dev, "VLAN is enforced on this port\n"); |
304 | goto out; | 326 | err = -EPROTONOSUPPORT; |
305 | } | 327 | goto out; |
328 | } | ||
306 | 329 | ||
307 | if (field & (1 << 6)) { | 330 | if (field & QUERY_FUNC_CAP_ETH_PROPS_FORCE_MAC) { |
308 | mlx4_err(dev, "Force mac is enabled on this port\n"); | 331 | mlx4_err(dev, "Force mac is enabled on this port\n"); |
309 | err = -EPROTONOSUPPORT; | 332 | err = -EPROTONOSUPPORT; |
310 | goto out; | 333 | goto out; |
334 | } | ||
335 | } else if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) { | ||
336 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_RDMA_PROPS_OFFSET); | ||
337 | if (field & QUERY_FUNC_CAP_RDMA_PROPS_FORCE_PHY_WQE_GID) { | ||
338 | mlx4_err(dev, "phy_wqe_gid is " | ||
339 | "enforced on this ib port\n"); | ||
340 | err = -EPROTONOSUPPORT; | ||
341 | goto out; | ||
342 | } | ||
311 | } | 343 | } |
312 | 344 | ||
313 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); | 345 | MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); |
@@ -707,14 +739,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
707 | { | 739 | { |
708 | u64 def_mac; | 740 | u64 def_mac; |
709 | u8 port_type; | 741 | u8 port_type; |
742 | u16 short_field; | ||
710 | int err; | 743 | int err; |
711 | 744 | ||
712 | #define MLX4_PORT_SUPPORT_IB (1 << 0) | 745 | #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 |
713 | #define MLX4_PORT_SUGGEST_TYPE (1 << 3) | 746 | #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c |
714 | #define MLX4_PORT_DEFAULT_SENSE (1 << 4) | 747 | #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e |
715 | #define MLX4_VF_PORT_ETH_ONLY_MASK (0xff & ~MLX4_PORT_SUPPORT_IB & \ | ||
716 | ~MLX4_PORT_SUGGEST_TYPE & \ | ||
717 | ~MLX4_PORT_DEFAULT_SENSE) | ||
718 | 748 | ||
719 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, | 749 | err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, |
720 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, | 750 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, |
@@ -730,20 +760,58 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
730 | MLX4_GET(port_type, outbox->buf, | 760 | MLX4_GET(port_type, outbox->buf, |
731 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 761 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
732 | 762 | ||
733 | /* Allow only Eth port, no link sensing allowed */ | 763 | /* No link sensing allowed */ |
734 | port_type &= MLX4_VF_PORT_ETH_ONLY_MASK; | 764 | port_type &= MLX4_VF_PORT_NO_LINK_SENSE_MASK; |
735 | 765 | /* set port type to currently operating port type */ | |
736 | /* check eth is enabled for this port */ | 766 | port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); |
737 | if (!(port_type & 2)) | ||
738 | mlx4_dbg(dev, "QUERY PORT: eth not supported by host"); | ||
739 | 767 | ||
740 | MLX4_PUT(outbox->buf, port_type, | 768 | MLX4_PUT(outbox->buf, port_type, |
741 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); | 769 | QUERY_PORT_SUPPORTED_TYPE_OFFSET); |
770 | |||
771 | short_field = 1; /* slave max gids */ | ||
772 | MLX4_PUT(outbox->buf, short_field, | ||
773 | QUERY_PORT_CUR_MAX_GID_OFFSET); | ||
774 | |||
775 | short_field = dev->caps.pkey_table_len[vhcr->in_modifier]; | ||
776 | MLX4_PUT(outbox->buf, short_field, | ||
777 | QUERY_PORT_CUR_MAX_PKEY_OFFSET); | ||
742 | } | 778 | } |
743 | 779 | ||
744 | return err; | 780 | return err; |
745 | } | 781 | } |
746 | 782 | ||
783 | int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port, | ||
784 | int *gid_tbl_len, int *pkey_tbl_len) | ||
785 | { | ||
786 | struct mlx4_cmd_mailbox *mailbox; | ||
787 | u32 *outbox; | ||
788 | u16 field; | ||
789 | int err; | ||
790 | |||
791 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
792 | if (IS_ERR(mailbox)) | ||
793 | return PTR_ERR(mailbox); | ||
794 | |||
795 | err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 0, | ||
796 | MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, | ||
797 | MLX4_CMD_WRAPPED); | ||
798 | if (err) | ||
799 | goto out; | ||
800 | |||
801 | outbox = mailbox->buf; | ||
802 | |||
803 | MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_GID_OFFSET); | ||
804 | *gid_tbl_len = field; | ||
805 | |||
806 | MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_PKEY_OFFSET); | ||
807 | *pkey_tbl_len = field; | ||
808 | |||
809 | out: | ||
810 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
811 | return err; | ||
812 | } | ||
813 | EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len); | ||
814 | |||
747 | int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) | 815 | int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) |
748 | { | 816 | { |
749 | struct mlx4_cmd_mailbox *mailbox; | 817 | struct mlx4_cmd_mailbox *mailbox; |
@@ -890,11 +958,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) | |||
890 | ((fw_ver & 0xffff0000ull) >> 16) | | 958 | ((fw_ver & 0xffff0000ull) >> 16) | |
891 | ((fw_ver & 0x0000ffffull) << 16); | 959 | ((fw_ver & 0x0000ffffull) << 16); |
892 | 960 | ||
961 | MLX4_GET(lg, outbox, QUERY_FW_PPF_ID); | ||
962 | dev->caps.function = lg; | ||
963 | |||
893 | if (mlx4_is_slave(dev)) | 964 | if (mlx4_is_slave(dev)) |
894 | goto out; | 965 | goto out; |
895 | 966 | ||
896 | MLX4_GET(lg, outbox, QUERY_FW_PPF_ID); | ||
897 | dev->caps.function = lg; | ||
898 | 967 | ||
899 | MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); | 968 | MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); |
900 | if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV || | 969 | if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV || |
@@ -975,9 +1044,12 @@ int mlx4_QUERY_FW_wrapper(struct mlx4_dev *dev, int slave, | |||
975 | if (err) | 1044 | if (err) |
976 | return err; | 1045 | return err; |
977 | 1046 | ||
978 | /* for slaves, zero out everything except FW version */ | 1047 | /* for slaves, set pci PPF ID to invalid and zero out everything |
1048 | * else except FW version */ | ||
979 | outbuf[0] = outbuf[1] = 0; | 1049 | outbuf[0] = outbuf[1] = 0; |
980 | memset(&outbuf[8], 0, QUERY_FW_OUT_SIZE - 8); | 1050 | memset(&outbuf[8], 0, QUERY_FW_OUT_SIZE - 8); |
1051 | outbuf[QUERY_FW_PPF_ID] = MLX4_INVALID_SLAVE_ID; | ||
1052 | |||
981 | return 0; | 1053 | return 0; |
982 | } | 1054 | } |
983 | 1055 | ||