aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/port.c
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2014-03-19 12:11:52 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-20 16:18:30 -0400
commit449fc48866f7d84b0d9a19201de18a4dd4d3488c (patch)
tree20db12e2dd676c6c824a8173601c9023632d3c37 /drivers/net/ethernet/mellanox/mlx4/port.c
parentf74462acf8f390528c8b7937f227c6c90d017f3b (diff)
net/mlx4: Adapt code for N-Port VF
Adds support for N-Port VFs, this includes: 1. Adding support in the wrapped FW command In wrapped commands, we need to verify and convert the slave's port into the real physical port. Furthermore, when sending the response back to the slave, a reverse conversion should be made. 2. Adjusting sqpn for QP1 para-virtualization The slave assumes that sqpn is used for QP1 communication. If the slave is assigned to a port != (first port), we need to adjust the sqpn that will direct its QP1 packets into the correct endpoint. 3. Adjusting gid[5] to modify the port for raw ethernet In B0 steering, gid[5] contains the port. It needs to be adjusted into the physical port. 4. Adjusting number of ports in the query / ports caps in the FW commands When a slave queries the hardware, it needs to view only the physical ports it's assigned to. 5. Adjusting the sched_qp according to the port number The QP port is encoded in the sched_qp, thus in modify_qp we need to encode the correct port in sched_qp. Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/port.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c158
1 files changed, 138 insertions, 20 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index ece328166e94..2705b9ab9463 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -507,30 +507,82 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
507} 507}
508static struct mlx4_roce_gid_entry zgid_entry; 508static struct mlx4_roce_gid_entry zgid_entry;
509 509
510int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave) 510int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port)
511{ 511{
512 int vfs;
513 int slave_gid = slave;
514 unsigned i;
515 struct mlx4_slaves_pport slaves_pport;
516 struct mlx4_active_ports actv_ports;
517 unsigned max_port_p_one;
518
512 if (slave == 0) 519 if (slave == 0)
513 return MLX4_ROCE_PF_GIDS; 520 return MLX4_ROCE_PF_GIDS;
514 if (slave <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % dev->num_vfs)) 521
515 return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs) + 1; 522 /* Slave is a VF */
516 return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs; 523 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
524 actv_ports = mlx4_get_active_ports(dev, slave);
525 max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
526 bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
527
528 for (i = 1; i < max_port_p_one; i++) {
529 struct mlx4_active_ports exclusive_ports;
530 struct mlx4_slaves_pport slaves_pport_actv;
531 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
532 set_bit(i - 1, exclusive_ports.ports);
533 if (i == port)
534 continue;
535 slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
536 dev, &exclusive_ports);
537 slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
538 dev->num_vfs + 1);
539 }
540 vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
541 if (slave_gid <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % vfs))
542 return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs) + 1;
543 return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / vfs;
517} 544}
518 545
519int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave) 546int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port)
520{ 547{
521 int gids; 548 int gids;
549 unsigned i;
550 int slave_gid = slave;
522 int vfs; 551 int vfs;
523 552
524 gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; 553 struct mlx4_slaves_pport slaves_pport;
525 vfs = dev->num_vfs; 554 struct mlx4_active_ports actv_ports;
555 unsigned max_port_p_one;
526 556
527 if (slave == 0) 557 if (slave == 0)
528 return 0; 558 return 0;
529 if (slave <= gids % vfs)
530 return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1);
531 559
532 return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1)); 560 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
561 actv_ports = mlx4_get_active_ports(dev, slave);
562 max_port_p_one = find_first_bit(actv_ports.ports, dev->caps.num_ports) +
563 bitmap_weight(actv_ports.ports, dev->caps.num_ports) + 1;
564
565 for (i = 1; i < max_port_p_one; i++) {
566 struct mlx4_active_ports exclusive_ports;
567 struct mlx4_slaves_pport slaves_pport_actv;
568 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
569 set_bit(i - 1, exclusive_ports.ports);
570 if (i == port)
571 continue;
572 slaves_pport_actv = mlx4_phys_to_slaves_pport_actv(
573 dev, &exclusive_ports);
574 slave_gid -= bitmap_weight(slaves_pport_actv.slaves,
575 dev->num_vfs + 1);
576 }
577 gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
578 vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
579 if (slave_gid <= gids % vfs)
580 return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave_gid - 1);
581
582 return MLX4_ROCE_PF_GIDS + (gids % vfs) +
583 ((gids / vfs) * (slave_gid - 1));
533} 584}
585EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix);
534 586
535static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, 587static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
536 u8 op_mod, struct mlx4_cmd_mailbox *inbox) 588 u8 op_mod, struct mlx4_cmd_mailbox *inbox)
@@ -617,8 +669,8 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
617 * need a FOR-loop here over number of gids the guest has. 669 * need a FOR-loop here over number of gids the guest has.
618 * 1. Check no duplicates in gids passed by slave 670 * 1. Check no duplicates in gids passed by slave
619 */ 671 */
620 num_gids = mlx4_get_slave_num_gids(dev, slave); 672 num_gids = mlx4_get_slave_num_gids(dev, slave, port);
621 base = mlx4_get_base_gid_ix(dev, slave); 673 base = mlx4_get_base_gid_ix(dev, slave, port);
622 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); 674 gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf);
623 for (i = 0; i < num_gids; gid_entry_mbox++, i++) { 675 for (i = 0; i < num_gids; gid_entry_mbox++, i++) {
624 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, 676 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw,
@@ -738,6 +790,15 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
738 struct mlx4_cmd_mailbox *outbox, 790 struct mlx4_cmd_mailbox *outbox,
739 struct mlx4_cmd_info *cmd) 791 struct mlx4_cmd_info *cmd)
740{ 792{
793 int port = mlx4_slave_convert_port(
794 dev, slave, vhcr->in_modifier & 0xFF);
795
796 if (port < 0)
797 return -EINVAL;
798
799 vhcr->in_modifier = (vhcr->in_modifier & ~0xFF) |
800 (port & 0xFF);
801
741 return mlx4_common_set_port(dev, slave, vhcr->in_modifier, 802 return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
742 vhcr->op_modifier, inbox); 803 vhcr->op_modifier, inbox);
743} 804}
@@ -1026,10 +1087,16 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
1026 struct mlx4_priv *priv = mlx4_priv(dev); 1087 struct mlx4_priv *priv = mlx4_priv(dev);
1027 int i, found_ix = -1; 1088 int i, found_ix = -1;
1028 int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; 1089 int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS;
1090 struct mlx4_slaves_pport slaves_pport;
1091 unsigned num_vfs;
1092 int slave_gid;
1029 1093
1030 if (!mlx4_is_mfunc(dev)) 1094 if (!mlx4_is_mfunc(dev))
1031 return -EINVAL; 1095 return -EINVAL;
1032 1096
1097 slaves_pport = mlx4_phys_to_slaves_pport(dev, port);
1098 num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1;
1099
1033 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { 1100 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) {
1034 if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) { 1101 if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) {
1035 found_ix = i; 1102 found_ix = i;
@@ -1039,16 +1106,67 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
1039 1106
1040 if (found_ix >= 0) { 1107 if (found_ix >= 0) {
1041 if (found_ix < MLX4_ROCE_PF_GIDS) 1108 if (found_ix < MLX4_ROCE_PF_GIDS)
1042 *slave_id = 0; 1109 slave_gid = 0;
1043 else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % dev->num_vfs) * 1110 else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
1044 (vf_gids / dev->num_vfs + 1)) 1111 (vf_gids / num_vfs + 1))
1045 *slave_id = ((found_ix - MLX4_ROCE_PF_GIDS) / 1112 slave_gid = ((found_ix - MLX4_ROCE_PF_GIDS) /
1046 (vf_gids / dev->num_vfs + 1)) + 1; 1113 (vf_gids / num_vfs + 1)) + 1;
1047 else 1114 else
1048 *slave_id = 1115 slave_gid =
1049 ((found_ix - MLX4_ROCE_PF_GIDS - 1116 ((found_ix - MLX4_ROCE_PF_GIDS -
1050 ((vf_gids % dev->num_vfs) * ((vf_gids / dev->num_vfs + 1)))) / 1117 ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
1051 (vf_gids / dev->num_vfs)) + vf_gids % dev->num_vfs + 1; 1118 (vf_gids / num_vfs)) + vf_gids % num_vfs + 1;
1119
1120 if (slave_gid) {
1121 struct mlx4_active_ports exclusive_ports;
1122 struct mlx4_active_ports actv_ports;
1123 struct mlx4_slaves_pport slaves_pport_actv;
1124 unsigned max_port_p_one;
1125 int num_slaves_before = 1;
1126
1127 for (i = 1; i < port; i++) {
1128 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
1129 set_bit(i, exclusive_ports.ports);
1130 slaves_pport_actv =
1131 mlx4_phys_to_slaves_pport_actv(
1132 dev, &exclusive_ports);
1133 num_slaves_before += bitmap_weight(
1134 slaves_pport_actv.slaves,
1135 dev->num_vfs + 1);
1136 }
1137
1138 if (slave_gid < num_slaves_before) {
1139 bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
1140 set_bit(port - 1, exclusive_ports.ports);
1141 slaves_pport_actv =
1142 mlx4_phys_to_slaves_pport_actv(
1143 dev, &exclusive_ports);
1144 slave_gid += bitmap_weight(
1145 slaves_pport_actv.slaves,
1146 dev->num_vfs + 1) -
1147 num_slaves_before;
1148 }
1149 actv_ports = mlx4_get_active_ports(dev, slave_gid);
1150 max_port_p_one = find_first_bit(
1151 actv_ports.ports, dev->caps.num_ports) +
1152 bitmap_weight(actv_ports.ports,
1153 dev->caps.num_ports) + 1;
1154
1155 for (i = 1; i < max_port_p_one; i++) {
1156 if (i == port)
1157 continue;
1158 bitmap_zero(exclusive_ports.ports,
1159 dev->caps.num_ports);
1160 set_bit(i - 1, exclusive_ports.ports);
1161 slaves_pport_actv =
1162 mlx4_phys_to_slaves_pport_actv(
1163 dev, &exclusive_ports);
1164 slave_gid += bitmap_weight(
1165 slaves_pport_actv.slaves,
1166 dev->num_vfs + 1);
1167 }
1168 }
1169 *slave_id = slave_gid;
1052 } 1170 }
1053 1171
1054 return (found_ix >= 0) ? 0 : -EINVAL; 1172 return (found_ix >= 0) ? 0 : -EINVAL;