diff options
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 98 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.h | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 263 |
3 files changed, 76 insertions, 290 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 9e7baa8b57a9..acd00831ef08 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -1566,31 +1566,56 @@ int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status) | |||
1566 | CMD_TIME_CLASS_B, status); | 1566 | CMD_TIME_CLASS_B, status); |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 1569 | int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur, |
1570 | int is_ee, struct mthca_mailbox *mailbox, u32 optmask, | 1570 | enum ib_qp_state next, u32 num, int is_ee, |
1571 | struct mthca_mailbox *mailbox, u32 optmask, | ||
1571 | u8 *status) | 1572 | u8 *status) |
1572 | { | 1573 | { |
1573 | static const u16 op[] = { | 1574 | static const u16 op[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { |
1574 | [MTHCA_TRANS_RST2INIT] = CMD_RST2INIT_QPEE, | 1575 | [IB_QPS_RESET] = { |
1575 | [MTHCA_TRANS_INIT2INIT] = CMD_INIT2INIT_QPEE, | 1576 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, |
1576 | [MTHCA_TRANS_INIT2RTR] = CMD_INIT2RTR_QPEE, | 1577 | [IB_QPS_ERR] = CMD_2ERR_QPEE, |
1577 | [MTHCA_TRANS_RTR2RTS] = CMD_RTR2RTS_QPEE, | 1578 | [IB_QPS_INIT] = CMD_RST2INIT_QPEE, |
1578 | [MTHCA_TRANS_RTS2RTS] = CMD_RTS2RTS_QPEE, | 1579 | }, |
1579 | [MTHCA_TRANS_SQERR2RTS] = CMD_SQERR2RTS_QPEE, | 1580 | [IB_QPS_INIT] = { |
1580 | [MTHCA_TRANS_ANY2ERR] = CMD_2ERR_QPEE, | 1581 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, |
1581 | [MTHCA_TRANS_RTS2SQD] = CMD_RTS2SQD_QPEE, | 1582 | [IB_QPS_ERR] = CMD_2ERR_QPEE, |
1582 | [MTHCA_TRANS_SQD2SQD] = CMD_SQD2SQD_QPEE, | 1583 | [IB_QPS_INIT] = CMD_INIT2INIT_QPEE, |
1583 | [MTHCA_TRANS_SQD2RTS] = CMD_SQD2RTS_QPEE, | 1584 | [IB_QPS_RTR] = CMD_INIT2RTR_QPEE, |
1584 | [MTHCA_TRANS_ANY2RST] = CMD_ERR2RST_QPEE | 1585 | }, |
1586 | [IB_QPS_RTR] = { | ||
1587 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, | ||
1588 | [IB_QPS_ERR] = CMD_2ERR_QPEE, | ||
1589 | [IB_QPS_RTS] = CMD_RTR2RTS_QPEE, | ||
1590 | }, | ||
1591 | [IB_QPS_RTS] = { | ||
1592 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, | ||
1593 | [IB_QPS_ERR] = CMD_2ERR_QPEE, | ||
1594 | [IB_QPS_RTS] = CMD_RTS2RTS_QPEE, | ||
1595 | [IB_QPS_SQD] = CMD_RTS2SQD_QPEE, | ||
1596 | }, | ||
1597 | [IB_QPS_SQD] = { | ||
1598 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, | ||
1599 | [IB_QPS_ERR] = CMD_2ERR_QPEE, | ||
1600 | [IB_QPS_RTS] = CMD_SQD2RTS_QPEE, | ||
1601 | [IB_QPS_SQD] = CMD_SQD2SQD_QPEE, | ||
1602 | }, | ||
1603 | [IB_QPS_SQE] = { | ||
1604 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, | ||
1605 | [IB_QPS_ERR] = CMD_2ERR_QPEE, | ||
1606 | [IB_QPS_RTS] = CMD_SQERR2RTS_QPEE, | ||
1607 | }, | ||
1608 | [IB_QPS_ERR] = { | ||
1609 | [IB_QPS_RESET] = CMD_ERR2RST_QPEE, | ||
1610 | [IB_QPS_ERR] = CMD_2ERR_QPEE, | ||
1611 | } | ||
1585 | }; | 1612 | }; |
1613 | |||
1586 | u8 op_mod = 0; | 1614 | u8 op_mod = 0; |
1587 | int my_mailbox = 0; | 1615 | int my_mailbox = 0; |
1588 | int err; | 1616 | int err; |
1589 | 1617 | ||
1590 | if (trans < 0 || trans >= ARRAY_SIZE(op)) | 1618 | if (op[cur][next] == CMD_ERR2RST_QPEE) { |
1591 | return -EINVAL; | ||
1592 | |||
1593 | if (trans == MTHCA_TRANS_ANY2RST) { | ||
1594 | op_mod = 3; /* don't write outbox, any->reset */ | 1619 | op_mod = 3; /* don't write outbox, any->reset */ |
1595 | 1620 | ||
1596 | /* For debugging */ | 1621 | /* For debugging */ |
@@ -1602,34 +1627,35 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | |||
1602 | } else | 1627 | } else |
1603 | mailbox = NULL; | 1628 | mailbox = NULL; |
1604 | } | 1629 | } |
1605 | } else { | 1630 | |
1606 | if (0) { | 1631 | err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, |
1632 | (!!is_ee << 24) | num, op_mod, | ||
1633 | op[cur][next], CMD_TIME_CLASS_C, status); | ||
1634 | |||
1635 | if (0 && mailbox) { | ||
1607 | int i; | 1636 | int i; |
1608 | mthca_dbg(dev, "Dumping QP context:\n"); | 1637 | mthca_dbg(dev, "Dumping QP context:\n"); |
1609 | printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf)); | 1638 | printk(" %08x\n", be32_to_cpup(mailbox->buf)); |
1610 | for (i = 0; i < 0x100 / 4; ++i) { | 1639 | for (i = 0; i < 0x100 / 4; ++i) { |
1611 | if (i % 8 == 0) | 1640 | if (i % 8 == 0) |
1612 | printk(" [%02x] ", i * 4); | 1641 | printk("[%02x] ", i * 4); |
1613 | printk(" %08x", | 1642 | printk(" %08x", |
1614 | be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); | 1643 | be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); |
1615 | if ((i + 1) % 8 == 0) | 1644 | if ((i + 1) % 8 == 0) |
1616 | printk("\n"); | 1645 | printk("\n"); |
1617 | } | 1646 | } |
1618 | } | 1647 | } |
1619 | } | ||
1620 | 1648 | ||
1621 | if (trans == MTHCA_TRANS_ANY2RST) { | 1649 | if (my_mailbox) |
1622 | err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, | 1650 | mthca_free_mailbox(dev, mailbox); |
1623 | (!!is_ee << 24) | num, op_mod, | 1651 | } else { |
1624 | op[trans], CMD_TIME_CLASS_C, status); | 1652 | if (0) { |
1625 | |||
1626 | if (0 && mailbox) { | ||
1627 | int i; | 1653 | int i; |
1628 | mthca_dbg(dev, "Dumping QP context:\n"); | 1654 | mthca_dbg(dev, "Dumping QP context:\n"); |
1629 | printk(" %08x\n", be32_to_cpup(mailbox->buf)); | 1655 | printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf)); |
1630 | for (i = 0; i < 0x100 / 4; ++i) { | 1656 | for (i = 0; i < 0x100 / 4; ++i) { |
1631 | if (i % 8 == 0) | 1657 | if (i % 8 == 0) |
1632 | printk("[%02x] ", i * 4); | 1658 | printk(" [%02x] ", i * 4); |
1633 | printk(" %08x", | 1659 | printk(" %08x", |
1634 | be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); | 1660 | be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); |
1635 | if ((i + 1) % 8 == 0) | 1661 | if ((i + 1) % 8 == 0) |
@@ -1637,13 +1663,9 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | |||
1637 | } | 1663 | } |
1638 | } | 1664 | } |
1639 | 1665 | ||
1640 | } else | 1666 | err = mthca_cmd(dev, mailbox->dma, optmask | (!!is_ee << 24) | num, |
1641 | err = mthca_cmd(dev, mailbox->dma, | 1667 | op_mod, op[cur][next], CMD_TIME_CLASS_C, status); |
1642 | optmask | (!!is_ee << 24) | num, | 1668 | } |
1643 | op_mod, op[trans], CMD_TIME_CLASS_C, status); | ||
1644 | |||
1645 | if (my_mailbox) | ||
1646 | mthca_free_mailbox(dev, mailbox); | ||
1647 | 1669 | ||
1648 | return err; | 1670 | return err; |
1649 | } | 1671 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index a8da84b0a0f1..5156701ae52c 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h | |||
@@ -306,8 +306,9 @@ int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, | |||
306 | int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, | 306 | int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
307 | int srq_num, u8 *status); | 307 | int srq_num, u8 *status); |
308 | int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status); | 308 | int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status); |
309 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 309 | int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur, |
310 | int is_ee, struct mthca_mailbox *mailbox, u32 optmask, | 310 | enum ib_qp_state next, u32 num, int is_ee, |
311 | struct mthca_mailbox *mailbox, u32 optmask, | ||
311 | u8 *status); | 312 | u8 *status); |
312 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, | 313 | int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee, |
313 | struct mthca_mailbox *mailbox, u8 *status); | 314 | struct mthca_mailbox *mailbox, u8 *status); |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 97f5303d2c02..c2d3300dace9 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -286,213 +286,6 @@ static int to_mthca_st(int transport) | |||
286 | } | 286 | } |
287 | } | 287 | } |
288 | 288 | ||
289 | static const struct { | ||
290 | int trans; | ||
291 | u32 req_param[NUM_TRANS]; | ||
292 | u32 opt_param[NUM_TRANS]; | ||
293 | } state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { | ||
294 | [IB_QPS_RESET] = { | ||
295 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
296 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
297 | [IB_QPS_INIT] = { | ||
298 | .trans = MTHCA_TRANS_RST2INIT, | ||
299 | .req_param = { | ||
300 | [UD] = (IB_QP_PKEY_INDEX | | ||
301 | IB_QP_PORT | | ||
302 | IB_QP_QKEY), | ||
303 | [UC] = (IB_QP_PKEY_INDEX | | ||
304 | IB_QP_PORT | | ||
305 | IB_QP_ACCESS_FLAGS), | ||
306 | [RC] = (IB_QP_PKEY_INDEX | | ||
307 | IB_QP_PORT | | ||
308 | IB_QP_ACCESS_FLAGS), | ||
309 | [MLX] = (IB_QP_PKEY_INDEX | | ||
310 | IB_QP_QKEY), | ||
311 | }, | ||
312 | /* bug-for-bug compatibility with VAPI: */ | ||
313 | .opt_param = { | ||
314 | [MLX] = IB_QP_PORT | ||
315 | } | ||
316 | }, | ||
317 | }, | ||
318 | [IB_QPS_INIT] = { | ||
319 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
320 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
321 | [IB_QPS_INIT] = { | ||
322 | .trans = MTHCA_TRANS_INIT2INIT, | ||
323 | .opt_param = { | ||
324 | [UD] = (IB_QP_PKEY_INDEX | | ||
325 | IB_QP_PORT | | ||
326 | IB_QP_QKEY), | ||
327 | [UC] = (IB_QP_PKEY_INDEX | | ||
328 | IB_QP_PORT | | ||
329 | IB_QP_ACCESS_FLAGS), | ||
330 | [RC] = (IB_QP_PKEY_INDEX | | ||
331 | IB_QP_PORT | | ||
332 | IB_QP_ACCESS_FLAGS), | ||
333 | [MLX] = (IB_QP_PKEY_INDEX | | ||
334 | IB_QP_QKEY), | ||
335 | } | ||
336 | }, | ||
337 | [IB_QPS_RTR] = { | ||
338 | .trans = MTHCA_TRANS_INIT2RTR, | ||
339 | .req_param = { | ||
340 | [UC] = (IB_QP_AV | | ||
341 | IB_QP_PATH_MTU | | ||
342 | IB_QP_DEST_QPN | | ||
343 | IB_QP_RQ_PSN), | ||
344 | [RC] = (IB_QP_AV | | ||
345 | IB_QP_PATH_MTU | | ||
346 | IB_QP_DEST_QPN | | ||
347 | IB_QP_RQ_PSN | | ||
348 | IB_QP_MAX_DEST_RD_ATOMIC | | ||
349 | IB_QP_MIN_RNR_TIMER), | ||
350 | }, | ||
351 | .opt_param = { | ||
352 | [UD] = (IB_QP_PKEY_INDEX | | ||
353 | IB_QP_QKEY), | ||
354 | [UC] = (IB_QP_ALT_PATH | | ||
355 | IB_QP_ACCESS_FLAGS | | ||
356 | IB_QP_PKEY_INDEX), | ||
357 | [RC] = (IB_QP_ALT_PATH | | ||
358 | IB_QP_ACCESS_FLAGS | | ||
359 | IB_QP_PKEY_INDEX), | ||
360 | [MLX] = (IB_QP_PKEY_INDEX | | ||
361 | IB_QP_QKEY), | ||
362 | } | ||
363 | } | ||
364 | }, | ||
365 | [IB_QPS_RTR] = { | ||
366 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
367 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
368 | [IB_QPS_RTS] = { | ||
369 | .trans = MTHCA_TRANS_RTR2RTS, | ||
370 | .req_param = { | ||
371 | [UD] = IB_QP_SQ_PSN, | ||
372 | [UC] = IB_QP_SQ_PSN, | ||
373 | [RC] = (IB_QP_TIMEOUT | | ||
374 | IB_QP_RETRY_CNT | | ||
375 | IB_QP_RNR_RETRY | | ||
376 | IB_QP_SQ_PSN | | ||
377 | IB_QP_MAX_QP_RD_ATOMIC), | ||
378 | [MLX] = IB_QP_SQ_PSN, | ||
379 | }, | ||
380 | .opt_param = { | ||
381 | [UD] = (IB_QP_CUR_STATE | | ||
382 | IB_QP_QKEY), | ||
383 | [UC] = (IB_QP_CUR_STATE | | ||
384 | IB_QP_ALT_PATH | | ||
385 | IB_QP_ACCESS_FLAGS | | ||
386 | IB_QP_PATH_MIG_STATE), | ||
387 | [RC] = (IB_QP_CUR_STATE | | ||
388 | IB_QP_ALT_PATH | | ||
389 | IB_QP_ACCESS_FLAGS | | ||
390 | IB_QP_MIN_RNR_TIMER | | ||
391 | IB_QP_PATH_MIG_STATE), | ||
392 | [MLX] = (IB_QP_CUR_STATE | | ||
393 | IB_QP_QKEY), | ||
394 | } | ||
395 | } | ||
396 | }, | ||
397 | [IB_QPS_RTS] = { | ||
398 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
399 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
400 | [IB_QPS_RTS] = { | ||
401 | .trans = MTHCA_TRANS_RTS2RTS, | ||
402 | .opt_param = { | ||
403 | [UD] = (IB_QP_CUR_STATE | | ||
404 | IB_QP_QKEY), | ||
405 | [UC] = (IB_QP_ACCESS_FLAGS | | ||
406 | IB_QP_ALT_PATH | | ||
407 | IB_QP_PATH_MIG_STATE), | ||
408 | [RC] = (IB_QP_ACCESS_FLAGS | | ||
409 | IB_QP_ALT_PATH | | ||
410 | IB_QP_PATH_MIG_STATE | | ||
411 | IB_QP_MIN_RNR_TIMER), | ||
412 | [MLX] = (IB_QP_CUR_STATE | | ||
413 | IB_QP_QKEY), | ||
414 | } | ||
415 | }, | ||
416 | [IB_QPS_SQD] = { | ||
417 | .trans = MTHCA_TRANS_RTS2SQD, | ||
418 | .opt_param = { | ||
419 | [UD] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
420 | [UC] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
421 | [RC] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
422 | [MLX] = IB_QP_EN_SQD_ASYNC_NOTIFY | ||
423 | } | ||
424 | }, | ||
425 | }, | ||
426 | [IB_QPS_SQD] = { | ||
427 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
428 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
429 | [IB_QPS_RTS] = { | ||
430 | .trans = MTHCA_TRANS_SQD2RTS, | ||
431 | .opt_param = { | ||
432 | [UD] = (IB_QP_CUR_STATE | | ||
433 | IB_QP_QKEY), | ||
434 | [UC] = (IB_QP_CUR_STATE | | ||
435 | IB_QP_ALT_PATH | | ||
436 | IB_QP_ACCESS_FLAGS | | ||
437 | IB_QP_PATH_MIG_STATE), | ||
438 | [RC] = (IB_QP_CUR_STATE | | ||
439 | IB_QP_ALT_PATH | | ||
440 | IB_QP_ACCESS_FLAGS | | ||
441 | IB_QP_MIN_RNR_TIMER | | ||
442 | IB_QP_PATH_MIG_STATE), | ||
443 | [MLX] = (IB_QP_CUR_STATE | | ||
444 | IB_QP_QKEY), | ||
445 | } | ||
446 | }, | ||
447 | [IB_QPS_SQD] = { | ||
448 | .trans = MTHCA_TRANS_SQD2SQD, | ||
449 | .opt_param = { | ||
450 | [UD] = (IB_QP_PKEY_INDEX | | ||
451 | IB_QP_QKEY), | ||
452 | [UC] = (IB_QP_AV | | ||
453 | IB_QP_CUR_STATE | | ||
454 | IB_QP_ALT_PATH | | ||
455 | IB_QP_ACCESS_FLAGS | | ||
456 | IB_QP_PKEY_INDEX | | ||
457 | IB_QP_PATH_MIG_STATE), | ||
458 | [RC] = (IB_QP_AV | | ||
459 | IB_QP_TIMEOUT | | ||
460 | IB_QP_RETRY_CNT | | ||
461 | IB_QP_RNR_RETRY | | ||
462 | IB_QP_MAX_QP_RD_ATOMIC | | ||
463 | IB_QP_MAX_DEST_RD_ATOMIC | | ||
464 | IB_QP_CUR_STATE | | ||
465 | IB_QP_ALT_PATH | | ||
466 | IB_QP_ACCESS_FLAGS | | ||
467 | IB_QP_PKEY_INDEX | | ||
468 | IB_QP_MIN_RNR_TIMER | | ||
469 | IB_QP_PATH_MIG_STATE), | ||
470 | [MLX] = (IB_QP_PKEY_INDEX | | ||
471 | IB_QP_QKEY), | ||
472 | } | ||
473 | } | ||
474 | }, | ||
475 | [IB_QPS_SQE] = { | ||
476 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
477 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }, | ||
478 | [IB_QPS_RTS] = { | ||
479 | .trans = MTHCA_TRANS_SQERR2RTS, | ||
480 | .opt_param = { | ||
481 | [UD] = (IB_QP_CUR_STATE | | ||
482 | IB_QP_QKEY), | ||
483 | [UC] = (IB_QP_CUR_STATE | | ||
484 | IB_QP_ACCESS_FLAGS), | ||
485 | [MLX] = (IB_QP_CUR_STATE | | ||
486 | IB_QP_QKEY), | ||
487 | } | ||
488 | } | ||
489 | }, | ||
490 | [IB_QPS_ERR] = { | ||
491 | [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST }, | ||
492 | [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR } | ||
493 | } | ||
494 | }; | ||
495 | |||
496 | static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr, | 289 | static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr, |
497 | int attr_mask) | 290 | int attr_mask) |
498 | { | 291 | { |
@@ -582,19 +375,12 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
582 | struct mthca_mailbox *mailbox; | 375 | struct mthca_mailbox *mailbox; |
583 | struct mthca_qp_param *qp_param; | 376 | struct mthca_qp_param *qp_param; |
584 | struct mthca_qp_context *qp_context; | 377 | struct mthca_qp_context *qp_context; |
585 | u32 req_param, opt_param; | ||
586 | u32 sqd_event = 0; | 378 | u32 sqd_event = 0; |
587 | u8 status; | 379 | u8 status; |
588 | int err; | 380 | int err; |
589 | 381 | ||
590 | if (attr_mask & IB_QP_CUR_STATE) { | 382 | if (attr_mask & IB_QP_CUR_STATE) { |
591 | if (attr->cur_qp_state != IB_QPS_RTR && | 383 | cur_state = attr->cur_qp_state; |
592 | attr->cur_qp_state != IB_QPS_RTS && | ||
593 | attr->cur_qp_state != IB_QPS_SQD && | ||
594 | attr->cur_qp_state != IB_QPS_SQE) | ||
595 | return -EINVAL; | ||
596 | else | ||
597 | cur_state = attr->cur_qp_state; | ||
598 | } else { | 384 | } else { |
599 | spin_lock_irq(&qp->sq.lock); | 385 | spin_lock_irq(&qp->sq.lock); |
600 | spin_lock(&qp->rq.lock); | 386 | spin_lock(&qp->rq.lock); |
@@ -603,37 +389,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
603 | spin_unlock_irq(&qp->sq.lock); | 389 | spin_unlock_irq(&qp->sq.lock); |
604 | } | 390 | } |
605 | 391 | ||
606 | if (attr_mask & IB_QP_STATE) { | 392 | new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; |
607 | if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR) | ||
608 | return -EINVAL; | ||
609 | new_state = attr->qp_state; | ||
610 | } else | ||
611 | new_state = cur_state; | ||
612 | |||
613 | if (state_table[cur_state][new_state].trans == MTHCA_TRANS_INVALID) { | ||
614 | mthca_dbg(dev, "Illegal QP transition " | ||
615 | "%d->%d\n", cur_state, new_state); | ||
616 | return -EINVAL; | ||
617 | } | ||
618 | |||
619 | req_param = state_table[cur_state][new_state].req_param[qp->transport]; | ||
620 | opt_param = state_table[cur_state][new_state].opt_param[qp->transport]; | ||
621 | |||
622 | if ((req_param & attr_mask) != req_param) { | ||
623 | mthca_dbg(dev, "QP transition " | ||
624 | "%d->%d missing req attr 0x%08x\n", | ||
625 | cur_state, new_state, | ||
626 | req_param & ~attr_mask); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | 393 | ||
630 | if (attr_mask & ~(req_param | opt_param | IB_QP_STATE)) { | 394 | if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) { |
631 | mthca_dbg(dev, "QP transition (transport %d) " | 395 | mthca_dbg(dev, "Bad QP transition (transport %d) " |
632 | "%d->%d has extra attr 0x%08x\n", | 396 | "%d->%d with attr 0x%08x\n", |
633 | qp->transport, | 397 | qp->transport, cur_state, new_state, |
634 | cur_state, new_state, | 398 | attr_mask); |
635 | attr_mask & ~(req_param | opt_param | | ||
636 | IB_QP_STATE)); | ||
637 | return -EINVAL; | 399 | return -EINVAL; |
638 | } | 400 | } |
639 | 401 | ||
@@ -853,11 +615,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
853 | attr->en_sqd_async_notify) | 615 | attr->en_sqd_async_notify) |
854 | sqd_event = 1 << 31; | 616 | sqd_event = 1 << 31; |
855 | 617 | ||
856 | err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans, | 618 | err = mthca_MODIFY_QP(dev, cur_state, new_state, qp->qpn, 0, |
857 | qp->qpn, 0, mailbox, sqd_event, &status); | 619 | mailbox, sqd_event, &status); |
858 | if (status) { | 620 | if (status) { |
859 | mthca_warn(dev, "modify QP %d returned status %02x.\n", | 621 | mthca_warn(dev, "modify QP %d->%d returned status %02x.\n", |
860 | state_table[cur_state][new_state].trans, status); | 622 | cur_state, new_state, status); |
861 | err = -EINVAL; | 623 | err = -EINVAL; |
862 | } | 624 | } |
863 | 625 | ||
@@ -1405,7 +1167,8 @@ void mthca_free_qp(struct mthca_dev *dev, | |||
1405 | wait_event(qp->wait, !atomic_read(&qp->refcount)); | 1167 | wait_event(qp->wait, !atomic_read(&qp->refcount)); |
1406 | 1168 | ||
1407 | if (qp->state != IB_QPS_RESET) | 1169 | if (qp->state != IB_QPS_RESET) |
1408 | mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status); | 1170 | mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0, |
1171 | NULL, 0, &status); | ||
1409 | 1172 | ||
1410 | /* | 1173 | /* |
1411 | * If this is a userspace QP, the buffers, MR, CQs and so on | 1174 | * If this is a userspace QP, the buffers, MR, CQs and so on |