net/mlx4: Add utils for N-Port VFs
authorMatan Barak <matanb@mellanox.com>
Wed, 19 Mar 2014 16:11:51 +0000 (18:11 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 20 Mar 2014 20:18:29 +0000 (16:18 -0400)
This patch adds the following utils:
1. Convert slave_id -> VF
2. Get the active ports by slave_id
3. Convert slave's port to real port
4. Get the slave's port from real port
5. Get all slaves that uses the i'th real port
6. Get all slaves that uses the i'th real port exclusively

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>
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
include/linux/mlx4/device.h

index 2b0b45ece14b203ce0ba08f0bafc90e65ba38274..59a1b27032819f7067c7c44c212822cf4b044e02 100644 (file)
@@ -2234,6 +2234,112 @@ static int mlx4_get_slave_indx(struct mlx4_dev *dev, int vf)
        return vf+1;
 }
 
+int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave)
+{
+       if (slave < 1 || slave > dev->num_vfs) {
+               mlx4_err(dev,
+                        "Bad slave number:%d (number of activated slaves: %lu)\n",
+                        slave, dev->num_slaves);
+               return -EINVAL;
+       }
+       return slave - 1;
+}
+
+struct mlx4_active_ports mlx4_get_active_ports(struct mlx4_dev *dev, int slave)
+{
+       struct mlx4_active_ports actv_ports;
+       int vf;
+
+       bitmap_zero(actv_ports.ports, MLX4_MAX_PORTS);
+
+       if (slave == 0) {
+               bitmap_fill(actv_ports.ports, dev->caps.num_ports);
+               return actv_ports;
+       }
+
+       vf = mlx4_get_vf_indx(dev, slave);
+       if (vf < 0)
+               return actv_ports;
+
+       bitmap_set(actv_ports.ports, dev->dev_vfs[vf].min_port - 1,
+                  min((int)dev->dev_vfs[mlx4_get_vf_indx(dev, slave)].n_ports,
+                  dev->caps.num_ports));
+
+       return actv_ports;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_active_ports);
+
+int mlx4_slave_convert_port(struct mlx4_dev *dev, int slave, int port)
+{
+       unsigned n;
+       struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave);
+       unsigned m = bitmap_weight(actv_ports.ports, dev->caps.num_ports);
+
+       if (port <= 0 || port > m)
+               return -EINVAL;
+
+       n = find_first_bit(actv_ports.ports, dev->caps.num_ports);
+       if (port <= n)
+               port = n + 1;
+
+       return port;
+}
+EXPORT_SYMBOL_GPL(mlx4_slave_convert_port);
+
+int mlx4_phys_to_slave_port(struct mlx4_dev *dev, int slave, int port)
+{
+       struct mlx4_active_ports actv_ports = mlx4_get_active_ports(dev, slave);
+       if (test_bit(port - 1, actv_ports.ports))
+               return port -
+                       find_first_bit(actv_ports.ports, dev->caps.num_ports);
+
+       return -1;
+}
+EXPORT_SYMBOL_GPL(mlx4_phys_to_slave_port);
+
+struct mlx4_slaves_pport mlx4_phys_to_slaves_pport(struct mlx4_dev *dev,
+                                                  int port)
+{
+       unsigned i;
+       struct mlx4_slaves_pport slaves_pport;
+
+       bitmap_zero(slaves_pport.slaves, MLX4_MFUNC_MAX);
+
+       if (port <= 0 || port > dev->caps.num_ports)
+               return slaves_pport;
+
+       for (i = 0; i < dev->num_vfs + 1; i++) {
+               struct mlx4_active_ports actv_ports =
+                       mlx4_get_active_ports(dev, i);
+               if (test_bit(port - 1, actv_ports.ports))
+                       set_bit(i, slaves_pport.slaves);
+       }
+
+       return slaves_pport;
+}
+EXPORT_SYMBOL_GPL(mlx4_phys_to_slaves_pport);
+
+struct mlx4_slaves_pport mlx4_phys_to_slaves_pport_actv(
+               struct mlx4_dev *dev,
+               const struct mlx4_active_ports *crit_ports)
+{
+       unsigned i;
+       struct mlx4_slaves_pport slaves_pport;
+
+       bitmap_zero(slaves_pport.slaves, MLX4_MFUNC_MAX);
+
+       for (i = 0; i < dev->num_vfs + 1; i++) {
+               struct mlx4_active_ports actv_ports =
+                       mlx4_get_active_ports(dev, i);
+               if (bitmap_equal(crit_ports->ports, actv_ports.ports,
+                                dev->caps.num_ports))
+                       set_bit(i, slaves_pport.slaves);
+       }
+
+       return slaves_pport;
+}
+EXPORT_SYMBOL_GPL(mlx4_phys_to_slaves_pport_actv);
+
 int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
index 6ba38c98c49245e447fc9fa919779c7c3ccf669a..fe8715e35afa72b1ce93039e7bddda4432fcb45a 100644 (file)
@@ -1289,5 +1289,7 @@ void mlx4_init_quotas(struct mlx4_dev *dev);
 
 int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave);
 int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave);
+/* Returns the VF index of slave */
+int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave);
 
 #endif /* MLX4_H */
index b3044f32aef1e1adc42ade7cfc8c58b3315f2d2c..122c7cabaee744239d4467a40e3f1be144951ccf 100644 (file)
@@ -1204,4 +1204,31 @@ int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
 
 cycle_t mlx4_read_clock(struct mlx4_dev *dev);
 
+struct mlx4_active_ports {
+       DECLARE_BITMAP(ports, MLX4_MAX_PORTS);
+};
+/* Returns a bitmap of the physical ports which are assigned to slave */
+struct mlx4_active_ports mlx4_get_active_ports(struct mlx4_dev *dev, int slave);
+
+/* Returns the physical port that represents the virtual port of the slave, */
+/* or a value < 0 in case of an error. If a slave has 2 ports, the identity */
+/* mapping is returned.                                                            */
+int mlx4_slave_convert_port(struct mlx4_dev *dev, int slave, int port);
+
+struct mlx4_slaves_pport {
+       DECLARE_BITMAP(slaves, MLX4_MFUNC_MAX);
+};
+/* Returns a bitmap of all slaves that are assigned to port. */
+struct mlx4_slaves_pport mlx4_phys_to_slaves_pport(struct mlx4_dev *dev,
+                                                  int port);
+
+/* Returns a bitmap of all slaves that are assigned exactly to all the */
+/* the ports that are set in crit_ports.                              */
+struct mlx4_slaves_pport mlx4_phys_to_slaves_pport_actv(
+               struct mlx4_dev *dev,
+               const struct mlx4_active_ports *crit_ports);
+
+/* Returns the slave's virtual port that represents the physical port. */
+int mlx4_phys_to_slave_port(struct mlx4_dev *dev, int slave, int port);
+
 #endif /* MLX4_DEVICE_H */