diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/cmd.c')
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 69 | 
1 files changed, 40 insertions, 29 deletions
| diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index c678344d22a2..8d751383530b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -2241,43 +2241,52 @@ void mlx4_master_comm_channel(struct work_struct *work)  	struct mlx4_priv *priv =  		container_of(mfunc, struct mlx4_priv, mfunc);  	struct mlx4_dev *dev = &priv->dev; -	__be32 *bit_vec; +	u32 lbit_vec[COMM_CHANNEL_BIT_ARRAY_SIZE]; +	u32 nmbr_bits;  	u32 comm_cmd; -	u32 vec; -	int i, j, slave; +	int i, slave;  	int toggle; +	bool first = true;  	int served = 0;  	int reported = 0;  	u32 slt; -	bit_vec = master->comm_arm_bit_vector; -	for (i = 0; i < COMM_CHANNEL_BIT_ARRAY_SIZE; i++) { -		vec = be32_to_cpu(bit_vec[i]); -		for (j = 0; j < 32; j++) { -			if (!(vec & (1 << j))) -				continue; -			++reported; -			slave = (i * 32) + j; -			comm_cmd = swab32(readl( -					  &mfunc->comm[slave].slave_write)); -			slt = swab32(readl(&mfunc->comm[slave].slave_read)) -				     >> 31; -			toggle = comm_cmd >> 31; -			if (toggle != slt) { -				if (master->slave_state[slave].comm_toggle -				    != slt) { -					pr_info("slave %d out of sync. read toggle %d, state toggle %d. Resynching.\n", -						slave, slt, -						master->slave_state[slave].comm_toggle); -					master->slave_state[slave].comm_toggle = -						slt; -				} -				mlx4_master_do_cmd(dev, slave, -						   comm_cmd >> 16 & 0xff, -						   comm_cmd & 0xffff, toggle); -				++served; +	for (i = 0; i < COMM_CHANNEL_BIT_ARRAY_SIZE; i++) +		lbit_vec[i] = be32_to_cpu(master->comm_arm_bit_vector[i]); +	nmbr_bits = dev->persist->num_vfs + 1; +	if (++master->next_slave >= nmbr_bits) +		master->next_slave = 0; +	slave = master->next_slave; +	while (true) { +		slave = find_next_bit((const unsigned long *)&lbit_vec, nmbr_bits, slave); +		if  (!first && slave >= master->next_slave) +			break; +		if (slave == nmbr_bits) { +			if (!first) +				break; +			first = false; +			slave = 0; +			continue; +		} +		++reported; +		comm_cmd = swab32(readl(&mfunc->comm[slave].slave_write)); +		slt = swab32(readl(&mfunc->comm[slave].slave_read)) >> 31; +		toggle = comm_cmd >> 31; +		if (toggle != slt) { +			if (master->slave_state[slave].comm_toggle +			    != slt) { +				pr_info("slave %d out of sync. read toggle %d, state toggle %d. Resynching.\n", +					slave, slt, +					master->slave_state[slave].comm_toggle); +				master->slave_state[slave].comm_toggle = +					slt;  			} +			mlx4_master_do_cmd(dev, slave, +					   comm_cmd >> 16 & 0xff, +					   comm_cmd & 0xffff, toggle); +			++served;  		} +		slave++;  	}  	if (reported && reported != served) @@ -2389,6 +2398,8 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)  		if (!priv->mfunc.master.vf_oper)  			goto err_comm_oper; +		priv->mfunc.master.next_slave = 0; +  		for (i = 0; i < dev->num_slaves; ++i) {  			vf_admin = &priv->mfunc.master.vf_admin[i];  			vf_oper = &priv->mfunc.master.vf_oper[i]; | 
