aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugenia Emantayev <eugenia@mellanox.com>2014-07-16 04:57:50 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-17 02:26:25 -0400
commit816e59846bb683e8d5c91e35df5f8fabac20494f (patch)
treed80363b42687b9a7df283133719fed9b57e9eae7
parent75908376038c44ea154e4c2782ee367e679c81b1 (diff)
net/mlx4_core: In SR-IOV mode host should add promisc QP to default entry only
In current situation host is adding the promiscuous QP to all steering entries and the default entry as well. In this case when having PV and SR-IOV on the same setup bridge will receive all traffic that is targeted to the other VMs. This is bad. Solution: In SR-IOV mode host can add promiscuous QP to default entry only. The above problem and fix are relevant for B0 steering mode only. Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c169
1 files changed, 99 insertions, 70 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 39ab85a56c9a..9d92bc22b9e5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -433,43 +433,58 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
433 } 433 }
434 mgm = mailbox->buf; 434 mgm = mailbox->buf;
435 435
436 /* the promisc qp needs to be added for each one of the steering 436 if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
437 * entries, if it already exists, needs to be added as a duplicate 437 /* The promisc QP needs to be added for each one of the steering
438 * for this entry */ 438 * entries. If it already exists, needs to be added as
439 list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 439 * a duplicate for this entry.
440 err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 440 */
441 if (err) 441 list_for_each_entry(entry,
442 goto out_mailbox; 442 &s_steer->steer_entries[steer],
443 list) {
444 err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
445 if (err)
446 goto out_mailbox;
443 447
444 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 448 members_count = be32_to_cpu(mgm->members_count) &
445 prot = be32_to_cpu(mgm->members_count) >> 30; 449 0xffffff;
446 found = false; 450 prot = be32_to_cpu(mgm->members_count) >> 30;
447 for (i = 0; i < members_count; i++) { 451 found = false;
448 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { 452 for (i = 0; i < members_count; i++) {
449 /* Entry already exists, add to duplicates */ 453 if ((be32_to_cpu(mgm->qp[i]) &
450 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 454 MGM_QPN_MASK) == qpn) {
451 if (!dqp) { 455 /* Entry already exists.
456 * Add to duplicates.
457 */
458 dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
459 if (!dqp) {
460 err = -ENOMEM;
461 goto out_mailbox;
462 }
463 dqp->qpn = qpn;
464 list_add_tail(&dqp->list,
465 &entry->duplicates);
466 found = true;
467 }
468 }
469 if (!found) {
470 /* Need to add the qpn to mgm */
471 if (members_count ==
472 dev->caps.num_qp_per_mgm) {
473 /* entry is full */
452 err = -ENOMEM; 474 err = -ENOMEM;
453 goto out_mailbox; 475 goto out_mailbox;
454 } 476 }
455 dqp->qpn = qpn; 477 mgm->qp[members_count++] =
456 list_add_tail(&dqp->list, &entry->duplicates); 478 cpu_to_be32(qpn & MGM_QPN_MASK);
457 found = true; 479 mgm->members_count =
480 cpu_to_be32(members_count |
481 (prot << 30));
482 err = mlx4_WRITE_ENTRY(dev, entry->index,
483 mailbox);
484 if (err)
485 goto out_mailbox;
458 } 486 }
459 } 487 }
460 if (!found) {
461 /* Need to add the qpn to mgm */
462 if (members_count == dev->caps.num_qp_per_mgm) {
463 /* entry is full */
464 err = -ENOMEM;
465 goto out_mailbox;
466 }
467 mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK);
468 mgm->members_count = cpu_to_be32(members_count | (prot << 30));
469 err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
470 if (err)
471 goto out_mailbox;
472 }
473 } 488 }
474 489
475 /* add the new qpn to list of promisc qps */ 490 /* add the new qpn to list of promisc qps */
@@ -556,51 +571,65 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
556 if (err) 571 if (err)
557 goto out_mailbox; 572 goto out_mailbox;
558 573
559 /* remove the qp from all the steering entries*/ 574 if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
560 list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 575 /* remove the qp from all the steering entries*/
561 found = false; 576 list_for_each_entry(entry,
562 list_for_each_entry(dqp, &entry->duplicates, list) { 577 &s_steer->steer_entries[steer],
563 if (dqp->qpn == qpn) { 578 list) {
564 found = true; 579 found = false;
565 break; 580 list_for_each_entry(dqp, &entry->duplicates, list) {
581 if (dqp->qpn == qpn) {
582 found = true;
583 break;
584 }
566 } 585 }
567 } 586 if (found) {
568 if (found) { 587 /* A duplicate, no need to change the MGM,
569 /* a duplicate, no need to change the mgm, 588 * only update the duplicates list
570 * only update the duplicates list */ 589 */
571 list_del(&dqp->list); 590 list_del(&dqp->list);
572 kfree(dqp); 591 kfree(dqp);
573 } else { 592 } else {
574 int loc = -1; 593 int loc = -1;
575 err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 594
576 if (err) 595 err = mlx4_READ_ENTRY(dev,
596 entry->index,
597 mailbox);
598 if (err)
599 goto out_mailbox;
600 members_count =
601 be32_to_cpu(mgm->members_count) &
602 0xffffff;
603 for (i = 0; i < members_count; ++i)
604 if ((be32_to_cpu(mgm->qp[i]) &
605 MGM_QPN_MASK) == qpn) {
606 loc = i;
607 break;
608 }
609
610 if (loc < 0) {
611 mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
612 qpn, entry->index);
613 err = -EINVAL;
577 goto out_mailbox; 614 goto out_mailbox;
578 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
579 for (i = 0; i < members_count; ++i)
580 if ((be32_to_cpu(mgm->qp[i]) &
581 MGM_QPN_MASK) == qpn) {
582 loc = i;
583 break;
584 } 615 }
585 616
586 if (loc < 0) { 617 /* copy the last QP in this MGM
587 mlx4_err(dev, "QP %06x wasn't found in entry %d\n", 618 * over removed QP
588 qpn, entry->index); 619 */
589 err = -EINVAL; 620 mgm->qp[loc] = mgm->qp[members_count - 1];
590 goto out_mailbox; 621 mgm->qp[members_count - 1] = 0;
622 mgm->members_count =
623 cpu_to_be32(--members_count |
624 (MLX4_PROT_ETH << 30));
625
626 err = mlx4_WRITE_ENTRY(dev,
627 entry->index,
628 mailbox);
629 if (err)
630 goto out_mailbox;
591 } 631 }
592
593 /* copy the last QP in this MGM over removed QP */
594 mgm->qp[loc] = mgm->qp[members_count - 1];
595 mgm->qp[members_count - 1] = 0;
596 mgm->members_count = cpu_to_be32(--members_count |
597 (MLX4_PROT_ETH << 30));
598
599 err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
600 if (err)
601 goto out_mailbox;
602 } 632 }
603
604 } 633 }
605 634
606out_mailbox: 635out_mailbox: