aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/fw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/fw.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c132
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
783int 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
809out:
810 mlx4_free_cmd_mailbox(dev, mailbox);
811 return err;
812}
813EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len);
814
747int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) 815int 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