diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 117 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 3 |
4 files changed, 127 insertions, 14 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 7cf9dadcb471..c187d748115f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -2044,6 +2044,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
2044 | if (!mlx4_is_slave(dev)) { | 2044 | if (!mlx4_is_slave(dev)) { |
2045 | mlx4_init_mac_table(dev, &info->mac_table); | 2045 | mlx4_init_mac_table(dev, &info->mac_table); |
2046 | mlx4_init_vlan_table(dev, &info->vlan_table); | 2046 | mlx4_init_vlan_table(dev, &info->vlan_table); |
2047 | mlx4_init_roce_gid_table(dev, &info->gid_table); | ||
2047 | info->base_qpn = mlx4_get_base_qpn(dev, port); | 2048 | info->base_qpn = mlx4_get_base_qpn(dev, port); |
2048 | } | 2049 | } |
2049 | 2050 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 212cea440f90..8e9eb02e09cb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -695,6 +695,17 @@ struct mlx4_mac_table { | |||
695 | int max; | 695 | int max; |
696 | }; | 696 | }; |
697 | 697 | ||
698 | #define MLX4_ROCE_GID_ENTRY_SIZE 16 | ||
699 | |||
700 | struct mlx4_roce_gid_entry { | ||
701 | u8 raw[MLX4_ROCE_GID_ENTRY_SIZE]; | ||
702 | }; | ||
703 | |||
704 | struct mlx4_roce_gid_table { | ||
705 | struct mlx4_roce_gid_entry roce_gids[MLX4_ROCE_MAX_GIDS]; | ||
706 | struct mutex mutex; | ||
707 | }; | ||
708 | |||
698 | #define MLX4_MAX_VLAN_NUM 128 | 709 | #define MLX4_MAX_VLAN_NUM 128 |
699 | #define MLX4_VLAN_TABLE_SIZE (MLX4_MAX_VLAN_NUM << 2) | 710 | #define MLX4_VLAN_TABLE_SIZE (MLX4_MAX_VLAN_NUM << 2) |
700 | 711 | ||
@@ -758,6 +769,7 @@ struct mlx4_port_info { | |||
758 | struct device_attribute port_mtu_attr; | 769 | struct device_attribute port_mtu_attr; |
759 | struct mlx4_mac_table mac_table; | 770 | struct mlx4_mac_table mac_table; |
760 | struct mlx4_vlan_table vlan_table; | 771 | struct mlx4_vlan_table vlan_table; |
772 | struct mlx4_roce_gid_table gid_table; | ||
761 | int base_qpn; | 773 | int base_qpn; |
762 | }; | 774 | }; |
763 | 775 | ||
@@ -788,10 +800,6 @@ enum { | |||
788 | MLX4_USE_RR = 1, | 800 | MLX4_USE_RR = 1, |
789 | }; | 801 | }; |
790 | 802 | ||
791 | struct mlx4_roce_gid_entry { | ||
792 | u8 raw[16]; | ||
793 | }; | ||
794 | |||
795 | struct mlx4_priv { | 803 | struct mlx4_priv { |
796 | struct mlx4_dev dev; | 804 | struct mlx4_dev dev; |
797 | 805 | ||
@@ -839,7 +847,6 @@ struct mlx4_priv { | |||
839 | int fs_hash_mode; | 847 | int fs_hash_mode; |
840 | u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; | 848 | u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; |
841 | __be64 slave_node_guids[MLX4_MFUNC_MAX]; | 849 | __be64 slave_node_guids[MLX4_MFUNC_MAX]; |
842 | struct mlx4_roce_gid_entry roce_gids[MLX4_MAX_PORTS][MLX4_ROCE_MAX_GIDS]; | ||
843 | 850 | ||
844 | atomic_t opreq_count; | 851 | atomic_t opreq_count; |
845 | struct work_struct opreq_task; | 852 | struct work_struct opreq_task; |
@@ -1140,6 +1147,8 @@ int mlx4_change_port_types(struct mlx4_dev *dev, | |||
1140 | 1147 | ||
1141 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); | 1148 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); |
1142 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); | 1149 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); |
1150 | void mlx4_init_roce_gid_table(struct mlx4_dev *dev, | ||
1151 | struct mlx4_roce_gid_table *table); | ||
1143 | void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); | 1152 | void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); |
1144 | int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); | 1153 | int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); |
1145 | 1154 | ||
@@ -1149,6 +1158,7 @@ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, | |||
1149 | enum mlx4_resource resource_type, | 1158 | enum mlx4_resource resource_type, |
1150 | u64 resource_id, int *slave); | 1159 | u64 resource_id, int *slave); |
1151 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); | 1160 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); |
1161 | void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave); | ||
1152 | int mlx4_init_resource_tracker(struct mlx4_dev *dev); | 1162 | int mlx4_init_resource_tracker(struct mlx4_dev *dev); |
1153 | 1163 | ||
1154 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, | 1164 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index b5b3549b0c8d..5ec6f203c6e6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -75,6 +75,16 @@ void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table) | |||
75 | table->total = 0; | 75 | table->total = 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | void mlx4_init_roce_gid_table(struct mlx4_dev *dev, | ||
79 | struct mlx4_roce_gid_table *table) | ||
80 | { | ||
81 | int i; | ||
82 | |||
83 | mutex_init(&table->mutex); | ||
84 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) | ||
85 | memset(table->roce_gids[i].raw, 0, MLX4_ROCE_GID_ENTRY_SIZE); | ||
86 | } | ||
87 | |||
78 | static int validate_index(struct mlx4_dev *dev, | 88 | static int validate_index(struct mlx4_dev *dev, |
79 | struct mlx4_mac_table *table, int index) | 89 | struct mlx4_mac_table *table, int index) |
80 | { | 90 | { |
@@ -584,6 +594,84 @@ int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port) | |||
584 | } | 594 | } |
585 | EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix); | 595 | EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix); |
586 | 596 | ||
597 | static int mlx4_reset_roce_port_gids(struct mlx4_dev *dev, int slave, | ||
598 | int port, struct mlx4_cmd_mailbox *mailbox) | ||
599 | { | ||
600 | struct mlx4_roce_gid_entry *gid_entry_mbox; | ||
601 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
602 | int num_gids, base, offset; | ||
603 | int i, err; | ||
604 | |||
605 | num_gids = mlx4_get_slave_num_gids(dev, slave, port); | ||
606 | base = mlx4_get_base_gid_ix(dev, slave, port); | ||
607 | |||
608 | memset(mailbox->buf, 0, MLX4_MAILBOX_SIZE); | ||
609 | |||
610 | mutex_lock(&(priv->port[port].gid_table.mutex)); | ||
611 | /* Zero-out gids belonging to that slave in the port GID table */ | ||
612 | for (i = 0, offset = base; i < num_gids; offset++, i++) | ||
613 | memcpy(priv->port[port].gid_table.roce_gids[offset].raw, | ||
614 | zgid_entry.raw, MLX4_ROCE_GID_ENTRY_SIZE); | ||
615 | |||
616 | /* Now, copy roce port gids table to mailbox for passing to FW */ | ||
617 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)mailbox->buf; | ||
618 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) | ||
619 | memcpy(gid_entry_mbox->raw, | ||
620 | priv->port[port].gid_table.roce_gids[i].raw, | ||
621 | MLX4_ROCE_GID_ENTRY_SIZE); | ||
622 | |||
623 | err = mlx4_cmd(dev, mailbox->dma, | ||
624 | ((u32)port) | (MLX4_SET_PORT_GID_TABLE << 8), 1, | ||
625 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | ||
626 | MLX4_CMD_NATIVE); | ||
627 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
628 | return err; | ||
629 | } | ||
630 | |||
631 | |||
632 | void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave) | ||
633 | { | ||
634 | struct mlx4_active_ports actv_ports; | ||
635 | struct mlx4_cmd_mailbox *mailbox; | ||
636 | int num_eth_ports, err; | ||
637 | int i; | ||
638 | |||
639 | if (slave < 0 || slave > dev->num_vfs) | ||
640 | return; | ||
641 | |||
642 | actv_ports = mlx4_get_active_ports(dev, slave); | ||
643 | |||
644 | for (i = 0, num_eth_ports = 0; i < dev->caps.num_ports; i++) { | ||
645 | if (test_bit(i, actv_ports.ports)) { | ||
646 | if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH) | ||
647 | continue; | ||
648 | num_eth_ports++; | ||
649 | } | ||
650 | } | ||
651 | |||
652 | if (!num_eth_ports) | ||
653 | return; | ||
654 | |||
655 | /* have ETH ports. Alloc mailbox for SET_PORT command */ | ||
656 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
657 | if (IS_ERR(mailbox)) | ||
658 | return; | ||
659 | |||
660 | for (i = 0; i < dev->caps.num_ports; i++) { | ||
661 | if (test_bit(i, actv_ports.ports)) { | ||
662 | if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH) | ||
663 | continue; | ||
664 | err = mlx4_reset_roce_port_gids(dev, slave, i + 1, mailbox); | ||
665 | if (err) | ||
666 | mlx4_warn(dev, "Could not reset ETH port GID table for slave %d, port %d (%d)\n", | ||
667 | slave, i + 1, err); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
672 | return; | ||
673 | } | ||
674 | |||
587 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | 675 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, |
588 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) | 676 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) |
589 | { | 677 | { |
@@ -692,10 +780,12 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
692 | /* 2. Check that do not have duplicates in OTHER | 780 | /* 2. Check that do not have duplicates in OTHER |
693 | * entries in the port GID table | 781 | * entries in the port GID table |
694 | */ | 782 | */ |
783 | |||
784 | mutex_lock(&(priv->port[port].gid_table.mutex)); | ||
695 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 785 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { |
696 | if (i >= base && i < base + num_gids) | 786 | if (i >= base && i < base + num_gids) |
697 | continue; /* don't compare to slave's current gids */ | 787 | continue; /* don't compare to slave's current gids */ |
698 | gid_entry_tbl = &priv->roce_gids[port - 1][i]; | 788 | gid_entry_tbl = &priv->port[port].gid_table.roce_gids[i]; |
699 | if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) | 789 | if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) |
700 | continue; | 790 | continue; |
701 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 791 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
@@ -709,6 +799,7 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
709 | mlx4_warn(dev, "requested gid entry for slave:%d " | 799 | mlx4_warn(dev, "requested gid entry for slave:%d " |
710 | "is a duplicate of gid at index %d\n", | 800 | "is a duplicate of gid at index %d\n", |
711 | slave, i); | 801 | slave, i); |
802 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
712 | return -EINVAL; | 803 | return -EINVAL; |
713 | } | 804 | } |
714 | } | 805 | } |
@@ -717,16 +808,24 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
717 | /* insert slave GIDs with memcpy, starting at slave's base index */ | 808 | /* insert slave GIDs with memcpy, starting at slave's base index */ |
718 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 809 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
719 | for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) | 810 | for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) |
720 | memcpy(priv->roce_gids[port - 1][offset].raw, gid_entry_mbox->raw, 16); | 811 | memcpy(priv->port[port].gid_table.roce_gids[offset].raw, |
812 | gid_entry_mbox->raw, MLX4_ROCE_GID_ENTRY_SIZE); | ||
721 | 813 | ||
722 | /* Now, copy roce port gids table to current mailbox for passing to FW */ | 814 | /* Now, copy roce port gids table to current mailbox for passing to FW */ |
723 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 815 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
724 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) | 816 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) |
725 | memcpy(gid_entry_mbox->raw, priv->roce_gids[port - 1][i].raw, 16); | 817 | memcpy(gid_entry_mbox->raw, |
726 | 818 | priv->port[port].gid_table.roce_gids[i].raw, | |
727 | break; | 819 | MLX4_ROCE_GID_ENTRY_SIZE); |
820 | |||
821 | err = mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod, | ||
822 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | ||
823 | MLX4_CMD_NATIVE); | ||
824 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
825 | return err; | ||
728 | } | 826 | } |
729 | return mlx4_cmd(dev, inbox->dma, in_mod, op_mod, | 827 | |
828 | return mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod, | ||
730 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | 829 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, |
731 | MLX4_CMD_NATIVE); | 830 | MLX4_CMD_NATIVE); |
732 | } | 831 | } |
@@ -1099,7 +1198,8 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
1099 | num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1; | 1198 | num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1; |
1100 | 1199 | ||
1101 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 1200 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { |
1102 | if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) { | 1201 | if (!memcmp(priv->port[port].gid_table.roce_gids[i].raw, gid, |
1202 | MLX4_ROCE_GID_ENTRY_SIZE)) { | ||
1103 | found_ix = i; | 1203 | found_ix = i; |
1104 | break; | 1204 | break; |
1105 | } | 1205 | } |
@@ -1187,7 +1287,8 @@ int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, | |||
1187 | if (!mlx4_is_master(dev)) | 1287 | if (!mlx4_is_master(dev)) |
1188 | return -EINVAL; | 1288 | return -EINVAL; |
1189 | 1289 | ||
1190 | memcpy(gid, priv->roce_gids[port - 1][slave_id].raw, 16); | 1290 | memcpy(gid, priv->port[port].gid_table.roce_gids[slave_id].raw, |
1291 | MLX4_ROCE_GID_ENTRY_SIZE); | ||
1191 | return 0; | 1292 | return 0; |
1192 | } | 1293 | } |
1193 | EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); | 1294 | EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 8f1254a79832..f16e539749c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -586,6 +586,7 @@ void mlx4_free_resource_tracker(struct mlx4_dev *dev, | |||
586 | } | 586 | } |
587 | /* free master's vlans */ | 587 | /* free master's vlans */ |
588 | i = dev->caps.function; | 588 | i = dev->caps.function; |
589 | mlx4_reset_roce_gids(dev, i); | ||
589 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); | 590 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); |
590 | rem_slave_vlans(dev, i); | 591 | rem_slave_vlans(dev, i); |
591 | mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); | 592 | mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); |
@@ -4681,7 +4682,7 @@ static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) | |||
4681 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) | 4682 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) |
4682 | { | 4683 | { |
4683 | struct mlx4_priv *priv = mlx4_priv(dev); | 4684 | struct mlx4_priv *priv = mlx4_priv(dev); |
4684 | 4685 | mlx4_reset_roce_gids(dev, slave); | |
4685 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); | 4686 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); |
4686 | rem_slave_vlans(dev, slave); | 4687 | rem_slave_vlans(dev, slave); |
4687 | rem_slave_macs(dev, slave); | 4688 | rem_slave_macs(dev, slave); |