diff options
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 43 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 11 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 2 |
6 files changed, 92 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 58c45fb5bd31..c27141fef1ab 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -184,8 +184,10 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
184 | break; | 184 | break; |
185 | 185 | ||
186 | case IB_SMP_ATTR_GUID_INFO: | 186 | case IB_SMP_ATTR_GUID_INFO: |
187 | mlx4_ib_dispatch_event(dev, port_num, | 187 | /* paravirtualized master's guid is guid 0 -- does not change */ |
188 | IB_EVENT_GID_CHANGE); | 188 | if (!mlx4_is_master(dev->dev)) |
189 | mlx4_ib_dispatch_event(dev, port_num, | ||
190 | IB_EVENT_GID_CHANGE); | ||
189 | break; | 191 | break; |
190 | default: | 192 | default: |
191 | break; | 193 | break; |
@@ -487,7 +489,9 @@ void handle_port_mgmt_change_event(struct work_struct *work) | |||
487 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_PKEY_CHANGE); | 489 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_PKEY_CHANGE); |
488 | break; | 490 | break; |
489 | case MLX4_DEV_PMC_SUBTYPE_GUID_INFO: | 491 | case MLX4_DEV_PMC_SUBTYPE_GUID_INFO: |
490 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_GID_CHANGE); | 492 | /* paravirtualized master's guid is guid 0 -- does not change */ |
493 | if (!mlx4_is_master(dev->dev)) | ||
494 | mlx4_ib_dispatch_event(dev, port, IB_EVENT_GID_CHANGE); | ||
491 | break; | 495 | break; |
492 | default: | 496 | default: |
493 | pr_warn("Unsupported subtype 0x%x for " | 497 | pr_warn("Unsupported subtype 0x%x for " |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 5549f6b3bb67..473d63b63b4e 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 | ||
774 | int 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 | |||
800 | out: | ||
801 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
802 | return err; | ||
803 | } | ||
804 | EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len); | ||
805 | |||
763 | int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) | 806 | int 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 58544b72bacb..5df3ac40a490 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 | ||
1185 | static 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 | |||
1176 | static int mlx4_init_hca(struct mlx4_dev *dev) | 1196 | static 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 4d11d12b9db4..cde6e511899f 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, | |||
969 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); | 969 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); |
970 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); | 970 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); |
971 | 971 | ||
972 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port); | 972 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz); |
973 | /* resource tracker functions*/ | 973 | /* resource tracker functions*/ |
974 | int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, | 974 | int 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); |
1013 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); | 1013 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); |
1014 | 1014 | ||
1015 | int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port, | ||
1016 | int *gid_tbl_len, int *pkey_tbl_len); | ||
1015 | 1017 | ||
1016 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 1018 | int 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 a8fb52992c64..90dc47542b8b 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, | |||
726 | enum { | 726 | enum { |
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 | ||
733 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | 734 | int 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, |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index c30a314e095c..441caf1a497d 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -268,6 +268,8 @@ static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor) | |||
268 | } | 268 | } |
269 | 269 | ||
270 | struct mlx4_phys_caps { | 270 | struct mlx4_phys_caps { |
271 | u32 gid_phys_table_len[MLX4_MAX_PORTS + 1]; | ||
272 | u32 pkey_phys_table_len[MLX4_MAX_PORTS + 1]; | ||
271 | u32 num_phys_eqs; | 273 | u32 num_phys_eqs; |
272 | }; | 274 | }; |
273 | 275 | ||