aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h20
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c117
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c3
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
700struct mlx4_roce_gid_entry {
701 u8 raw[MLX4_ROCE_GID_ENTRY_SIZE];
702};
703
704struct 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
791struct mlx4_roce_gid_entry {
792 u8 raw[16];
793};
794
795struct mlx4_priv { 803struct 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
1141void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); 1148void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
1142void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); 1149void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
1150void mlx4_init_roce_gid_table(struct mlx4_dev *dev,
1151 struct mlx4_roce_gid_table *table);
1143void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); 1152void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);
1144int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); 1153int __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);
1151void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); 1160void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id);
1161void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave);
1152int mlx4_init_resource_tracker(struct mlx4_dev *dev); 1162int mlx4_init_resource_tracker(struct mlx4_dev *dev);
1153 1163
1154void mlx4_free_resource_tracker(struct mlx4_dev *dev, 1164void 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
78void 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
78static int validate_index(struct mlx4_dev *dev, 88static 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}
585EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix); 595EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix);
586 596
597static 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
632void 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
587static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, 675static 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}
1193EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); 1294EXPORT_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)
4681void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) 4682void 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);