diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/en_netdev.c')
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 86 | 
1 files changed, 46 insertions, 40 deletions
| diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index bb4d8d99f36..995d4b6d5c1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv)  	struct mlx4_en_dev *mdev = priv->mdev;  	struct mlx4_dev *dev = mdev->dev;  	int qpn = priv->base_qpn; -	u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); - -	en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", -	       priv->dev->dev_addr); -	mlx4_unregister_mac(dev, priv->port, mac); +	u64 mac; -	if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { +	if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) { +		mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); +		en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", +		       priv->dev->dev_addr); +		mlx4_unregister_mac(dev, priv->port, mac); +	} else {  		struct mlx4_mac_entry *entry;  		struct hlist_node *tmp;  		struct hlist_head *bucket; -		unsigned int mac_hash; +		unsigned int i; -		mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX]; -		bucket = &priv->mac_hash[mac_hash]; -		hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { -			if (ether_addr_equal_64bits(entry->mac, -						    priv->dev->dev_addr)) { -				en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n", -				       priv->port, priv->dev->dev_addr, qpn); +		for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) { +			bucket = &priv->mac_hash[i]; +			hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { +				mac = mlx4_en_mac_to_u64(entry->mac); +				en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", +				       entry->mac);  				mlx4_en_uc_steer_release(priv, entry->mac,  							 qpn, entry->reg_id); -				mlx4_qp_release_range(dev, qpn, 1); +				mlx4_unregister_mac(dev, priv->port, mac);  				hlist_del_rcu(&entry->hlist);  				kfree_rcu(entry, rcu); -				break;  			}  		} + +		en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n", +		       priv->port, qpn); +		mlx4_qp_release_range(dev, qpn, 1); +		priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC;  	}  } @@ -650,28 +654,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr)  	return mac;  } -static int mlx4_en_set_mac(struct net_device *dev, void *addr) -{ -	struct mlx4_en_priv *priv = netdev_priv(dev); -	struct mlx4_en_dev *mdev = priv->mdev; -	struct sockaddr *saddr = addr; - -	if (!is_valid_ether_addr(saddr->sa_data)) -		return -EADDRNOTAVAIL; - -	memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); -	queue_work(mdev->workqueue, &priv->mac_task); -	return 0; -} - -static void mlx4_en_do_set_mac(struct work_struct *work) +static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)  { -	struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, -						 mac_task); -	struct mlx4_en_dev *mdev = priv->mdev;  	int err = 0; -	mutex_lock(&mdev->state_lock);  	if (priv->port_up) {  		/* Remove old MAC and insert the new one */  		err = mlx4_en_replace_mac(priv, priv->base_qpn, @@ -683,7 +669,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work)  	} else  		en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); +	return err; +} + +static int mlx4_en_set_mac(struct net_device *dev, void *addr) +{ +	struct mlx4_en_priv *priv = netdev_priv(dev); +	struct mlx4_en_dev *mdev = priv->mdev; +	struct sockaddr *saddr = addr; +	int err; + +	if (!is_valid_ether_addr(saddr->sa_data)) +		return -EADDRNOTAVAIL; + +	memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); + +	mutex_lock(&mdev->state_lock); +	err = mlx4_en_do_set_mac(priv);  	mutex_unlock(&mdev->state_lock); + +	return err;  }  static void mlx4_en_clear_list(struct net_device *dev) @@ -1348,7 +1353,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)  		queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);  	}  	if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { -		queue_work(mdev->workqueue, &priv->mac_task); +		mlx4_en_do_set_mac(priv);  		mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;  	}  	mutex_unlock(&mdev->state_lock); @@ -1828,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)  	}  #ifdef CONFIG_RFS_ACCEL -	priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); -	if (!priv->dev->rx_cpu_rmap) -		goto err; +	if (priv->mdev->dev->caps.comp_pool) { +		priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); +		if (!priv->dev->rx_cpu_rmap) +			goto err; +	}  #endif  	return 0; @@ -2078,7 +2085,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,  	priv->msg_enable = MLX4_EN_MSG_LEVEL;  	spin_lock_init(&priv->stats_lock);  	INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); -	INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);  	INIT_WORK(&priv->watchdog_task, mlx4_en_restart);  	INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);  	INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); |