aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-08-03 04:40:45 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-30 23:33:34 -0400
commit0a9a01884d447c216eff75f8f274a0a3e82c7cee (patch)
treec25b38c66c4d26c71b82c65a558316eeb4419231 /drivers/infiniband
parent37bfc7c1e83f1589bcdc5918c7216422662644ee (diff)
mlx4: MAD_IFC paravirtualization
The MAD_IFC firmware command fulfills two functions. First, it is used in the QP0/QP1 MAD-handling flow to obtain information from the FW (for answering queries), and for setting variables in the HCA (MAD SET packets). For this, MAD_IFC should provide the FW (physical) view of the data. This is the view that OpenSM needs. We call this the "network view". In the second case, MAD_IFC is used by various verbs to obtain data regarding the local HCA (e.g., ib_query_device()). We call this the "host view". This data needs to be paravirtualized. MAD_IFC therefore needs a wrapper function, and also needs another flag indicating whether it should provide the network view (when it is called by ib_process_mad in special-qp packet handling), or the host view (when it is called while implementing a verb). There are currently 2 flag parameters in mlx4_MAD_IFC already: ignore_bkey and ignore_mkey. These two parameters are replaced by a single "mad_ifc_flags" parameter, with different bits set for each flag. A third flag is added: "network-view/host-view". Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c20
-rw-r--r--drivers/infiniband/hw/mlx4/main.c64
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h14
3 files changed, 72 insertions, 26 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 8dfbf69f8370..ba2580693f79 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -75,7 +75,7 @@ struct mlx4_rcv_tunnel_mad {
75 struct ib_mad mad; 75 struct ib_mad mad;
76} __packed; 76} __packed;
77 77
78int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, 78int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags,
79 int port, struct ib_wc *in_wc, struct ib_grh *in_grh, 79 int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
80 void *in_mad, void *response_mad) 80 void *in_mad, void *response_mad)
81{ 81{
@@ -102,10 +102,13 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey,
102 * Key check traps can't be generated unless we have in_wc to 102 * Key check traps can't be generated unless we have in_wc to
103 * tell us where to send the trap. 103 * tell us where to send the trap.
104 */ 104 */
105 if (ignore_mkey || !in_wc) 105 if ((mad_ifc_flags & MLX4_MAD_IFC_IGNORE_MKEY) || !in_wc)
106 op_modifier |= 0x1; 106 op_modifier |= 0x1;
107 if (ignore_bkey || !in_wc) 107 if ((mad_ifc_flags & MLX4_MAD_IFC_IGNORE_BKEY) || !in_wc)
108 op_modifier |= 0x2; 108 op_modifier |= 0x2;
109 if (mlx4_is_mfunc(dev->dev) &&
110 (mad_ifc_flags & MLX4_MAD_IFC_NET_VIEW || in_wc))
111 op_modifier |= 0x8;
109 112
110 if (in_wc) { 113 if (in_wc) {
111 struct { 114 struct {
@@ -138,10 +141,10 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey,
138 in_modifier |= in_wc->slid << 16; 141 in_modifier |= in_wc->slid << 16;
139 } 142 }
140 143
141 err = mlx4_cmd_box(dev->dev, inmailbox->dma, outmailbox->dma, 144 err = mlx4_cmd_box(dev->dev, inmailbox->dma, outmailbox->dma, in_modifier,
142 in_modifier, op_modifier, 145 mlx4_is_master(dev->dev) ? (op_modifier & ~0x8) : op_modifier,
143 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, 146 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
144 MLX4_CMD_NATIVE); 147 (op_modifier & 0x8) ? MLX4_CMD_NATIVE : MLX4_CMD_WRAPPED);
145 148
146 if (!err) 149 if (!err)
147 memcpy(response_mad, outmailbox->buf, 256); 150 memcpy(response_mad, outmailbox->buf, 256);
@@ -614,8 +617,9 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
614 prev_lid = pattr.lid; 617 prev_lid = pattr.lid;
615 618
616 err = mlx4_MAD_IFC(to_mdev(ibdev), 619 err = mlx4_MAD_IFC(to_mdev(ibdev),
617 mad_flags & IB_MAD_IGNORE_MKEY, 620 (mad_flags & IB_MAD_IGNORE_MKEY ? MLX4_MAD_IFC_IGNORE_MKEY : 0) |
618 mad_flags & IB_MAD_IGNORE_BKEY, 621 (mad_flags & IB_MAD_IGNORE_BKEY ? MLX4_MAD_IFC_IGNORE_BKEY : 0) |
622 MLX4_MAD_IFC_NET_VIEW,
619 port_num, in_wc, in_grh, in_mad, out_mad); 623 port_num, in_wc, in_grh, in_mad, out_mad);
620 if (err) 624 if (err)
621 return IB_MAD_RESULT_FAILURE; 625 return IB_MAD_RESULT_FAILURE;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 8e10ec2af7b6..45a6cc04036b 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -98,7 +98,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
98 init_query_mad(in_mad); 98 init_query_mad(in_mad);
99 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; 99 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
100 100
101 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, 1, NULL, NULL, in_mad, out_mad); 101 err = mlx4_MAD_IFC(to_mdev(ibdev), MLX4_MAD_IFC_IGNORE_KEYS,
102 1, NULL, NULL, in_mad, out_mad);
102 if (err) 103 if (err)
103 goto out; 104 goto out;
104 105
@@ -182,11 +183,12 @@ mlx4_ib_port_link_layer(struct ib_device *device, u8 port_num)
182} 183}
183 184
184static int ib_link_query_port(struct ib_device *ibdev, u8 port, 185static int ib_link_query_port(struct ib_device *ibdev, u8 port,
185 struct ib_port_attr *props) 186 struct ib_port_attr *props, int netw_view)
186{ 187{
187 struct ib_smp *in_mad = NULL; 188 struct ib_smp *in_mad = NULL;
188 struct ib_smp *out_mad = NULL; 189 struct ib_smp *out_mad = NULL;
189 int ext_active_speed; 190 int ext_active_speed;
191 int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS;
190 int err = -ENOMEM; 192 int err = -ENOMEM;
191 193
192 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); 194 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
@@ -198,7 +200,10 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
198 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; 200 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
199 in_mad->attr_mod = cpu_to_be32(port); 201 in_mad->attr_mod = cpu_to_be32(port);
200 202
201 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, 203 if (mlx4_is_mfunc(to_mdev(ibdev)->dev) && netw_view)
204 mad_ifc_flags |= MLX4_MAD_IFC_NET_VIEW;
205
206 err = mlx4_MAD_IFC(to_mdev(ibdev), mad_ifc_flags, port, NULL, NULL,
202 in_mad, out_mad); 207 in_mad, out_mad);
203 if (err) 208 if (err)
204 goto out; 209 goto out;
@@ -211,7 +216,10 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
211 props->state = out_mad->data[32] & 0xf; 216 props->state = out_mad->data[32] & 0xf;
212 props->phys_state = out_mad->data[33] >> 4; 217 props->phys_state = out_mad->data[33] >> 4;
213 props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20)); 218 props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20));
214 props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port]; 219 if (netw_view)
220 props->gid_tbl_len = out_mad->data[50];
221 else
222 props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port];
215 props->max_msg_sz = to_mdev(ibdev)->dev->caps.max_msg_sz; 223 props->max_msg_sz = to_mdev(ibdev)->dev->caps.max_msg_sz;
216 props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len[port]; 224 props->pkey_tbl_len = to_mdev(ibdev)->dev->caps.pkey_table_len[port];
217 props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46)); 225 props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46));
@@ -244,7 +252,7 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
244 in_mad->attr_id = MLX4_ATTR_EXTENDED_PORT_INFO; 252 in_mad->attr_id = MLX4_ATTR_EXTENDED_PORT_INFO;
245 in_mad->attr_mod = cpu_to_be32(port); 253 in_mad->attr_mod = cpu_to_be32(port);
246 254
247 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, 255 err = mlx4_MAD_IFC(to_mdev(ibdev), mad_ifc_flags, port,
248 NULL, NULL, in_mad, out_mad); 256 NULL, NULL, in_mad, out_mad);
249 if (err) 257 if (err)
250 goto out; 258 goto out;
@@ -270,7 +278,7 @@ static u8 state_to_phys_state(enum ib_port_state state)
270} 278}
271 279
272static int eth_link_query_port(struct ib_device *ibdev, u8 port, 280static int eth_link_query_port(struct ib_device *ibdev, u8 port,
273 struct ib_port_attr *props) 281 struct ib_port_attr *props, int netw_view)
274{ 282{
275 283
276 struct mlx4_ib_dev *mdev = to_mdev(ibdev); 284 struct mlx4_ib_dev *mdev = to_mdev(ibdev);
@@ -320,20 +328,27 @@ out:
320 return err; 328 return err;
321} 329}
322 330
323static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port, 331int __mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
324 struct ib_port_attr *props) 332 struct ib_port_attr *props, int netw_view)
325{ 333{
326 int err; 334 int err;
327 335
328 memset(props, 0, sizeof *props); 336 memset(props, 0, sizeof *props);
329 337
330 err = mlx4_ib_port_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND ? 338 err = mlx4_ib_port_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND ?
331 ib_link_query_port(ibdev, port, props) : 339 ib_link_query_port(ibdev, port, props, netw_view) :
332 eth_link_query_port(ibdev, port, props); 340 eth_link_query_port(ibdev, port, props, netw_view);
333 341
334 return err; 342 return err;
335} 343}
336 344
345static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
346 struct ib_port_attr *props)
347{
348 /* returns host view */
349 return __mlx4_ib_query_port(ibdev, port, props, 0);
350}
351
337static int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index, 352static int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
338 union ib_gid *gid) 353 union ib_gid *gid)
339{ 354{
@@ -350,7 +365,8 @@ static int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
350 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; 365 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
351 in_mad->attr_mod = cpu_to_be32(port); 366 in_mad->attr_mod = cpu_to_be32(port);
352 367
353 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad); 368 err = mlx4_MAD_IFC(to_mdev(ibdev), MLX4_MAD_IFC_IGNORE_KEYS, port,
369 NULL, NULL, in_mad, out_mad);
354 if (err) 370 if (err)
355 goto out; 371 goto out;
356 372
@@ -360,7 +376,8 @@ static int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
360 in_mad->attr_id = IB_SMP_ATTR_GUID_INFO; 376 in_mad->attr_id = IB_SMP_ATTR_GUID_INFO;
361 in_mad->attr_mod = cpu_to_be32(index / 8); 377 in_mad->attr_mod = cpu_to_be32(index / 8);
362 378
363 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad); 379 err = mlx4_MAD_IFC(to_mdev(ibdev), MLX4_MAD_IFC_IGNORE_KEYS, port,
380 NULL, NULL, in_mad, out_mad);
364 if (err) 381 if (err)
365 goto out; 382 goto out;
366 383
@@ -391,11 +408,12 @@ static int mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
391 return iboe_query_gid(ibdev, port, index, gid); 408 return iboe_query_gid(ibdev, port, index, gid);
392} 409}
393 410
394static int mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index, 411int __mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
395 u16 *pkey) 412 u16 *pkey, int netw_view)
396{ 413{
397 struct ib_smp *in_mad = NULL; 414 struct ib_smp *in_mad = NULL;
398 struct ib_smp *out_mad = NULL; 415 struct ib_smp *out_mad = NULL;
416 int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS;
399 int err = -ENOMEM; 417 int err = -ENOMEM;
400 418
401 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); 419 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
@@ -407,7 +425,11 @@ static int mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
407 in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE; 425 in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE;
408 in_mad->attr_mod = cpu_to_be32(index / 32); 426 in_mad->attr_mod = cpu_to_be32(index / 32);
409 427
410 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad); 428 if (mlx4_is_mfunc(to_mdev(ibdev)->dev) && netw_view)
429 mad_ifc_flags |= MLX4_MAD_IFC_NET_VIEW;
430
431 err = mlx4_MAD_IFC(to_mdev(ibdev), mad_ifc_flags, port, NULL, NULL,
432 in_mad, out_mad);
411 if (err) 433 if (err)
412 goto out; 434 goto out;
413 435
@@ -419,6 +441,11 @@ out:
419 return err; 441 return err;
420} 442}
421 443
444static int mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
445{
446 return __mlx4_ib_query_pkey(ibdev, port, index, pkey, 0);
447}
448
422static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, 449static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
423 struct ib_device_modify *props) 450 struct ib_device_modify *props)
424{ 451{
@@ -849,6 +876,7 @@ static int init_node_data(struct mlx4_ib_dev *dev)
849{ 876{
850 struct ib_smp *in_mad = NULL; 877 struct ib_smp *in_mad = NULL;
851 struct ib_smp *out_mad = NULL; 878 struct ib_smp *out_mad = NULL;
879 int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS;
852 int err = -ENOMEM; 880 int err = -ENOMEM;
853 881
854 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); 882 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
@@ -858,8 +886,10 @@ static int init_node_data(struct mlx4_ib_dev *dev)
858 886
859 init_query_mad(in_mad); 887 init_query_mad(in_mad);
860 in_mad->attr_id = IB_SMP_ATTR_NODE_DESC; 888 in_mad->attr_id = IB_SMP_ATTR_NODE_DESC;
889 if (mlx4_is_master(dev->dev))
890 mad_ifc_flags |= MLX4_MAD_IFC_NET_VIEW;
861 891
862 err = mlx4_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad); 892 err = mlx4_MAD_IFC(dev, mad_ifc_flags, 1, NULL, NULL, in_mad, out_mad);
863 if (err) 893 if (err)
864 goto out; 894 goto out;
865 895
@@ -867,7 +897,7 @@ static int init_node_data(struct mlx4_ib_dev *dev)
867 897
868 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; 898 in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
869 899
870 err = mlx4_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad); 900 err = mlx4_MAD_IFC(dev, mad_ifc_flags, 1, NULL, NULL, in_mad, out_mad);
871 if (err) 901 if (err)
872 goto out; 902 goto out;
873 903
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 137941d79870..ac71d56ffc7e 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -176,6 +176,14 @@ enum mlx4_ib_qp_type {
176 MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER | \ 176 MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER | \
177 MLX4_IB_QPT_TUN_SMI | MLX4_IB_QPT_TUN_GSI) 177 MLX4_IB_QPT_TUN_SMI | MLX4_IB_QPT_TUN_GSI)
178 178
179enum mlx4_ib_mad_ifc_flags {
180 MLX4_MAD_IFC_IGNORE_MKEY = 1,
181 MLX4_MAD_IFC_IGNORE_BKEY = 2,
182 MLX4_MAD_IFC_IGNORE_KEYS = (MLX4_MAD_IFC_IGNORE_MKEY |
183 MLX4_MAD_IFC_IGNORE_BKEY),
184 MLX4_MAD_IFC_NET_VIEW = 4,
185};
186
179enum { 187enum {
180 MLX4_NUM_TUNNEL_BUFS = 256, 188 MLX4_NUM_TUNNEL_BUFS = 256,
181}; 189};
@@ -512,7 +520,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
512int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, 520int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
513 struct ib_recv_wr **bad_wr); 521 struct ib_recv_wr **bad_wr);
514 522
515int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, 523int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags,
516 int port, struct ib_wc *in_wc, struct ib_grh *in_grh, 524 int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
517 void *in_mad, void *response_mad); 525 void *in_mad, void *response_mad);
518int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 526int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
@@ -527,6 +535,10 @@ int mlx4_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, int npages,
527 u64 iova); 535 u64 iova);
528int mlx4_ib_unmap_fmr(struct list_head *fmr_list); 536int mlx4_ib_unmap_fmr(struct list_head *fmr_list);
529int mlx4_ib_fmr_dealloc(struct ib_fmr *fmr); 537int mlx4_ib_fmr_dealloc(struct ib_fmr *fmr);
538int __mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
539 struct ib_port_attr *props, int netw_view);
540int __mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
541 u16 *pkey, int netw_view);
530 542
531int mlx4_ib_resolve_grh(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr, 543int mlx4_ib_resolve_grh(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr,
532 u8 *mac, int *is_mcast, u8 port); 544 u8 *mac, int *is_mcast, u8 port);