Commit 90683061 authored by Eugenia Emantayev's avatar Eugenia Emantayev Committed by David S. Miller
Browse files

net/mlx4_en: Fix HW timestamp init issue upon system startup



mlx4_en_init_timestamp was called before creation of netdev and port
init, thus used uninitialized values.  Specifically - NIC frequency was
incorrect causing wrong calculations and later wrong HW timestamps.

Fixes: 1ec4864b ('net/mlx4_en: Fixed crash when port type is changed')
Signed-off-by: default avatarEugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: default avatarMarina Varshaver <marinav@mellanox.com>
Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fc9f5ea9
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -242,6 +242,13 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
	unsigned long flags;
	unsigned long flags;
	u64 ns, zero = 0;
	u64 ns, zero = 0;


	/* mlx4_en_init_timestamp is called for each netdev.
	 * mdev->ptp_clock is common for all ports, skip initialization if
	 * was done for other port.
	 */
	if (mdev->ptp_clock)
		return;

	rwlock_init(&mdev->clock_lock);
	rwlock_init(&mdev->clock_lock);


	memset(&mdev->cycles, 0, sizeof(mdev->cycles));
	memset(&mdev->cycles, 0, sizeof(mdev->cycles));
+0 −7
Original line number Original line Diff line number Diff line
@@ -232,9 +232,6 @@ static void mlx4_en_remove(struct mlx4_dev *dev, void *endev_ptr)
		if (mdev->pndev[i])
		if (mdev->pndev[i])
			mlx4_en_destroy_netdev(mdev->pndev[i]);
			mlx4_en_destroy_netdev(mdev->pndev[i]);


	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
		mlx4_en_remove_timestamp(mdev);

	flush_workqueue(mdev->workqueue);
	flush_workqueue(mdev->workqueue);
	destroy_workqueue(mdev->workqueue);
	destroy_workqueue(mdev->workqueue);
	(void) mlx4_mr_free(dev, &mdev->mr);
	(void) mlx4_mr_free(dev, &mdev->mr);
@@ -320,10 +317,6 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
	mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
	mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
		mdev->port_cnt++;
		mdev->port_cnt++;


	/* Initialize time stamp mechanism */
	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
		mlx4_en_init_timestamp(mdev);

	/* Set default number of RX rings*/
	/* Set default number of RX rings*/
	mlx4_en_set_num_rx_rings(mdev);
	mlx4_en_set_num_rx_rings(mdev);


+7 −0
Original line number Original line Diff line number Diff line
@@ -2072,6 +2072,9 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
	/* flush any pending task for this netdev */
	/* flush any pending task for this netdev */
	flush_workqueue(mdev->workqueue);
	flush_workqueue(mdev->workqueue);


	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
		mlx4_en_remove_timestamp(mdev);

	/* Detach the netdev so tasks would not attempt to access it */
	/* Detach the netdev so tasks would not attempt to access it */
	mutex_lock(&mdev->state_lock);
	mutex_lock(&mdev->state_lock);
	mdev->pndev[priv->port] = NULL;
	mdev->pndev[priv->port] = NULL;
@@ -3058,6 +3061,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
	}
	}
	queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
	queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);


	/* Initialize time stamp mechanism */
	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
		mlx4_en_init_timestamp(mdev);

	queue_delayed_work(mdev->workqueue, &priv->service_task,
	queue_delayed_work(mdev->workqueue, &priv->service_task,
			   SERVICE_TASK_DELAY);
			   SERVICE_TASK_DELAY);