forked from mirrors/linux
		
	net/mlx4: Spoofcheck and zero MAC can't coexist
Spoofcheck can't be enabled if VF MAC is zero.
Vice versa, can't zero MAC if spoofcheck is on.
Fixes: 8f7ba3ca12 ('net/mlx4: Add set VF mac address support')
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									423b3aecf2
								
							
						
					
					
						commit
						745d8ae462
					
				
					 4 changed files with 32 additions and 8 deletions
				
			
		|  | @ -43,6 +43,7 @@ | |||
| #include <linux/semaphore.h> | ||||
| #include <rdma/ib_smi.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/etherdevice.h> | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
|  | @ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port, | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | ||||
| int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac) | ||||
| { | ||||
| 	struct mlx4_priv *priv = mlx4_priv(dev); | ||||
| 	struct mlx4_vport_state *s_info; | ||||
|  | @ -2964,13 +2965,22 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) | |||
| 	if (!mlx4_is_master(dev)) | ||||
| 		return -EPROTONOSUPPORT; | ||||
| 
 | ||||
| 	if (is_multicast_ether_addr(mac)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	slave = mlx4_get_slave_indx(dev, vf); | ||||
| 	if (slave < 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	port = mlx4_slaves_closest_port(dev, slave, port); | ||||
| 	s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | ||||
| 	s_info->mac = mac; | ||||
| 
 | ||||
| 	if (s_info->spoofchk && is_zero_ether_addr(mac)) { | ||||
| 		mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n"); | ||||
| 		return -EPERM; | ||||
| 	} | ||||
| 
 | ||||
| 	s_info->mac = mlx4_mac_to_u64(mac); | ||||
| 	mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n", | ||||
| 		  vf, port, s_info->mac); | ||||
| 	return 0; | ||||
|  | @ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting) | |||
| 	struct mlx4_priv *priv = mlx4_priv(dev); | ||||
| 	struct mlx4_vport_state *s_info; | ||||
| 	int slave; | ||||
| 	u8 mac[ETH_ALEN]; | ||||
| 
 | ||||
| 	if ((!mlx4_is_master(dev)) || | ||||
| 	    !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM)) | ||||
|  | @ -3154,6 +3165,13 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting) | |||
| 
 | ||||
| 	port = mlx4_slaves_closest_port(dev, slave, port); | ||||
| 	s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; | ||||
| 
 | ||||
| 	mlx4_u64_to_mac(mac, s_info->mac); | ||||
| 	if (setting && !is_valid_ether_addr(mac)) { | ||||
| 		mlx4_info(dev, "Illegal MAC with spoofchk\n"); | ||||
| 		return -EPERM; | ||||
| 	} | ||||
| 
 | ||||
| 	s_info->spoofchk = setting; | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -2485,12 +2485,8 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac) | |||
| { | ||||
| 	struct mlx4_en_priv *en_priv = netdev_priv(dev); | ||||
| 	struct mlx4_en_dev *mdev = en_priv->mdev; | ||||
| 	u64 mac_u64 = mlx4_mac_to_u64(mac); | ||||
| 
 | ||||
| 	if (is_multicast_ether_addr(mac)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); | ||||
| 	return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac); | ||||
| } | ||||
| 
 | ||||
| static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, | ||||
|  |  | |||
|  | @ -308,7 +308,7 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index, | |||
| int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx, | ||||
| 		      struct ifla_vf_stats *vf_stats); | ||||
| u32 mlx4_comm_get_version(void); | ||||
| int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); | ||||
| int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac); | ||||
| int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, | ||||
| 		     u8 qos, __be16 proto); | ||||
| int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate, | ||||
|  |  | |||
|  | @ -104,4 +104,14 @@ static inline u64 mlx4_mac_to_u64(u8 *addr) | |||
| 	return mac; | ||||
| } | ||||
| 
 | ||||
| static inline void mlx4_u64_to_mac(u8 *addr, u64 mac) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = ETH_ALEN; i > 0; i--) { | ||||
| 		addr[i - 1] = mac && 0xFF; | ||||
| 		mac >>= 8; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif /* MLX4_DRIVER_H */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eugenia Emantayev
						Eugenia Emantayev