diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/mad.c')
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 85 |
1 files changed, 40 insertions, 45 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 21a794152d15..0a903c129f0a 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
| @@ -409,38 +409,45 @@ int mlx4_ib_find_real_gid(struct ib_device *ibdev, u8 port, __be64 guid) | |||
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | 411 | ||
| 412 | static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix, | 412 | static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, |
| 413 | u8 *full_pk_ix, u8 *partial_pk_ix, | 413 | u8 port, u16 pkey, u16 *ix) |
| 414 | int *is_full_member) | ||
| 415 | { | 414 | { |
| 416 | u16 search_pkey; | 415 | int i, ret; |
| 417 | int fm; | 416 | u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF; |
| 418 | int err = 0; | 417 | u16 slot_pkey; |
| 419 | u16 pk; | ||
| 420 | 418 | ||
| 421 | err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey); | 419 | if (slave == mlx4_master_func_num(dev->dev)) |
| 422 | if (err) | 420 | return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix); |
| 423 | return err; | ||
| 424 | 421 | ||
| 425 | fm = (search_pkey & 0x8000) ? 1 : 0; | 422 | unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1; |
| 426 | if (fm) { | ||
| 427 | *full_pk_ix = ph_pkey_ix; | ||
| 428 | search_pkey &= 0x7FFF; | ||
| 429 | } else { | ||
| 430 | *partial_pk_ix = ph_pkey_ix; | ||
| 431 | search_pkey |= 0x8000; | ||
| 432 | } | ||
| 433 | 423 | ||
| 434 | if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk)) | 424 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { |
| 435 | pk = 0xFFFF; | 425 | if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix) |
| 426 | continue; | ||
| 436 | 427 | ||
| 437 | if (fm) | 428 | pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i]; |
| 438 | *partial_pk_ix = (pk & 0xFF); | ||
| 439 | else | ||
| 440 | *full_pk_ix = (pk & 0xFF); | ||
| 441 | 429 | ||
| 442 | *is_full_member = fm; | 430 | ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey); |
| 443 | return err; | 431 | if (ret) |
| 432 | continue; | ||
| 433 | if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) { | ||
| 434 | if (slot_pkey & 0x8000) { | ||
| 435 | *ix = (u16) pkey_ix; | ||
| 436 | return 0; | ||
| 437 | } else { | ||
| 438 | /* take first partial pkey index found */ | ||
| 439 | if (partial_ix == 0xFF) | ||
| 440 | partial_ix = pkey_ix; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | if (partial_ix < 0xFF) { | ||
| 446 | *ix = (u16) partial_ix; | ||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | return -EINVAL; | ||
| 444 | } | 451 | } |
| 445 | 452 | ||
| 446 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | 453 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
| @@ -458,10 +465,8 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
| 458 | unsigned tun_tx_ix = 0; | 465 | unsigned tun_tx_ix = 0; |
| 459 | int dqpn; | 466 | int dqpn; |
| 460 | int ret = 0; | 467 | int ret = 0; |
| 461 | int i; | ||
| 462 | int is_full_member = 0; | ||
| 463 | u16 tun_pkey_ix; | 468 | u16 tun_pkey_ix; |
| 464 | u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0; | 469 | u16 cached_pkey; |
| 465 | 470 | ||
| 466 | if (dest_qpt > IB_QPT_GSI) | 471 | if (dest_qpt > IB_QPT_GSI) |
| 467 | return -EINVAL; | 472 | return -EINVAL; |
| @@ -481,27 +486,17 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, | |||
| 481 | else | 486 | else |
| 482 | tun_qp = &tun_ctx->qp[1]; | 487 | tun_qp = &tun_ctx->qp[1]; |
| 483 | 488 | ||
| 484 | /* compute pkey index for slave */ | 489 | /* compute P_Key index to put in tunnel header for slave */ |
| 485 | /* get physical pkey -- virtualized Dom0 pkey to phys*/ | ||
| 486 | if (dest_qpt) { | 490 | if (dest_qpt) { |
| 487 | ph_pkey_ix = | 491 | u16 pkey_ix; |
| 488 | dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index]; | 492 | ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey); |
| 489 | |||
| 490 | /* now, translate this to the slave pkey index */ | ||
| 491 | ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix, | ||
| 492 | &partial_pk_ix, &is_full_member); | ||
| 493 | if (ret) | 493 | if (ret) |
| 494 | return -EINVAL; | 494 | return -EINVAL; |
| 495 | 495 | ||
| 496 | for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { | 496 | ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix); |
| 497 | if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) || | 497 | if (ret) |
| 498 | (is_full_member && | ||
| 499 | (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix))) | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | if (i == dev->dev->caps.pkey_table_len[port]) | ||
| 503 | return -EINVAL; | 498 | return -EINVAL; |
| 504 | tun_pkey_ix = i; | 499 | tun_pkey_ix = pkey_ix; |
| 505 | } else | 500 | } else |
| 506 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; | 501 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; |
| 507 | 502 | ||
