aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-06-19 04:21:44 -0400
committerRoland Dreier <roland@purestorage.com>2012-07-11 14:52:23 -0400
commit6634961c14d38ef64ec284c07aecb03d3dd03b4a (patch)
treea91bc4fa44848799c3035a9bfea1b288c2edac82 /drivers/net
parent105c320f6ac37af30252577d419e47b39edb5843 (diff)
mlx4: Put physical GID and P_Key table sizes in mlx4_phys_caps struct and paravirtualize them
To allow easy paravirtualization of P_Key and GID table sizes, keep paravirtualized sizes in mlx4_dev->caps, but save the actual physical sizes from FW in struct: mlx4_dev->phys_cap. In addition, in SR-IOV mode, do the following: 1. Reduce reported P_Key table size by 1. This is done to reserve the highest P_Key index for internal use, for declaring an invalid P_Key in P_Key paravirtualization. We require a P_Key index which always contain an invalid P_Key value for this purpose (i.e., one which cannot be modified by the subnet manager). The way to do this is to reduce the P_Key table size reported to the subnet manager by 1, so that it will not attempt to access the P_Key at index #127. 2. Paravirtualize the GID table size to 1. Thus, each guest sees only a single GID (at its paravirtualized index 0). In addition, since we are paravirtualizing the GID table size to 1, we add paravirtualization of the master GID event here (i.e., we do not do ib_dispatch_event() for the GUID change event on the master, since its (only) GUID never changes). Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c43
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c11
4 files changed, 83 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 5549f6b3bb6..473d63b63b4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -730,9 +730,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
730{ 730{
731 u64 def_mac; 731 u64 def_mac;
732 u8 port_type; 732 u8 port_type;
733 u16 short_field;
733 int err; 734 int err;
734 735
735#define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 736#define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0
737#define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c
738#define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e
736 739
737 err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, 740 err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0,
738 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, 741 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B,
@@ -755,11 +758,51 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
755 758
756 MLX4_PUT(outbox->buf, port_type, 759 MLX4_PUT(outbox->buf, port_type,
757 QUERY_PORT_SUPPORTED_TYPE_OFFSET); 760 QUERY_PORT_SUPPORTED_TYPE_OFFSET);
761
762 short_field = 1; /* slave max gids */
763 MLX4_PUT(outbox->buf, short_field,
764 QUERY_PORT_CUR_MAX_GID_OFFSET);
765
766 short_field = dev->caps.pkey_table_len[vhcr->in_modifier];
767 MLX4_PUT(outbox->buf, short_field,
768 QUERY_PORT_CUR_MAX_PKEY_OFFSET);
758 } 769 }
759 770
760 return err; 771 return err;
761} 772}
762 773
774int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port,
775 int *gid_tbl_len, int *pkey_tbl_len)
776{
777 struct mlx4_cmd_mailbox *mailbox;
778 u32 *outbox;
779 u16 field;
780 int err;
781
782 mailbox = mlx4_alloc_cmd_mailbox(dev);
783 if (IS_ERR(mailbox))
784 return PTR_ERR(mailbox);
785
786 err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 0,
787 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B,
788 MLX4_CMD_WRAPPED);
789 if (err)
790 goto out;
791
792 outbox = mailbox->buf;
793
794 MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_GID_OFFSET);
795 *gid_tbl_len = field;
796
797 MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_PKEY_OFFSET);
798 *pkey_tbl_len = field;
799
800out:
801 mlx4_free_cmd_mailbox(dev, mailbox);
802 return err;
803}
804EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len);
805
763int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) 806int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt)
764{ 807{
765 struct mlx4_cmd_mailbox *mailbox; 808 struct mlx4_cmd_mailbox *mailbox;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 58544b72bac..5df3ac40a49 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -215,6 +215,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
215 for (i = 1; i <= dev->caps.num_ports; ++i) { 215 for (i = 1; i <= dev->caps.num_ports; ++i) {
216 dev->caps.vl_cap[i] = dev_cap->max_vl[i]; 216 dev->caps.vl_cap[i] = dev_cap->max_vl[i];
217 dev->caps.ib_mtu_cap[i] = dev_cap->ib_mtu[i]; 217 dev->caps.ib_mtu_cap[i] = dev_cap->ib_mtu[i];
218 dev->phys_caps.gid_phys_table_len[i] = dev_cap->max_gids[i];
219 dev->phys_caps.pkey_phys_table_len[i] = dev_cap->max_pkeys[i];
220 /* set gid and pkey table operating lengths by default
221 * to non-sriov values */
218 dev->caps.gid_table_len[i] = dev_cap->max_gids[i]; 222 dev->caps.gid_table_len[i] = dev_cap->max_gids[i];
219 dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i]; 223 dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i];
220 dev->caps.port_width_cap[i] = dev_cap->max_port_width[i]; 224 dev->caps.port_width_cap[i] = dev_cap->max_port_width[i];
@@ -498,8 +502,13 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
498 return -ENODEV; 502 return -ENODEV;
499 } 503 }
500 504
501 for (i = 1; i <= dev->caps.num_ports; ++i) 505 for (i = 1; i <= dev->caps.num_ports; ++i) {
502 dev->caps.port_mask[i] = dev->caps.port_type[i]; 506 dev->caps.port_mask[i] = dev->caps.port_type[i];
507 if (mlx4_get_slave_pkey_gid_tbl_len(dev, i,
508 &dev->caps.gid_table_len[i],
509 &dev->caps.pkey_table_len[i]))
510 return -ENODEV;
511 }
503 512
504 if (dev->caps.uar_page_size * (dev->caps.num_uars - 513 if (dev->caps.uar_page_size * (dev->caps.num_uars -
505 dev->caps.reserved_uars) > 514 dev->caps.reserved_uars) >
@@ -536,7 +545,7 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
536 for (port = 1; port <= dev->caps.num_ports; port++) { 545 for (port = 1; port <= dev->caps.num_ports; port++) {
537 mlx4_CLOSE_PORT(dev, port); 546 mlx4_CLOSE_PORT(dev, port);
538 dev->caps.port_type[port] = port_types[port - 1]; 547 dev->caps.port_type[port] = port_types[port - 1];
539 err = mlx4_SET_PORT(dev, port); 548 err = mlx4_SET_PORT(dev, port, -1);
540 if (err) { 549 if (err) {
541 mlx4_err(dev, "Failed to set port %d, " 550 mlx4_err(dev, "Failed to set port %d, "
542 "aborting\n", port); 551 "aborting\n", port);
@@ -722,7 +731,7 @@ static ssize_t set_port_ib_mtu(struct device *dev,
722 mlx4_unregister_device(mdev); 731 mlx4_unregister_device(mdev);
723 for (port = 1; port <= mdev->caps.num_ports; port++) { 732 for (port = 1; port <= mdev->caps.num_ports; port++) {
724 mlx4_CLOSE_PORT(mdev, port); 733 mlx4_CLOSE_PORT(mdev, port);
725 err = mlx4_SET_PORT(mdev, port); 734 err = mlx4_SET_PORT(mdev, port, -1);
726 if (err) { 735 if (err) {
727 mlx4_err(mdev, "Failed to set port %d, " 736 mlx4_err(mdev, "Failed to set port %d, "
728 "aborting\n", port); 737 "aborting\n", port);
@@ -1173,6 +1182,17 @@ err:
1173 return -EIO; 1182 return -EIO;
1174} 1183}
1175 1184
1185static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev)
1186{
1187 int i;
1188
1189 for (i = 1; i <= dev->caps.num_ports; i++) {
1190 dev->caps.gid_table_len[i] = 1;
1191 dev->caps.pkey_table_len[i] =
1192 dev->phys_caps.pkey_phys_table_len[i] - 1;
1193 }
1194}
1195
1176static int mlx4_init_hca(struct mlx4_dev *dev) 1196static int mlx4_init_hca(struct mlx4_dev *dev)
1177{ 1197{
1178 struct mlx4_priv *priv = mlx4_priv(dev); 1198 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1212,6 +1232,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
1212 goto err_stop_fw; 1232 goto err_stop_fw;
1213 } 1233 }
1214 1234
1235 if (mlx4_is_master(dev))
1236 mlx4_parav_master_pf_caps(dev);
1237
1215 profile = default_profile; 1238 profile = default_profile;
1216 1239
1217 icm_size = mlx4_make_profile(dev, &profile, &dev_cap, 1240 icm_size = mlx4_make_profile(dev, &profile, &dev_cap,
@@ -1500,7 +1523,8 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
1500 else 1523 else
1501 dev->caps.port_ib_mtu[port] = IB_MTU_4096; 1524 dev->caps.port_ib_mtu[port] = IB_MTU_4096;
1502 1525
1503 err = mlx4_SET_PORT(dev, port); 1526 err = mlx4_SET_PORT(dev, port, mlx4_is_master(dev) ?
1527 dev->caps.pkey_table_len[port] : -1);
1504 if (err) { 1528 if (err) {
1505 mlx4_err(dev, "Failed to set port %d, aborting\n", 1529 mlx4_err(dev, "Failed to set port %d, aborting\n",
1506 port); 1530 port);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 4d11d12b9db..cde6e511899 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -969,7 +969,7 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
969void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); 969void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
970void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); 970void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
971 971
972int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port); 972int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz);
973/* resource tracker functions*/ 973/* resource tracker functions*/
974int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, 974int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
975 enum mlx4_resource resource_type, 975 enum mlx4_resource resource_type,
@@ -1012,6 +1012,8 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
1012 struct mlx4_cmd_info *cmd); 1012 struct mlx4_cmd_info *cmd);
1013int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); 1013int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps);
1014 1014
1015int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port,
1016 int *gid_tbl_len, int *pkey_tbl_len);
1015 1017
1016int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, 1018int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
1017 struct mlx4_vhcr *vhcr, 1019 struct mlx4_vhcr *vhcr,
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index a8fb52992c6..90dc47542b8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -726,14 +726,15 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
726enum { 726enum {
727 MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */ 727 MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */
728 MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */ 728 MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */
729 MLX4_CHANGE_PORT_PKEY_TBL_SZ = 20,
729 MLX4_CHANGE_PORT_VL_CAP = 21, 730 MLX4_CHANGE_PORT_VL_CAP = 21,
730 MLX4_CHANGE_PORT_MTU_CAP = 22, 731 MLX4_CHANGE_PORT_MTU_CAP = 22,
731}; 732};
732 733
733int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) 734int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz)
734{ 735{
735 struct mlx4_cmd_mailbox *mailbox; 736 struct mlx4_cmd_mailbox *mailbox;
736 int err, vl_cap; 737 int err, vl_cap, pkey_tbl_flag = 0;
737 738
738 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) 739 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
739 return 0; 740 return 0;
@@ -746,11 +747,17 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
746 747
747 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; 748 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
748 749
750 if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) {
751 pkey_tbl_flag = 1;
752 ((__be16 *) mailbox->buf)[20] = cpu_to_be16(pkey_tbl_sz);
753 }
754
749 /* IB VL CAP enum isn't used by the firmware, just numerical values */ 755 /* IB VL CAP enum isn't used by the firmware, just numerical values */
750 for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) { 756 for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) {
751 ((__be32 *) mailbox->buf)[0] = cpu_to_be32( 757 ((__be32 *) mailbox->buf)[0] = cpu_to_be32(
752 (1 << MLX4_CHANGE_PORT_MTU_CAP) | 758 (1 << MLX4_CHANGE_PORT_MTU_CAP) |
753 (1 << MLX4_CHANGE_PORT_VL_CAP) | 759 (1 << MLX4_CHANGE_PORT_VL_CAP) |
760 (pkey_tbl_flag << MLX4_CHANGE_PORT_PKEY_TBL_SZ) |
754 (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) | 761 (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) |
755 (vl_cap << MLX4_SET_PORT_VL_CAP)); 762 (vl_cap << MLX4_SET_PORT_VL_CAP));
756 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, 763 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,