net/mlx4_core: Fix slave id computation for single port VF
The code that deals with computing the slave id based on a given GID
gave wrong results when the number of single port VFs wasn't the
same for port 1 vs. port 2 and the relevant VF is single ported on
port 2. As a result, incoming CM MADs were dispatched to the wrong VF.
Fixed that and added documentation to clarify the computation steps.
Fixes: 449fc48
('net/mlx4: Adapt code for N-Port VF')
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>
This commit is contained in:
parent
531d9014d5
commit
0254bc8205
|
@ -1106,6 +1106,9 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
|
|||
}
|
||||
|
||||
if (found_ix >= 0) {
|
||||
/* Calculate a slave_gid which is the slave number in the gid
|
||||
* table and not a globally unique slave number.
|
||||
*/
|
||||
if (found_ix < MLX4_ROCE_PF_GIDS)
|
||||
slave_gid = 0;
|
||||
else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
|
||||
|
@ -1118,41 +1121,43 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
|
|||
((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
|
||||
(vf_gids / num_vfs)) + vf_gids % num_vfs + 1;
|
||||
|
||||
/* Calculate the globally unique slave id */
|
||||
if (slave_gid) {
|
||||
struct mlx4_active_ports exclusive_ports;
|
||||
struct mlx4_active_ports actv_ports;
|
||||
struct mlx4_slaves_pport slaves_pport_actv;
|
||||
unsigned max_port_p_one;
|
||||
int num_slaves_before = 1;
|
||||
int num_vfs_before = 0;
|
||||
int candidate_slave_gid;
|
||||
|
||||
/* Calculate how many VFs are on the previous port, if exists */
|
||||
for (i = 1; i < port; i++) {
|
||||
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
|
||||
set_bit(i, exclusive_ports.ports);
|
||||
set_bit(i - 1, exclusive_ports.ports);
|
||||
slaves_pport_actv =
|
||||
mlx4_phys_to_slaves_pport_actv(
|
||||
dev, &exclusive_ports);
|
||||
num_slaves_before += bitmap_weight(
|
||||
num_vfs_before += bitmap_weight(
|
||||
slaves_pport_actv.slaves,
|
||||
dev->num_vfs + 1);
|
||||
}
|
||||
|
||||
if (slave_gid < num_slaves_before) {
|
||||
bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
|
||||
set_bit(port - 1, exclusive_ports.ports);
|
||||
slaves_pport_actv =
|
||||
mlx4_phys_to_slaves_pport_actv(
|
||||
dev, &exclusive_ports);
|
||||
slave_gid += bitmap_weight(
|
||||
slaves_pport_actv.slaves,
|
||||
dev->num_vfs + 1) -
|
||||
num_slaves_before;
|
||||
}
|
||||
actv_ports = mlx4_get_active_ports(dev, slave_gid);
|
||||
/* candidate_slave_gid isn't necessarily the correct slave, but
|
||||
* it has the same number of ports and is assigned to the same
|
||||
* ports as the real slave we're looking for. On dual port VF,
|
||||
* slave_gid = [single port VFs on port <port>] +
|
||||
* [offset of the current slave from the first dual port VF] +
|
||||
* 1 (for the PF).
|
||||
*/
|
||||
candidate_slave_gid = slave_gid + num_vfs_before;
|
||||
|
||||
actv_ports = mlx4_get_active_ports(dev, candidate_slave_gid);
|
||||
max_port_p_one = find_first_bit(
|
||||
actv_ports.ports, dev->caps.num_ports) +
|
||||
bitmap_weight(actv_ports.ports,
|
||||
dev->caps.num_ports) + 1;
|
||||
|
||||
/* Calculate the real slave number */
|
||||
for (i = 1; i < max_port_p_one; i++) {
|
||||
if (i == port)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue